/* Minification failed. Returning unminified contents.
(53029,17-18): run-time error JS1195: Expected expression: )
(53029,20-21): run-time error JS1195: Expected expression: >
(53032,6-7): run-time error JS1195: Expected expression: ,
(53034,5-6): run-time error JS1007: Expected ']': ;
(53035,1-2): run-time error JS1002: Syntax error: }
(53037,41-42): run-time error JS1004: Expected ';': {
(53122,7-8): run-time error JS1002: Syntax error: }
(53124,34-35): run-time error JS1004: Expected ';': {
(53136,8-9): run-time error JS1195: Expected expression: )
(53138,34-35): run-time error JS1004: Expected ';': {
(53169,8-9): run-time error JS1195: Expected expression: )
(53171,34-35): run-time error JS1004: Expected ';': {
(53175,8-9): run-time error JS1195: Expected expression: )
(53177,34-35): run-time error JS1004: Expected ';': {
(53181,8-9): run-time error JS1195: Expected expression: )
(53183,34-35): run-time error JS1004: Expected ';': {
(53187,8-9): run-time error JS1195: Expected expression: )
(53189,55-56): run-time error JS1004: Expected ';': {
(53227,8-9): run-time error JS1195: Expected expression: )
 */
//     Underscore.js 1.5.2
//     http://underscorejs.org
//     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
//     Underscore may be freely distributed under the MIT license.
(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,w=Object.keys,_=i.bind,j=function(n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.5.2";var A=j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a=j.keys(n),u=0,i=a.length;i>u;u++)if(t.call(e,n[a[u]],a[u],n)===r)return};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var E="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(E);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(E);return r},j.find=j.detect=function(n,t,r){var e;return O(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var O=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:O(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,function(n){return n[t]})},j.where=function(n,t,r){return j.isEmpty(t)?r?void 0:[]:j[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},j.findWhere=function(n,t){return j.where(n,t,!0)},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&j.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&j.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a<e.computed&&(e={value:n,computed:a})}),e.value},j.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=j.random(r++),e[r-1]=e[t],e[t]=n}),e},j.sample=function(n,t,r){return arguments.length<2||r?n[j.random(n.length-1)]:j.shuffle(n).slice(0,Math.max(0,t))};var k=function(n){return j.isFunction(n)?n:function(t){return t[n]}};j.sortBy=function(n,t,r){var e=k(t);return j.pluck(j.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={},i=null==r?j.identity:k(r);return A(t,function(r,a){var o=i.call(e,r,a,t);n(u,o,r)}),u}};j.groupBy=F(function(n,t,r){(j.has(n,t)?n[t]:n[t]=[]).push(r)}),j.indexBy=F(function(n,t,r){n[t]=r}),j.countBy=F(function(n,t){j.has(n,t)?n[t]++:n[t]=1}),j.sortedIndex=function(n,t,r,e){r=null==r?j.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])<u?i=o+1:a=o}return i},j.toArray=function(n){return n?j.isArray(n)?o.call(n):n.length===+n.length?j.map(n,j.identity):j.values(n):[]},j.size=function(n){return null==n?0:n.length===+n.length?n.length:j.keys(n).length},j.first=j.head=j.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},j.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},j.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},j.rest=j.tail=j.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},j.compact=function(n){return j.filter(n,j.identity)};var M=function(n,t,r){return t&&j.every(n,j.isArray)?c.apply(r,n):(A(n,function(n){j.isArray(n)||j.isArguments(n)?t?a.apply(r,n):M(n,t,r):r.push(n)}),r)};j.flatten=function(n,t){return M(n,t,[])},j.without=function(n){return j.difference(n,o.call(arguments,1))},j.uniq=j.unique=function(n,t,r,e){j.isFunction(t)&&(e=r,r=t,t=!1);var u=r?j.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:j.contains(a,r))||(a.push(r),i.push(n[e]))}),i},j.union=function(){return j.uniq(j.flatten(arguments,!0))},j.intersection=function(n){var t=o.call(arguments,1);return j.filter(j.uniq(n),function(n){return j.every(t,function(t){return j.indexOf(t,n)>=0})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var R=function(){};j.bind=function(n,t){var r,e;if(_&&n.bind===_)return _.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));R.prototype=n.prototype;var u=new R;R.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u,i,a,o;return function(){i=this,u=arguments,a=new Date;var c=function(){var l=new Date-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u)))},l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u)),o}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=w||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},j.pairs=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},j.invert=function(n){for(var t={},r=j.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var I={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"}};I.unescape=j.invert(I.escape);var T={escape:new RegExp("["+j.keys(I.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(I.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(T[n],function(t){return I[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);
;
/******/ (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 = "/resources/js/";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 148);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

var ChocolateyPackages = __webpack_require__(110);
var cssdk = __webpack_require__(12);

var angular = __webpack_require__(38);

module.exports = angular.module("chocolateyClient", ['ngSanitize'])
.factory("chocolateyPackages", ["chocolateyClientConfig", function(chocolateyClientConfig) {
	return new ChocolateyPackages(cssdk, chocolateyClientConfig);
}])
.provider("chocolateyClientConfig", function() {
	this.cloudShareHostname = window.location.host;
	this.apiId = null;
	this.apiKey = null;
	this.chocolateyIconSmallImagePath = "/resources/imgs/chocolateyicon_white_small.png";
	this.preloaderImagePath = "/resources/imgs/csapp/create/preloader.gif";

	this.$get = function() {
		return {
			cloudShareHostname: this.cloudShareHostname,
			apiId: this.apiId,
			apiKey: this.apiKey,
			chocolateyIconSmallImagePath: this.chocolateyIconSmallImagePath,
			preloaderImagePath: this.preloaderImagePath
		};
	};
});



/***/ }),
/* 1 */
/***/ (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
  }
}


/***/ }),
/* 2 */
/***/ (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__(47)
var ieee754 = __webpack_require__(90)
var isArray = __webpack_require__(33)

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__(4)))

/***/ }),
/* 3 */
/***/ (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__(20);
/*</replacement>*/

/*<replacement>*/
var util = __webpack_require__(7);
util.inherits = __webpack_require__(1);
/*</replacement>*/

var Readable = __webpack_require__(35);
var Writable = __webpack_require__(22);

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);
  }
}

/***/ }),
/* 4 */
/***/ (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;


/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(process, global) {var require;/*!
 * @overview es6-promise - a tiny implementation of Promises/A+.
 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
 * @license   Licensed under MIT license
 *            See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
 * @version   3.3.1
 */

(function (global, factory) {
     true ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global.ES6Promise = factory());
}(this, (function () { 'use strict';

function objectOrFunction(x) {
  return typeof x === 'function' || typeof x === 'object' && x !== null;
}

function isFunction(x) {
  return typeof x === 'function';
}

var _isArray = undefined;
if (!Array.isArray) {
  _isArray = function (x) {
    return Object.prototype.toString.call(x) === '[object Array]';
  };
} else {
  _isArray = Array.isArray;
}

var isArray = _isArray;

var len = 0;
var vertxNext = undefined;
var customSchedulerFn = undefined;

var asap = function asap(callback, arg) {
  queue[len] = callback;
  queue[len + 1] = arg;
  len += 2;
  if (len === 2) {
    // If len is 2, that means that we need to schedule an async flush.
    // If additional callbacks are queued before the queue is flushed, they
    // will be processed by this flush that we are scheduling.
    if (customSchedulerFn) {
      customSchedulerFn(flush);
    } else {
      scheduleFlush();
    }
  }
};

function setScheduler(scheduleFn) {
  customSchedulerFn = scheduleFn;
}

function setAsap(asapFn) {
  asap = asapFn;
}

var browserWindow = typeof window !== 'undefined' ? window : undefined;
var browserGlobal = browserWindow || {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';

// test for web worker but not in IE10
var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';

// node
function useNextTick() {
  // node version 0.10.x displays a deprecation warning when nextTick is used recursively
  // see https://github.com/cujojs/when/issues/410 for details
  return function () {
    return process.nextTick(flush);
  };
}

// vertx
function useVertxTimer() {
  return function () {
    vertxNext(flush);
  };
}

function useMutationObserver() {
  var iterations = 0;
  var observer = new BrowserMutationObserver(flush);
  var node = document.createTextNode('');
  observer.observe(node, { characterData: true });

  return function () {
    node.data = iterations = ++iterations % 2;
  };
}

// web worker
function useMessageChannel() {
  var channel = new MessageChannel();
  channel.port1.onmessage = flush;
  return function () {
    return channel.port2.postMessage(0);
  };
}

function useSetTimeout() {
  // Store setTimeout reference so es6-promise will be unaffected by
  // other code modifying setTimeout (like sinon.useFakeTimers())
  var globalSetTimeout = setTimeout;
  return function () {
    return globalSetTimeout(flush, 1);
  };
}

var queue = new Array(1000);
function flush() {
  for (var i = 0; i < len; i += 2) {
    var callback = queue[i];
    var arg = queue[i + 1];

    callback(arg);

    queue[i] = undefined;
    queue[i + 1] = undefined;
  }

  len = 0;
}

function attemptVertx() {
  try {
    var r = require;
    var vertx = __webpack_require__(145);
    vertxNext = vertx.runOnLoop || vertx.runOnContext;
    return useVertxTimer();
  } catch (e) {
    return useSetTimeout();
  }
}

var scheduleFlush = undefined;
// Decide what async method to use to triggering processing of queued callbacks:
if (isNode) {
  scheduleFlush = useNextTick();
} else if (BrowserMutationObserver) {
  scheduleFlush = useMutationObserver();
} else if (isWorker) {
  scheduleFlush = useMessageChannel();
} else if (browserWindow === undefined && "function" === 'function') {
  scheduleFlush = attemptVertx();
} else {
  scheduleFlush = useSetTimeout();
}

function then(onFulfillment, onRejection) {
  var _arguments = arguments;

  var parent = this;

  var child = new this.constructor(noop);

  if (child[PROMISE_ID] === undefined) {
    makePromise(child);
  }

  var _state = parent._state;

  if (_state) {
    (function () {
      var callback = _arguments[_state - 1];
      asap(function () {
        return invokeCallback(_state, child, callback, parent._result);
      });
    })();
  } else {
    subscribe(parent, child, onFulfillment, onRejection);
  }

  return child;
}

/**
  `Promise.resolve` returns a promise that will become resolved with the
  passed `value`. It is shorthand for the following:

  ```javascript
  let promise = new Promise(function(resolve, reject){
    resolve(1);
  });

  promise.then(function(value){
    // value === 1
  });
  ```

  Instead of writing the above, your code now simply becomes the following:

  ```javascript
  let promise = Promise.resolve(1);

  promise.then(function(value){
    // value === 1
  });
  ```

  @method resolve
  @static
  @param {Any} value value that the returned promise will be resolved with
  Useful for tooling.
  @return {Promise} a promise that will become fulfilled with the given
  `value`
*/
function resolve(object) {
  /*jshint validthis:true */
  var Constructor = this;

  if (object && typeof object === 'object' && object.constructor === Constructor) {
    return object;
  }

  var promise = new Constructor(noop);
  _resolve(promise, object);
  return promise;
}

var PROMISE_ID = Math.random().toString(36).substring(16);

function noop() {}

var PENDING = void 0;
var FULFILLED = 1;
var REJECTED = 2;

var GET_THEN_ERROR = new ErrorObject();

function selfFulfillment() {
  return new TypeError("You cannot resolve a promise with itself");
}

function cannotReturnOwn() {
  return new TypeError('A promises callback cannot return that same promise.');
}

function getThen(promise) {
  try {
    return promise.then;
  } catch (error) {
    GET_THEN_ERROR.error = error;
    return GET_THEN_ERROR;
  }
}

function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
  try {
    then.call(value, fulfillmentHandler, rejectionHandler);
  } catch (e) {
    return e;
  }
}

function handleForeignThenable(promise, thenable, then) {
  asap(function (promise) {
    var sealed = false;
    var error = tryThen(then, thenable, function (value) {
      if (sealed) {
        return;
      }
      sealed = true;
      if (thenable !== value) {
        _resolve(promise, value);
      } else {
        fulfill(promise, value);
      }
    }, function (reason) {
      if (sealed) {
        return;
      }
      sealed = true;

      _reject(promise, reason);
    }, 'Settle: ' + (promise._label || ' unknown promise'));

    if (!sealed && error) {
      sealed = true;
      _reject(promise, error);
    }
  }, promise);
}

function handleOwnThenable(promise, thenable) {
  if (thenable._state === FULFILLED) {
    fulfill(promise, thenable._result);
  } else if (thenable._state === REJECTED) {
    _reject(promise, thenable._result);
  } else {
    subscribe(thenable, undefined, function (value) {
      return _resolve(promise, value);
    }, function (reason) {
      return _reject(promise, reason);
    });
  }
}

function handleMaybeThenable(promise, maybeThenable, then$$) {
  if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) {
    handleOwnThenable(promise, maybeThenable);
  } else {
    if (then$$ === GET_THEN_ERROR) {
      _reject(promise, GET_THEN_ERROR.error);
    } else if (then$$ === undefined) {
      fulfill(promise, maybeThenable);
    } else if (isFunction(then$$)) {
      handleForeignThenable(promise, maybeThenable, then$$);
    } else {
      fulfill(promise, maybeThenable);
    }
  }
}

function _resolve(promise, value) {
  if (promise === value) {
    _reject(promise, selfFulfillment());
  } else if (objectOrFunction(value)) {
    handleMaybeThenable(promise, value, getThen(value));
  } else {
    fulfill(promise, value);
  }
}

function publishRejection(promise) {
  if (promise._onerror) {
    promise._onerror(promise._result);
  }

  publish(promise);
}

function fulfill(promise, value) {
  if (promise._state !== PENDING) {
    return;
  }

  promise._result = value;
  promise._state = FULFILLED;

  if (promise._subscribers.length !== 0) {
    asap(publish, promise);
  }
}

function _reject(promise, reason) {
  if (promise._state !== PENDING) {
    return;
  }
  promise._state = REJECTED;
  promise._result = reason;

  asap(publishRejection, promise);
}

function subscribe(parent, child, onFulfillment, onRejection) {
  var _subscribers = parent._subscribers;
  var length = _subscribers.length;

  parent._onerror = null;

  _subscribers[length] = child;
  _subscribers[length + FULFILLED] = onFulfillment;
  _subscribers[length + REJECTED] = onRejection;

  if (length === 0 && parent._state) {
    asap(publish, parent);
  }
}

function publish(promise) {
  var subscribers = promise._subscribers;
  var settled = promise._state;

  if (subscribers.length === 0) {
    return;
  }

  var child = undefined,
      callback = undefined,
      detail = promise._result;

  for (var i = 0; i < subscribers.length; i += 3) {
    child = subscribers[i];
    callback = subscribers[i + settled];

    if (child) {
      invokeCallback(settled, child, callback, detail);
    } else {
      callback(detail);
    }
  }

  promise._subscribers.length = 0;
}

function ErrorObject() {
  this.error = null;
}

var TRY_CATCH_ERROR = new ErrorObject();

function tryCatch(callback, detail) {
  try {
    return callback(detail);
  } catch (e) {
    TRY_CATCH_ERROR.error = e;
    return TRY_CATCH_ERROR;
  }
}

function invokeCallback(settled, promise, callback, detail) {
  var hasCallback = isFunction(callback),
      value = undefined,
      error = undefined,
      succeeded = undefined,
      failed = undefined;

  if (hasCallback) {
    value = tryCatch(callback, detail);

    if (value === TRY_CATCH_ERROR) {
      failed = true;
      error = value.error;
      value = null;
    } else {
      succeeded = true;
    }

    if (promise === value) {
      _reject(promise, cannotReturnOwn());
      return;
    }
  } else {
    value = detail;
    succeeded = true;
  }

  if (promise._state !== PENDING) {
    // noop
  } else if (hasCallback && succeeded) {
      _resolve(promise, value);
    } else if (failed) {
      _reject(promise, error);
    } else if (settled === FULFILLED) {
      fulfill(promise, value);
    } else if (settled === REJECTED) {
      _reject(promise, value);
    }
}

function initializePromise(promise, resolver) {
  try {
    resolver(function resolvePromise(value) {
      _resolve(promise, value);
    }, function rejectPromise(reason) {
      _reject(promise, reason);
    });
  } catch (e) {
    _reject(promise, e);
  }
}

var id = 0;
function nextId() {
  return id++;
}

function makePromise(promise) {
  promise[PROMISE_ID] = id++;
  promise._state = undefined;
  promise._result = undefined;
  promise._subscribers = [];
}

function Enumerator(Constructor, input) {
  this._instanceConstructor = Constructor;
  this.promise = new Constructor(noop);

  if (!this.promise[PROMISE_ID]) {
    makePromise(this.promise);
  }

  if (isArray(input)) {
    this._input = input;
    this.length = input.length;
    this._remaining = input.length;

    this._result = new Array(this.length);

    if (this.length === 0) {
      fulfill(this.promise, this._result);
    } else {
      this.length = this.length || 0;
      this._enumerate();
      if (this._remaining === 0) {
        fulfill(this.promise, this._result);
      }
    }
  } else {
    _reject(this.promise, validationError());
  }
}

function validationError() {
  return new Error('Array Methods must be provided an Array');
};

Enumerator.prototype._enumerate = function () {
  var length = this.length;
  var _input = this._input;

  for (var i = 0; this._state === PENDING && i < length; i++) {
    this._eachEntry(_input[i], i);
  }
};

Enumerator.prototype._eachEntry = function (entry, i) {
  var c = this._instanceConstructor;
  var resolve$$ = c.resolve;

  if (resolve$$ === resolve) {
    var _then = getThen(entry);

    if (_then === then && entry._state !== PENDING) {
      this._settledAt(entry._state, i, entry._result);
    } else if (typeof _then !== 'function') {
      this._remaining--;
      this._result[i] = entry;
    } else if (c === Promise) {
      var promise = new c(noop);
      handleMaybeThenable(promise, entry, _then);
      this._willSettleAt(promise, i);
    } else {
      this._willSettleAt(new c(function (resolve$$) {
        return resolve$$(entry);
      }), i);
    }
  } else {
    this._willSettleAt(resolve$$(entry), i);
  }
};

Enumerator.prototype._settledAt = function (state, i, value) {
  var promise = this.promise;

  if (promise._state === PENDING) {
    this._remaining--;

    if (state === REJECTED) {
      _reject(promise, value);
    } else {
      this._result[i] = value;
    }
  }

  if (this._remaining === 0) {
    fulfill(promise, this._result);
  }
};

Enumerator.prototype._willSettleAt = function (promise, i) {
  var enumerator = this;

  subscribe(promise, undefined, function (value) {
    return enumerator._settledAt(FULFILLED, i, value);
  }, function (reason) {
    return enumerator._settledAt(REJECTED, i, reason);
  });
};

/**
  `Promise.all` accepts an array of promises, and returns a new promise which
  is fulfilled with an array of fulfillment values for the passed promises, or
  rejected with the reason of the first passed promise to be rejected. It casts all
  elements of the passed iterable to promises as it runs this algorithm.

  Example:

  ```javascript
  let promise1 = resolve(1);
  let promise2 = resolve(2);
  let promise3 = resolve(3);
  let promises = [ promise1, promise2, promise3 ];

  Promise.all(promises).then(function(array){
    // The array here would be [ 1, 2, 3 ];
  });
  ```

  If any of the `promises` given to `all` are rejected, the first promise
  that is rejected will be given as an argument to the returned promises's
  rejection handler. For example:

  Example:

  ```javascript
  let promise1 = resolve(1);
  let promise2 = reject(new Error("2"));
  let promise3 = reject(new Error("3"));
  let promises = [ promise1, promise2, promise3 ];

  Promise.all(promises).then(function(array){
    // Code here never runs because there are rejected promises!
  }, function(error) {
    // error.message === "2"
  });
  ```

  @method all
  @static
  @param {Array} entries array of promises
  @param {String} label optional string for labeling the promise.
  Useful for tooling.
  @return {Promise} promise that is fulfilled when all `promises` have been
  fulfilled, or rejected if any of them become rejected.
  @static
*/
function all(entries) {
  return new Enumerator(this, entries).promise;
}

/**
  `Promise.race` returns a new promise which is settled in the same way as the
  first passed promise to settle.

  Example:

  ```javascript
  let promise1 = new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve('promise 1');
    }, 200);
  });

  let promise2 = new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve('promise 2');
    }, 100);
  });

  Promise.race([promise1, promise2]).then(function(result){
    // result === 'promise 2' because it was resolved before promise1
    // was resolved.
  });
  ```

  `Promise.race` is deterministic in that only the state of the first
  settled promise matters. For example, even if other promises given to the
  `promises` array argument are resolved, but the first settled promise has
  become rejected before the other promises became fulfilled, the returned
  promise will become rejected:

  ```javascript
  let promise1 = new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve('promise 1');
    }, 200);
  });

  let promise2 = new Promise(function(resolve, reject){
    setTimeout(function(){
      reject(new Error('promise 2'));
    }, 100);
  });

  Promise.race([promise1, promise2]).then(function(result){
    // Code here never runs
  }, function(reason){
    // reason.message === 'promise 2' because promise 2 became rejected before
    // promise 1 became fulfilled
  });
  ```

  An example real-world use case is implementing timeouts:

  ```javascript
  Promise.race([ajax('foo.json'), timeout(5000)])
  ```

  @method race
  @static
  @param {Array} promises array of promises to observe
  Useful for tooling.
  @return {Promise} a promise which settles in the same way as the first passed
  promise to settle.
*/
function race(entries) {
  /*jshint validthis:true */
  var Constructor = this;

  if (!isArray(entries)) {
    return new Constructor(function (_, reject) {
      return reject(new TypeError('You must pass an array to race.'));
    });
  } else {
    return new Constructor(function (resolve, reject) {
      var length = entries.length;
      for (var i = 0; i < length; i++) {
        Constructor.resolve(entries[i]).then(resolve, reject);
      }
    });
  }
}

/**
  `Promise.reject` returns a promise rejected with the passed `reason`.
  It is shorthand for the following:

  ```javascript
  let promise = new Promise(function(resolve, reject){
    reject(new Error('WHOOPS'));
  });

  promise.then(function(value){
    // Code here doesn't run because the promise is rejected!
  }, function(reason){
    // reason.message === 'WHOOPS'
  });
  ```

  Instead of writing the above, your code now simply becomes the following:

  ```javascript
  let promise = Promise.reject(new Error('WHOOPS'));

  promise.then(function(value){
    // Code here doesn't run because the promise is rejected!
  }, function(reason){
    // reason.message === 'WHOOPS'
  });
  ```

  @method reject
  @static
  @param {Any} reason value that the returned promise will be rejected with.
  Useful for tooling.
  @return {Promise} a promise rejected with the given `reason`.
*/
function reject(reason) {
  /*jshint validthis:true */
  var Constructor = this;
  var promise = new Constructor(noop);
  _reject(promise, reason);
  return promise;
}

function needsResolver() {
  throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}

function needsNew() {
  throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}

/**
  Promise objects represent the eventual result of an asynchronous operation. The
  primary way of interacting with a promise is through its `then` method, which
  registers callbacks to receive either a promise's eventual value or the reason
  why the promise cannot be fulfilled.

  Terminology
  -----------

  - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
  - `thenable` is an object or function that defines a `then` method.
  - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
  - `exception` is a value that is thrown using the throw statement.
  - `reason` is a value that indicates why a promise was rejected.
  - `settled` the final resting state of a promise, fulfilled or rejected.

  A promise can be in one of three states: pending, fulfilled, or rejected.

  Promises that are fulfilled have a fulfillment value and are in the fulfilled
  state.  Promises that are rejected have a rejection reason and are in the
  rejected state.  A fulfillment value is never a thenable.

  Promises can also be said to *resolve* a value.  If this value is also a
  promise, then the original promise's settled state will match the value's
  settled state.  So a promise that *resolves* a promise that rejects will
  itself reject, and a promise that *resolves* a promise that fulfills will
  itself fulfill.


  Basic Usage:
  ------------

  ```js
  let promise = new Promise(function(resolve, reject) {
    // on success
    resolve(value);

    // on failure
    reject(reason);
  });

  promise.then(function(value) {
    // on fulfillment
  }, function(reason) {
    // on rejection
  });
  ```

  Advanced Usage:
  ---------------

  Promises shine when abstracting away asynchronous interactions such as
  `XMLHttpRequest`s.

  ```js
  function getJSON(url) {
    return new Promise(function(resolve, reject){
      let xhr = new XMLHttpRequest();

      xhr.open('GET', url);
      xhr.onreadystatechange = handler;
      xhr.responseType = 'json';
      xhr.setRequestHeader('Accept', 'application/json');
      xhr.send();

      function handler() {
        if (this.readyState === this.DONE) {
          if (this.status === 200) {
            resolve(this.response);
          } else {
            reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
          }
        }
      };
    });
  }

  getJSON('/posts.json').then(function(json) {
    // on fulfillment
  }, function(reason) {
    // on rejection
  });
  ```

  Unlike callbacks, promises are great composable primitives.

  ```js
  Promise.all([
    getJSON('/posts'),
    getJSON('/comments')
  ]).then(function(values){
    values[0] // => postsJSON
    values[1] // => commentsJSON

    return values;
  });
  ```

  @class Promise
  @param {function} resolver
  Useful for tooling.
  @constructor
*/
function Promise(resolver) {
  this[PROMISE_ID] = nextId();
  this._result = this._state = undefined;
  this._subscribers = [];

  if (noop !== resolver) {
    typeof resolver !== 'function' && needsResolver();
    this instanceof Promise ? initializePromise(this, resolver) : needsNew();
  }
}

Promise.all = all;
Promise.race = race;
Promise.resolve = resolve;
Promise.reject = reject;
Promise._setScheduler = setScheduler;
Promise._setAsap = setAsap;
Promise._asap = asap;

Promise.prototype = {
  constructor: Promise,

  /**
    The primary way of interacting with a promise is through its `then` method,
    which registers callbacks to receive either a promise's eventual value or the
    reason why the promise cannot be fulfilled.
  
    ```js
    findUser().then(function(user){
      // user is available
    }, function(reason){
      // user is unavailable, and you are given the reason why
    });
    ```
  
    Chaining
    --------
  
    The return value of `then` is itself a promise.  This second, 'downstream'
    promise is resolved with the return value of the first promise's fulfillment
    or rejection handler, or rejected if the handler throws an exception.
  
    ```js
    findUser().then(function (user) {
      return user.name;
    }, function (reason) {
      return 'default name';
    }).then(function (userName) {
      // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
      // will be `'default name'`
    });
  
    findUser().then(function (user) {
      throw new Error('Found user, but still unhappy');
    }, function (reason) {
      throw new Error('`findUser` rejected and we're unhappy');
    }).then(function (value) {
      // never reached
    }, function (reason) {
      // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
      // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
    });
    ```
    If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
  
    ```js
    findUser().then(function (user) {
      throw new PedagogicalException('Upstream error');
    }).then(function (value) {
      // never reached
    }).then(function (value) {
      // never reached
    }, function (reason) {
      // The `PedgagocialException` is propagated all the way down to here
    });
    ```
  
    Assimilation
    ------------
  
    Sometimes the value you want to propagate to a downstream promise can only be
    retrieved asynchronously. This can be achieved by returning a promise in the
    fulfillment or rejection handler. The downstream promise will then be pending
    until the returned promise is settled. This is called *assimilation*.
  
    ```js
    findUser().then(function (user) {
      return findCommentsByAuthor(user);
    }).then(function (comments) {
      // The user's comments are now available
    });
    ```
  
    If the assimliated promise rejects, then the downstream promise will also reject.
  
    ```js
    findUser().then(function (user) {
      return findCommentsByAuthor(user);
    }).then(function (comments) {
      // If `findCommentsByAuthor` fulfills, we'll have the value here
    }, function (reason) {
      // If `findCommentsByAuthor` rejects, we'll have the reason here
    });
    ```
  
    Simple Example
    --------------
  
    Synchronous Example
  
    ```javascript
    let result;
  
    try {
      result = findResult();
      // success
    } catch(reason) {
      // failure
    }
    ```
  
    Errback Example
  
    ```js
    findResult(function(result, err){
      if (err) {
        // failure
      } else {
        // success
      }
    });
    ```
  
    Promise Example;
  
    ```javascript
    findResult().then(function(result){
      // success
    }, function(reason){
      // failure
    });
    ```
  
    Advanced Example
    --------------
  
    Synchronous Example
  
    ```javascript
    let author, books;
  
    try {
      author = findAuthor();
      books  = findBooksByAuthor(author);
      // success
    } catch(reason) {
      // failure
    }
    ```
  
    Errback Example
  
    ```js
  
    function foundBooks(books) {
  
    }
  
    function failure(reason) {
  
    }
  
    findAuthor(function(author, err){
      if (err) {
        failure(err);
        // failure
      } else {
        try {
          findBoooksByAuthor(author, function(books, err) {
            if (err) {
              failure(err);
            } else {
              try {
                foundBooks(books);
              } catch(reason) {
                failure(reason);
              }
            }
          });
        } catch(error) {
          failure(err);
        }
        // success
      }
    });
    ```
  
    Promise Example;
  
    ```javascript
    findAuthor().
      then(findBooksByAuthor).
      then(function(books){
        // found books
    }).catch(function(reason){
      // something went wrong
    });
    ```
  
    @method then
    @param {Function} onFulfilled
    @param {Function} onRejected
    Useful for tooling.
    @return {Promise}
  */
  then: then,

  /**
    `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
    as the catch block of a try/catch statement.
  
    ```js
    function findAuthor(){
      throw new Error('couldn't find that author');
    }
  
    // synchronous
    try {
      findAuthor();
    } catch(reason) {
      // something went wrong
    }
  
    // async with promises
    findAuthor().catch(function(reason){
      // something went wrong
    });
    ```
  
    @method catch
    @param {Function} onRejection
    Useful for tooling.
    @return {Promise}
  */
  'catch': function _catch(onRejection) {
    return this.then(null, onRejection);
  }
};

function polyfill() {
    var local = undefined;

    if (typeof global !== 'undefined') {
        local = global;
    } else if (typeof self !== 'undefined') {
        local = self;
    } else {
        try {
            local = Function('return this')();
        } catch (e) {
            throw new Error('polyfill failed because global object is unavailable in this environment');
        }
    }

    var P = local.Promise;

    if (P) {
        var promiseToString = null;
        try {
            promiseToString = Object.prototype.toString.call(P.resolve());
        } catch (e) {
            // silently ignored
        }

        if (promiseToString === '[object Promise]' && !P.cast) {
            return;
        }
    }

    local.Promise = Promise;
}

polyfill();
// Strange compat..
Promise.polyfill = polyfill;
Promise.Promise = Promise;

return Promise;

})));
//# sourceMappingURL=es6-promise.map
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6), __webpack_require__(4)))

/***/ }),
/* 6 */
/***/ (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; };


/***/ }),
/* 7 */
/***/ (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__(2).Buffer))

/***/ }),
/* 8 */
/***/ (function(module, exports) {

//Types of elements found in the DOM
module.exports = {
	Text: "text", //Text
	Directive: "directive", //<? ... ?>
	Comment: "comment", //<!-- ... -->
	Script: "script", //<script> tags
	Style: "style", //<style> tags
	Tag: "tag", //Any tag
	CDATA: "cdata", //<![CDATA[ ... ]]>
	Doctype: "doctype",

	isTag: function(elem){
		return elem.type === "tag" || elem.type === "script" || elem.type === "style";
	}
};


/***/ }),
/* 9 */
/***/ (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;
}


/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

var Parser = __webpack_require__(30),
    DomHandler = __webpack_require__(54);

function defineProp(name, value){
	delete module.exports[name];
	module.exports[name] = value;
	return value;
}

module.exports = {
	Parser: Parser,
	Tokenizer: __webpack_require__(31),
	ElementType: __webpack_require__(8),
	DomHandler: DomHandler,
	get FeedHandler(){
		return defineProp("FeedHandler", __webpack_require__(87));
	},
	get Stream(){
		return defineProp("Stream", __webpack_require__(89));
	},
	get WritableStream(){
		return defineProp("WritableStream", __webpack_require__(32));
	},
	get ProxyHandler(){
		return defineProp("ProxyHandler", __webpack_require__(88));
	},
	get DomUtils(){
		return defineProp("DomUtils", __webpack_require__(56));
	},
	get CollectingHandler(){
		return defineProp("CollectingHandler", __webpack_require__(86));
	},
	// For legacy support
	DefaultHandler: DomHandler,
	get RssHandler(){
		return defineProp("RssHandler", this.FeedHandler);
	},
	//helper methods
	parseDOM: function(data, options){
		var handler = new DomHandler(options);
		new Parser(handler, options).end(data);
		return handler.dom;
	},
	parseFeed: function(feed, options){
		var handler = new module.exports.FeedHandler(options);
		new Parser(handler, options).end(feed);
		return handler.dom;
	},
	createDomStream: function(cb, options, elementCb){
		var handler = new DomHandler(cb, options, elementCb);
		return new Parser(handler, options);
	},
	// List of all events that the parser emits
	EVENTS: { /* Format: eventname: number of arguments */
		attribute: 2,
		cdatastart: 0,
		cdataend: 0,
		text: 1,
		processinginstruction: 2,
		comment: 1,
		commentend: 0,
		closetag: 1,
		opentag: 2,
		opentagname: 1,
		error: 1,
		end: 0
	}
};


/***/ }),
/* 11 */
/***/ (function(module, exports) {

module.exports = jQuery;

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

/*
@license
Copyright 2015 CloudShare Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var bottle = __webpack_require__(126);

module.exports = bottle.container.CloudShareClient;

/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(module, global) {var __WEBPACK_AMD_DEFINE_RESULT__;;(function(undefined) {
    'use strict';
    /**
     * BottleJS v1.6.0 - 2017-02-22
     * A powerful dependency injection micro container
     *
     * Copyright (c) 2017 Stephen Young
     * Licensed MIT
     */
    
    /**
     * Unique id counter;
     *
     * @type Number
     */
    var id = 0;
    
    /**
     * Local slice alias
     *
     * @type Functions
     */
    var slice = Array.prototype.slice;
    
    /**
     * Iterator used to walk down a nested object.
     *
     * If Bottle.config.strict is true, this method will throw an exception if it encounters an
     * undefined path
     *
     * @param Object obj
     * @param String prop
     * @return mixed
     * @throws Error if Bottle is unable to resolve the requested service.
     */
    var getNested = function getNested(obj, prop) {
        var service = obj[prop];
        if (service === undefined && globalConfig.strict) {
            throw new Error('Bottle was unable to resolve a service.  `' + prop + '` is undefined.');
        }
        return service;
    };
    
    /**
     * Get a nested bottle. Will set and return if not set.
     *
     * @param String name
     * @return Bottle
     */
    var getNestedBottle = function getNestedBottle(name) {
        return this.nested[name] || (this.nested[name] = Bottle.pop());
    };
    
    /**
     * Get a service stored under a nested key
     *
     * @param String fullname
     * @return Service
     */
    var getNestedService = function getNestedService(fullname) {
        return fullname.split('.').reduce(getNested, this);
    };
    
    /**
     * Register a constant
     *
     * @param String name
     * @param mixed value
     * @return Bottle
     */
    var constant = function constant(name, value) {
        var parts = name.split('.');
        name = parts.pop();
        defineConstant.call(parts.reduce(setValueObject, this.container), name, value);
        return this;
    };
    
    var defineConstant = function defineConstant(name, value) {
        Object.defineProperty(this, name, {
            configurable : false,
            enumerable : true,
            value : value,
            writable : false
        });
    };
    
    /**
     * Register decorator.
     *
     * @param String fullname
     * @param Function func
     * @return Bottle
     */
    var decorator = function decorator(fullname, func) {
        var parts, name;
        if (typeof fullname === 'function') {
            func = fullname;
            fullname = '__global__';
        }
    
        parts = fullname.split('.');
        name = parts.shift();
        if (parts.length) {
            getNestedBottle.call(this, name).decorator(parts.join('.'), func);
        } else {
            if (!this.decorators[name]) {
                this.decorators[name] = [];
            }
            this.decorators[name].push(func);
        }
        return this;
    };
    
    /**
     * Register a function that will be executed when Bottle#resolve is called.
     *
     * @param Function func
     * @return Bottle
     */
    var defer = function defer(func) {
        this.deferred.push(func);
        return this;
    };
    
    
    /**
     * Immediately instantiates the provided list of services and returns them.
     *
     * @param Array services
     * @return Array Array of instances (in the order they were provided)
     */
    var digest = function digest(services) {
        return (services || []).map(getNestedService, this.container);
    };
    
    /**
     * Register a factory inside a generic provider.
     *
     * @param String name
     * @param Function Factory
     * @return Bottle
     */
    var factory = function factory(name, Factory) {
        return provider.call(this, name, function GenericProvider() {
            this.$get = Factory;
        });
    };
    
    /**
     * Register an instance factory inside a generic factory.
     *
     * @param {String} name - The name of the service
     * @param {Function} Factory - The factory function, matches the signature required for the
     * `factory` method
     * @return Bottle
     */
    var instanceFactory = function instanceFactory(name, Factory) {
        return factory.call(this, name, function GenericInstanceFactory(container) {
            return {
                instance : Factory.bind(Factory, container)
            };
        });
    };
    
    /**
     * A filter function for removing bottle container methods and providers from a list of keys
     */
    var byMethod = function byMethod(name) {
        return !/^\$(?:decorator|register|list)$|Provider$/.test(name);
    };
    
    /**
     * List the services registered on the container.
     *
     * @param Object container
     * @return Array
     */
    var list = function list(container) {
        return Object.keys(container || this.container || {}).filter(byMethod);
    };
    
    /**
     * Function used by provider to set up middleware for each request.
     *
     * @param Number id
     * @param String name
     * @param Object instance
     * @param Object container
     * @return void
     */
    var applyMiddleware = function applyMiddleware(middleware, name, instance, container) {
        var descriptor = {
            configurable : true,
            enumerable : true
        };
        if (middleware.length) {
            descriptor.get = function getWithMiddlewear() {
                var index = 0;
                var next = function nextMiddleware(err) {
                    if (err) {
                        throw err;
                    }
                    if (middleware[index]) {
                        middleware[index++](instance, next);
                    }
                };
                next();
                return instance;
            };
        } else {
            descriptor.value = instance;
            descriptor.writable = true;
        }
    
        Object.defineProperty(container, name, descriptor);
    
        return container[name];
    };
    
    /**
     * Register middleware.
     *
     * @param String name
     * @param Function func
     * @return Bottle
     */
    var middleware = function middleware(fullname, func) {
        var parts, name;
        if (typeof fullname === 'function') {
            func = fullname;
            fullname = '__global__';
        }
    
        parts = fullname.split('.');
        name = parts.shift();
        if (parts.length) {
            getNestedBottle.call(this, name).middleware(parts.join('.'), func);
        } else {
            if (!this.middlewares[name]) {
                this.middlewares[name] = [];
            }
            this.middlewares[name].push(func);
        }
        return this;
    };
    
    /**
     * Named bottle instances
     *
     * @type Object
     */
    var bottles = {};
    
    /**
     * Get an instance of bottle.
     *
     * If a name is provided the instance will be stored in a local hash.  Calling Bottle.pop multiple
     * times with the same name will return the same instance.
     *
     * @param String name
     * @return Bottle
     */
    var pop = function pop(name) {
        var instance;
        if (typeof name === 'string') {
            instance = bottles[name];
            if (!instance) {
                bottles[name] = instance = new Bottle();
                instance.constant('BOTTLE_NAME', name);
            }
            return instance;
        }
        return new Bottle();
    };
    
    /**
     * Clear all named bottles.
     */
    var clear = function clear(name) {
        if (typeof name === 'string') {
            delete bottles[name];
        } else {
            bottles = {};
        }
    };
    
    /**
     * Used to process decorators in the provider
     *
     * @param Object instance
     * @param Function func
     * @return Mixed
     */
    var reducer = function reducer(instance, func) {
        return func(instance);
    };
    
    /**
     * Register a provider.
     *
     * @param String fullname
     * @param Function Provider
     * @return Bottle
     */
    var provider = function provider(fullname, Provider) {
        var parts, name;
        parts = fullname.split('.');
        if (this.providerMap[fullname] && parts.length === 1 && !this.container[fullname + 'Provider']) {
            return console.error(fullname + ' provider already instantiated.');
        }
        this.originalProviders[fullname] = Provider;
        this.providerMap[fullname] = true;
    
        name = parts.shift();
    
        if (parts.length) {
            createSubProvider.call(this, name, Provider, parts);
            return this;
        }
        return createProvider.call(this, name, Provider);
    };
    
    /**
     * Get decorators and middleware including globals
     *
     * @return array
     */
    var getWithGlobal = function getWithGlobal(collection, name) {
        return (collection[name] || []).concat(collection.__global__ || []);
    };
    
    /**
     * Create the provider properties on the container
     *
     * @param String name
     * @param Function Provider
     * @return Bottle
     */
    var createProvider = function createProvider(name, Provider) {
        var providerName, properties, container, id, decorators, middlewares;
    
        id = this.id;
        container = this.container;
        decorators = this.decorators;
        middlewares = this.middlewares;
        providerName = name + 'Provider';
    
        properties = Object.create(null);
        properties[providerName] = {
            configurable : true,
            enumerable : true,
            get : function getProvider() {
                var instance = new Provider();
                delete container[providerName];
                container[providerName] = instance;
                return instance;
            }
        };
    
        properties[name] = {
            configurable : true,
            enumerable : true,
            get : function getService() {
                var provider = container[providerName];
                var instance;
                if (provider) {
                    // filter through decorators
                    instance = getWithGlobal(decorators, name).reduce(reducer, provider.$get(container));
    
                    delete container[providerName];
                    delete container[name];
                }
                return instance === undefined ? instance : applyMiddleware(getWithGlobal(middlewares, name),
                    name, instance, container);
            }
        };
    
        Object.defineProperties(container, properties);
        return this;
    };
    
    /**
     * Creates a bottle container on the current bottle container, and registers
     * the provider under the sub container.
     *
     * @param String name
     * @param Function Provider
     * @param Array parts
     * @return Bottle
     */
    var createSubProvider = function createSubProvider(name, Provider, parts) {
        var bottle;
        bottle = getNestedBottle.call(this, name);
        this.factory(name, function SubProviderFactory() {
            return bottle.container;
        });
        return bottle.provider(parts.join('.'), Provider);
    };
    
    /**
     * Register a service, factory, provider, or value based on properties on the object.
     *
     * properties:
     *  * Obj.$name   String required ex: `'Thing'`
     *  * Obj.$type   String optional 'service', 'factory', 'provider', 'value'.  Default: 'service'
     *  * Obj.$inject Mixed  optional only useful with $type 'service' name or array of names
     *  * Obj.$value  Mixed  optional Normally Obj is registered on the container.  However, if this
     *                       property is included, it's value will be registered on the container
     *                       instead of the object itsself.  Useful for registering objects on the
     *                       bottle container without modifying those objects with bottle specific keys.
     *
     * @param Function Obj
     * @return Bottle
     */
    var register = function register(Obj) {
        var value = Obj.$value === undefined ? Obj : Obj.$value;
        return this[Obj.$type || 'service'].apply(this, [Obj.$name, value].concat(Obj.$inject || []));
    };
    
    /**
     * Deletes providers from the map and container.
     *
     * @param String name
     * @return void
     */
    var removeProviderMap = function resetProvider(name) {
        delete this.providerMap[name];
        delete this.container[name];
        delete this.container[name + 'Provider'];
    };
    
    /**
     * Resets all providers on a bottle instance.
     *
     * @return void
     */
    var resetProviders = function resetProviders() {
        var providers = this.originalProviders;
        Object.keys(this.originalProviders).forEach(function resetPrvider(provider) {
            var parts = provider.split('.');
            if (parts.length > 1) {
                removeProviderMap.call(this, parts[0]);
                parts.forEach(removeProviderMap, getNestedBottle.call(this, parts[0]));
            }
            removeProviderMap.call(this, provider);
            this.provider(provider, providers[provider]);
        }, this);
    };
    
    
    /**
     * Execute any deferred functions
     *
     * @param Mixed data
     * @return Bottle
     */
    var resolve = function resolve(data) {
        this.deferred.forEach(function deferredIterator(func) {
            func(data);
        });
    
        return this;
    };
    
    /**
     * Register a service inside a generic factory.
     *
     * @param String name
     * @param Function Service
     * @return Bottle
     */
    var service = function service(name, Service) {
        var deps = arguments.length > 2 ? slice.call(arguments, 2) : null;
        var bottle = this;
        return factory.call(this, name, function GenericFactory() {
            if (deps) {
                deps = deps.map(getNestedService, bottle.container);
                deps.unshift(Service);
                Service = Service.bind.apply(Service, deps);
            }
            return new Service();
        });
    };
    
    /**
     * Register a value
     *
     * @param String name
     * @param mixed val
     * @return Bottle
     */
    var value = function value(name, val) {
        var parts;
        parts = name.split('.');
        name = parts.pop();
        defineValue.call(parts.reduce(setValueObject, this.container), name, val);
        return this;
    };
    
    /**
     * Iterator for setting a plain object literal via defineValue
     *
     * @param Object container
     * @param string name
     */
    var setValueObject = function setValueObject(container, name) {
        var nestedContainer = container[name];
        if (!nestedContainer) {
            nestedContainer = {};
            defineValue.call(container, name, nestedContainer);
        }
        return nestedContainer;
    };
    
    /**
     * Define a mutable property on the container.
     *
     * @param String name
     * @param mixed val
     * @return void
     * @scope container
     */
    var defineValue = function defineValue(name, val) {
        Object.defineProperty(this, name, {
            configurable : true,
            enumerable : true,
            value : val,
            writable : true
        });
    };
    
    
    /**
     * Bottle constructor
     *
     * @param String name Optional name for functional construction
     */
    var Bottle = function Bottle(name) {
        if (!(this instanceof Bottle)) {
            return Bottle.pop(name);
        }
    
        this.id = id++;
    
        this.decorators = {};
        this.middlewares = {};
        this.nested = {};
        this.providerMap = {};
        this.originalProviders = {};
        this.deferred = [];
        this.container = {
            $decorator : decorator.bind(this),
            $register : register.bind(this),
            $list : list.bind(this)
        };
    };
    
    /**
     * Bottle prototype
     */
    Bottle.prototype = {
        constant : constant,
        decorator : decorator,
        defer : defer,
        digest : digest,
        factory : factory,
        instanceFactory: instanceFactory,
        list : list,
        middleware : middleware,
        provider : provider,
        resetProviders : resetProviders,
        register : register,
        resolve : resolve,
        service : service,
        value : value
    };
    
    /**
     * Bottle static
     */
    Bottle.pop = pop;
    Bottle.clear = clear;
    Bottle.list = list;
    
    /**
     * Global config
     */
    var globalConfig = Bottle.config = {
        strict : false
    };
    
    /**
     * Exports script adapted from lodash v2.4.1 Modern Build
     *
     * @see http://lodash.com/
     */
    
    /**
     * Valid object type map
     *
     * @type Object
     */
    var objectTypes = {
        'function' : true,
        'object' : true
    };
    
    (function exportBottle(root) {
    
        /**
         * Free variable exports
         *
         * @type Function
         */
        var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
    
        /**
         * Free variable module
         *
         * @type Object
         */
        var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
    
        /**
         * CommonJS module.exports
         *
         * @type Function
         */
        var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
    
        /**
         * Free variable `global`
         *
         * @type Object
         */
        var freeGlobal = objectTypes[typeof global] && global;
        if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
            root = freeGlobal;
        }
    
        /**
         * Export
         */
        if (true) {
            root.Bottle = Bottle;
            !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { return Bottle; }.call(exports, __webpack_require__, exports, module),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
        } else if (freeExports && freeModule) {
            if (moduleExports) {
                (freeModule.exports = Bottle).Bottle = Bottle;
            } else {
                freeExports.Bottle = Bottle;
            }
        } else {
            root.Bottle = Bottle;
        }
    }((objectTypes[typeof window] && window) || this));
    
}.call(this));
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(108)(module), __webpack_require__(4)))

/***/ }),
/* 14 */
/***/ (function(module, exports) {

module.exports = function() {
	var list = [];
	list.toString = function toString() {
		var result = [];
		for(var i = 0; i < this.length; i++) {
			var item = this[i];
			if(item[2]) {
				result.push("@media " + item[2] + "{" + item[1] + "}");
			} else {
				result.push(item[1]);
			}
		}
		return result.join("");
	};
	return list;
}

/***/ }),
/* 15 */
/***/ (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__(9).EventEmitter;
var inherits = __webpack_require__(1);

inherits(Stream, EE);
Stream.Readable = __webpack_require__(96);
Stream.Writable = __webpack_require__(98);
Stream.Duplex = __webpack_require__(93);
Stream.Transform = __webpack_require__(97);
Stream.PassThrough = __webpack_require__(95);

// 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;
};


/***/ }),
/* 16 */
/***/ (function(module, exports) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var stylesInDom = {},
	memoize = function(fn) {
		var memo;
		return function () {
			if (typeof memo === "undefined") memo = fn.apply(this, arguments);
			return memo;
		};
	},
	isOldIE = memoize(function() {
		return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
	}),
	getHeadElement = memoize(function () {
		return document.head || document.getElementsByTagName("head")[0];
	}),
	singletonElement = null,
	singletonCounter = 0;

module.exports = function(list, options) {
	if(typeof DEBUG !== "undefined" && DEBUG) {
		if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};
	// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (typeof options.singleton === "undefined") options.singleton = isOldIE();

	var styles = listToStyles(list);
	addStylesToDom(styles, options);

	return function update(newList) {
		var mayRemove = [];
		for(var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
			domStyle.refs--;
			mayRemove.push(domStyle);
		}
		if(newList) {
			var newStyles = listToStyles(newList);
			addStylesToDom(newStyles, options);
		}
		for(var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];
			if(domStyle.refs === 0) {
				for(var j = 0; j < domStyle.parts.length; j++)
					domStyle.parts[j]();
				delete stylesInDom[domStyle.id];
			}
		}
	};
}

function addStylesToDom(styles, options) {
	for(var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];
		if(domStyle) {
			domStyle.refs++;
			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}
			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];
			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}
			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles(list) {
	var styles = [];
	var newStyles = {};
	for(var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};
		if(!newStyles[id])
			styles.push(newStyles[id] = {id: id, parts: [part]});
		else
			newStyles[id].parts.push(part);
	}
	return styles;
}

function createStyleElement() {
	var styleElement = document.createElement("style");
	var head = getHeadElement();
	styleElement.type = "text/css";
	head.appendChild(styleElement);
	return styleElement;
}

function createLinkElement() {
	var linkElement = document.createElement("link");
	var head = getHeadElement();
	linkElement.rel = "stylesheet";
	head.appendChild(linkElement);
	return linkElement;
}

function addStyle(obj, options) {
	var styleElement, update, remove;

	if (options.singleton) {
		var styleIndex = singletonCounter++;
		styleElement = singletonElement || (singletonElement = createStyleElement());
		update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
		remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
	} else if(obj.sourceMap &&
		typeof URL === "function" &&
		typeof URL.createObjectURL === "function" &&
		typeof URL.revokeObjectURL === "function" &&
		typeof Blob === "function" &&
		typeof btoa === "function") {
		styleElement = createLinkElement();
		update = updateLink.bind(null, styleElement);
		remove = function() {
			styleElement.parentNode.removeChild(styleElement);
			if(styleElement.href)
				URL.revokeObjectURL(styleElement.href);
		};
	} else {
		styleElement = createStyleElement();
		update = applyToTag.bind(null, styleElement);
		remove = function() {
			styleElement.parentNode.removeChild(styleElement);
		};
	}

	update(obj);

	return function updateStyle(newObj) {
		if(newObj) {
			if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
				return;
			update(obj = newObj);
		} else {
			remove();
		}
	};
}

var replaceText = (function () {
	var textStore = [];

	return function (index, replacement) {
		textStore[index] = replacement;
		return textStore.filter(Boolean).join('\n');
	};
})();

function applyToSingletonTag(styleElement, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if (styleElement.styleSheet) {
		styleElement.styleSheet.cssText = replaceText(index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = styleElement.childNodes;
		if (childNodes[index]) styleElement.removeChild(childNodes[index]);
		if (childNodes.length) {
			styleElement.insertBefore(cssNode, childNodes[index]);
		} else {
			styleElement.appendChild(cssNode);
		}
	}
}

function applyToTag(styleElement, obj) {
	var css = obj.css;
	var media = obj.media;
	var sourceMap = obj.sourceMap;

	if(media) {
		styleElement.setAttribute("media", media)
	}

	if(styleElement.styleSheet) {
		styleElement.styleSheet.cssText = css;
	} else {
		while(styleElement.firstChild) {
			styleElement.removeChild(styleElement.firstChild);
		}
		styleElement.appendChild(document.createTextNode(css));
	}
}

function updateLink(linkElement, obj) {
	var css = obj.css;
	var media = obj.media;
	var sourceMap = obj.sourceMap;

	if(sourceMap) {
		// http://stackoverflow.com/a/26603875
		css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
	}

	var blob = new Blob([css], { type: "text/css" });

	var oldSrc = linkElement.href;

	linkElement.href = URL.createObjectURL(blob);

	if(oldSrc)
		URL.revokeObjectURL(oldSrc);
}


/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(global) {

var buffer = __webpack_require__(2);
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__(4)))

/***/ }),
/* 18 */
/***/ (function(module, exports) {

module.exports = {
	"Aacute": "Á",
	"aacute": "á",
	"Abreve": "Ă",
	"abreve": "ă",
	"ac": "∾",
	"acd": "∿",
	"acE": "∾̳",
	"Acirc": "Â",
	"acirc": "â",
	"acute": "´",
	"Acy": "А",
	"acy": "а",
	"AElig": "Æ",
	"aelig": "æ",
	"af": "⁡",
	"Afr": "𝔄",
	"afr": "𝔞",
	"Agrave": "À",
	"agrave": "à",
	"alefsym": "ℵ",
	"aleph": "ℵ",
	"Alpha": "Α",
	"alpha": "α",
	"Amacr": "Ā",
	"amacr": "ā",
	"amalg": "⨿",
	"amp": "&",
	"AMP": "&",
	"andand": "⩕",
	"And": "⩓",
	"and": "∧",
	"andd": "⩜",
	"andslope": "⩘",
	"andv": "⩚",
	"ang": "∠",
	"ange": "⦤",
	"angle": "∠",
	"angmsdaa": "⦨",
	"angmsdab": "⦩",
	"angmsdac": "⦪",
	"angmsdad": "⦫",
	"angmsdae": "⦬",
	"angmsdaf": "⦭",
	"angmsdag": "⦮",
	"angmsdah": "⦯",
	"angmsd": "∡",
	"angrt": "∟",
	"angrtvb": "⊾",
	"angrtvbd": "⦝",
	"angsph": "∢",
	"angst": "Å",
	"angzarr": "⍼",
	"Aogon": "Ą",
	"aogon": "ą",
	"Aopf": "𝔸",
	"aopf": "𝕒",
	"apacir": "⩯",
	"ap": "≈",
	"apE": "⩰",
	"ape": "≊",
	"apid": "≋",
	"apos": "'",
	"ApplyFunction": "⁡",
	"approx": "≈",
	"approxeq": "≊",
	"Aring": "Å",
	"aring": "å",
	"Ascr": "𝒜",
	"ascr": "𝒶",
	"Assign": "≔",
	"ast": "*",
	"asymp": "≈",
	"asympeq": "≍",
	"Atilde": "Ã",
	"atilde": "ã",
	"Auml": "Ä",
	"auml": "ä",
	"awconint": "∳",
	"awint": "⨑",
	"backcong": "≌",
	"backepsilon": "϶",
	"backprime": "‵",
	"backsim": "∽",
	"backsimeq": "⋍",
	"Backslash": "∖",
	"Barv": "⫧",
	"barvee": "⊽",
	"barwed": "⌅",
	"Barwed": "⌆",
	"barwedge": "⌅",
	"bbrk": "⎵",
	"bbrktbrk": "⎶",
	"bcong": "≌",
	"Bcy": "Б",
	"bcy": "б",
	"bdquo": "„",
	"becaus": "∵",
	"because": "∵",
	"Because": "∵",
	"bemptyv": "⦰",
	"bepsi": "϶",
	"bernou": "ℬ",
	"Bernoullis": "ℬ",
	"Beta": "Β",
	"beta": "β",
	"beth": "ℶ",
	"between": "≬",
	"Bfr": "𝔅",
	"bfr": "𝔟",
	"bigcap": "⋂",
	"bigcirc": "◯",
	"bigcup": "⋃",
	"bigodot": "⨀",
	"bigoplus": "⨁",
	"bigotimes": "⨂",
	"bigsqcup": "⨆",
	"bigstar": "★",
	"bigtriangledown": "▽",
	"bigtriangleup": "△",
	"biguplus": "⨄",
	"bigvee": "⋁",
	"bigwedge": "⋀",
	"bkarow": "⤍",
	"blacklozenge": "⧫",
	"blacksquare": "▪",
	"blacktriangle": "▴",
	"blacktriangledown": "▾",
	"blacktriangleleft": "◂",
	"blacktriangleright": "▸",
	"blank": "␣",
	"blk12": "▒",
	"blk14": "░",
	"blk34": "▓",
	"block": "█",
	"bne": "=⃥",
	"bnequiv": "≡⃥",
	"bNot": "⫭",
	"bnot": "⌐",
	"Bopf": "𝔹",
	"bopf": "𝕓",
	"bot": "⊥",
	"bottom": "⊥",
	"bowtie": "⋈",
	"boxbox": "⧉",
	"boxdl": "┐",
	"boxdL": "╕",
	"boxDl": "╖",
	"boxDL": "╗",
	"boxdr": "┌",
	"boxdR": "╒",
	"boxDr": "╓",
	"boxDR": "╔",
	"boxh": "─",
	"boxH": "═",
	"boxhd": "┬",
	"boxHd": "╤",
	"boxhD": "╥",
	"boxHD": "╦",
	"boxhu": "┴",
	"boxHu": "╧",
	"boxhU": "╨",
	"boxHU": "╩",
	"boxminus": "⊟",
	"boxplus": "⊞",
	"boxtimes": "⊠",
	"boxul": "┘",
	"boxuL": "╛",
	"boxUl": "╜",
	"boxUL": "╝",
	"boxur": "└",
	"boxuR": "╘",
	"boxUr": "╙",
	"boxUR": "╚",
	"boxv": "│",
	"boxV": "║",
	"boxvh": "┼",
	"boxvH": "╪",
	"boxVh": "╫",
	"boxVH": "╬",
	"boxvl": "┤",
	"boxvL": "╡",
	"boxVl": "╢",
	"boxVL": "╣",
	"boxvr": "├",
	"boxvR": "╞",
	"boxVr": "╟",
	"boxVR": "╠",
	"bprime": "‵",
	"breve": "˘",
	"Breve": "˘",
	"brvbar": "¦",
	"bscr": "𝒷",
	"Bscr": "ℬ",
	"bsemi": "⁏",
	"bsim": "∽",
	"bsime": "⋍",
	"bsolb": "⧅",
	"bsol": "\\",
	"bsolhsub": "⟈",
	"bull": "•",
	"bullet": "•",
	"bump": "≎",
	"bumpE": "⪮",
	"bumpe": "≏",
	"Bumpeq": "≎",
	"bumpeq": "≏",
	"Cacute": "Ć",
	"cacute": "ć",
	"capand": "⩄",
	"capbrcup": "⩉",
	"capcap": "⩋",
	"cap": "∩",
	"Cap": "⋒",
	"capcup": "⩇",
	"capdot": "⩀",
	"CapitalDifferentialD": "ⅅ",
	"caps": "∩︀",
	"caret": "⁁",
	"caron": "ˇ",
	"Cayleys": "ℭ",
	"ccaps": "⩍",
	"Ccaron": "Č",
	"ccaron": "č",
	"Ccedil": "Ç",
	"ccedil": "ç",
	"Ccirc": "Ĉ",
	"ccirc": "ĉ",
	"Cconint": "∰",
	"ccups": "⩌",
	"ccupssm": "⩐",
	"Cdot": "Ċ",
	"cdot": "ċ",
	"cedil": "¸",
	"Cedilla": "¸",
	"cemptyv": "⦲",
	"cent": "¢",
	"centerdot": "·",
	"CenterDot": "·",
	"cfr": "𝔠",
	"Cfr": "ℭ",
	"CHcy": "Ч",
	"chcy": "ч",
	"check": "✓",
	"checkmark": "✓",
	"Chi": "Χ",
	"chi": "χ",
	"circ": "ˆ",
	"circeq": "≗",
	"circlearrowleft": "↺",
	"circlearrowright": "↻",
	"circledast": "⊛",
	"circledcirc": "⊚",
	"circleddash": "⊝",
	"CircleDot": "⊙",
	"circledR": "®",
	"circledS": "Ⓢ",
	"CircleMinus": "⊖",
	"CirclePlus": "⊕",
	"CircleTimes": "⊗",
	"cir": "○",
	"cirE": "⧃",
	"cire": "≗",
	"cirfnint": "⨐",
	"cirmid": "⫯",
	"cirscir": "⧂",
	"ClockwiseContourIntegral": "∲",
	"CloseCurlyDoubleQuote": "”",
	"CloseCurlyQuote": "’",
	"clubs": "♣",
	"clubsuit": "♣",
	"colon": ":",
	"Colon": "∷",
	"Colone": "⩴",
	"colone": "≔",
	"coloneq": "≔",
	"comma": ",",
	"commat": "@",
	"comp": "∁",
	"compfn": "∘",
	"complement": "∁",
	"complexes": "ℂ",
	"cong": "≅",
	"congdot": "⩭",
	"Congruent": "≡",
	"conint": "∮",
	"Conint": "∯",
	"ContourIntegral": "∮",
	"copf": "𝕔",
	"Copf": "ℂ",
	"coprod": "∐",
	"Coproduct": "∐",
	"copy": "©",
	"COPY": "©",
	"copysr": "℗",
	"CounterClockwiseContourIntegral": "∳",
	"crarr": "↵",
	"cross": "✗",
	"Cross": "⨯",
	"Cscr": "𝒞",
	"cscr": "𝒸",
	"csub": "⫏",
	"csube": "⫑",
	"csup": "⫐",
	"csupe": "⫒",
	"ctdot": "⋯",
	"cudarrl": "⤸",
	"cudarrr": "⤵",
	"cuepr": "⋞",
	"cuesc": "⋟",
	"cularr": "↶",
	"cularrp": "⤽",
	"cupbrcap": "⩈",
	"cupcap": "⩆",
	"CupCap": "≍",
	"cup": "∪",
	"Cup": "⋓",
	"cupcup": "⩊",
	"cupdot": "⊍",
	"cupor": "⩅",
	"cups": "∪︀",
	"curarr": "↷",
	"curarrm": "⤼",
	"curlyeqprec": "⋞",
	"curlyeqsucc": "⋟",
	"curlyvee": "⋎",
	"curlywedge": "⋏",
	"curren": "¤",
	"curvearrowleft": "↶",
	"curvearrowright": "↷",
	"cuvee": "⋎",
	"cuwed": "⋏",
	"cwconint": "∲",
	"cwint": "∱",
	"cylcty": "⌭",
	"dagger": "†",
	"Dagger": "‡",
	"daleth": "ℸ",
	"darr": "↓",
	"Darr": "↡",
	"dArr": "⇓",
	"dash": "‐",
	"Dashv": "⫤",
	"dashv": "⊣",
	"dbkarow": "⤏",
	"dblac": "˝",
	"Dcaron": "Ď",
	"dcaron": "ď",
	"Dcy": "Д",
	"dcy": "д",
	"ddagger": "‡",
	"ddarr": "⇊",
	"DD": "ⅅ",
	"dd": "ⅆ",
	"DDotrahd": "⤑",
	"ddotseq": "⩷",
	"deg": "°",
	"Del": "∇",
	"Delta": "Δ",
	"delta": "δ",
	"demptyv": "⦱",
	"dfisht": "⥿",
	"Dfr": "𝔇",
	"dfr": "𝔡",
	"dHar": "⥥",
	"dharl": "⇃",
	"dharr": "⇂",
	"DiacriticalAcute": "´",
	"DiacriticalDot": "˙",
	"DiacriticalDoubleAcute": "˝",
	"DiacriticalGrave": "`",
	"DiacriticalTilde": "˜",
	"diam": "⋄",
	"diamond": "⋄",
	"Diamond": "⋄",
	"diamondsuit": "♦",
	"diams": "♦",
	"die": "¨",
	"DifferentialD": "ⅆ",
	"digamma": "ϝ",
	"disin": "⋲",
	"div": "÷",
	"divide": "÷",
	"divideontimes": "⋇",
	"divonx": "⋇",
	"DJcy": "Ђ",
	"djcy": "ђ",
	"dlcorn": "⌞",
	"dlcrop": "⌍",
	"dollar": "$",
	"Dopf": "𝔻",
	"dopf": "𝕕",
	"Dot": "¨",
	"dot": "˙",
	"DotDot": "⃜",
	"doteq": "≐",
	"doteqdot": "≑",
	"DotEqual": "≐",
	"dotminus": "∸",
	"dotplus": "∔",
	"dotsquare": "⊡",
	"doublebarwedge": "⌆",
	"DoubleContourIntegral": "∯",
	"DoubleDot": "¨",
	"DoubleDownArrow": "⇓",
	"DoubleLeftArrow": "⇐",
	"DoubleLeftRightArrow": "⇔",
	"DoubleLeftTee": "⫤",
	"DoubleLongLeftArrow": "⟸",
	"DoubleLongLeftRightArrow": "⟺",
	"DoubleLongRightArrow": "⟹",
	"DoubleRightArrow": "⇒",
	"DoubleRightTee": "⊨",
	"DoubleUpArrow": "⇑",
	"DoubleUpDownArrow": "⇕",
	"DoubleVerticalBar": "∥",
	"DownArrowBar": "⤓",
	"downarrow": "↓",
	"DownArrow": "↓",
	"Downarrow": "⇓",
	"DownArrowUpArrow": "⇵",
	"DownBreve": "̑",
	"downdownarrows": "⇊",
	"downharpoonleft": "⇃",
	"downharpoonright": "⇂",
	"DownLeftRightVector": "⥐",
	"DownLeftTeeVector": "⥞",
	"DownLeftVectorBar": "⥖",
	"DownLeftVector": "↽",
	"DownRightTeeVector": "⥟",
	"DownRightVectorBar": "⥗",
	"DownRightVector": "⇁",
	"DownTeeArrow": "↧",
	"DownTee": "⊤",
	"drbkarow": "⤐",
	"drcorn": "⌟",
	"drcrop": "⌌",
	"Dscr": "𝒟",
	"dscr": "𝒹",
	"DScy": "Ѕ",
	"dscy": "ѕ",
	"dsol": "⧶",
	"Dstrok": "Đ",
	"dstrok": "đ",
	"dtdot": "⋱",
	"dtri": "▿",
	"dtrif": "▾",
	"duarr": "⇵",
	"duhar": "⥯",
	"dwangle": "⦦",
	"DZcy": "Џ",
	"dzcy": "џ",
	"dzigrarr": "⟿",
	"Eacute": "É",
	"eacute": "é",
	"easter": "⩮",
	"Ecaron": "Ě",
	"ecaron": "ě",
	"Ecirc": "Ê",
	"ecirc": "ê",
	"ecir": "≖",
	"ecolon": "≕",
	"Ecy": "Э",
	"ecy": "э",
	"eDDot": "⩷",
	"Edot": "Ė",
	"edot": "ė",
	"eDot": "≑",
	"ee": "ⅇ",
	"efDot": "≒",
	"Efr": "𝔈",
	"efr": "𝔢",
	"eg": "⪚",
	"Egrave": "È",
	"egrave": "è",
	"egs": "⪖",
	"egsdot": "⪘",
	"el": "⪙",
	"Element": "∈",
	"elinters": "⏧",
	"ell": "ℓ",
	"els": "⪕",
	"elsdot": "⪗",
	"Emacr": "Ē",
	"emacr": "ē",
	"empty": "∅",
	"emptyset": "∅",
	"EmptySmallSquare": "◻",
	"emptyv": "∅",
	"EmptyVerySmallSquare": "▫",
	"emsp13": " ",
	"emsp14": " ",
	"emsp": " ",
	"ENG": "Ŋ",
	"eng": "ŋ",
	"ensp": " ",
	"Eogon": "Ę",
	"eogon": "ę",
	"Eopf": "𝔼",
	"eopf": "𝕖",
	"epar": "⋕",
	"eparsl": "⧣",
	"eplus": "⩱",
	"epsi": "ε",
	"Epsilon": "Ε",
	"epsilon": "ε",
	"epsiv": "ϵ",
	"eqcirc": "≖",
	"eqcolon": "≕",
	"eqsim": "≂",
	"eqslantgtr": "⪖",
	"eqslantless": "⪕",
	"Equal": "⩵",
	"equals": "=",
	"EqualTilde": "≂",
	"equest": "≟",
	"Equilibrium": "⇌",
	"equiv": "≡",
	"equivDD": "⩸",
	"eqvparsl": "⧥",
	"erarr": "⥱",
	"erDot": "≓",
	"escr": "ℯ",
	"Escr": "ℰ",
	"esdot": "≐",
	"Esim": "⩳",
	"esim": "≂",
	"Eta": "Η",
	"eta": "η",
	"ETH": "Ð",
	"eth": "ð",
	"Euml": "Ë",
	"euml": "ë",
	"euro": "€",
	"excl": "!",
	"exist": "∃",
	"Exists": "∃",
	"expectation": "ℰ",
	"exponentiale": "ⅇ",
	"ExponentialE": "ⅇ",
	"fallingdotseq": "≒",
	"Fcy": "Ф",
	"fcy": "ф",
	"female": "♀",
	"ffilig": "ﬃ",
	"fflig": "ﬀ",
	"ffllig": "ﬄ",
	"Ffr": "𝔉",
	"ffr": "𝔣",
	"filig": "ﬁ",
	"FilledSmallSquare": "◼",
	"FilledVerySmallSquare": "▪",
	"fjlig": "fj",
	"flat": "♭",
	"fllig": "ﬂ",
	"fltns": "▱",
	"fnof": "ƒ",
	"Fopf": "𝔽",
	"fopf": "𝕗",
	"forall": "∀",
	"ForAll": "∀",
	"fork": "⋔",
	"forkv": "⫙",
	"Fouriertrf": "ℱ",
	"fpartint": "⨍",
	"frac12": "½",
	"frac13": "⅓",
	"frac14": "¼",
	"frac15": "⅕",
	"frac16": "⅙",
	"frac18": "⅛",
	"frac23": "⅔",
	"frac25": "⅖",
	"frac34": "¾",
	"frac35": "⅗",
	"frac38": "⅜",
	"frac45": "⅘",
	"frac56": "⅚",
	"frac58": "⅝",
	"frac78": "⅞",
	"frasl": "⁄",
	"frown": "⌢",
	"fscr": "𝒻",
	"Fscr": "ℱ",
	"gacute": "ǵ",
	"Gamma": "Γ",
	"gamma": "γ",
	"Gammad": "Ϝ",
	"gammad": "ϝ",
	"gap": "⪆",
	"Gbreve": "Ğ",
	"gbreve": "ğ",
	"Gcedil": "Ģ",
	"Gcirc": "Ĝ",
	"gcirc": "ĝ",
	"Gcy": "Г",
	"gcy": "г",
	"Gdot": "Ġ",
	"gdot": "ġ",
	"ge": "≥",
	"gE": "≧",
	"gEl": "⪌",
	"gel": "⋛",
	"geq": "≥",
	"geqq": "≧",
	"geqslant": "⩾",
	"gescc": "⪩",
	"ges": "⩾",
	"gesdot": "⪀",
	"gesdoto": "⪂",
	"gesdotol": "⪄",
	"gesl": "⋛︀",
	"gesles": "⪔",
	"Gfr": "𝔊",
	"gfr": "𝔤",
	"gg": "≫",
	"Gg": "⋙",
	"ggg": "⋙",
	"gimel": "ℷ",
	"GJcy": "Ѓ",
	"gjcy": "ѓ",
	"gla": "⪥",
	"gl": "≷",
	"glE": "⪒",
	"glj": "⪤",
	"gnap": "⪊",
	"gnapprox": "⪊",
	"gne": "⪈",
	"gnE": "≩",
	"gneq": "⪈",
	"gneqq": "≩",
	"gnsim": "⋧",
	"Gopf": "𝔾",
	"gopf": "𝕘",
	"grave": "`",
	"GreaterEqual": "≥",
	"GreaterEqualLess": "⋛",
	"GreaterFullEqual": "≧",
	"GreaterGreater": "⪢",
	"GreaterLess": "≷",
	"GreaterSlantEqual": "⩾",
	"GreaterTilde": "≳",
	"Gscr": "𝒢",
	"gscr": "ℊ",
	"gsim": "≳",
	"gsime": "⪎",
	"gsiml": "⪐",
	"gtcc": "⪧",
	"gtcir": "⩺",
	"gt": ">",
	"GT": ">",
	"Gt": "≫",
	"gtdot": "⋗",
	"gtlPar": "⦕",
	"gtquest": "⩼",
	"gtrapprox": "⪆",
	"gtrarr": "⥸",
	"gtrdot": "⋗",
	"gtreqless": "⋛",
	"gtreqqless": "⪌",
	"gtrless": "≷",
	"gtrsim": "≳",
	"gvertneqq": "≩︀",
	"gvnE": "≩︀",
	"Hacek": "ˇ",
	"hairsp": " ",
	"half": "½",
	"hamilt": "ℋ",
	"HARDcy": "Ъ",
	"hardcy": "ъ",
	"harrcir": "⥈",
	"harr": "↔",
	"hArr": "⇔",
	"harrw": "↭",
	"Hat": "^",
	"hbar": "ℏ",
	"Hcirc": "Ĥ",
	"hcirc": "ĥ",
	"hearts": "♥",
	"heartsuit": "♥",
	"hellip": "…",
	"hercon": "⊹",
	"hfr": "𝔥",
	"Hfr": "ℌ",
	"HilbertSpace": "ℋ",
	"hksearow": "⤥",
	"hkswarow": "⤦",
	"hoarr": "⇿",
	"homtht": "∻",
	"hookleftarrow": "↩",
	"hookrightarrow": "↪",
	"hopf": "𝕙",
	"Hopf": "ℍ",
	"horbar": "―",
	"HorizontalLine": "─",
	"hscr": "𝒽",
	"Hscr": "ℋ",
	"hslash": "ℏ",
	"Hstrok": "Ħ",
	"hstrok": "ħ",
	"HumpDownHump": "≎",
	"HumpEqual": "≏",
	"hybull": "⁃",
	"hyphen": "‐",
	"Iacute": "Í",
	"iacute": "í",
	"ic": "⁣",
	"Icirc": "Î",
	"icirc": "î",
	"Icy": "И",
	"icy": "и",
	"Idot": "İ",
	"IEcy": "Е",
	"iecy": "е",
	"iexcl": "¡",
	"iff": "⇔",
	"ifr": "𝔦",
	"Ifr": "ℑ",
	"Igrave": "Ì",
	"igrave": "ì",
	"ii": "ⅈ",
	"iiiint": "⨌",
	"iiint": "∭",
	"iinfin": "⧜",
	"iiota": "℩",
	"IJlig": "Ĳ",
	"ijlig": "ĳ",
	"Imacr": "Ī",
	"imacr": "ī",
	"image": "ℑ",
	"ImaginaryI": "ⅈ",
	"imagline": "ℐ",
	"imagpart": "ℑ",
	"imath": "ı",
	"Im": "ℑ",
	"imof": "⊷",
	"imped": "Ƶ",
	"Implies": "⇒",
	"incare": "℅",
	"in": "∈",
	"infin": "∞",
	"infintie": "⧝",
	"inodot": "ı",
	"intcal": "⊺",
	"int": "∫",
	"Int": "∬",
	"integers": "ℤ",
	"Integral": "∫",
	"intercal": "⊺",
	"Intersection": "⋂",
	"intlarhk": "⨗",
	"intprod": "⨼",
	"InvisibleComma": "⁣",
	"InvisibleTimes": "⁢",
	"IOcy": "Ё",
	"iocy": "ё",
	"Iogon": "Į",
	"iogon": "į",
	"Iopf": "𝕀",
	"iopf": "𝕚",
	"Iota": "Ι",
	"iota": "ι",
	"iprod": "⨼",
	"iquest": "¿",
	"iscr": "𝒾",
	"Iscr": "ℐ",
	"isin": "∈",
	"isindot": "⋵",
	"isinE": "⋹",
	"isins": "⋴",
	"isinsv": "⋳",
	"isinv": "∈",
	"it": "⁢",
	"Itilde": "Ĩ",
	"itilde": "ĩ",
	"Iukcy": "І",
	"iukcy": "і",
	"Iuml": "Ï",
	"iuml": "ï",
	"Jcirc": "Ĵ",
	"jcirc": "ĵ",
	"Jcy": "Й",
	"jcy": "й",
	"Jfr": "𝔍",
	"jfr": "𝔧",
	"jmath": "ȷ",
	"Jopf": "𝕁",
	"jopf": "𝕛",
	"Jscr": "𝒥",
	"jscr": "𝒿",
	"Jsercy": "Ј",
	"jsercy": "ј",
	"Jukcy": "Є",
	"jukcy": "є",
	"Kappa": "Κ",
	"kappa": "κ",
	"kappav": "ϰ",
	"Kcedil": "Ķ",
	"kcedil": "ķ",
	"Kcy": "К",
	"kcy": "к",
	"Kfr": "𝔎",
	"kfr": "𝔨",
	"kgreen": "ĸ",
	"KHcy": "Х",
	"khcy": "х",
	"KJcy": "Ќ",
	"kjcy": "ќ",
	"Kopf": "𝕂",
	"kopf": "𝕜",
	"Kscr": "𝒦",
	"kscr": "𝓀",
	"lAarr": "⇚",
	"Lacute": "Ĺ",
	"lacute": "ĺ",
	"laemptyv": "⦴",
	"lagran": "ℒ",
	"Lambda": "Λ",
	"lambda": "λ",
	"lang": "⟨",
	"Lang": "⟪",
	"langd": "⦑",
	"langle": "⟨",
	"lap": "⪅",
	"Laplacetrf": "ℒ",
	"laquo": "«",
	"larrb": "⇤",
	"larrbfs": "⤟",
	"larr": "←",
	"Larr": "↞",
	"lArr": "⇐",
	"larrfs": "⤝",
	"larrhk": "↩",
	"larrlp": "↫",
	"larrpl": "⤹",
	"larrsim": "⥳",
	"larrtl": "↢",
	"latail": "⤙",
	"lAtail": "⤛",
	"lat": "⪫",
	"late": "⪭",
	"lates": "⪭︀",
	"lbarr": "⤌",
	"lBarr": "⤎",
	"lbbrk": "❲",
	"lbrace": "{",
	"lbrack": "[",
	"lbrke": "⦋",
	"lbrksld": "⦏",
	"lbrkslu": "⦍",
	"Lcaron": "Ľ",
	"lcaron": "ľ",
	"Lcedil": "Ļ",
	"lcedil": "ļ",
	"lceil": "⌈",
	"lcub": "{",
	"Lcy": "Л",
	"lcy": "л",
	"ldca": "⤶",
	"ldquo": "“",
	"ldquor": "„",
	"ldrdhar": "⥧",
	"ldrushar": "⥋",
	"ldsh": "↲",
	"le": "≤",
	"lE": "≦",
	"LeftAngleBracket": "⟨",
	"LeftArrowBar": "⇤",
	"leftarrow": "←",
	"LeftArrow": "←",
	"Leftarrow": "⇐",
	"LeftArrowRightArrow": "⇆",
	"leftarrowtail": "↢",
	"LeftCeiling": "⌈",
	"LeftDoubleBracket": "⟦",
	"LeftDownTeeVector": "⥡",
	"LeftDownVectorBar": "⥙",
	"LeftDownVector": "⇃",
	"LeftFloor": "⌊",
	"leftharpoondown": "↽",
	"leftharpoonup": "↼",
	"leftleftarrows": "⇇",
	"leftrightarrow": "↔",
	"LeftRightArrow": "↔",
	"Leftrightarrow": "⇔",
	"leftrightarrows": "⇆",
	"leftrightharpoons": "⇋",
	"leftrightsquigarrow": "↭",
	"LeftRightVector": "⥎",
	"LeftTeeArrow": "↤",
	"LeftTee": "⊣",
	"LeftTeeVector": "⥚",
	"leftthreetimes": "⋋",
	"LeftTriangleBar": "⧏",
	"LeftTriangle": "⊲",
	"LeftTriangleEqual": "⊴",
	"LeftUpDownVector": "⥑",
	"LeftUpTeeVector": "⥠",
	"LeftUpVectorBar": "⥘",
	"LeftUpVector": "↿",
	"LeftVectorBar": "⥒",
	"LeftVector": "↼",
	"lEg": "⪋",
	"leg": "⋚",
	"leq": "≤",
	"leqq": "≦",
	"leqslant": "⩽",
	"lescc": "⪨",
	"les": "⩽",
	"lesdot": "⩿",
	"lesdoto": "⪁",
	"lesdotor": "⪃",
	"lesg": "⋚︀",
	"lesges": "⪓",
	"lessapprox": "⪅",
	"lessdot": "⋖",
	"lesseqgtr": "⋚",
	"lesseqqgtr": "⪋",
	"LessEqualGreater": "⋚",
	"LessFullEqual": "≦",
	"LessGreater": "≶",
	"lessgtr": "≶",
	"LessLess": "⪡",
	"lesssim": "≲",
	"LessSlantEqual": "⩽",
	"LessTilde": "≲",
	"lfisht": "⥼",
	"lfloor": "⌊",
	"Lfr": "𝔏",
	"lfr": "𝔩",
	"lg": "≶",
	"lgE": "⪑",
	"lHar": "⥢",
	"lhard": "↽",
	"lharu": "↼",
	"lharul": "⥪",
	"lhblk": "▄",
	"LJcy": "Љ",
	"ljcy": "љ",
	"llarr": "⇇",
	"ll": "≪",
	"Ll": "⋘",
	"llcorner": "⌞",
	"Lleftarrow": "⇚",
	"llhard": "⥫",
	"lltri": "◺",
	"Lmidot": "Ŀ",
	"lmidot": "ŀ",
	"lmoustache": "⎰",
	"lmoust": "⎰",
	"lnap": "⪉",
	"lnapprox": "⪉",
	"lne": "⪇",
	"lnE": "≨",
	"lneq": "⪇",
	"lneqq": "≨",
	"lnsim": "⋦",
	"loang": "⟬",
	"loarr": "⇽",
	"lobrk": "⟦",
	"longleftarrow": "⟵",
	"LongLeftArrow": "⟵",
	"Longleftarrow": "⟸",
	"longleftrightarrow": "⟷",
	"LongLeftRightArrow": "⟷",
	"Longleftrightarrow": "⟺",
	"longmapsto": "⟼",
	"longrightarrow": "⟶",
	"LongRightArrow": "⟶",
	"Longrightarrow": "⟹",
	"looparrowleft": "↫",
	"looparrowright": "↬",
	"lopar": "⦅",
	"Lopf": "𝕃",
	"lopf": "𝕝",
	"loplus": "⨭",
	"lotimes": "⨴",
	"lowast": "∗",
	"lowbar": "_",
	"LowerLeftArrow": "↙",
	"LowerRightArrow": "↘",
	"loz": "◊",
	"lozenge": "◊",
	"lozf": "⧫",
	"lpar": "(",
	"lparlt": "⦓",
	"lrarr": "⇆",
	"lrcorner": "⌟",
	"lrhar": "⇋",
	"lrhard": "⥭",
	"lrm": "‎",
	"lrtri": "⊿",
	"lsaquo": "‹",
	"lscr": "𝓁",
	"Lscr": "ℒ",
	"lsh": "↰",
	"Lsh": "↰",
	"lsim": "≲",
	"lsime": "⪍",
	"lsimg": "⪏",
	"lsqb": "[",
	"lsquo": "‘",
	"lsquor": "‚",
	"Lstrok": "Ł",
	"lstrok": "ł",
	"ltcc": "⪦",
	"ltcir": "⩹",
	"lt": "<",
	"LT": "<",
	"Lt": "≪",
	"ltdot": "⋖",
	"lthree": "⋋",
	"ltimes": "⋉",
	"ltlarr": "⥶",
	"ltquest": "⩻",
	"ltri": "◃",
	"ltrie": "⊴",
	"ltrif": "◂",
	"ltrPar": "⦖",
	"lurdshar": "⥊",
	"luruhar": "⥦",
	"lvertneqq": "≨︀",
	"lvnE": "≨︀",
	"macr": "¯",
	"male": "♂",
	"malt": "✠",
	"maltese": "✠",
	"Map": "⤅",
	"map": "↦",
	"mapsto": "↦",
	"mapstodown": "↧",
	"mapstoleft": "↤",
	"mapstoup": "↥",
	"marker": "▮",
	"mcomma": "⨩",
	"Mcy": "М",
	"mcy": "м",
	"mdash": "—",
	"mDDot": "∺",
	"measuredangle": "∡",
	"MediumSpace": " ",
	"Mellintrf": "ℳ",
	"Mfr": "𝔐",
	"mfr": "𝔪",
	"mho": "℧",
	"micro": "µ",
	"midast": "*",
	"midcir": "⫰",
	"mid": "∣",
	"middot": "·",
	"minusb": "⊟",
	"minus": "−",
	"minusd": "∸",
	"minusdu": "⨪",
	"MinusPlus": "∓",
	"mlcp": "⫛",
	"mldr": "…",
	"mnplus": "∓",
	"models": "⊧",
	"Mopf": "𝕄",
	"mopf": "𝕞",
	"mp": "∓",
	"mscr": "𝓂",
	"Mscr": "ℳ",
	"mstpos": "∾",
	"Mu": "Μ",
	"mu": "μ",
	"multimap": "⊸",
	"mumap": "⊸",
	"nabla": "∇",
	"Nacute": "Ń",
	"nacute": "ń",
	"nang": "∠⃒",
	"nap": "≉",
	"napE": "⩰̸",
	"napid": "≋̸",
	"napos": "ŉ",
	"napprox": "≉",
	"natural": "♮",
	"naturals": "ℕ",
	"natur": "♮",
	"nbsp": " ",
	"nbump": "≎̸",
	"nbumpe": "≏̸",
	"ncap": "⩃",
	"Ncaron": "Ň",
	"ncaron": "ň",
	"Ncedil": "Ņ",
	"ncedil": "ņ",
	"ncong": "≇",
	"ncongdot": "⩭̸",
	"ncup": "⩂",
	"Ncy": "Н",
	"ncy": "н",
	"ndash": "–",
	"nearhk": "⤤",
	"nearr": "↗",
	"neArr": "⇗",
	"nearrow": "↗",
	"ne": "≠",
	"nedot": "≐̸",
	"NegativeMediumSpace": "​",
	"NegativeThickSpace": "​",
	"NegativeThinSpace": "​",
	"NegativeVeryThinSpace": "​",
	"nequiv": "≢",
	"nesear": "⤨",
	"nesim": "≂̸",
	"NestedGreaterGreater": "≫",
	"NestedLessLess": "≪",
	"NewLine": "\n",
	"nexist": "∄",
	"nexists": "∄",
	"Nfr": "𝔑",
	"nfr": "𝔫",
	"ngE": "≧̸",
	"nge": "≱",
	"ngeq": "≱",
	"ngeqq": "≧̸",
	"ngeqslant": "⩾̸",
	"nges": "⩾̸",
	"nGg": "⋙̸",
	"ngsim": "≵",
	"nGt": "≫⃒",
	"ngt": "≯",
	"ngtr": "≯",
	"nGtv": "≫̸",
	"nharr": "↮",
	"nhArr": "⇎",
	"nhpar": "⫲",
	"ni": "∋",
	"nis": "⋼",
	"nisd": "⋺",
	"niv": "∋",
	"NJcy": "Њ",
	"njcy": "њ",
	"nlarr": "↚",
	"nlArr": "⇍",
	"nldr": "‥",
	"nlE": "≦̸",
	"nle": "≰",
	"nleftarrow": "↚",
	"nLeftarrow": "⇍",
	"nleftrightarrow": "↮",
	"nLeftrightarrow": "⇎",
	"nleq": "≰",
	"nleqq": "≦̸",
	"nleqslant": "⩽̸",
	"nles": "⩽̸",
	"nless": "≮",
	"nLl": "⋘̸",
	"nlsim": "≴",
	"nLt": "≪⃒",
	"nlt": "≮",
	"nltri": "⋪",
	"nltrie": "⋬",
	"nLtv": "≪̸",
	"nmid": "∤",
	"NoBreak": "⁠",
	"NonBreakingSpace": " ",
	"nopf": "𝕟",
	"Nopf": "ℕ",
	"Not": "⫬",
	"not": "¬",
	"NotCongruent": "≢",
	"NotCupCap": "≭",
	"NotDoubleVerticalBar": "∦",
	"NotElement": "∉",
	"NotEqual": "≠",
	"NotEqualTilde": "≂̸",
	"NotExists": "∄",
	"NotGreater": "≯",
	"NotGreaterEqual": "≱",
	"NotGreaterFullEqual": "≧̸",
	"NotGreaterGreater": "≫̸",
	"NotGreaterLess": "≹",
	"NotGreaterSlantEqual": "⩾̸",
	"NotGreaterTilde": "≵",
	"NotHumpDownHump": "≎̸",
	"NotHumpEqual": "≏̸",
	"notin": "∉",
	"notindot": "⋵̸",
	"notinE": "⋹̸",
	"notinva": "∉",
	"notinvb": "⋷",
	"notinvc": "⋶",
	"NotLeftTriangleBar": "⧏̸",
	"NotLeftTriangle": "⋪",
	"NotLeftTriangleEqual": "⋬",
	"NotLess": "≮",
	"NotLessEqual": "≰",
	"NotLessGreater": "≸",
	"NotLessLess": "≪̸",
	"NotLessSlantEqual": "⩽̸",
	"NotLessTilde": "≴",
	"NotNestedGreaterGreater": "⪢̸",
	"NotNestedLessLess": "⪡̸",
	"notni": "∌",
	"notniva": "∌",
	"notnivb": "⋾",
	"notnivc": "⋽",
	"NotPrecedes": "⊀",
	"NotPrecedesEqual": "⪯̸",
	"NotPrecedesSlantEqual": "⋠",
	"NotReverseElement": "∌",
	"NotRightTriangleBar": "⧐̸",
	"NotRightTriangle": "⋫",
	"NotRightTriangleEqual": "⋭",
	"NotSquareSubset": "⊏̸",
	"NotSquareSubsetEqual": "⋢",
	"NotSquareSuperset": "⊐̸",
	"NotSquareSupersetEqual": "⋣",
	"NotSubset": "⊂⃒",
	"NotSubsetEqual": "⊈",
	"NotSucceeds": "⊁",
	"NotSucceedsEqual": "⪰̸",
	"NotSucceedsSlantEqual": "⋡",
	"NotSucceedsTilde": "≿̸",
	"NotSuperset": "⊃⃒",
	"NotSupersetEqual": "⊉",
	"NotTilde": "≁",
	"NotTildeEqual": "≄",
	"NotTildeFullEqual": "≇",
	"NotTildeTilde": "≉",
	"NotVerticalBar": "∤",
	"nparallel": "∦",
	"npar": "∦",
	"nparsl": "⫽⃥",
	"npart": "∂̸",
	"npolint": "⨔",
	"npr": "⊀",
	"nprcue": "⋠",
	"nprec": "⊀",
	"npreceq": "⪯̸",
	"npre": "⪯̸",
	"nrarrc": "⤳̸",
	"nrarr": "↛",
	"nrArr": "⇏",
	"nrarrw": "↝̸",
	"nrightarrow": "↛",
	"nRightarrow": "⇏",
	"nrtri": "⋫",
	"nrtrie": "⋭",
	"nsc": "⊁",
	"nsccue": "⋡",
	"nsce": "⪰̸",
	"Nscr": "𝒩",
	"nscr": "𝓃",
	"nshortmid": "∤",
	"nshortparallel": "∦",
	"nsim": "≁",
	"nsime": "≄",
	"nsimeq": "≄",
	"nsmid": "∤",
	"nspar": "∦",
	"nsqsube": "⋢",
	"nsqsupe": "⋣",
	"nsub": "⊄",
	"nsubE": "⫅̸",
	"nsube": "⊈",
	"nsubset": "⊂⃒",
	"nsubseteq": "⊈",
	"nsubseteqq": "⫅̸",
	"nsucc": "⊁",
	"nsucceq": "⪰̸",
	"nsup": "⊅",
	"nsupE": "⫆̸",
	"nsupe": "⊉",
	"nsupset": "⊃⃒",
	"nsupseteq": "⊉",
	"nsupseteqq": "⫆̸",
	"ntgl": "≹",
	"Ntilde": "Ñ",
	"ntilde": "ñ",
	"ntlg": "≸",
	"ntriangleleft": "⋪",
	"ntrianglelefteq": "⋬",
	"ntriangleright": "⋫",
	"ntrianglerighteq": "⋭",
	"Nu": "Ν",
	"nu": "ν",
	"num": "#",
	"numero": "№",
	"numsp": " ",
	"nvap": "≍⃒",
	"nvdash": "⊬",
	"nvDash": "⊭",
	"nVdash": "⊮",
	"nVDash": "⊯",
	"nvge": "≥⃒",
	"nvgt": ">⃒",
	"nvHarr": "⤄",
	"nvinfin": "⧞",
	"nvlArr": "⤂",
	"nvle": "≤⃒",
	"nvlt": "<⃒",
	"nvltrie": "⊴⃒",
	"nvrArr": "⤃",
	"nvrtrie": "⊵⃒",
	"nvsim": "∼⃒",
	"nwarhk": "⤣",
	"nwarr": "↖",
	"nwArr": "⇖",
	"nwarrow": "↖",
	"nwnear": "⤧",
	"Oacute": "Ó",
	"oacute": "ó",
	"oast": "⊛",
	"Ocirc": "Ô",
	"ocirc": "ô",
	"ocir": "⊚",
	"Ocy": "О",
	"ocy": "о",
	"odash": "⊝",
	"Odblac": "Ő",
	"odblac": "ő",
	"odiv": "⨸",
	"odot": "⊙",
	"odsold": "⦼",
	"OElig": "Œ",
	"oelig": "œ",
	"ofcir": "⦿",
	"Ofr": "𝔒",
	"ofr": "𝔬",
	"ogon": "˛",
	"Ograve": "Ò",
	"ograve": "ò",
	"ogt": "⧁",
	"ohbar": "⦵",
	"ohm": "Ω",
	"oint": "∮",
	"olarr": "↺",
	"olcir": "⦾",
	"olcross": "⦻",
	"oline": "‾",
	"olt": "⧀",
	"Omacr": "Ō",
	"omacr": "ō",
	"Omega": "Ω",
	"omega": "ω",
	"Omicron": "Ο",
	"omicron": "ο",
	"omid": "⦶",
	"ominus": "⊖",
	"Oopf": "𝕆",
	"oopf": "𝕠",
	"opar": "⦷",
	"OpenCurlyDoubleQuote": "“",
	"OpenCurlyQuote": "‘",
	"operp": "⦹",
	"oplus": "⊕",
	"orarr": "↻",
	"Or": "⩔",
	"or": "∨",
	"ord": "⩝",
	"order": "ℴ",
	"orderof": "ℴ",
	"ordf": "ª",
	"ordm": "º",
	"origof": "⊶",
	"oror": "⩖",
	"orslope": "⩗",
	"orv": "⩛",
	"oS": "Ⓢ",
	"Oscr": "𝒪",
	"oscr": "ℴ",
	"Oslash": "Ø",
	"oslash": "ø",
	"osol": "⊘",
	"Otilde": "Õ",
	"otilde": "õ",
	"otimesas": "⨶",
	"Otimes": "⨷",
	"otimes": "⊗",
	"Ouml": "Ö",
	"ouml": "ö",
	"ovbar": "⌽",
	"OverBar": "‾",
	"OverBrace": "⏞",
	"OverBracket": "⎴",
	"OverParenthesis": "⏜",
	"para": "¶",
	"parallel": "∥",
	"par": "∥",
	"parsim": "⫳",
	"parsl": "⫽",
	"part": "∂",
	"PartialD": "∂",
	"Pcy": "П",
	"pcy": "п",
	"percnt": "%",
	"period": ".",
	"permil": "‰",
	"perp": "⊥",
	"pertenk": "‱",
	"Pfr": "𝔓",
	"pfr": "𝔭",
	"Phi": "Φ",
	"phi": "φ",
	"phiv": "ϕ",
	"phmmat": "ℳ",
	"phone": "☎",
	"Pi": "Π",
	"pi": "π",
	"pitchfork": "⋔",
	"piv": "ϖ",
	"planck": "ℏ",
	"planckh": "ℎ",
	"plankv": "ℏ",
	"plusacir": "⨣",
	"plusb": "⊞",
	"pluscir": "⨢",
	"plus": "+",
	"plusdo": "∔",
	"plusdu": "⨥",
	"pluse": "⩲",
	"PlusMinus": "±",
	"plusmn": "±",
	"plussim": "⨦",
	"plustwo": "⨧",
	"pm": "±",
	"Poincareplane": "ℌ",
	"pointint": "⨕",
	"popf": "𝕡",
	"Popf": "ℙ",
	"pound": "£",
	"prap": "⪷",
	"Pr": "⪻",
	"pr": "≺",
	"prcue": "≼",
	"precapprox": "⪷",
	"prec": "≺",
	"preccurlyeq": "≼",
	"Precedes": "≺",
	"PrecedesEqual": "⪯",
	"PrecedesSlantEqual": "≼",
	"PrecedesTilde": "≾",
	"preceq": "⪯",
	"precnapprox": "⪹",
	"precneqq": "⪵",
	"precnsim": "⋨",
	"pre": "⪯",
	"prE": "⪳",
	"precsim": "≾",
	"prime": "′",
	"Prime": "″",
	"primes": "ℙ",
	"prnap": "⪹",
	"prnE": "⪵",
	"prnsim": "⋨",
	"prod": "∏",
	"Product": "∏",
	"profalar": "⌮",
	"profline": "⌒",
	"profsurf": "⌓",
	"prop": "∝",
	"Proportional": "∝",
	"Proportion": "∷",
	"propto": "∝",
	"prsim": "≾",
	"prurel": "⊰",
	"Pscr": "𝒫",
	"pscr": "𝓅",
	"Psi": "Ψ",
	"psi": "ψ",
	"puncsp": " ",
	"Qfr": "𝔔",
	"qfr": "𝔮",
	"qint": "⨌",
	"qopf": "𝕢",
	"Qopf": "ℚ",
	"qprime": "⁗",
	"Qscr": "𝒬",
	"qscr": "𝓆",
	"quaternions": "ℍ",
	"quatint": "⨖",
	"quest": "?",
	"questeq": "≟",
	"quot": "\"",
	"QUOT": "\"",
	"rAarr": "⇛",
	"race": "∽̱",
	"Racute": "Ŕ",
	"racute": "ŕ",
	"radic": "√",
	"raemptyv": "⦳",
	"rang": "⟩",
	"Rang": "⟫",
	"rangd": "⦒",
	"range": "⦥",
	"rangle": "⟩",
	"raquo": "»",
	"rarrap": "⥵",
	"rarrb": "⇥",
	"rarrbfs": "⤠",
	"rarrc": "⤳",
	"rarr": "→",
	"Rarr": "↠",
	"rArr": "⇒",
	"rarrfs": "⤞",
	"rarrhk": "↪",
	"rarrlp": "↬",
	"rarrpl": "⥅",
	"rarrsim": "⥴",
	"Rarrtl": "⤖",
	"rarrtl": "↣",
	"rarrw": "↝",
	"ratail": "⤚",
	"rAtail": "⤜",
	"ratio": "∶",
	"rationals": "ℚ",
	"rbarr": "⤍",
	"rBarr": "⤏",
	"RBarr": "⤐",
	"rbbrk": "❳",
	"rbrace": "}",
	"rbrack": "]",
	"rbrke": "⦌",
	"rbrksld": "⦎",
	"rbrkslu": "⦐",
	"Rcaron": "Ř",
	"rcaron": "ř",
	"Rcedil": "Ŗ",
	"rcedil": "ŗ",
	"rceil": "⌉",
	"rcub": "}",
	"Rcy": "Р",
	"rcy": "р",
	"rdca": "⤷",
	"rdldhar": "⥩",
	"rdquo": "”",
	"rdquor": "”",
	"rdsh": "↳",
	"real": "ℜ",
	"realine": "ℛ",
	"realpart": "ℜ",
	"reals": "ℝ",
	"Re": "ℜ",
	"rect": "▭",
	"reg": "®",
	"REG": "®",
	"ReverseElement": "∋",
	"ReverseEquilibrium": "⇋",
	"ReverseUpEquilibrium": "⥯",
	"rfisht": "⥽",
	"rfloor": "⌋",
	"rfr": "𝔯",
	"Rfr": "ℜ",
	"rHar": "⥤",
	"rhard": "⇁",
	"rharu": "⇀",
	"rharul": "⥬",
	"Rho": "Ρ",
	"rho": "ρ",
	"rhov": "ϱ",
	"RightAngleBracket": "⟩",
	"RightArrowBar": "⇥",
	"rightarrow": "→",
	"RightArrow": "→",
	"Rightarrow": "⇒",
	"RightArrowLeftArrow": "⇄",
	"rightarrowtail": "↣",
	"RightCeiling": "⌉",
	"RightDoubleBracket": "⟧",
	"RightDownTeeVector": "⥝",
	"RightDownVectorBar": "⥕",
	"RightDownVector": "⇂",
	"RightFloor": "⌋",
	"rightharpoondown": "⇁",
	"rightharpoonup": "⇀",
	"rightleftarrows": "⇄",
	"rightleftharpoons": "⇌",
	"rightrightarrows": "⇉",
	"rightsquigarrow": "↝",
	"RightTeeArrow": "↦",
	"RightTee": "⊢",
	"RightTeeVector": "⥛",
	"rightthreetimes": "⋌",
	"RightTriangleBar": "⧐",
	"RightTriangle": "⊳",
	"RightTriangleEqual": "⊵",
	"RightUpDownVector": "⥏",
	"RightUpTeeVector": "⥜",
	"RightUpVectorBar": "⥔",
	"RightUpVector": "↾",
	"RightVectorBar": "⥓",
	"RightVector": "⇀",
	"ring": "˚",
	"risingdotseq": "≓",
	"rlarr": "⇄",
	"rlhar": "⇌",
	"rlm": "‏",
	"rmoustache": "⎱",
	"rmoust": "⎱",
	"rnmid": "⫮",
	"roang": "⟭",
	"roarr": "⇾",
	"robrk": "⟧",
	"ropar": "⦆",
	"ropf": "𝕣",
	"Ropf": "ℝ",
	"roplus": "⨮",
	"rotimes": "⨵",
	"RoundImplies": "⥰",
	"rpar": ")",
	"rpargt": "⦔",
	"rppolint": "⨒",
	"rrarr": "⇉",
	"Rrightarrow": "⇛",
	"rsaquo": "›",
	"rscr": "𝓇",
	"Rscr": "ℛ",
	"rsh": "↱",
	"Rsh": "↱",
	"rsqb": "]",
	"rsquo": "’",
	"rsquor": "’",
	"rthree": "⋌",
	"rtimes": "⋊",
	"rtri": "▹",
	"rtrie": "⊵",
	"rtrif": "▸",
	"rtriltri": "⧎",
	"RuleDelayed": "⧴",
	"ruluhar": "⥨",
	"rx": "℞",
	"Sacute": "Ś",
	"sacute": "ś",
	"sbquo": "‚",
	"scap": "⪸",
	"Scaron": "Š",
	"scaron": "š",
	"Sc": "⪼",
	"sc": "≻",
	"sccue": "≽",
	"sce": "⪰",
	"scE": "⪴",
	"Scedil": "Ş",
	"scedil": "ş",
	"Scirc": "Ŝ",
	"scirc": "ŝ",
	"scnap": "⪺",
	"scnE": "⪶",
	"scnsim": "⋩",
	"scpolint": "⨓",
	"scsim": "≿",
	"Scy": "С",
	"scy": "с",
	"sdotb": "⊡",
	"sdot": "⋅",
	"sdote": "⩦",
	"searhk": "⤥",
	"searr": "↘",
	"seArr": "⇘",
	"searrow": "↘",
	"sect": "§",
	"semi": ";",
	"seswar": "⤩",
	"setminus": "∖",
	"setmn": "∖",
	"sext": "✶",
	"Sfr": "𝔖",
	"sfr": "𝔰",
	"sfrown": "⌢",
	"sharp": "♯",
	"SHCHcy": "Щ",
	"shchcy": "щ",
	"SHcy": "Ш",
	"shcy": "ш",
	"ShortDownArrow": "↓",
	"ShortLeftArrow": "←",
	"shortmid": "∣",
	"shortparallel": "∥",
	"ShortRightArrow": "→",
	"ShortUpArrow": "↑",
	"shy": "­",
	"Sigma": "Σ",
	"sigma": "σ",
	"sigmaf": "ς",
	"sigmav": "ς",
	"sim": "∼",
	"simdot": "⩪",
	"sime": "≃",
	"simeq": "≃",
	"simg": "⪞",
	"simgE": "⪠",
	"siml": "⪝",
	"simlE": "⪟",
	"simne": "≆",
	"simplus": "⨤",
	"simrarr": "⥲",
	"slarr": "←",
	"SmallCircle": "∘",
	"smallsetminus": "∖",
	"smashp": "⨳",
	"smeparsl": "⧤",
	"smid": "∣",
	"smile": "⌣",
	"smt": "⪪",
	"smte": "⪬",
	"smtes": "⪬︀",
	"SOFTcy": "Ь",
	"softcy": "ь",
	"solbar": "⌿",
	"solb": "⧄",
	"sol": "/",
	"Sopf": "𝕊",
	"sopf": "𝕤",
	"spades": "♠",
	"spadesuit": "♠",
	"spar": "∥",
	"sqcap": "⊓",
	"sqcaps": "⊓︀",
	"sqcup": "⊔",
	"sqcups": "⊔︀",
	"Sqrt": "√",
	"sqsub": "⊏",
	"sqsube": "⊑",
	"sqsubset": "⊏",
	"sqsubseteq": "⊑",
	"sqsup": "⊐",
	"sqsupe": "⊒",
	"sqsupset": "⊐",
	"sqsupseteq": "⊒",
	"square": "□",
	"Square": "□",
	"SquareIntersection": "⊓",
	"SquareSubset": "⊏",
	"SquareSubsetEqual": "⊑",
	"SquareSuperset": "⊐",
	"SquareSupersetEqual": "⊒",
	"SquareUnion": "⊔",
	"squarf": "▪",
	"squ": "□",
	"squf": "▪",
	"srarr": "→",
	"Sscr": "𝒮",
	"sscr": "𝓈",
	"ssetmn": "∖",
	"ssmile": "⌣",
	"sstarf": "⋆",
	"Star": "⋆",
	"star": "☆",
	"starf": "★",
	"straightepsilon": "ϵ",
	"straightphi": "ϕ",
	"strns": "¯",
	"sub": "⊂",
	"Sub": "⋐",
	"subdot": "⪽",
	"subE": "⫅",
	"sube": "⊆",
	"subedot": "⫃",
	"submult": "⫁",
	"subnE": "⫋",
	"subne": "⊊",
	"subplus": "⪿",
	"subrarr": "⥹",
	"subset": "⊂",
	"Subset": "⋐",
	"subseteq": "⊆",
	"subseteqq": "⫅",
	"SubsetEqual": "⊆",
	"subsetneq": "⊊",
	"subsetneqq": "⫋",
	"subsim": "⫇",
	"subsub": "⫕",
	"subsup": "⫓",
	"succapprox": "⪸",
	"succ": "≻",
	"succcurlyeq": "≽",
	"Succeeds": "≻",
	"SucceedsEqual": "⪰",
	"SucceedsSlantEqual": "≽",
	"SucceedsTilde": "≿",
	"succeq": "⪰",
	"succnapprox": "⪺",
	"succneqq": "⪶",
	"succnsim": "⋩",
	"succsim": "≿",
	"SuchThat": "∋",
	"sum": "∑",
	"Sum": "∑",
	"sung": "♪",
	"sup1": "¹",
	"sup2": "²",
	"sup3": "³",
	"sup": "⊃",
	"Sup": "⋑",
	"supdot": "⪾",
	"supdsub": "⫘",
	"supE": "⫆",
	"supe": "⊇",
	"supedot": "⫄",
	"Superset": "⊃",
	"SupersetEqual": "⊇",
	"suphsol": "⟉",
	"suphsub": "⫗",
	"suplarr": "⥻",
	"supmult": "⫂",
	"supnE": "⫌",
	"supne": "⊋",
	"supplus": "⫀",
	"supset": "⊃",
	"Supset": "⋑",
	"supseteq": "⊇",
	"supseteqq": "⫆",
	"supsetneq": "⊋",
	"supsetneqq": "⫌",
	"supsim": "⫈",
	"supsub": "⫔",
	"supsup": "⫖",
	"swarhk": "⤦",
	"swarr": "↙",
	"swArr": "⇙",
	"swarrow": "↙",
	"swnwar": "⤪",
	"szlig": "ß",
	"Tab": "\t",
	"target": "⌖",
	"Tau": "Τ",
	"tau": "τ",
	"tbrk": "⎴",
	"Tcaron": "Ť",
	"tcaron": "ť",
	"Tcedil": "Ţ",
	"tcedil": "ţ",
	"Tcy": "Т",
	"tcy": "т",
	"tdot": "⃛",
	"telrec": "⌕",
	"Tfr": "𝔗",
	"tfr": "𝔱",
	"there4": "∴",
	"therefore": "∴",
	"Therefore": "∴",
	"Theta": "Θ",
	"theta": "θ",
	"thetasym": "ϑ",
	"thetav": "ϑ",
	"thickapprox": "≈",
	"thicksim": "∼",
	"ThickSpace": "  ",
	"ThinSpace": " ",
	"thinsp": " ",
	"thkap": "≈",
	"thksim": "∼",
	"THORN": "Þ",
	"thorn": "þ",
	"tilde": "˜",
	"Tilde": "∼",
	"TildeEqual": "≃",
	"TildeFullEqual": "≅",
	"TildeTilde": "≈",
	"timesbar": "⨱",
	"timesb": "⊠",
	"times": "×",
	"timesd": "⨰",
	"tint": "∭",
	"toea": "⤨",
	"topbot": "⌶",
	"topcir": "⫱",
	"top": "⊤",
	"Topf": "𝕋",
	"topf": "𝕥",
	"topfork": "⫚",
	"tosa": "⤩",
	"tprime": "‴",
	"trade": "™",
	"TRADE": "™",
	"triangle": "▵",
	"triangledown": "▿",
	"triangleleft": "◃",
	"trianglelefteq": "⊴",
	"triangleq": "≜",
	"triangleright": "▹",
	"trianglerighteq": "⊵",
	"tridot": "◬",
	"trie": "≜",
	"triminus": "⨺",
	"TripleDot": "⃛",
	"triplus": "⨹",
	"trisb": "⧍",
	"tritime": "⨻",
	"trpezium": "⏢",
	"Tscr": "𝒯",
	"tscr": "𝓉",
	"TScy": "Ц",
	"tscy": "ц",
	"TSHcy": "Ћ",
	"tshcy": "ћ",
	"Tstrok": "Ŧ",
	"tstrok": "ŧ",
	"twixt": "≬",
	"twoheadleftarrow": "↞",
	"twoheadrightarrow": "↠",
	"Uacute": "Ú",
	"uacute": "ú",
	"uarr": "↑",
	"Uarr": "↟",
	"uArr": "⇑",
	"Uarrocir": "⥉",
	"Ubrcy": "Ў",
	"ubrcy": "ў",
	"Ubreve": "Ŭ",
	"ubreve": "ŭ",
	"Ucirc": "Û",
	"ucirc": "û",
	"Ucy": "У",
	"ucy": "у",
	"udarr": "⇅",
	"Udblac": "Ű",
	"udblac": "ű",
	"udhar": "⥮",
	"ufisht": "⥾",
	"Ufr": "𝔘",
	"ufr": "𝔲",
	"Ugrave": "Ù",
	"ugrave": "ù",
	"uHar": "⥣",
	"uharl": "↿",
	"uharr": "↾",
	"uhblk": "▀",
	"ulcorn": "⌜",
	"ulcorner": "⌜",
	"ulcrop": "⌏",
	"ultri": "◸",
	"Umacr": "Ū",
	"umacr": "ū",
	"uml": "¨",
	"UnderBar": "_",
	"UnderBrace": "⏟",
	"UnderBracket": "⎵",
	"UnderParenthesis": "⏝",
	"Union": "⋃",
	"UnionPlus": "⊎",
	"Uogon": "Ų",
	"uogon": "ų",
	"Uopf": "𝕌",
	"uopf": "𝕦",
	"UpArrowBar": "⤒",
	"uparrow": "↑",
	"UpArrow": "↑",
	"Uparrow": "⇑",
	"UpArrowDownArrow": "⇅",
	"updownarrow": "↕",
	"UpDownArrow": "↕",
	"Updownarrow": "⇕",
	"UpEquilibrium": "⥮",
	"upharpoonleft": "↿",
	"upharpoonright": "↾",
	"uplus": "⊎",
	"UpperLeftArrow": "↖",
	"UpperRightArrow": "↗",
	"upsi": "υ",
	"Upsi": "ϒ",
	"upsih": "ϒ",
	"Upsilon": "Υ",
	"upsilon": "υ",
	"UpTeeArrow": "↥",
	"UpTee": "⊥",
	"upuparrows": "⇈",
	"urcorn": "⌝",
	"urcorner": "⌝",
	"urcrop": "⌎",
	"Uring": "Ů",
	"uring": "ů",
	"urtri": "◹",
	"Uscr": "𝒰",
	"uscr": "𝓊",
	"utdot": "⋰",
	"Utilde": "Ũ",
	"utilde": "ũ",
	"utri": "▵",
	"utrif": "▴",
	"uuarr": "⇈",
	"Uuml": "Ü",
	"uuml": "ü",
	"uwangle": "⦧",
	"vangrt": "⦜",
	"varepsilon": "ϵ",
	"varkappa": "ϰ",
	"varnothing": "∅",
	"varphi": "ϕ",
	"varpi": "ϖ",
	"varpropto": "∝",
	"varr": "↕",
	"vArr": "⇕",
	"varrho": "ϱ",
	"varsigma": "ς",
	"varsubsetneq": "⊊︀",
	"varsubsetneqq": "⫋︀",
	"varsupsetneq": "⊋︀",
	"varsupsetneqq": "⫌︀",
	"vartheta": "ϑ",
	"vartriangleleft": "⊲",
	"vartriangleright": "⊳",
	"vBar": "⫨",
	"Vbar": "⫫",
	"vBarv": "⫩",
	"Vcy": "В",
	"vcy": "в",
	"vdash": "⊢",
	"vDash": "⊨",
	"Vdash": "⊩",
	"VDash": "⊫",
	"Vdashl": "⫦",
	"veebar": "⊻",
	"vee": "∨",
	"Vee": "⋁",
	"veeeq": "≚",
	"vellip": "⋮",
	"verbar": "|",
	"Verbar": "‖",
	"vert": "|",
	"Vert": "‖",
	"VerticalBar": "∣",
	"VerticalLine": "|",
	"VerticalSeparator": "❘",
	"VerticalTilde": "≀",
	"VeryThinSpace": " ",
	"Vfr": "𝔙",
	"vfr": "𝔳",
	"vltri": "⊲",
	"vnsub": "⊂⃒",
	"vnsup": "⊃⃒",
	"Vopf": "𝕍",
	"vopf": "𝕧",
	"vprop": "∝",
	"vrtri": "⊳",
	"Vscr": "𝒱",
	"vscr": "𝓋",
	"vsubnE": "⫋︀",
	"vsubne": "⊊︀",
	"vsupnE": "⫌︀",
	"vsupne": "⊋︀",
	"Vvdash": "⊪",
	"vzigzag": "⦚",
	"Wcirc": "Ŵ",
	"wcirc": "ŵ",
	"wedbar": "⩟",
	"wedge": "∧",
	"Wedge": "⋀",
	"wedgeq": "≙",
	"weierp": "℘",
	"Wfr": "𝔚",
	"wfr": "𝔴",
	"Wopf": "𝕎",
	"wopf": "𝕨",
	"wp": "℘",
	"wr": "≀",
	"wreath": "≀",
	"Wscr": "𝒲",
	"wscr": "𝓌",
	"xcap": "⋂",
	"xcirc": "◯",
	"xcup": "⋃",
	"xdtri": "▽",
	"Xfr": "𝔛",
	"xfr": "𝔵",
	"xharr": "⟷",
	"xhArr": "⟺",
	"Xi": "Ξ",
	"xi": "ξ",
	"xlarr": "⟵",
	"xlArr": "⟸",
	"xmap": "⟼",
	"xnis": "⋻",
	"xodot": "⨀",
	"Xopf": "𝕏",
	"xopf": "𝕩",
	"xoplus": "⨁",
	"xotime": "⨂",
	"xrarr": "⟶",
	"xrArr": "⟹",
	"Xscr": "𝒳",
	"xscr": "𝓍",
	"xsqcup": "⨆",
	"xuplus": "⨄",
	"xutri": "△",
	"xvee": "⋁",
	"xwedge": "⋀",
	"Yacute": "Ý",
	"yacute": "ý",
	"YAcy": "Я",
	"yacy": "я",
	"Ycirc": "Ŷ",
	"ycirc": "ŷ",
	"Ycy": "Ы",
	"ycy": "ы",
	"yen": "¥",
	"Yfr": "𝔜",
	"yfr": "𝔶",
	"YIcy": "Ї",
	"yicy": "ї",
	"Yopf": "𝕐",
	"yopf": "𝕪",
	"Yscr": "𝒴",
	"yscr": "𝓎",
	"YUcy": "Ю",
	"yucy": "ю",
	"yuml": "ÿ",
	"Yuml": "Ÿ",
	"Zacute": "Ź",
	"zacute": "ź",
	"Zcaron": "Ž",
	"zcaron": "ž",
	"Zcy": "З",
	"zcy": "з",
	"Zdot": "Ż",
	"zdot": "ż",
	"zeetrf": "ℨ",
	"ZeroWidthSpace": "​",
	"Zeta": "Ζ",
	"zeta": "ζ",
	"zfr": "𝔷",
	"Zfr": "ℨ",
	"ZHcy": "Ж",
	"zhcy": "ж",
	"zigrarr": "⇝",
	"zopf": "𝕫",
	"Zopf": "ℤ",
	"Zscr": "𝒵",
	"zscr": "𝓏",
	"zwj": "‍",
	"zwnj": "‌"
};

/***/ }),
/* 19 */
/***/ (function(module, exports) {

module.exports = {
	"amp": "&",
	"apos": "'",
	"gt": ">",
	"lt": "<",
	"quot": "\""
};

/***/ }),
/* 20 */
/***/ (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__(6)))

/***/ }),
/* 21 */
/***/ (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__(3);

/*<replacement>*/
var util = __webpack_require__(7);
util.inherits = __webpack_require__(1);
/*</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);
}

/***/ }),
/* 22 */
/***/ (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__(20);
/*</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__(7);
util.inherits = __webpack_require__(1);
/*</replacement>*/

/*<replacement>*/
var internalUtil = {
  deprecate: __webpack_require__(107)
};
/*</replacement>*/

/*<replacement>*/
var Stream;
(function () {
  try {
    Stream = __webpack_require__(15);
  } catch (_) {} finally {
    if (!Stream) Stream = __webpack_require__(9).EventEmitter;
  }
})();
/*</replacement>*/

var Buffer = __webpack_require__(2).Buffer;
/*<replacement>*/
var bufferShim = __webpack_require__(17);
/*</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__(3);

  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__(3);

  // 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__(6), __webpack_require__(106).setImmediate))

/***/ }),
/* 23 */
/***/ (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__(2).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;
}


/***/ }),
/* 24 */
/***/ (function(module, exports) {

module.exports = _;

/***/ }),
/* 25 */
/***/ (function(module, exports) {

module.exports =
/******/ (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;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// 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 = "/resources/js/";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./src/Common/Libraries/Websockets/CloudShareWebSockets/index.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./node_modules/core-js/modules/_a-function.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_a-function.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = function(it){
  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
  return it;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_a-number-value.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/_a-number-value.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var cof = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js");
module.exports = function(it, msg){
  if(typeof it != 'number' && cof(it) != 'Number')throw TypeError(msg);
  return +it;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_add-to-unscopables.js":
/*!*************************************************************!*\
  !*** ./node_modules/core-js/modules/_add-to-unscopables.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 22.1.3.31 Array.prototype[@@unscopables]
var UNSCOPABLES = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('unscopables')
  , ArrayProto  = Array.prototype;
if(ArrayProto[UNSCOPABLES] == undefined)__webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")(ArrayProto, UNSCOPABLES, {});
module.exports = function(key){
  ArrayProto[UNSCOPABLES][key] = true;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_an-instance.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_an-instance.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_an-object.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_an-object.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js");
module.exports = function(it){
  if(!isObject(it))throw TypeError(it + ' is not an object!');
  return it;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_array-copy-within.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/_array-copy-within.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)

var toObject = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , toIndex  = __webpack_require__(/*! ./_to-index */ "./node_modules/core-js/modules/_to-index.js")
  , toLength = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js");

module.exports = [].copyWithin || function copyWithin(target/*= 0*/, start/*= 0, end = @length*/){
  var O     = toObject(this)
    , len   = toLength(O.length)
    , to    = toIndex(target, len)
    , from  = toIndex(start, len)
    , end   = arguments.length > 2 ? arguments[2] : undefined
    , count = Math.min((end === undefined ? len : toIndex(end, len)) - from, len - to)
    , inc   = 1;
  if(from < to && to < from + count){
    inc  = -1;
    from += count - 1;
    to   += count - 1;
  }
  while(count-- > 0){
    if(from in O)O[to] = O[from];
    else delete O[to];
    to   += inc;
    from += inc;
  } return O;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_array-fill.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_array-fill.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)

var toObject = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , toIndex  = __webpack_require__(/*! ./_to-index */ "./node_modules/core-js/modules/_to-index.js")
  , toLength = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js");
module.exports = function fill(value /*, start = 0, end = @length */){
  var O      = toObject(this)
    , length = toLength(O.length)
    , aLen   = arguments.length
    , index  = toIndex(aLen > 1 ? arguments[1] : undefined, length)
    , end    = aLen > 2 ? arguments[2] : undefined
    , endPos = end === undefined ? length : toIndex(end, length);
  while(endPos > index)O[index++] = value;
  return O;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_array-from-iterable.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/_array-from-iterable.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var forOf = __webpack_require__(/*! ./_for-of */ "./node_modules/core-js/modules/_for-of.js");

module.exports = function(iter, ITERATOR){
  var result = [];
  forOf(iter, false, result.push, result, ITERATOR);
  return result;
};


/***/ }),

/***/ "./node_modules/core-js/modules/_array-includes.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/_array-includes.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// false -> Array#indexOf
// true  -> Array#includes
var toIObject = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , toLength  = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , toIndex   = __webpack_require__(/*! ./_to-index */ "./node_modules/core-js/modules/_to-index.js");
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;
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_array-methods.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_array-methods.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 0 -> Array#forEach
// 1 -> Array#map
// 2 -> Array#filter
// 3 -> Array#some
// 4 -> Array#every
// 5 -> Array#find
// 6 -> Array#findIndex
var ctx      = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
  , IObject  = __webpack_require__(/*! ./_iobject */ "./node_modules/core-js/modules/_iobject.js")
  , toObject = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , toLength = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , asc      = __webpack_require__(/*! ./_array-species-create */ "./node_modules/core-js/modules/_array-species-create.js");
module.exports = function(TYPE, $create){
  var IS_MAP        = TYPE == 1
    , IS_FILTER     = TYPE == 2
    , IS_SOME       = TYPE == 3
    , IS_EVERY      = TYPE == 4
    , IS_FIND_INDEX = TYPE == 6
    , NO_HOLES      = TYPE == 5 || IS_FIND_INDEX
    , create        = $create || asc;
  return function($this, callbackfn, that){
    var O      = toObject($this)
      , self   = IObject(O)
      , f      = ctx(callbackfn, that, 3)
      , length = toLength(self.length)
      , index  = 0
      , result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined
      , val, res;
    for(;length > index; index++)if(NO_HOLES || index in self){
      val = self[index];
      res = f(val, index, O);
      if(TYPE){
        if(IS_MAP)result[index] = res;            // map
        else if(res)switch(TYPE){
          case 3: return true;                    // some
          case 5: return val;                     // find
          case 6: return index;                   // findIndex
          case 2: result.push(val);               // filter
        } else if(IS_EVERY)return false;          // every
      }
    }
    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_array-reduce.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/_array-reduce.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , toObject  = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , IObject   = __webpack_require__(/*! ./_iobject */ "./node_modules/core-js/modules/_iobject.js")
  , toLength  = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js");

module.exports = function(that, callbackfn, aLen, memo, isRight){
  aFunction(callbackfn);
  var O      = toObject(that)
    , self   = IObject(O)
    , length = toLength(O.length)
    , index  = isRight ? length - 1 : 0
    , i      = isRight ? -1 : 1;
  if(aLen < 2)for(;;){
    if(index in self){
      memo = self[index];
      index += i;
      break;
    }
    index += i;
    if(isRight ? index < 0 : length <= index){
      throw TypeError('Reduce of empty array with no initial value');
    }
  }
  for(;isRight ? index >= 0 : length > index; index += i)if(index in self){
    memo = callbackfn(memo, self[index], index, O);
  }
  return memo;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_array-species-constructor.js":
/*!********************************************************************!*\
  !*** ./node_modules/core-js/modules/_array-species-constructor.js ***!
  \********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , isArray  = __webpack_require__(/*! ./_is-array */ "./node_modules/core-js/modules/_is-array.js")
  , SPECIES  = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('species');

module.exports = function(original){
  var C;
  if(isArray(original)){
    C = original.constructor;
    // cross-realm fallback
    if(typeof C == 'function' && (C === Array || isArray(C.prototype)))C = undefined;
    if(isObject(C)){
      C = C[SPECIES];
      if(C === null)C = undefined;
    }
  } return C === undefined ? Array : C;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_array-species-create.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/_array-species-create.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
var speciesConstructor = __webpack_require__(/*! ./_array-species-constructor */ "./node_modules/core-js/modules/_array-species-constructor.js");

module.exports = function(original, length){
  return new (speciesConstructor(original))(length);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_bind.js":
/*!***********************************************!*\
  !*** ./node_modules/core-js/modules/_bind.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var aFunction  = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , isObject   = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , invoke     = __webpack_require__(/*! ./_invoke */ "./node_modules/core-js/modules/_invoke.js")
  , arraySlice = [].slice
  , factories  = {};

var construct = function(F, len, args){
  if(!(len in factories)){
    for(var n = [], i = 0; i < len; i++)n[i] = 'a[' + i + ']';
    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');
  } return factories[len](F, args);
};

module.exports = Function.bind || function bind(that /*, args... */){
  var fn       = aFunction(this)
    , partArgs = arraySlice.call(arguments, 1);
  var bound = function(/* args... */){
    var args = partArgs.concat(arraySlice.call(arguments));
    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);
  };
  if(isObject(fn.prototype))bound.prototype = fn.prototype;
  return bound;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_classof.js":
/*!**************************************************!*\
  !*** ./node_modules/core-js/modules/_classof.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// getting tag from 19.1.3.6 Object.prototype.toString()
var cof = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js")
  , TAG = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_cof.js":
/*!**********************************************!*\
  !*** ./node_modules/core-js/modules/_cof.js ***!
  \**********************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var toString = {}.toString;

module.exports = function(it){
  return toString.call(it).slice(8, -1);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_collection-strong.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/_collection-strong.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var dP          = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f
  , create      = __webpack_require__(/*! ./_object-create */ "./node_modules/core-js/modules/_object-create.js")
  , redefineAll = __webpack_require__(/*! ./_redefine-all */ "./node_modules/core-js/modules/_redefine-all.js")
  , ctx         = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
  , anInstance  = __webpack_require__(/*! ./_an-instance */ "./node_modules/core-js/modules/_an-instance.js")
  , defined     = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js")
  , forOf       = __webpack_require__(/*! ./_for-of */ "./node_modules/core-js/modules/_for-of.js")
  , $iterDefine = __webpack_require__(/*! ./_iter-define */ "./node_modules/core-js/modules/_iter-define.js")
  , step        = __webpack_require__(/*! ./_iter-step */ "./node_modules/core-js/modules/_iter-step.js")
  , setSpecies  = __webpack_require__(/*! ./_set-species */ "./node_modules/core-js/modules/_set-species.js")
  , DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js")
  , fastKey     = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js").fastKey
  , SIZE        = DESCRIPTORS ? '_s' : 'size';

var getEntry = function(that, key){
  // fast case
  var index = fastKey(key), entry;
  if(index !== 'F')return that._i[index];
  // frozen object case
  for(entry = that._f; entry; entry = entry.n){
    if(entry.k == key)return entry;
  }
};

module.exports = {
  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
    var C = wrapper(function(that, iterable){
      anInstance(that, C, NAME, '_i');
      that._i = create(null); // index
      that._f = undefined;    // first entry
      that._l = undefined;    // last entry
      that[SIZE] = 0;         // size
      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.1.3.1 Map.prototype.clear()
      // 23.2.3.2 Set.prototype.clear()
      clear: function clear(){
        for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){
          entry.r = true;
          if(entry.p)entry.p = entry.p.n = undefined;
          delete data[entry.i];
        }
        that._f = that._l = undefined;
        that[SIZE] = 0;
      },
      // 23.1.3.3 Map.prototype.delete(key)
      // 23.2.3.4 Set.prototype.delete(value)
      'delete': function(key){
        var that  = this
          , entry = getEntry(that, key);
        if(entry){
          var next = entry.n
            , prev = entry.p;
          delete that._i[entry.i];
          entry.r = true;
          if(prev)prev.n = next;
          if(next)next.p = prev;
          if(that._f == entry)that._f = next;
          if(that._l == entry)that._l = prev;
          that[SIZE]--;
        } return !!entry;
      },
      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
      forEach: function forEach(callbackfn /*, that = undefined */){
        anInstance(this, C, 'forEach');
        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)
          , entry;
        while(entry = entry ? entry.n : this._f){
          f(entry.v, entry.k, this);
          // revert to the last existing entry
          while(entry && entry.r)entry = entry.p;
        }
      },
      // 23.1.3.7 Map.prototype.has(key)
      // 23.2.3.7 Set.prototype.has(value)
      has: function has(key){
        return !!getEntry(this, key);
      }
    });
    if(DESCRIPTORS)dP(C.prototype, 'size', {
      get: function(){
        return defined(this[SIZE]);
      }
    });
    return C;
  },
  def: function(that, key, value){
    var entry = getEntry(that, key)
      , prev, index;
    // change existing entry
    if(entry){
      entry.v = value;
    // create new entry
    } else {
      that._l = entry = {
        i: index = fastKey(key, true), // <- index
        k: key,                        // <- key
        v: value,                      // <- value
        p: prev = that._l,             // <- previous entry
        n: undefined,                  // <- next entry
        r: false                       // <- removed
      };
      if(!that._f)that._f = entry;
      if(prev)prev.n = entry;
      that[SIZE]++;
      // add to index
      if(index !== 'F')that._i[index] = entry;
    } return that;
  },
  getEntry: getEntry,
  setStrong: function(C, NAME, IS_MAP){
    // add .keys, .values, .entries, [@@iterator]
    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
    $iterDefine(C, NAME, function(iterated, kind){
      this._t = iterated;  // target
      this._k = kind;      // kind
      this._l = undefined; // previous
    }, function(){
      var that  = this
        , kind  = that._k
        , entry = that._l;
      // revert to the last existing entry
      while(entry && entry.r)entry = entry.p;
      // get next entry
      if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){
        // or finish the iteration
        that._t = undefined;
        return step(1);
      }
      // return step by kind
      if(kind == 'keys'  )return step(0, entry.k);
      if(kind == 'values')return step(0, entry.v);
      return step(0, [entry.k, entry.v]);
    }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true);

    // add [@@species], 23.1.2.2, 23.2.2.2
    setSpecies(NAME);
  }
};

/***/ }),

/***/ "./node_modules/core-js/modules/_collection-to-json.js":
/*!*************************************************************!*\
  !*** ./node_modules/core-js/modules/_collection-to-json.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var classof = __webpack_require__(/*! ./_classof */ "./node_modules/core-js/modules/_classof.js")
  , from    = __webpack_require__(/*! ./_array-from-iterable */ "./node_modules/core-js/modules/_array-from-iterable.js");
module.exports = function(NAME){
  return function toJSON(){
    if(classof(this) != NAME)throw TypeError(NAME + "#toJSON isn't generic");
    return from(this);
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_collection-weak.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/_collection-weak.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var redefineAll       = __webpack_require__(/*! ./_redefine-all */ "./node_modules/core-js/modules/_redefine-all.js")
  , getWeak           = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js").getWeak
  , anObject          = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , isObject          = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , anInstance        = __webpack_require__(/*! ./_an-instance */ "./node_modules/core-js/modules/_an-instance.js")
  , forOf             = __webpack_require__(/*! ./_for-of */ "./node_modules/core-js/modules/_for-of.js")
  , createArrayMethod = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")
  , $has              = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , arrayFind         = createArrayMethod(5)
  , arrayFindIndex    = createArrayMethod(6)
  , id                = 0;

// fallback for uncaught frozen keys
var uncaughtFrozenStore = function(that){
  return that._l || (that._l = new UncaughtFrozenStore);
};
var UncaughtFrozenStore = function(){
  this.a = [];
};
var findUncaughtFrozen = function(store, key){
  return arrayFind(store.a, function(it){
    return it[0] === key;
  });
};
UncaughtFrozenStore.prototype = {
  get: function(key){
    var entry = findUncaughtFrozen(this, key);
    if(entry)return entry[1];
  },
  has: function(key){
    return !!findUncaughtFrozen(this, key);
  },
  set: function(key, value){
    var entry = findUncaughtFrozen(this, key);
    if(entry)entry[1] = value;
    else this.a.push([key, value]);
  },
  'delete': function(key){
    var index = arrayFindIndex(this.a, function(it){
      return it[0] === key;
    });
    if(~index)this.a.splice(index, 1);
    return !!~index;
  }
};

module.exports = {
  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
    var C = wrapper(function(that, iterable){
      anInstance(that, C, NAME, '_i');
      that._i = id++;      // collection id
      that._l = undefined; // leak store for uncaught frozen objects
      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.3.3.2 WeakMap.prototype.delete(key)
      // 23.4.3.3 WeakSet.prototype.delete(value)
      'delete': function(key){
        if(!isObject(key))return false;
        var data = getWeak(key);
        if(data === true)return uncaughtFrozenStore(this)['delete'](key);
        return data && $has(data, this._i) && delete data[this._i];
      },
      // 23.3.3.4 WeakMap.prototype.has(key)
      // 23.4.3.4 WeakSet.prototype.has(value)
      has: function has(key){
        if(!isObject(key))return false;
        var data = getWeak(key);
        if(data === true)return uncaughtFrozenStore(this).has(key);
        return data && $has(data, this._i);
      }
    });
    return C;
  },
  def: function(that, key, value){
    var data = getWeak(anObject(key), true);
    if(data === true)uncaughtFrozenStore(that).set(key, value);
    else data[that._i] = value;
    return that;
  },
  ufstore: uncaughtFrozenStore
};

/***/ }),

/***/ "./node_modules/core-js/modules/_collection.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_collection.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var global            = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , $export           = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , redefine          = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")
  , redefineAll       = __webpack_require__(/*! ./_redefine-all */ "./node_modules/core-js/modules/_redefine-all.js")
  , meta              = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js")
  , forOf             = __webpack_require__(/*! ./_for-of */ "./node_modules/core-js/modules/_for-of.js")
  , anInstance        = __webpack_require__(/*! ./_an-instance */ "./node_modules/core-js/modules/_an-instance.js")
  , isObject          = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , fails             = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , $iterDetect       = __webpack_require__(/*! ./_iter-detect */ "./node_modules/core-js/modules/_iter-detect.js")
  , setToStringTag    = __webpack_require__(/*! ./_set-to-string-tag */ "./node_modules/core-js/modules/_set-to-string-tag.js")
  , inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ "./node_modules/core-js/modules/_inherit-if-required.js");

module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){
  var Base  = global[NAME]
    , C     = Base
    , ADDER = IS_MAP ? 'set' : 'add'
    , proto = C && C.prototype
    , O     = {};
  var fixMethod = function(KEY){
    var fn = proto[KEY];
    redefine(proto, KEY,
      KEY == 'delete' ? function(a){
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'has' ? function has(a){
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'get' ? function get(a){
        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; }
        : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; }
    );
  };
  if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){
    new C().entries().next();
  }))){
    // create collection constructor
    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
    redefineAll(C.prototype, methods);
    meta.NEED = true;
  } else {
    var instance             = new C
      // early implementations not supports chaining
      , HASNT_CHAINING       = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance
      // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false
      , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); })
      // most early implementations doesn't supports iterables, most modern - not close it correctly
      , ACCEPT_ITERABLES     = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new
      // for early implementations -0 and +0 not the same
      , BUGGY_ZERO = !IS_WEAK && fails(function(){
        // V8 ~ Chromium 42- fails only with 5+ elements
        var $instance = new C()
          , index     = 5;
        while(index--)$instance[ADDER](index, index);
        return !$instance.has(-0);
      });
    if(!ACCEPT_ITERABLES){ 
      C = wrapper(function(target, iterable){
        anInstance(target, C, NAME);
        var that = inheritIfRequired(new Base, target, C);
        if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
        return that;
      });
      C.prototype = proto;
      proto.constructor = C;
    }
    if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){
      fixMethod('delete');
      fixMethod('has');
      IS_MAP && fixMethod('get');
    }
    if(BUGGY_ZERO || HASNT_CHAINING)fixMethod(ADDER);
    // weak collections should not contains .clear method
    if(IS_WEAK && proto.clear)delete proto.clear;
  }

  setToStringTag(C, NAME);

  O[NAME] = C;
  $export($export.G + $export.W + $export.F * (C != Base), O);

  if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP);

  return C;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_core.js":
/*!***********************************************!*\
  !*** ./node_modules/core-js/modules/_core.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var core = module.exports = {version: '2.4.0'};
if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef

/***/ }),

/***/ "./node_modules/core-js/modules/_create-property.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/_create-property.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $defineProperty = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
  , createDesc      = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js");

module.exports = function(object, index, value){
  if(index in object)$defineProperty.f(object, index, createDesc(0, value));
  else object[index] = value;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_ctx.js":
/*!**********************************************!*\
  !*** ./node_modules/core-js/modules/_ctx.js ***!
  \**********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// optional / simple context binding
var aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js");
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);
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_date-to-primitive.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/_date-to-primitive.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var anObject    = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , toPrimitive = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
  , NUMBER      = 'number';

module.exports = function(hint){
  if(hint !== 'string' && hint !== NUMBER && hint !== 'default')throw TypeError('Incorrect hint');
  return toPrimitive(anObject(this), hint != NUMBER);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_defined.js":
/*!**************************************************!*\
  !*** ./node_modules/core-js/modules/_defined.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_descriptors.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_descriptors.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// Thank's IE8 for his funny defineProperty
module.exports = !__webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
});

/***/ }),

/***/ "./node_modules/core-js/modules/_dom-create.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_dom-create.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , document = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").document
  // in old IE typeof document.createElement is 'object'
  , is = isObject(document) && isObject(document.createElement);
module.exports = function(it){
  return is ? document.createElement(it) : {};
};

/***/ }),

/***/ "./node_modules/core-js/modules/_enum-bug-keys.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_enum-bug-keys.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// IE 8- don't enum bug keys
module.exports = (
  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
).split(',');

/***/ }),

/***/ "./node_modules/core-js/modules/_enum-keys.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_enum-keys.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// all enumerable object keys, includes symbols
var getKeys = __webpack_require__(/*! ./_object-keys */ "./node_modules/core-js/modules/_object-keys.js")
  , gOPS    = __webpack_require__(/*! ./_object-gops */ "./node_modules/core-js/modules/_object-gops.js")
  , pIE     = __webpack_require__(/*! ./_object-pie */ "./node_modules/core-js/modules/_object-pie.js");
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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_export.js":
/*!*************************************************!*\
  !*** ./node_modules/core-js/modules/_export.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var global    = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , core      = __webpack_require__(/*! ./_core */ "./node_modules/core-js/modules/_core.js")
  , hide      = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , redefine  = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")
  , ctx       = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
  , 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
    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]
    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
    , expProto  = exports[PROTOTYPE] || (exports[PROTOTYPE] = {})
    , key, own, out, exp;
  if(IS_GLOBAL)source = name;
  for(key in source){
    // contains in native
    own = !IS_FORCED && target && target[key] !== undefined;
    // export native or passed
    out = (own ? target : source)[key];
    // bind timers to global for call from export context
    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
    // extend global
    if(target)redefine(target, key, out, type & $export.U);
    // export
    if(exports[key] != out)hide(exports, key, exp);
    if(IS_PROTO && expProto[key] != out)expProto[key] = out;
  }
};
global.core = core;
// 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;

/***/ }),

/***/ "./node_modules/core-js/modules/_fails-is-regexp.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/_fails-is-regexp.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var MATCH = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('match');
module.exports = function(KEY){
  var re = /./;
  try {
    '/./'[KEY](re);
  } catch(e){
    try {
      re[MATCH] = false;
      return !'/./'[KEY](re);
    } catch(f){ /* empty */ }
  } return true;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_fails.js":
/*!************************************************!*\
  !*** ./node_modules/core-js/modules/_fails.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = function(exec){
  try {
    return !!exec();
  } catch(e){
    return true;
  }
};

/***/ }),

/***/ "./node_modules/core-js/modules/_fix-re-wks.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_fix-re-wks.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var hide     = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , redefine = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")
  , fails    = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , defined  = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js")
  , wks      = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js");

module.exports = function(KEY, length, exec){
  var SYMBOL   = wks(KEY)
    , fns      = exec(defined, SYMBOL, ''[KEY])
    , strfn    = fns[0]
    , rxfn     = fns[1];
  if(fails(function(){
    var O = {};
    O[SYMBOL] = function(){ return 7; };
    return ''[KEY](O) != 7;
  })){
    redefine(String.prototype, KEY, strfn);
    hide(RegExp.prototype, SYMBOL, length == 2
      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
      // 21.2.5.11 RegExp.prototype[@@split](string, limit)
      ? function(string, arg){ return rxfn.call(string, this, arg); }
      // 21.2.5.6 RegExp.prototype[@@match](string)
      // 21.2.5.9 RegExp.prototype[@@search](string)
      : function(string){ return rxfn.call(string, this); }
    );
  }
};

/***/ }),

/***/ "./node_modules/core-js/modules/_flags.js":
/*!************************************************!*\
  !*** ./node_modules/core-js/modules/_flags.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 21.2.5.3 get RegExp.prototype.flags
var anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");
module.exports = function(){
  var that   = anObject(this)
    , result = '';
  if(that.global)     result += 'g';
  if(that.ignoreCase) result += 'i';
  if(that.multiline)  result += 'm';
  if(that.unicode)    result += 'u';
  if(that.sticky)     result += 'y';
  return result;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_for-of.js":
/*!*************************************************!*\
  !*** ./node_modules/core-js/modules/_for-of.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var ctx         = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
  , call        = __webpack_require__(/*! ./_iter-call */ "./node_modules/core-js/modules/_iter-call.js")
  , isArrayIter = __webpack_require__(/*! ./_is-array-iter */ "./node_modules/core-js/modules/_is-array-iter.js")
  , anObject    = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , toLength    = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , getIterFn   = __webpack_require__(/*! ./core.get-iterator-method */ "./node_modules/core-js/modules/core.get-iterator-method.js")
  , 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;

/***/ }),

/***/ "./node_modules/core-js/modules/_global.js":
/*!*************************************************!*\
  !*** ./node_modules/core-js/modules/_global.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (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

/***/ }),

/***/ "./node_modules/core-js/modules/_has.js":
/*!**********************************************!*\
  !*** ./node_modules/core-js/modules/_has.js ***!
  \**********************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var hasOwnProperty = {}.hasOwnProperty;
module.exports = function(it, key){
  return hasOwnProperty.call(it, key);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_hide.js":
/*!***********************************************!*\
  !*** ./node_modules/core-js/modules/_hide.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var dP         = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
  , createDesc = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js");
module.exports = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") ? function(object, key, value){
  return dP.f(object, key, createDesc(1, value));
} : function(object, key, value){
  object[key] = value;
  return object;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_html.js":
/*!***********************************************!*\
  !*** ./node_modules/core-js/modules/_html.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").document && document.documentElement;

/***/ }),

/***/ "./node_modules/core-js/modules/_ie8-dom-define.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/_ie8-dom-define.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = !__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && !__webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ "./node_modules/core-js/modules/_dom-create.js")('div'), 'a', {get: function(){ return 7; }}).a != 7;
});

/***/ }),

/***/ "./node_modules/core-js/modules/_inherit-if-required.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/_inherit-if-required.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var isObject       = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , setPrototypeOf = __webpack_require__(/*! ./_set-proto */ "./node_modules/core-js/modules/_set-proto.js").set;
module.exports = function(that, target, C){
  var P, S = target.constructor;
  if(S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf){
    setPrototypeOf(that, P);
  } return that;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_invoke.js":
/*!*************************************************!*\
  !*** ./node_modules/core-js/modules/_invoke.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (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);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_iobject.js":
/*!**************************************************!*\
  !*** ./node_modules/core-js/modules/_iobject.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// fallback for non-array-like ES3 and non-enumerable old V8 strings
var cof = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js");
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
  return cof(it) == 'String' ? it.split('') : Object(it);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_is-array-iter.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_is-array-iter.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// check on default Array iterator
var Iterators  = __webpack_require__(/*! ./_iterators */ "./node_modules/core-js/modules/_iterators.js")
  , ITERATOR   = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('iterator')
  , ArrayProto = Array.prototype;

module.exports = function(it){
  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_is-array.js":
/*!***************************************************!*\
  !*** ./node_modules/core-js/modules/_is-array.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 7.2.2 IsArray(argument)
var cof = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js");
module.exports = Array.isArray || function isArray(arg){
  return cof(arg) == 'Array';
};

/***/ }),

/***/ "./node_modules/core-js/modules/_is-integer.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_is-integer.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.3 Number.isInteger(number)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , floor    = Math.floor;
module.exports = function isInteger(it){
  return !isObject(it) && isFinite(it) && floor(it) === it;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_is-object.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_is-object.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = function(it){
  return typeof it === 'object' ? it !== null : typeof it === 'function';
};

/***/ }),

/***/ "./node_modules/core-js/modules/_is-regexp.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_is-regexp.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 7.2.8 IsRegExp(argument)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , cof      = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js")
  , MATCH    = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('match');
module.exports = function(it){
  var isRegExp;
  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
};

/***/ }),

/***/ "./node_modules/core-js/modules/_iter-call.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_iter-call.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// call something on iterator step with safe closing on error
var anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");
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;
  }
};

/***/ }),

/***/ "./node_modules/core-js/modules/_iter-create.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_iter-create.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var create         = __webpack_require__(/*! ./_object-create */ "./node_modules/core-js/modules/_object-create.js")
  , descriptor     = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js")
  , setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ "./node_modules/core-js/modules/_set-to-string-tag.js")
  , IteratorPrototype = {};

// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
__webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")(IteratorPrototype, __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('iterator'), function(){ return this; });

module.exports = function(Constructor, NAME, next){
  Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});
  setToStringTag(Constructor, NAME + ' Iterator');
};

/***/ }),

/***/ "./node_modules/core-js/modules/_iter-define.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_iter-define.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var LIBRARY        = __webpack_require__(/*! ./_library */ "./node_modules/core-js/modules/_library.js")
  , $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , redefine       = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")
  , hide           = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , has            = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , Iterators      = __webpack_require__(/*! ./_iterators */ "./node_modules/core-js/modules/_iterators.js")
  , $iterCreate    = __webpack_require__(/*! ./_iter-create */ "./node_modules/core-js/modules/_iter-create.js")
  , setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ "./node_modules/core-js/modules/_set-to-string-tag.js")
  , getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , ITERATOR       = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_iter-detect.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_iter-detect.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var ITERATOR     = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_iter-step.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_iter-step.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = function(done, value){
  return {value: value, done: !!done};
};

/***/ }),

/***/ "./node_modules/core-js/modules/_iterators.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_iterators.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = {};

/***/ }),

/***/ "./node_modules/core-js/modules/_keyof.js":
/*!************************************************!*\
  !*** ./node_modules/core-js/modules/_keyof.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var getKeys   = __webpack_require__(/*! ./_object-keys */ "./node_modules/core-js/modules/_object-keys.js")
  , toIObject = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js");
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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_library.js":
/*!**************************************************!*\
  !*** ./node_modules/core-js/modules/_library.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = false;

/***/ }),

/***/ "./node_modules/core-js/modules/_math-expm1.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_math-expm1.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// 20.2.2.14 Math.expm1(x)
var $expm1 = Math.expm1;
module.exports = (!$expm1
  // Old FF bug
  || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168
  // Tor Browser bug
  || $expm1(-2e-17) != -2e-17
) ? function expm1(x){
  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;
} : $expm1;

/***/ }),

/***/ "./node_modules/core-js/modules/_math-log1p.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_math-log1p.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// 20.2.2.20 Math.log1p(x)
module.exports = Math.log1p || function log1p(x){
  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_math-sign.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_math-sign.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// 20.2.2.28 Math.sign(x)
module.exports = Math.sign || function sign(x){
  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_meta.js":
/*!***********************************************!*\
  !*** ./node_modules/core-js/modules/_meta.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var META     = __webpack_require__(/*! ./_uid */ "./node_modules/core-js/modules/_uid.js")('meta')
  , isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , has      = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , setDesc  = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f
  , id       = 0;
var isExtensible = Object.isExtensible || function(){
  return true;
};
var FREEZE = !__webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(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
};

/***/ }),

/***/ "./node_modules/core-js/modules/_metadata.js":
/*!***************************************************!*\
  !*** ./node_modules/core-js/modules/_metadata.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var Map     = __webpack_require__(/*! ./es6.map */ "./node_modules/core-js/modules/es6.map.js")
  , $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , shared  = __webpack_require__(/*! ./_shared */ "./node_modules/core-js/modules/_shared.js")('metadata')
  , store   = shared.store || (shared.store = new (__webpack_require__(/*! ./es6.weak-map */ "./node_modules/core-js/modules/es6.weak-map.js")));

var getOrCreateMetadataMap = function(target, targetKey, create){
  var targetMetadata = store.get(target);
  if(!targetMetadata){
    if(!create)return undefined;
    store.set(target, targetMetadata = new Map);
  }
  var keyMetadata = targetMetadata.get(targetKey);
  if(!keyMetadata){
    if(!create)return undefined;
    targetMetadata.set(targetKey, keyMetadata = new Map);
  } return keyMetadata;
};
var ordinaryHasOwnMetadata = function(MetadataKey, O, P){
  var metadataMap = getOrCreateMetadataMap(O, P, false);
  return metadataMap === undefined ? false : metadataMap.has(MetadataKey);
};
var ordinaryGetOwnMetadata = function(MetadataKey, O, P){
  var metadataMap = getOrCreateMetadataMap(O, P, false);
  return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);
};
var ordinaryDefineOwnMetadata = function(MetadataKey, MetadataValue, O, P){
  getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);
};
var ordinaryOwnMetadataKeys = function(target, targetKey){
  var metadataMap = getOrCreateMetadataMap(target, targetKey, false)
    , keys        = [];
  if(metadataMap)metadataMap.forEach(function(_, key){ keys.push(key); });
  return keys;
};
var toMetaKey = function(it){
  return it === undefined || typeof it == 'symbol' ? it : String(it);
};
var exp = function(O){
  $export($export.S, 'Reflect', O);
};

module.exports = {
  store: store,
  map: getOrCreateMetadataMap,
  has: ordinaryHasOwnMetadata,
  get: ordinaryGetOwnMetadata,
  set: ordinaryDefineOwnMetadata,
  keys: ordinaryOwnMetadataKeys,
  key: toMetaKey,
  exp: exp
};

/***/ }),

/***/ "./node_modules/core-js/modules/_microtask.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_microtask.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var global    = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , macrotask = __webpack_require__(/*! ./_task */ "./node_modules/core-js/modules/_task.js").set
  , Observer  = global.MutationObserver || global.WebKitMutationObserver
  , process   = global.process
  , Promise   = global.Promise
  , isNode    = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js")(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;
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-assign.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_object-assign.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 19.1.2.1 Object.assign(target, source, ...)
var getKeys  = __webpack_require__(/*! ./_object-keys */ "./node_modules/core-js/modules/_object-keys.js")
  , gOPS     = __webpack_require__(/*! ./_object-gops */ "./node_modules/core-js/modules/_object-gops.js")
  , pIE      = __webpack_require__(/*! ./_object-pie */ "./node_modules/core-js/modules/_object-pie.js")
  , toObject = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , IObject  = __webpack_require__(/*! ./_iobject */ "./node_modules/core-js/modules/_iobject.js")
  , $assign  = Object.assign;

// should work with symbols and should have deterministic property order (V8 bug)
module.exports = !$assign || __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(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;

/***/ }),

/***/ "./node_modules/core-js/modules/_object-create.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_object-create.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject    = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , dPs         = __webpack_require__(/*! ./_object-dps */ "./node_modules/core-js/modules/_object-dps.js")
  , enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ "./node_modules/core-js/modules/_enum-bug-keys.js")
  , IE_PROTO    = __webpack_require__(/*! ./_shared-key */ "./node_modules/core-js/modules/_shared-key.js")('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__(/*! ./_dom-create */ "./node_modules/core-js/modules/_dom-create.js")('iframe')
    , i      = enumBugKeys.length
    , lt     = '<'
    , gt     = '>'
    , iframeDocument;
  iframe.style.display = 'none';
  __webpack_require__(/*! ./_html */ "./node_modules/core-js/modules/_html.js").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);
};


/***/ }),

/***/ "./node_modules/core-js/modules/_object-dp.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_object-dp.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var anObject       = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ "./node_modules/core-js/modules/_ie8-dom-define.js")
  , toPrimitive    = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
  , dP             = Object.defineProperty;

exports.f = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") ? 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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-dps.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_object-dps.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var dP       = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
  , anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , getKeys  = __webpack_require__(/*! ./_object-keys */ "./node_modules/core-js/modules/_object-keys.js");

module.exports = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") ? 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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-forced-pam.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/_object-forced-pam.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// Forced replacement prototype accessors methods
module.exports = __webpack_require__(/*! ./_library */ "./node_modules/core-js/modules/_library.js")|| !__webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  var K = Math.random();
  // In FF throws only define methods
  __defineSetter__.call(null, K, function(){ /* empty */});
  delete __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")[K];
});

/***/ }),

/***/ "./node_modules/core-js/modules/_object-gopd.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_object-gopd.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var pIE            = __webpack_require__(/*! ./_object-pie */ "./node_modules/core-js/modules/_object-pie.js")
  , createDesc     = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js")
  , toIObject      = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , toPrimitive    = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
  , has            = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ "./node_modules/core-js/modules/_ie8-dom-define.js")
  , gOPD           = Object.getOwnPropertyDescriptor;

exports.f = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") ? 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]);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-gopn-ext.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/_object-gopn-ext.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
var toIObject = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , gOPN      = __webpack_require__(/*! ./_object-gopn */ "./node_modules/core-js/modules/_object-gopn.js").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));
};


/***/ }),

/***/ "./node_modules/core-js/modules/_object-gopn.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_object-gopn.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
var $keys      = __webpack_require__(/*! ./_object-keys-internal */ "./node_modules/core-js/modules/_object-keys-internal.js")
  , hiddenKeys = __webpack_require__(/*! ./_enum-bug-keys */ "./node_modules/core-js/modules/_enum-bug-keys.js").concat('length', 'prototype');

exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){
  return $keys(O, hiddenKeys);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-gops.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_object-gops.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

exports.f = Object.getOwnPropertySymbols;

/***/ }),

/***/ "./node_modules/core-js/modules/_object-gpo.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_object-gpo.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has         = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , toObject    = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , IE_PROTO    = __webpack_require__(/*! ./_shared-key */ "./node_modules/core-js/modules/_shared-key.js")('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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-keys-internal.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/_object-keys-internal.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var has          = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , toIObject    = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , arrayIndexOf = __webpack_require__(/*! ./_array-includes */ "./node_modules/core-js/modules/_array-includes.js")(false)
  , IE_PROTO     = __webpack_require__(/*! ./_shared-key */ "./node_modules/core-js/modules/_shared-key.js")('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;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-keys.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_object-keys.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys       = __webpack_require__(/*! ./_object-keys-internal */ "./node_modules/core-js/modules/_object-keys-internal.js")
  , enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ "./node_modules/core-js/modules/_enum-bug-keys.js");

module.exports = Object.keys || function keys(O){
  return $keys(O, enumBugKeys);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-pie.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_object-pie.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

exports.f = {}.propertyIsEnumerable;

/***/ }),

/***/ "./node_modules/core-js/modules/_object-sap.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_object-sap.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// most Object methods by ES6 should accept primitives
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , core    = __webpack_require__(/*! ./_core */ "./node_modules/core-js/modules/_core.js")
  , fails   = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js");
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);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_object-to-array.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/_object-to-array.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var getKeys   = __webpack_require__(/*! ./_object-keys */ "./node_modules/core-js/modules/_object-keys.js")
  , toIObject = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , isEnum    = __webpack_require__(/*! ./_object-pie */ "./node_modules/core-js/modules/_object-pie.js").f;
module.exports = function(isEntries){
  return function(it){
    var O      = toIObject(it)
      , keys   = getKeys(O)
      , length = keys.length
      , i      = 0
      , result = []
      , key;
    while(length > i)if(isEnum.call(O, key = keys[i++])){
      result.push(isEntries ? [key, O[key]] : O[key]);
    } return result;
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_own-keys.js":
/*!***************************************************!*\
  !*** ./node_modules/core-js/modules/_own-keys.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// all object keys, includes non-enumerable and symbols
var gOPN     = __webpack_require__(/*! ./_object-gopn */ "./node_modules/core-js/modules/_object-gopn.js")
  , gOPS     = __webpack_require__(/*! ./_object-gops */ "./node_modules/core-js/modules/_object-gops.js")
  , anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , Reflect  = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").Reflect;
module.exports = Reflect && Reflect.ownKeys || function ownKeys(it){
  var keys       = gOPN.f(anObject(it))
    , getSymbols = gOPS.f;
  return getSymbols ? keys.concat(getSymbols(it)) : keys;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_parse-float.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_parse-float.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $parseFloat = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").parseFloat
  , $trim       = __webpack_require__(/*! ./_string-trim */ "./node_modules/core-js/modules/_string-trim.js").trim;

module.exports = 1 / $parseFloat(__webpack_require__(/*! ./_string-ws */ "./node_modules/core-js/modules/_string-ws.js") + '-0') !== -Infinity ? function parseFloat(str){
  var string = $trim(String(str), 3)
    , result = $parseFloat(string);
  return result === 0 && string.charAt(0) == '-' ? -0 : result;
} : $parseFloat;

/***/ }),

/***/ "./node_modules/core-js/modules/_parse-int.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_parse-int.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $parseInt = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").parseInt
  , $trim     = __webpack_require__(/*! ./_string-trim */ "./node_modules/core-js/modules/_string-trim.js").trim
  , ws        = __webpack_require__(/*! ./_string-ws */ "./node_modules/core-js/modules/_string-ws.js")
  , hex       = /^[\-+]?0[xX]/;

module.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix){
  var string = $trim(String(str), 3);
  return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));
} : $parseInt;

/***/ }),

/***/ "./node_modules/core-js/modules/_partial.js":
/*!**************************************************!*\
  !*** ./node_modules/core-js/modules/_partial.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var path      = __webpack_require__(/*! ./_path */ "./node_modules/core-js/modules/_path.js")
  , invoke    = __webpack_require__(/*! ./_invoke */ "./node_modules/core-js/modules/_invoke.js")
  , aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js");
module.exports = function(/* ...pargs */){
  var fn     = aFunction(this)
    , length = arguments.length
    , pargs  = Array(length)
    , i      = 0
    , _      = path._
    , holder = false;
  while(length > i)if((pargs[i] = arguments[i++]) === _)holder = true;
  return function(/* ...args */){
    var that = this
      , aLen = arguments.length
      , j = 0, k = 0, args;
    if(!holder && !aLen)return invoke(fn, pargs, that);
    args = pargs.slice();
    if(holder)for(;length > j; j++)if(args[j] === _)args[j] = arguments[k++];
    while(aLen > k)args.push(arguments[k++]);
    return invoke(fn, args, that);
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_path.js":
/*!***********************************************!*\
  !*** ./node_modules/core-js/modules/_path.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js");

/***/ }),

/***/ "./node_modules/core-js/modules/_property-desc.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_property-desc.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = function(bitmap, value){
  return {
    enumerable  : !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable    : !(bitmap & 4),
    value       : value
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_redefine-all.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/_redefine-all.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var redefine = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js");
module.exports = function(target, src, safe){
  for(var key in src)redefine(target, key, src[key], safe);
  return target;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_redefine.js":
/*!***************************************************!*\
  !*** ./node_modules/core-js/modules/_redefine.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var global    = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , hide      = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , has       = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , SRC       = __webpack_require__(/*! ./_uid */ "./node_modules/core-js/modules/_uid.js")('src')
  , TO_STRING = 'toString'
  , $toString = Function[TO_STRING]
  , TPL       = ('' + $toString).split(TO_STRING);

__webpack_require__(/*! ./_core */ "./node_modules/core-js/modules/_core.js").inspectSource = function(it){
  return $toString.call(it);
};

(module.exports = function(O, key, val, safe){
  var isFunction = typeof val == 'function';
  if(isFunction)has(val, 'name') || hide(val, 'name', key);
  if(O[key] === val)return;
  if(isFunction)has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
  if(O === global){
    O[key] = val;
  } else {
    if(!safe){
      delete O[key];
      hide(O, key, val);
    } else {
      if(O[key])O[key] = val;
      else hide(O, key, val);
    }
  }
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, TO_STRING, function toString(){
  return typeof this == 'function' && this[SRC] || $toString.call(this);
});

/***/ }),

/***/ "./node_modules/core-js/modules/_same-value.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_same-value.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// 7.2.9 SameValue(x, y)
module.exports = Object.is || function is(x, y){
  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_set-proto.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_set-proto.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// Works with __proto__ only. Old v8 can't work with null proto objects.
/* eslint-disable no-proto */
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");
var check = function(O, proto){
  anObject(O);
  if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!");
};
module.exports = {
  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
    function(test, buggy, set){
      try {
        set = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")(Function.call, __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js").f(Object.prototype, '__proto__').set, 2);
        set(test, []);
        buggy = !(test instanceof Array);
      } catch(e){ buggy = true; }
      return function setPrototypeOf(O, proto){
        check(O, proto);
        if(buggy)O.__proto__ = proto;
        else set(O, proto);
        return O;
      };
    }({}, false) : undefined),
  check: check
};

/***/ }),

/***/ "./node_modules/core-js/modules/_set-species.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_set-species.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var global      = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , dP          = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
  , DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js")
  , SPECIES     = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('species');

module.exports = function(KEY){
  var C = global[KEY];
  if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {
    configurable: true,
    get: function(){ return this; }
  });
};

/***/ }),

/***/ "./node_modules/core-js/modules/_set-to-string-tag.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/_set-to-string-tag.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var def = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f
  , has = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , TAG = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('toStringTag');

module.exports = function(it, tag, stat){
  if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
};

/***/ }),

/***/ "./node_modules/core-js/modules/_shared-key.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_shared-key.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var shared = __webpack_require__(/*! ./_shared */ "./node_modules/core-js/modules/_shared.js")('keys')
  , uid    = __webpack_require__(/*! ./_uid */ "./node_modules/core-js/modules/_uid.js");
module.exports = function(key){
  return shared[key] || (shared[key] = uid(key));
};

/***/ }),

/***/ "./node_modules/core-js/modules/_shared.js":
/*!*************************************************!*\
  !*** ./node_modules/core-js/modules/_shared.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , SHARED = '__core-js_shared__'
  , store  = global[SHARED] || (global[SHARED] = {});
module.exports = function(key){
  return store[key] || (store[key] = {});
};

/***/ }),

/***/ "./node_modules/core-js/modules/_species-constructor.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/_species-constructor.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 7.3.20 SpeciesConstructor(O, defaultConstructor)
var anObject  = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , SPECIES   = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('species');
module.exports = function(O, D){
  var C = anObject(O).constructor, S;
  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_strict-method.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_strict-method.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var fails = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js");

module.exports = function(method, arg){
  return !!method && fails(function(){
    arg ? method.call(null, function(){}, 1) : method.call(null);
  });
};

/***/ }),

/***/ "./node_modules/core-js/modules/_string-at.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_string-at.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
  , defined   = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js");
// 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;
  };
};

/***/ }),

/***/ "./node_modules/core-js/modules/_string-context.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/_string-context.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// helper for String#{startsWith, endsWith, includes}
var isRegExp = __webpack_require__(/*! ./_is-regexp */ "./node_modules/core-js/modules/_is-regexp.js")
  , defined  = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js");

module.exports = function(that, searchString, NAME){
  if(isRegExp(searchString))throw TypeError('String#' + NAME + " doesn't accept regex!");
  return String(defined(that));
};

/***/ }),

/***/ "./node_modules/core-js/modules/_string-html.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_string-html.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , fails   = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , defined = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js")
  , quot    = /"/g;
// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
var createHTML = function(string, tag, attribute, value) {
  var S  = String(defined(string))
    , p1 = '<' + tag;
  if(attribute !== '')p1 += ' ' + attribute + '="' + String(value).replace(quot, '&quot;') + '"';
  return p1 + '>' + S + '</' + tag + '>';
};
module.exports = function(NAME, exec){
  var O = {};
  O[NAME] = exec(createHTML);
  $export($export.P + $export.F * fails(function(){
    var test = ''[NAME]('"');
    return test !== test.toLowerCase() || test.split('"').length > 3;
  }), 'String', O);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_string-pad.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_string-pad.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/tc39/proposal-string-pad-start-end
var toLength = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , repeat   = __webpack_require__(/*! ./_string-repeat */ "./node_modules/core-js/modules/_string-repeat.js")
  , defined  = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js");

module.exports = function(that, maxLength, fillString, left){
  var S            = String(defined(that))
    , stringLength = S.length
    , fillStr      = fillString === undefined ? ' ' : String(fillString)
    , intMaxLength = toLength(maxLength);
  if(intMaxLength <= stringLength || fillStr == '')return S;
  var fillLen = intMaxLength - stringLength
    , stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
  if(stringFiller.length > fillLen)stringFiller = stringFiller.slice(0, fillLen);
  return left ? stringFiller + S : S + stringFiller;
};


/***/ }),

/***/ "./node_modules/core-js/modules/_string-repeat.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/_string-repeat.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var toInteger = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
  , defined   = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js");

module.exports = function repeat(count){
  var str = String(defined(this))
    , res = ''
    , n   = toInteger(count);
  if(n < 0 || n == Infinity)throw RangeError("Count can't be negative");
  for(;n > 0; (n >>>= 1) && (str += str))if(n & 1)res += str;
  return res;
};

/***/ }),

/***/ "./node_modules/core-js/modules/_string-trim.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_string-trim.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , defined = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js")
  , fails   = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , spaces  = __webpack_require__(/*! ./_string-ws */ "./node_modules/core-js/modules/_string-ws.js")
  , space   = '[' + spaces + ']'
  , non     = '\u200b\u0085'
  , ltrim   = RegExp('^' + space + space + '*')
  , rtrim   = RegExp(space + space + '*$');

var exporter = function(KEY, exec, ALIAS){
  var exp   = {};
  var FORCE = fails(function(){
    return !!spaces[KEY]() || non[KEY]() != non;
  });
  var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];
  if(ALIAS)exp[ALIAS] = fn;
  $export($export.P + $export.F * FORCE, 'String', exp);
};

// 1 -> String#trimLeft
// 2 -> String#trimRight
// 3 -> String#trim
var trim = exporter.trim = function(string, TYPE){
  string = String(defined(string));
  if(TYPE & 1)string = string.replace(ltrim, '');
  if(TYPE & 2)string = string.replace(rtrim, '');
  return string;
};

module.exports = exporter;

/***/ }),

/***/ "./node_modules/core-js/modules/_string-ws.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_string-ws.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
  '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';

/***/ }),

/***/ "./node_modules/core-js/modules/_task.js":
/*!***********************************************!*\
  !*** ./node_modules/core-js/modules/_task.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var ctx                = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
  , invoke             = __webpack_require__(/*! ./_invoke */ "./node_modules/core-js/modules/_invoke.js")
  , html               = __webpack_require__(/*! ./_html */ "./node_modules/core-js/modules/_html.js")
  , cel                = __webpack_require__(/*! ./_dom-create */ "./node_modules/core-js/modules/_dom-create.js")
  , global             = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , 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__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js")(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
};

/***/ }),

/***/ "./node_modules/core-js/modules/_to-index.js":
/*!***************************************************!*\
  !*** ./node_modules/core-js/modules/_to-index.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var toInteger = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
  , max       = Math.max
  , min       = Math.min;
module.exports = function(index, length){
  index = toInteger(index);
  return index < 0 ? max(index + length, 0) : min(index, length);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_to-integer.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_to-integer.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (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);
};

/***/ }),

/***/ "./node_modules/core-js/modules/_to-iobject.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_to-iobject.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// to indexed object, toObject with fallback for non-array-like ES3 strings
var IObject = __webpack_require__(/*! ./_iobject */ "./node_modules/core-js/modules/_iobject.js")
  , defined = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js");
module.exports = function(it){
  return IObject(defined(it));
};

/***/ }),

/***/ "./node_modules/core-js/modules/_to-length.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_to-length.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 7.1.15 ToLength
var toInteger = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
  , min       = Math.min;
module.exports = function(it){
  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};

/***/ }),

/***/ "./node_modules/core-js/modules/_to-object.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/_to-object.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 7.1.13 ToObject(argument)
var defined = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js");
module.exports = function(it){
  return Object(defined(it));
};

/***/ }),

/***/ "./node_modules/core-js/modules/_to-primitive.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/_to-primitive.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js");
// 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");
};

/***/ }),

/***/ "./node_modules/core-js/modules/_typed-array.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/_typed-array.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

if(__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js")){
  var LIBRARY             = __webpack_require__(/*! ./_library */ "./node_modules/core-js/modules/_library.js")
    , global              = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
    , fails               = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
    , $export             = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
    , $typed              = __webpack_require__(/*! ./_typed */ "./node_modules/core-js/modules/_typed.js")
    , $buffer             = __webpack_require__(/*! ./_typed-buffer */ "./node_modules/core-js/modules/_typed-buffer.js")
    , ctx                 = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
    , anInstance          = __webpack_require__(/*! ./_an-instance */ "./node_modules/core-js/modules/_an-instance.js")
    , propertyDesc        = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js")
    , hide                = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
    , redefineAll         = __webpack_require__(/*! ./_redefine-all */ "./node_modules/core-js/modules/_redefine-all.js")
    , toInteger           = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
    , toLength            = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
    , toIndex             = __webpack_require__(/*! ./_to-index */ "./node_modules/core-js/modules/_to-index.js")
    , toPrimitive         = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
    , has                 = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
    , same                = __webpack_require__(/*! ./_same-value */ "./node_modules/core-js/modules/_same-value.js")
    , classof             = __webpack_require__(/*! ./_classof */ "./node_modules/core-js/modules/_classof.js")
    , isObject            = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
    , toObject            = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
    , isArrayIter         = __webpack_require__(/*! ./_is-array-iter */ "./node_modules/core-js/modules/_is-array-iter.js")
    , create              = __webpack_require__(/*! ./_object-create */ "./node_modules/core-js/modules/_object-create.js")
    , getPrototypeOf      = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
    , gOPN                = __webpack_require__(/*! ./_object-gopn */ "./node_modules/core-js/modules/_object-gopn.js").f
    , getIterFn           = __webpack_require__(/*! ./core.get-iterator-method */ "./node_modules/core-js/modules/core.get-iterator-method.js")
    , uid                 = __webpack_require__(/*! ./_uid */ "./node_modules/core-js/modules/_uid.js")
    , wks                 = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")
    , createArrayMethod   = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")
    , createArrayIncludes = __webpack_require__(/*! ./_array-includes */ "./node_modules/core-js/modules/_array-includes.js")
    , speciesConstructor  = __webpack_require__(/*! ./_species-constructor */ "./node_modules/core-js/modules/_species-constructor.js")
    , ArrayIterators      = __webpack_require__(/*! ./es6.array.iterator */ "./node_modules/core-js/modules/es6.array.iterator.js")
    , Iterators           = __webpack_require__(/*! ./_iterators */ "./node_modules/core-js/modules/_iterators.js")
    , $iterDetect         = __webpack_require__(/*! ./_iter-detect */ "./node_modules/core-js/modules/_iter-detect.js")
    , setSpecies          = __webpack_require__(/*! ./_set-species */ "./node_modules/core-js/modules/_set-species.js")
    , arrayFill           = __webpack_require__(/*! ./_array-fill */ "./node_modules/core-js/modules/_array-fill.js")
    , arrayCopyWithin     = __webpack_require__(/*! ./_array-copy-within */ "./node_modules/core-js/modules/_array-copy-within.js")
    , $DP                 = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
    , $GOPD               = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js")
    , dP                  = $DP.f
    , gOPD                = $GOPD.f
    , RangeError          = global.RangeError
    , TypeError           = global.TypeError
    , Uint8Array          = global.Uint8Array
    , ARRAY_BUFFER        = 'ArrayBuffer'
    , SHARED_BUFFER       = 'Shared' + ARRAY_BUFFER
    , BYTES_PER_ELEMENT   = 'BYTES_PER_ELEMENT'
    , PROTOTYPE           = 'prototype'
    , ArrayProto          = Array[PROTOTYPE]
    , $ArrayBuffer        = $buffer.ArrayBuffer
    , $DataView           = $buffer.DataView
    , arrayForEach        = createArrayMethod(0)
    , arrayFilter         = createArrayMethod(2)
    , arraySome           = createArrayMethod(3)
    , arrayEvery          = createArrayMethod(4)
    , arrayFind           = createArrayMethod(5)
    , arrayFindIndex      = createArrayMethod(6)
    , arrayIncludes       = createArrayIncludes(true)
    , arrayIndexOf        = createArrayIncludes(false)
    , arrayValues         = ArrayIterators.values
    , arrayKeys           = ArrayIterators.keys
    , arrayEntries        = ArrayIterators.entries
    , arrayLastIndexOf    = ArrayProto.lastIndexOf
    , arrayReduce         = ArrayProto.reduce
    , arrayReduceRight    = ArrayProto.reduceRight
    , arrayJoin           = ArrayProto.join
    , arraySort           = ArrayProto.sort
    , arraySlice          = ArrayProto.slice
    , arrayToString       = ArrayProto.toString
    , arrayToLocaleString = ArrayProto.toLocaleString
    , ITERATOR            = wks('iterator')
    , TAG                 = wks('toStringTag')
    , TYPED_CONSTRUCTOR   = uid('typed_constructor')
    , DEF_CONSTRUCTOR     = uid('def_constructor')
    , ALL_CONSTRUCTORS    = $typed.CONSTR
    , TYPED_ARRAY         = $typed.TYPED
    , VIEW                = $typed.VIEW
    , WRONG_LENGTH        = 'Wrong length!';

  var $map = createArrayMethod(1, function(O, length){
    return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length);
  });

  var LITTLE_ENDIAN = fails(function(){
    return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
  });

  var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function(){
    new Uint8Array(1).set({});
  });

  var strictToLength = function(it, SAME){
    if(it === undefined)throw TypeError(WRONG_LENGTH);
    var number = +it
      , length = toLength(it);
    if(SAME && !same(number, length))throw RangeError(WRONG_LENGTH);
    return length;
  };

  var toOffset = function(it, BYTES){
    var offset = toInteger(it);
    if(offset < 0 || offset % BYTES)throw RangeError('Wrong offset!');
    return offset;
  };

  var validate = function(it){
    if(isObject(it) && TYPED_ARRAY in it)return it;
    throw TypeError(it + ' is not a typed array!');
  };

  var allocate = function(C, length){
    if(!(isObject(C) && TYPED_CONSTRUCTOR in C)){
      throw TypeError('It is not a typed array constructor!');
    } return new C(length);
  };

  var speciesFromList = function(O, list){
    return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list);
  };

  var fromList = function(C, list){
    var index  = 0
      , length = list.length
      , result = allocate(C, length);
    while(length > index)result[index] = list[index++];
    return result;
  };

  var addGetter = function(it, key, internal){
    dP(it, key, {get: function(){ return this._d[internal]; }});
  };

  var $from = function from(source /*, mapfn, thisArg */){
    var O       = toObject(source)
      , aLen    = arguments.length
      , mapfn   = aLen > 1 ? arguments[1] : undefined
      , mapping = mapfn !== undefined
      , iterFn  = getIterFn(O)
      , i, length, values, result, step, iterator;
    if(iterFn != undefined && !isArrayIter(iterFn)){
      for(iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++){
        values.push(step.value);
      } O = values;
    }
    if(mapping && aLen > 2)mapfn = ctx(mapfn, arguments[2], 2);
    for(i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++){
      result[i] = mapping ? mapfn(O[i], i) : O[i];
    }
    return result;
  };

  var $of = function of(/*...items*/){
    var index  = 0
      , length = arguments.length
      , result = allocate(this, length);
    while(length > index)result[index] = arguments[index++];
    return result;
  };

  // iOS Safari 6.x fails here
  var TO_LOCALE_BUG = !!Uint8Array && fails(function(){ arrayToLocaleString.call(new Uint8Array(1)); });

  var $toLocaleString = function toLocaleString(){
    return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments);
  };

  var proto = {
    copyWithin: function copyWithin(target, start /*, end */){
      return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined);
    },
    every: function every(callbackfn /*, thisArg */){
      return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    fill: function fill(value /*, start, end */){ // eslint-disable-line no-unused-vars
      return arrayFill.apply(validate(this), arguments);
    },
    filter: function filter(callbackfn /*, thisArg */){
      return speciesFromList(this, arrayFilter(validate(this), callbackfn,
        arguments.length > 1 ? arguments[1] : undefined));
    },
    find: function find(predicate /*, thisArg */){
      return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    findIndex: function findIndex(predicate /*, thisArg */){
      return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    forEach: function forEach(callbackfn /*, thisArg */){
      arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    indexOf: function indexOf(searchElement /*, fromIndex */){
      return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    includes: function includes(searchElement /*, fromIndex */){
      return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    join: function join(separator){ // eslint-disable-line no-unused-vars
      return arrayJoin.apply(validate(this), arguments);
    },
    lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */){ // eslint-disable-line no-unused-vars
      return arrayLastIndexOf.apply(validate(this), arguments);
    },
    map: function map(mapfn /*, thisArg */){
      return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    reduce: function reduce(callbackfn /*, initialValue */){ // eslint-disable-line no-unused-vars
      return arrayReduce.apply(validate(this), arguments);
    },
    reduceRight: function reduceRight(callbackfn /*, initialValue */){ // eslint-disable-line no-unused-vars
      return arrayReduceRight.apply(validate(this), arguments);
    },
    reverse: function reverse(){
      var that   = this
        , length = validate(that).length
        , middle = Math.floor(length / 2)
        , index  = 0
        , value;
      while(index < middle){
        value         = that[index];
        that[index++] = that[--length];
        that[length]  = value;
      } return that;
    },
    some: function some(callbackfn /*, thisArg */){
      return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    sort: function sort(comparefn){
      return arraySort.call(validate(this), comparefn);
    },
    subarray: function subarray(begin, end){
      var O      = validate(this)
        , length = O.length
        , $begin = toIndex(begin, length);
      return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))(
        O.buffer,
        O.byteOffset + $begin * O.BYTES_PER_ELEMENT,
        toLength((end === undefined ? length : toIndex(end, length)) - $begin)
      );
    }
  };

  var $slice = function slice(start, end){
    return speciesFromList(this, arraySlice.call(validate(this), start, end));
  };

  var $set = function set(arrayLike /*, offset */){
    validate(this);
    var offset = toOffset(arguments[1], 1)
      , length = this.length
      , src    = toObject(arrayLike)
      , len    = toLength(src.length)
      , index  = 0;
    if(len + offset > length)throw RangeError(WRONG_LENGTH);
    while(index < len)this[offset + index] = src[index++];
  };

  var $iterators = {
    entries: function entries(){
      return arrayEntries.call(validate(this));
    },
    keys: function keys(){
      return arrayKeys.call(validate(this));
    },
    values: function values(){
      return arrayValues.call(validate(this));
    }
  };

  var isTAIndex = function(target, key){
    return isObject(target)
      && target[TYPED_ARRAY]
      && typeof key != 'symbol'
      && key in target
      && String(+key) == String(key);
  };
  var $getDesc = function getOwnPropertyDescriptor(target, key){
    return isTAIndex(target, key = toPrimitive(key, true))
      ? propertyDesc(2, target[key])
      : gOPD(target, key);
  };
  var $setDesc = function defineProperty(target, key, desc){
    if(isTAIndex(target, key = toPrimitive(key, true))
      && isObject(desc)
      && has(desc, 'value')
      && !has(desc, 'get')
      && !has(desc, 'set')
      // TODO: add validation descriptor w/o calling accessors
      && !desc.configurable
      && (!has(desc, 'writable') || desc.writable)
      && (!has(desc, 'enumerable') || desc.enumerable)
    ){
      target[key] = desc.value;
      return target;
    } else return dP(target, key, desc);
  };

  if(!ALL_CONSTRUCTORS){
    $GOPD.f = $getDesc;
    $DP.f   = $setDesc;
  }

  $export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', {
    getOwnPropertyDescriptor: $getDesc,
    defineProperty:           $setDesc
  });

  if(fails(function(){ arrayToString.call({}); })){
    arrayToString = arrayToLocaleString = function toString(){
      return arrayJoin.call(this);
    }
  }

  var $TypedArrayPrototype$ = redefineAll({}, proto);
  redefineAll($TypedArrayPrototype$, $iterators);
  hide($TypedArrayPrototype$, ITERATOR, $iterators.values);
  redefineAll($TypedArrayPrototype$, {
    slice:          $slice,
    set:            $set,
    constructor:    function(){ /* noop */ },
    toString:       arrayToString,
    toLocaleString: $toLocaleString
  });
  addGetter($TypedArrayPrototype$, 'buffer', 'b');
  addGetter($TypedArrayPrototype$, 'byteOffset', 'o');
  addGetter($TypedArrayPrototype$, 'byteLength', 'l');
  addGetter($TypedArrayPrototype$, 'length', 'e');
  dP($TypedArrayPrototype$, TAG, {
    get: function(){ return this[TYPED_ARRAY]; }
  });

  module.exports = function(KEY, BYTES, wrapper, CLAMPED){
    CLAMPED = !!CLAMPED;
    var NAME       = KEY + (CLAMPED ? 'Clamped' : '') + 'Array'
      , ISNT_UINT8 = NAME != 'Uint8Array'
      , GETTER     = 'get' + KEY
      , SETTER     = 'set' + KEY
      , TypedArray = global[NAME]
      , Base       = TypedArray || {}
      , TAC        = TypedArray && getPrototypeOf(TypedArray)
      , FORCED     = !TypedArray || !$typed.ABV
      , O          = {}
      , TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE];
    var getter = function(that, index){
      var data = that._d;
      return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN);
    };
    var setter = function(that, index, value){
      var data = that._d;
      if(CLAMPED)value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff;
      data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN);
    };
    var addElement = function(that, index){
      dP(that, index, {
        get: function(){
          return getter(this, index);
        },
        set: function(value){
          return setter(this, index, value);
        },
        enumerable: true
      });
    };
    if(FORCED){
      TypedArray = wrapper(function(that, data, $offset, $length){
        anInstance(that, TypedArray, NAME, '_d');
        var index  = 0
          , offset = 0
          , buffer, byteLength, length, klass;
        if(!isObject(data)){
          length     = strictToLength(data, true)
          byteLength = length * BYTES;
          buffer     = new $ArrayBuffer(byteLength);
        } else if(data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER){
          buffer = data;
          offset = toOffset($offset, BYTES);
          var $len = data.byteLength;
          if($length === undefined){
            if($len % BYTES)throw RangeError(WRONG_LENGTH);
            byteLength = $len - offset;
            if(byteLength < 0)throw RangeError(WRONG_LENGTH);
          } else {
            byteLength = toLength($length) * BYTES;
            if(byteLength + offset > $len)throw RangeError(WRONG_LENGTH);
          }
          length = byteLength / BYTES;
        } else if(TYPED_ARRAY in data){
          return fromList(TypedArray, data);
        } else {
          return $from.call(TypedArray, data);
        }
        hide(that, '_d', {
          b: buffer,
          o: offset,
          l: byteLength,
          e: length,
          v: new $DataView(buffer)
        });
        while(index < length)addElement(that, index++);
      });
      TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$);
      hide(TypedArrayPrototype, 'constructor', TypedArray);
    } else if(!$iterDetect(function(iter){
      // V8 works with iterators, but fails in many other cases
      // https://code.google.com/p/v8/issues/detail?id=4552
      new TypedArray(null); // eslint-disable-line no-new
      new TypedArray(iter); // eslint-disable-line no-new
    }, true)){
      TypedArray = wrapper(function(that, data, $offset, $length){
        anInstance(that, TypedArray, NAME);
        var klass;
        // `ws` module bug, temporarily remove validation length for Uint8Array
        // https://github.com/websockets/ws/pull/645
        if(!isObject(data))return new Base(strictToLength(data, ISNT_UINT8));
        if(data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER){
          return $length !== undefined
            ? new Base(data, toOffset($offset, BYTES), $length)
            : $offset !== undefined
              ? new Base(data, toOffset($offset, BYTES))
              : new Base(data);
        }
        if(TYPED_ARRAY in data)return fromList(TypedArray, data);
        return $from.call(TypedArray, data);
      });
      arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function(key){
        if(!(key in TypedArray))hide(TypedArray, key, Base[key]);
      });
      TypedArray[PROTOTYPE] = TypedArrayPrototype;
      if(!LIBRARY)TypedArrayPrototype.constructor = TypedArray;
    }
    var $nativeIterator   = TypedArrayPrototype[ITERATOR]
      , CORRECT_ITER_NAME = !!$nativeIterator && ($nativeIterator.name == 'values' || $nativeIterator.name == undefined)
      , $iterator         = $iterators.values;
    hide(TypedArray, TYPED_CONSTRUCTOR, true);
    hide(TypedArrayPrototype, TYPED_ARRAY, NAME);
    hide(TypedArrayPrototype, VIEW, true);
    hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray);

    if(CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)){
      dP(TypedArrayPrototype, TAG, {
        get: function(){ return NAME; }
      });
    }

    O[NAME] = TypedArray;

    $export($export.G + $export.W + $export.F * (TypedArray != Base), O);

    $export($export.S, NAME, {
      BYTES_PER_ELEMENT: BYTES,
      from: $from,
      of: $of
    });

    if(!(BYTES_PER_ELEMENT in TypedArrayPrototype))hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES);

    $export($export.P, NAME, proto);

    setSpecies(NAME);

    $export($export.P + $export.F * FORCED_SET, NAME, {set: $set});

    $export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators);

    $export($export.P + $export.F * (TypedArrayPrototype.toString != arrayToString), NAME, {toString: arrayToString});

    $export($export.P + $export.F * fails(function(){
      new TypedArray(1).slice();
    }), NAME, {slice: $slice});

    $export($export.P + $export.F * (fails(function(){
      return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString()
    }) || !fails(function(){
      TypedArrayPrototype.toLocaleString.call([1, 2]);
    })), NAME, {toLocaleString: $toLocaleString});

    Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator;
    if(!LIBRARY && !CORRECT_ITER_NAME)hide(TypedArrayPrototype, ITERATOR, $iterator);
  };
} else module.exports = function(){ /* empty */ };

/***/ }),

/***/ "./node_modules/core-js/modules/_typed-buffer.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/_typed-buffer.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var global         = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , DESCRIPTORS    = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js")
  , LIBRARY        = __webpack_require__(/*! ./_library */ "./node_modules/core-js/modules/_library.js")
  , $typed         = __webpack_require__(/*! ./_typed */ "./node_modules/core-js/modules/_typed.js")
  , hide           = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , redefineAll    = __webpack_require__(/*! ./_redefine-all */ "./node_modules/core-js/modules/_redefine-all.js")
  , fails          = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , anInstance     = __webpack_require__(/*! ./_an-instance */ "./node_modules/core-js/modules/_an-instance.js")
  , toInteger      = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
  , toLength       = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , gOPN           = __webpack_require__(/*! ./_object-gopn */ "./node_modules/core-js/modules/_object-gopn.js").f
  , dP             = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f
  , arrayFill      = __webpack_require__(/*! ./_array-fill */ "./node_modules/core-js/modules/_array-fill.js")
  , setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ "./node_modules/core-js/modules/_set-to-string-tag.js")
  , ARRAY_BUFFER   = 'ArrayBuffer'
  , DATA_VIEW      = 'DataView'
  , PROTOTYPE      = 'prototype'
  , WRONG_LENGTH   = 'Wrong length!'
  , WRONG_INDEX    = 'Wrong index!'
  , $ArrayBuffer   = global[ARRAY_BUFFER]
  , $DataView      = global[DATA_VIEW]
  , Math           = global.Math
  , RangeError     = global.RangeError
  , Infinity       = global.Infinity
  , BaseBuffer     = $ArrayBuffer
  , abs            = Math.abs
  , pow            = Math.pow
  , floor          = Math.floor
  , log            = Math.log
  , LN2            = Math.LN2
  , BUFFER         = 'buffer'
  , BYTE_LENGTH    = 'byteLength'
  , BYTE_OFFSET    = 'byteOffset'
  , $BUFFER        = DESCRIPTORS ? '_b' : BUFFER
  , $LENGTH        = DESCRIPTORS ? '_l' : BYTE_LENGTH
  , $OFFSET        = DESCRIPTORS ? '_o' : BYTE_OFFSET;

// IEEE754 conversions based on https://github.com/feross/ieee754
var packIEEE754 = function(value, mLen, nBytes){
  var buffer = Array(nBytes)
    , eLen   = nBytes * 8 - mLen - 1
    , eMax   = (1 << eLen) - 1
    , eBias  = eMax >> 1
    , rt     = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0
    , i      = 0
    , s      = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0
    , e, m, c;
  value = abs(value)
  if(value != value || value === Infinity){
    m = value != value ? 1 : 0;
    e = eMax;
  } else {
    e = floor(log(value) / LN2);
    if(value * (c = pow(2, -e)) < 1){
      e--;
      c *= 2;
    }
    if(e + eBias >= 1){
      value += rt / c;
    } else {
      value += rt * 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) * pow(2, mLen);
      e = e + eBias;
    } else {
      m = value * pow(2, eBias - 1) * pow(2, mLen);
      e = 0;
    }
  }
  for(; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8);
  e = e << mLen | m;
  eLen += mLen;
  for(; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8);
  buffer[--i] |= s * 128;
  return buffer;
};
var unpackIEEE754 = function(buffer, mLen, nBytes){
  var eLen  = nBytes * 8 - mLen - 1
    , eMax  = (1 << eLen) - 1
    , eBias = eMax >> 1
    , nBits = eLen - 7
    , i     = nBytes - 1
    , s     = buffer[i--]
    , e     = s & 127
    , m;
  s >>= 7;
  for(; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8);
  m = e & (1 << -nBits) - 1;
  e >>= -nBits;
  nBits += mLen;
  for(; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);
  if(e === 0){
    e = 1 - eBias;
  } else if(e === eMax){
    return m ? NaN : s ? -Infinity : Infinity;
  } else {
    m = m + pow(2, mLen);
    e = e - eBias;
  } return (s ? -1 : 1) * m * pow(2, e - mLen);
};

var unpackI32 = function(bytes){
  return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
};
var packI8 = function(it){
  return [it & 0xff];
};
var packI16 = function(it){
  return [it & 0xff, it >> 8 & 0xff];
};
var packI32 = function(it){
  return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff];
};
var packF64 = function(it){
  return packIEEE754(it, 52, 8);
};
var packF32 = function(it){
  return packIEEE754(it, 23, 4);
};

var addGetter = function(C, key, internal){
  dP(C[PROTOTYPE], key, {get: function(){ return this[internal]; }});
};

var get = function(view, bytes, index, isLittleEndian){
  var numIndex = +index
    , intIndex = toInteger(numIndex);
  if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view[$LENGTH])throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b
    , start = intIndex + view[$OFFSET]
    , pack  = store.slice(start, start + bytes);
  return isLittleEndian ? pack : pack.reverse();
};
var set = function(view, bytes, index, conversion, value, isLittleEndian){
  var numIndex = +index
    , intIndex = toInteger(numIndex);
  if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view[$LENGTH])throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b
    , start = intIndex + view[$OFFSET]
    , pack  = conversion(+value);
  for(var i = 0; i < bytes; i++)store[start + i] = pack[isLittleEndian ? i : bytes - i - 1];
};

var validateArrayBufferArguments = function(that, length){
  anInstance(that, $ArrayBuffer, ARRAY_BUFFER);
  var numberLength = +length
    , byteLength   = toLength(numberLength);
  if(numberLength != byteLength)throw RangeError(WRONG_LENGTH);
  return byteLength;
};

if(!$typed.ABV){
  $ArrayBuffer = function ArrayBuffer(length){
    var byteLength = validateArrayBufferArguments(this, length);
    this._b       = arrayFill.call(Array(byteLength), 0);
    this[$LENGTH] = byteLength;
  };

  $DataView = function DataView(buffer, byteOffset, byteLength){
    anInstance(this, $DataView, DATA_VIEW);
    anInstance(buffer, $ArrayBuffer, DATA_VIEW);
    var bufferLength = buffer[$LENGTH]
      , offset       = toInteger(byteOffset);
    if(offset < 0 || offset > bufferLength)throw RangeError('Wrong offset!');
    byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);
    if(offset + byteLength > bufferLength)throw RangeError(WRONG_LENGTH);
    this[$BUFFER] = buffer;
    this[$OFFSET] = offset;
    this[$LENGTH] = byteLength;
  };

  if(DESCRIPTORS){
    addGetter($ArrayBuffer, BYTE_LENGTH, '_l');
    addGetter($DataView, BUFFER, '_b');
    addGetter($DataView, BYTE_LENGTH, '_l');
    addGetter($DataView, BYTE_OFFSET, '_o');
  }

  redefineAll($DataView[PROTOTYPE], {
    getInt8: function getInt8(byteOffset){
      return get(this, 1, byteOffset)[0] << 24 >> 24;
    },
    getUint8: function getUint8(byteOffset){
      return get(this, 1, byteOffset)[0];
    },
    getInt16: function getInt16(byteOffset /*, littleEndian */){
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return (bytes[1] << 8 | bytes[0]) << 16 >> 16;
    },
    getUint16: function getUint16(byteOffset /*, littleEndian */){
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return bytes[1] << 8 | bytes[0];
    },
    getInt32: function getInt32(byteOffset /*, littleEndian */){
      return unpackI32(get(this, 4, byteOffset, arguments[1]));
    },
    getUint32: function getUint32(byteOffset /*, littleEndian */){
      return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0;
    },
    getFloat32: function getFloat32(byteOffset /*, littleEndian */){
      return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4);
    },
    getFloat64: function getFloat64(byteOffset /*, littleEndian */){
      return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8);
    },
    setInt8: function setInt8(byteOffset, value){
      set(this, 1, byteOffset, packI8, value);
    },
    setUint8: function setUint8(byteOffset, value){
      set(this, 1, byteOffset, packI8, value);
    },
    setInt16: function setInt16(byteOffset, value /*, littleEndian */){
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setUint16: function setUint16(byteOffset, value /*, littleEndian */){
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setInt32: function setInt32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setUint32: function setUint32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setFloat32: function setFloat32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packF32, value, arguments[2]);
    },
    setFloat64: function setFloat64(byteOffset, value /*, littleEndian */){
      set(this, 8, byteOffset, packF64, value, arguments[2]);
    }
  });
} else {
  if(!fails(function(){
    new $ArrayBuffer;     // eslint-disable-line no-new
  }) || !fails(function(){
    new $ArrayBuffer(.5); // eslint-disable-line no-new
  })){
    $ArrayBuffer = function ArrayBuffer(length){
      return new BaseBuffer(validateArrayBufferArguments(this, length));
    };
    var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE];
    for(var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j; ){
      if(!((key = keys[j++]) in $ArrayBuffer))hide($ArrayBuffer, key, BaseBuffer[key]);
    };
    if(!LIBRARY)ArrayBufferProto.constructor = $ArrayBuffer;
  }
  // iOS Safari 7.x bug
  var view = new $DataView(new $ArrayBuffer(2))
    , $setInt8 = $DataView[PROTOTYPE].setInt8;
  view.setInt8(0, 2147483648);
  view.setInt8(1, 2147483649);
  if(view.getInt8(0) || !view.getInt8(1))redefineAll($DataView[PROTOTYPE], {
    setInt8: function setInt8(byteOffset, value){
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    },
    setUint8: function setUint8(byteOffset, value){
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    }
  }, true);
}
setToStringTag($ArrayBuffer, ARRAY_BUFFER);
setToStringTag($DataView, DATA_VIEW);
hide($DataView[PROTOTYPE], $typed.VIEW, true);
exports[ARRAY_BUFFER] = $ArrayBuffer;
exports[DATA_VIEW] = $DataView;

/***/ }),

/***/ "./node_modules/core-js/modules/_typed.js":
/*!************************************************!*\
  !*** ./node_modules/core-js/modules/_typed.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var global = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , hide   = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , uid    = __webpack_require__(/*! ./_uid */ "./node_modules/core-js/modules/_uid.js")
  , TYPED  = uid('typed_array')
  , VIEW   = uid('view')
  , ABV    = !!(global.ArrayBuffer && global.DataView)
  , CONSTR = ABV
  , i = 0, l = 9, Typed;

var TypedArrayConstructors = (
  'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array'
).split(',');

while(i < l){
  if(Typed = global[TypedArrayConstructors[i++]]){
    hide(Typed.prototype, TYPED, true);
    hide(Typed.prototype, VIEW, true);
  } else CONSTR = false;
}

module.exports = {
  ABV:    ABV,
  CONSTR: CONSTR,
  TYPED:  TYPED,
  VIEW:   VIEW
};

/***/ }),

/***/ "./node_modules/core-js/modules/_uid.js":
/*!**********************************************!*\
  !*** ./node_modules/core-js/modules/_uid.js ***!
  \**********************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var id = 0
  , px = Math.random();
module.exports = function(key){
  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
};

/***/ }),

/***/ "./node_modules/core-js/modules/_wks-define.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/_wks-define.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var global         = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , core           = __webpack_require__(/*! ./_core */ "./node_modules/core-js/modules/_core.js")
  , LIBRARY        = __webpack_require__(/*! ./_library */ "./node_modules/core-js/modules/_library.js")
  , wksExt         = __webpack_require__(/*! ./_wks-ext */ "./node_modules/core-js/modules/_wks-ext.js")
  , defineProperty = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").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)});
};

/***/ }),

/***/ "./node_modules/core-js/modules/_wks-ext.js":
/*!**************************************************!*\
  !*** ./node_modules/core-js/modules/_wks-ext.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

exports.f = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js");

/***/ }),

/***/ "./node_modules/core-js/modules/_wks.js":
/*!**********************************************!*\
  !*** ./node_modules/core-js/modules/_wks.js ***!
  \**********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var store      = __webpack_require__(/*! ./_shared */ "./node_modules/core-js/modules/_shared.js")('wks')
  , uid        = __webpack_require__(/*! ./_uid */ "./node_modules/core-js/modules/_uid.js")
  , Symbol     = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").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;

/***/ }),

/***/ "./node_modules/core-js/modules/core.get-iterator-method.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/core.get-iterator-method.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var classof   = __webpack_require__(/*! ./_classof */ "./node_modules/core-js/modules/_classof.js")
  , ITERATOR  = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('iterator')
  , Iterators = __webpack_require__(/*! ./_iterators */ "./node_modules/core-js/modules/_iterators.js");
module.exports = __webpack_require__(/*! ./_core */ "./node_modules/core-js/modules/_core.js").getIteratorMethod = function(it){
  if(it != undefined)return it[ITERATOR]
    || it['@@iterator']
    || Iterators[classof(it)];
};

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.copy-within.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.copy-within.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.P, 'Array', {copyWithin: __webpack_require__(/*! ./_array-copy-within */ "./node_modules/core-js/modules/_array-copy-within.js")});

__webpack_require__(/*! ./_add-to-unscopables */ "./node_modules/core-js/modules/_add-to-unscopables.js")('copyWithin');

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.every.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.every.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $every  = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(4);

$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")([].every, true), 'Array', {
  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])
  every: function every(callbackfn /* , thisArg */){
    return $every(this, callbackfn, arguments[1]);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.fill.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.fill.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.P, 'Array', {fill: __webpack_require__(/*! ./_array-fill */ "./node_modules/core-js/modules/_array-fill.js")});

__webpack_require__(/*! ./_add-to-unscopables */ "./node_modules/core-js/modules/_add-to-unscopables.js")('fill');

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.filter.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.filter.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $filter = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(2);

$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")([].filter, true), 'Array', {
  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])
  filter: function filter(callbackfn /* , thisArg */){
    return $filter(this, callbackfn, arguments[1]);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.find-index.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.find-index.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $find   = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(6)
  , KEY     = 'findIndex'
  , forced  = true;
// Shouldn't skip holes
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  findIndex: function findIndex(callbackfn/*, that = undefined */){
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
__webpack_require__(/*! ./_add-to-unscopables */ "./node_modules/core-js/modules/_add-to-unscopables.js")(KEY);

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.find.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.find.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $find   = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(5)
  , KEY     = 'find'
  , forced  = true;
// Shouldn't skip holes
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  find: function find(callbackfn/*, that = undefined */){
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
__webpack_require__(/*! ./_add-to-unscopables */ "./node_modules/core-js/modules/_add-to-unscopables.js")(KEY);

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.for-each.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.for-each.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $forEach = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(0)
  , STRICT   = __webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")([].forEach, true);

$export($export.P + $export.F * !STRICT, 'Array', {
  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])
  forEach: function forEach(callbackfn /* , thisArg */){
    return $forEach(this, callbackfn, arguments[1]);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.from.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.from.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var ctx            = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
  , $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toObject       = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , call           = __webpack_require__(/*! ./_iter-call */ "./node_modules/core-js/modules/_iter-call.js")
  , isArrayIter    = __webpack_require__(/*! ./_is-array-iter */ "./node_modules/core-js/modules/_is-array-iter.js")
  , toLength       = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , createProperty = __webpack_require__(/*! ./_create-property */ "./node_modules/core-js/modules/_create-property.js")
  , getIterFn      = __webpack_require__(/*! ./core.get-iterator-method */ "./node_modules/core-js/modules/core.get-iterator-method.js");

$export($export.S + $export.F * !__webpack_require__(/*! ./_iter-detect */ "./node_modules/core-js/modules/_iter-detect.js")(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;
  }
});


/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.index-of.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.index-of.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export       = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $indexOf      = __webpack_require__(/*! ./_array-includes */ "./node_modules/core-js/modules/_array-includes.js")(false)
  , $native       = [].indexOf
  , NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")($native)), 'Array', {
  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])
  indexOf: function indexOf(searchElement /*, fromIndex = 0 */){
    return NEGATIVE_ZERO
      // convert -0 to +0
      ? $native.apply(this, arguments) || 0
      : $indexOf(this, searchElement, arguments[1]);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.is-array.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.is-array.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Array', {isArray: __webpack_require__(/*! ./_is-array */ "./node_modules/core-js/modules/_is-array.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.iterator.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.iterator.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var addToUnscopables = __webpack_require__(/*! ./_add-to-unscopables */ "./node_modules/core-js/modules/_add-to-unscopables.js")
  , step             = __webpack_require__(/*! ./_iter-step */ "./node_modules/core-js/modules/_iter-step.js")
  , Iterators        = __webpack_require__(/*! ./_iterators */ "./node_modules/core-js/modules/_iterators.js")
  , toIObject        = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js");

// 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__(/*! ./_iter-define */ "./node_modules/core-js/modules/_iter-define.js")(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');

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.join.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.join.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 22.1.3.13 Array.prototype.join(separator)
var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toIObject = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , arrayJoin = [].join;

// fallback for not array-like strings
$export($export.P + $export.F * (__webpack_require__(/*! ./_iobject */ "./node_modules/core-js/modules/_iobject.js") != Object || !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")(arrayJoin)), 'Array', {
  join: function join(separator){
    return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.last-index-of.js":
/*!*****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.last-index-of.js ***!
  \*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export       = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toIObject     = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , toInteger     = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
  , toLength      = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , $native       = [].lastIndexOf
  , NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")($native)), 'Array', {
  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])
  lastIndexOf: function lastIndexOf(searchElement /*, fromIndex = @[*-1] */){
    // convert -0 to +0
    if(NEGATIVE_ZERO)return $native.apply(this, arguments) || 0;
    var O      = toIObject(this)
      , length = toLength(O.length)
      , index  = length - 1;
    if(arguments.length > 1)index = Math.min(index, toInteger(arguments[1]));
    if(index < 0)index = length + index;
    for(;index >= 0; index--)if(index in O)if(O[index] === searchElement)return index || 0;
    return -1;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.map.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.map.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $map    = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(1);

$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")([].map, true), 'Array', {
  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])
  map: function map(callbackfn /* , thisArg */){
    return $map(this, callbackfn, arguments[1]);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.of.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.of.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , createProperty = __webpack_require__(/*! ./_create-property */ "./node_modules/core-js/modules/_create-property.js");

// WebKit Array.of isn't generic
$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  function F(){}
  return !(Array.of.call(F) instanceof F);
}), 'Array', {
  // 22.1.2.3 Array.of( ...items)
  of: function of(/* ...args */){
    var index  = 0
      , aLen   = arguments.length
      , result = new (typeof this == 'function' ? this : Array)(aLen);
    while(aLen > index)createProperty(result, index, arguments[index++]);
    result.length = aLen;
    return result;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.reduce-right.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.reduce-right.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $reduce = __webpack_require__(/*! ./_array-reduce */ "./node_modules/core-js/modules/_array-reduce.js");

$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")([].reduceRight, true), 'Array', {
  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])
  reduceRight: function reduceRight(callbackfn /* , initialValue */){
    return $reduce(this, callbackfn, arguments.length, arguments[1], true);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.reduce.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.reduce.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $reduce = __webpack_require__(/*! ./_array-reduce */ "./node_modules/core-js/modules/_array-reduce.js");

$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")([].reduce, true), 'Array', {
  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])
  reduce: function reduce(callbackfn /* , initialValue */){
    return $reduce(this, callbackfn, arguments.length, arguments[1], false);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.slice.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.slice.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export    = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , html       = __webpack_require__(/*! ./_html */ "./node_modules/core-js/modules/_html.js")
  , cof        = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js")
  , toIndex    = __webpack_require__(/*! ./_to-index */ "./node_modules/core-js/modules/_to-index.js")
  , toLength   = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , arraySlice = [].slice;

// fallback for not array-like ES3 strings and DOM objects
$export($export.P + $export.F * __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  if(html)arraySlice.call(html);
}), 'Array', {
  slice: function slice(begin, end){
    var len   = toLength(this.length)
      , klass = cof(this);
    end = end === undefined ? len : end;
    if(klass == 'Array')return arraySlice.call(this, begin, end);
    var start  = toIndex(begin, len)
      , upTo   = toIndex(end, len)
      , size   = toLength(upTo - start)
      , cloned = Array(size)
      , i      = 0;
    for(; i < size; i++)cloned[i] = klass == 'String'
      ? this.charAt(start + i)
      : this[start + i];
    return cloned;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.some.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.some.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $some   = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(3);

$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")([].some, true), 'Array', {
  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])
  some: function some(callbackfn /* , thisArg */){
    return $some(this, callbackfn, arguments[1]);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.sort.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.sort.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , toObject  = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , fails     = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , $sort     = [].sort
  , test      = [1, 2, 3];

$export($export.P + $export.F * (fails(function(){
  // IE8-
  test.sort(undefined);
}) || !fails(function(){
  // V8 bug
  test.sort(null);
  // Old WebKit
}) || !__webpack_require__(/*! ./_strict-method */ "./node_modules/core-js/modules/_strict-method.js")($sort)), 'Array', {
  // 22.1.3.25 Array.prototype.sort(comparefn)
  sort: function sort(comparefn){
    return comparefn === undefined
      ? $sort.call(toObject(this))
      : $sort.call(toObject(this), aFunction(comparefn));
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.array.species.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.array.species.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_set-species */ "./node_modules/core-js/modules/_set-species.js")('Array');

/***/ }),

/***/ "./node_modules/core-js/modules/es6.date.now.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.date.now.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.3.3.1 / 15.9.4.4 Date.now()
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Date', {now: function(){ return new Date().getTime(); }});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.date.to-iso-string.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.date.to-iso-string.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , fails   = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , getTime = Date.prototype.getTime;

var lz = function(num){
  return num > 9 ? num : '0' + num;
};

// PhantomJS / old WebKit has a broken implementations
$export($export.P + $export.F * (fails(function(){
  return new Date(-5e13 - 1).toISOString() != '0385-07-25T07:06:39.999Z';
}) || !fails(function(){
  new Date(NaN).toISOString();
})), 'Date', {
  toISOString: function toISOString(){
    if(!isFinite(getTime.call(this)))throw RangeError('Invalid time value');
    var d = this
      , y = d.getUTCFullYear()
      , m = d.getUTCMilliseconds()
      , s = y < 0 ? '-' : y > 9999 ? '+' : '';
    return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +
      '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +
      'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +
      ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.date.to-json.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.date.to-json.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export     = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toObject    = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , toPrimitive = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js");

$export($export.P + $export.F * __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  return new Date(NaN).toJSON() !== null || Date.prototype.toJSON.call({toISOString: function(){ return 1; }}) !== 1;
}), 'Date', {
  toJSON: function toJSON(key){
    var O  = toObject(this)
      , pv = toPrimitive(O);
    return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.date.to-primitive.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.date.to-primitive.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var TO_PRIMITIVE = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('toPrimitive')
  , proto        = Date.prototype;

if(!(TO_PRIMITIVE in proto))__webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")(proto, TO_PRIMITIVE, __webpack_require__(/*! ./_date-to-primitive */ "./node_modules/core-js/modules/_date-to-primitive.js"));

/***/ }),

/***/ "./node_modules/core-js/modules/es6.date.to-string.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.date.to-string.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var DateProto    = Date.prototype
  , INVALID_DATE = 'Invalid Date'
  , TO_STRING    = 'toString'
  , $toString    = DateProto[TO_STRING]
  , getTime      = DateProto.getTime;
if(new Date(NaN) + '' != INVALID_DATE){
  __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")(DateProto, TO_STRING, function toString(){
    var value = getTime.call(this);
    return value === value ? $toString.call(this) : INVALID_DATE;
  });
}

/***/ }),

/***/ "./node_modules/core-js/modules/es6.function.bind.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.function.bind.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.P, 'Function', {bind: __webpack_require__(/*! ./_bind */ "./node_modules/core-js/modules/_bind.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.function.has-instance.js":
/*!*******************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.function.has-instance.js ***!
  \*******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var isObject       = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , HAS_INSTANCE   = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('hasInstance')
  , FunctionProto  = Function.prototype;
// 19.2.3.6 Function.prototype[@@hasInstance](V)
if(!(HAS_INSTANCE in FunctionProto))__webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f(FunctionProto, HAS_INSTANCE, {value: function(O){
  if(typeof this != 'function' || !isObject(O))return false;
  if(!isObject(this.prototype))return O instanceof this;
  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:
  while(O = getPrototypeOf(O))if(this.prototype === O)return true;
  return false;
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.function.name.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.function.name.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var dP         = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f
  , createDesc = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js")
  , has        = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , FProto     = Function.prototype
  , nameRE     = /^\s*function ([^ (]*)/
  , NAME       = 'name';

var isExtensible = Object.isExtensible || function(){
  return true;
};

// 19.2.4.2 name
NAME in FProto || __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && dP(FProto, NAME, {
  configurable: true,
  get: function(){
    try {
      var that = this
        , name = ('' + that).match(nameRE)[1];
      has(that, NAME) || !isExtensible(that) || dP(that, NAME, createDesc(5, name));
      return name;
    } catch(e){
      return '';
    }
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.map.js":
/*!*************************************************!*\
  !*** ./node_modules/core-js/modules/es6.map.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var strong = __webpack_require__(/*! ./_collection-strong */ "./node_modules/core-js/modules/_collection-strong.js");

// 23.1 Map Objects
module.exports = __webpack_require__(/*! ./_collection */ "./node_modules/core-js/modules/_collection.js")('Map', function(get){
  return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.1.3.6 Map.prototype.get(key)
  get: function get(key){
    var entry = strong.getEntry(this, key);
    return entry && entry.v;
  },
  // 23.1.3.9 Map.prototype.set(key, value)
  set: function set(key, value){
    return strong.def(this, key === 0 ? 0 : key, value);
  }
}, strong, true);

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.acosh.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.acosh.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.3 Math.acosh(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , log1p   = __webpack_require__(/*! ./_math-log1p */ "./node_modules/core-js/modules/_math-log1p.js")
  , sqrt    = Math.sqrt
  , $acosh  = Math.acosh;

$export($export.S + $export.F * !($acosh
  // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509
  && Math.floor($acosh(Number.MAX_VALUE)) == 710
  // Tor Browser bug: Math.acosh(Infinity) -> NaN 
  && $acosh(Infinity) == Infinity
), 'Math', {
  acosh: function acosh(x){
    return (x = +x) < 1 ? NaN : x > 94906265.62425156
      ? Math.log(x) + Math.LN2
      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.asinh.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.asinh.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.5 Math.asinh(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $asinh  = Math.asinh;

function asinh(x){
  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));
}

// Tor Browser bug: Math.asinh(0) -> -0 
$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', {asinh: asinh});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.atanh.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.atanh.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.7 Math.atanh(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $atanh  = Math.atanh;

// Tor Browser bug: Math.atanh(-0) -> 0 
$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {
  atanh: function atanh(x){
    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.cbrt.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.cbrt.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.9 Math.cbrt(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , sign    = __webpack_require__(/*! ./_math-sign */ "./node_modules/core-js/modules/_math-sign.js");

$export($export.S, 'Math', {
  cbrt: function cbrt(x){
    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.clz32.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.clz32.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.11 Math.clz32(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  clz32: function clz32(x){
    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.cosh.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.cosh.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.12 Math.cosh(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , exp     = Math.exp;

$export($export.S, 'Math', {
  cosh: function cosh(x){
    return (exp(x = +x) + exp(-x)) / 2;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.expm1.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.expm1.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.14 Math.expm1(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $expm1  = __webpack_require__(/*! ./_math-expm1 */ "./node_modules/core-js/modules/_math-expm1.js");

$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', {expm1: $expm1});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.fround.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.fround.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.16 Math.fround(x)
var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , sign      = __webpack_require__(/*! ./_math-sign */ "./node_modules/core-js/modules/_math-sign.js")
  , pow       = Math.pow
  , EPSILON   = pow(2, -52)
  , EPSILON32 = pow(2, -23)
  , MAX32     = pow(2, 127) * (2 - EPSILON32)
  , MIN32     = pow(2, -126);

var roundTiesToEven = function(n){
  return n + 1 / EPSILON - 1 / EPSILON;
};


$export($export.S, 'Math', {
  fround: function fround(x){
    var $abs  = Math.abs(x)
      , $sign = sign(x)
      , a, result;
    if($abs < MIN32)return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;
    a = (1 + EPSILON32 / EPSILON) * $abs;
    result = a - (a - $abs);
    if(result > MAX32 || result != result)return $sign * Infinity;
    return $sign * result;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.hypot.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.hypot.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , abs     = Math.abs;

$export($export.S, 'Math', {
  hypot: function hypot(value1, value2){ // eslint-disable-line no-unused-vars
    var sum  = 0
      , i    = 0
      , aLen = arguments.length
      , larg = 0
      , arg, div;
    while(i < aLen){
      arg = abs(arguments[i++]);
      if(larg < arg){
        div  = larg / arg;
        sum  = sum * div * div + 1;
        larg = arg;
      } else if(arg > 0){
        div  = arg / larg;
        sum += div * div;
      } else sum += arg;
    }
    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.imul.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.imul.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.18 Math.imul(x, y)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $imul   = Math.imul;

// some WebKit versions fails with big numbers, some has wrong arity
$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;
}), 'Math', {
  imul: function imul(x, y){
    var UINT16 = 0xffff
      , xn = +x
      , yn = +y
      , xl = UINT16 & xn
      , yl = UINT16 & yn;
    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.log10.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.log10.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.21 Math.log10(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  log10: function log10(x){
    return Math.log(x) / Math.LN10;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.log1p.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.log1p.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.20 Math.log1p(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {log1p: __webpack_require__(/*! ./_math-log1p */ "./node_modules/core-js/modules/_math-log1p.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.log2.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.log2.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.22 Math.log2(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  log2: function log2(x){
    return Math.log(x) / Math.LN2;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.sign.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.sign.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.28 Math.sign(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {sign: __webpack_require__(/*! ./_math-sign */ "./node_modules/core-js/modules/_math-sign.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.sinh.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.sinh.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.30 Math.sinh(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , expm1   = __webpack_require__(/*! ./_math-expm1 */ "./node_modules/core-js/modules/_math-expm1.js")
  , exp     = Math.exp;

// V8 near Chromium 38 has a problem with very small numbers
$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  return !Math.sinh(-2e-17) != -2e-17;
}), 'Math', {
  sinh: function sinh(x){
    return Math.abs(x = +x) < 1
      ? (expm1(x) - expm1(-x)) / 2
      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.tanh.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.tanh.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.33 Math.tanh(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , expm1   = __webpack_require__(/*! ./_math-expm1 */ "./node_modules/core-js/modules/_math-expm1.js")
  , exp     = Math.exp;

$export($export.S, 'Math', {
  tanh: function tanh(x){
    var a = expm1(x = +x)
      , b = expm1(-x);
    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.math.trunc.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.math.trunc.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.2.2.34 Math.trunc(x)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  trunc: function trunc(it){
    return (it > 0 ? Math.floor : Math.ceil)(it);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.constructor.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.constructor.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var global            = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , has               = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , cof               = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js")
  , inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ "./node_modules/core-js/modules/_inherit-if-required.js")
  , toPrimitive       = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
  , fails             = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , gOPN              = __webpack_require__(/*! ./_object-gopn */ "./node_modules/core-js/modules/_object-gopn.js").f
  , gOPD              = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js").f
  , dP                = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f
  , $trim             = __webpack_require__(/*! ./_string-trim */ "./node_modules/core-js/modules/_string-trim.js").trim
  , NUMBER            = 'Number'
  , $Number           = global[NUMBER]
  , Base              = $Number
  , proto             = $Number.prototype
  // Opera ~12 has broken Object#toString
  , BROKEN_COF        = cof(__webpack_require__(/*! ./_object-create */ "./node_modules/core-js/modules/_object-create.js")(proto)) == NUMBER
  , TRIM              = 'trim' in String.prototype;

// 7.1.3 ToNumber(argument)
var toNumber = function(argument){
  var it = toPrimitive(argument, false);
  if(typeof it == 'string' && it.length > 2){
    it = TRIM ? it.trim() : $trim(it, 3);
    var first = it.charCodeAt(0)
      , third, radix, maxCode;
    if(first === 43 || first === 45){
      third = it.charCodeAt(2);
      if(third === 88 || third === 120)return NaN; // Number('+0x1') should be NaN, old V8 fix
    } else if(first === 48){
      switch(it.charCodeAt(1)){
        case 66 : case 98  : radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i
        case 79 : case 111 : radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i
        default : return +it;
      }
      for(var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++){
        code = digits.charCodeAt(i);
        // parseInt parses a string to a first unavailable symbol
        // but ToNumber should return NaN if a string contains unavailable symbols
        if(code < 48 || code > maxCode)return NaN;
      } return parseInt(digits, radix);
    }
  } return +it;
};

if(!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')){
  $Number = function Number(value){
    var it = arguments.length < 1 ? 0 : value
      , that = this;
    return that instanceof $Number
      // check on 1..constructor(foo) case
      && (BROKEN_COF ? fails(function(){ proto.valueOf.call(that); }) : cof(that) != NUMBER)
        ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);
  };
  for(var keys = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") ? gOPN(Base) : (
    // ES3:
    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
    // ES6 (in case, if modules with ES6 Number statics required before):
    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
  ).split(','), j = 0, key; keys.length > j; j++){
    if(has(Base, key = keys[j]) && !has($Number, key)){
      dP($Number, key, gOPD(Base, key));
    }
  }
  $Number.prototype = proto;
  proto.constructor = $Number;
  __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")(global, NUMBER, $Number);
}

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.epsilon.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.epsilon.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.1 Number.EPSILON
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Number', {EPSILON: Math.pow(2, -52)});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.is-finite.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.is-finite.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.2 Number.isFinite(number)
var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , _isFinite = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").isFinite;

$export($export.S, 'Number', {
  isFinite: function isFinite(it){
    return typeof it == 'number' && _isFinite(it);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.is-integer.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.is-integer.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.3 Number.isInteger(number)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Number', {isInteger: __webpack_require__(/*! ./_is-integer */ "./node_modules/core-js/modules/_is-integer.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.is-nan.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.is-nan.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.4 Number.isNaN(number)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Number', {
  isNaN: function isNaN(number){
    return number != number;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.is-safe-integer.js":
/*!********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.is-safe-integer.js ***!
  \********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.5 Number.isSafeInteger(number)
var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , isInteger = __webpack_require__(/*! ./_is-integer */ "./node_modules/core-js/modules/_is-integer.js")
  , abs       = Math.abs;

$export($export.S, 'Number', {
  isSafeInteger: function isSafeInteger(number){
    return isInteger(number) && abs(number) <= 0x1fffffffffffff;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.max-safe-integer.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.max-safe-integer.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.6 Number.MAX_SAFE_INTEGER
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Number', {MAX_SAFE_INTEGER: 0x1fffffffffffff});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.min-safe-integer.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.min-safe-integer.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 20.1.2.10 Number.MIN_SAFE_INTEGER
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Number', {MIN_SAFE_INTEGER: -0x1fffffffffffff});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.parse-float.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.parse-float.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export     = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $parseFloat = __webpack_require__(/*! ./_parse-float */ "./node_modules/core-js/modules/_parse-float.js");
// 20.1.2.12 Number.parseFloat(string)
$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', {parseFloat: $parseFloat});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.parse-int.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.parse-int.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $parseInt = __webpack_require__(/*! ./_parse-int */ "./node_modules/core-js/modules/_parse-int.js");
// 20.1.2.13 Number.parseInt(string, radix)
$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', {parseInt: $parseInt});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.to-fixed.js":
/*!*************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.to-fixed.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export      = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toInteger    = __webpack_require__(/*! ./_to-integer */ "./node_modules/core-js/modules/_to-integer.js")
  , aNumberValue = __webpack_require__(/*! ./_a-number-value */ "./node_modules/core-js/modules/_a-number-value.js")
  , repeat       = __webpack_require__(/*! ./_string-repeat */ "./node_modules/core-js/modules/_string-repeat.js")
  , $toFixed     = 1..toFixed
  , floor        = Math.floor
  , data         = [0, 0, 0, 0, 0, 0]
  , ERROR        = 'Number.toFixed: incorrect invocation!'
  , ZERO         = '0';

var multiply = function(n, c){
  var i  = -1
    , c2 = c;
  while(++i < 6){
    c2 += n * data[i];
    data[i] = c2 % 1e7;
    c2 = floor(c2 / 1e7);
  }
};
var divide = function(n){
  var i = 6
    , c = 0;
  while(--i >= 0){
    c += data[i];
    data[i] = floor(c / n);
    c = (c % n) * 1e7;
  }
};
var numToString = function(){
  var i = 6
    , s = '';
  while(--i >= 0){
    if(s !== '' || i === 0 || data[i] !== 0){
      var t = String(data[i]);
      s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;
    }
  } return s;
};
var pow = function(x, n, acc){
  return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
};
var log = function(x){
  var n  = 0
    , x2 = x;
  while(x2 >= 4096){
    n += 12;
    x2 /= 4096;
  }
  while(x2 >= 2){
    n  += 1;
    x2 /= 2;
  } return n;
};

$export($export.P + $export.F * (!!$toFixed && (
  0.00008.toFixed(3) !== '0.000' ||
  0.9.toFixed(0) !== '1' ||
  1.255.toFixed(2) !== '1.25' ||
  1000000000000000128..toFixed(0) !== '1000000000000000128'
) || !__webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  // V8 ~ Android 4.3-
  $toFixed.call({});
})), 'Number', {
  toFixed: function toFixed(fractionDigits){
    var x = aNumberValue(this, ERROR)
      , f = toInteger(fractionDigits)
      , s = ''
      , m = ZERO
      , e, z, j, k;
    if(f < 0 || f > 20)throw RangeError(ERROR);
    if(x != x)return 'NaN';
    if(x <= -1e21 || x >= 1e21)return String(x);
    if(x < 0){
      s = '-';
      x = -x;
    }
    if(x > 1e-21){
      e = log(x * pow(2, 69, 1)) - 69;
      z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);
      z *= 0x10000000000000;
      e = 52 - e;
      if(e > 0){
        multiply(0, z);
        j = f;
        while(j >= 7){
          multiply(1e7, 0);
          j -= 7;
        }
        multiply(pow(10, j, 1), 0);
        j = e - 1;
        while(j >= 23){
          divide(1 << 23);
          j -= 23;
        }
        divide(1 << j);
        multiply(1, 1);
        divide(2);
        m = numToString();
      } else {
        multiply(0, z);
        multiply(1 << -e, 0);
        m = numToString() + repeat.call(ZERO, f);
      }
    }
    if(f > 0){
      k = m.length;
      m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));
    } else {
      m = s + m;
    } return m;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.number.to-precision.js":
/*!*****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.number.to-precision.js ***!
  \*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export      = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $fails       = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , aNumberValue = __webpack_require__(/*! ./_a-number-value */ "./node_modules/core-js/modules/_a-number-value.js")
  , $toPrecision = 1..toPrecision;

$export($export.P + $export.F * ($fails(function(){
  // IE7-
  return $toPrecision.call(1, undefined) !== '1';
}) || !$fails(function(){
  // V8 ~ Android 4.3-
  $toPrecision.call({});
})), 'Number', {
  toPrecision: function toPrecision(precision){
    var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');
    return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision); 
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.assign.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.assign.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.3.1 Object.assign(target, source)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S + $export.F, 'Object', {assign: __webpack_require__(/*! ./_object-assign */ "./node_modules/core-js/modules/_object-assign.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.create.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.create.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
$export($export.S, 'Object', {create: __webpack_require__(/*! ./_object-create */ "./node_modules/core-js/modules/_object-create.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.define-properties.js":
/*!**********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.define-properties.js ***!
  \**********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");
// 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)
$export($export.S + $export.F * !__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js"), 'Object', {defineProperties: __webpack_require__(/*! ./_object-dps */ "./node_modules/core-js/modules/_object-dps.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.define-property.js":
/*!********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.define-property.js ***!
  \********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");
// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)
$export($export.S + $export.F * !__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js"), 'Object', {defineProperty: __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.freeze.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.freeze.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.5 Object.freeze(O)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , meta     = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js").onFreeze;

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('freeze', function($freeze){
  return function freeze(it){
    return $freeze && isObject(it) ? $freeze(meta(it)) : it;
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js":
/*!********************************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js ***!
  \********************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
var toIObject                 = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , $getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js").f;

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('getOwnPropertyDescriptor', function(){
  return function getOwnPropertyDescriptor(it, key){
    return $getOwnPropertyDescriptor(toIObject(it), key);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.get-own-property-names.js":
/*!***************************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.get-own-property-names.js ***!
  \***************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.7 Object.getOwnPropertyNames(O)
__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('getOwnPropertyNames', function(){
  return __webpack_require__(/*! ./_object-gopn-ext */ "./node_modules/core-js/modules/_object-gopn-ext.js").f;
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.get-prototype-of.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.get-prototype-of.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.9 Object.getPrototypeOf(O)
var toObject        = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , $getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js");

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('getPrototypeOf', function(){
  return function getPrototypeOf(it){
    return $getPrototypeOf(toObject(it));
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.is-extensible.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.is-extensible.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.11 Object.isExtensible(O)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js");

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('isExtensible', function($isExtensible){
  return function isExtensible(it){
    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.is-frozen.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.is-frozen.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.12 Object.isFrozen(O)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js");

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('isFrozen', function($isFrozen){
  return function isFrozen(it){
    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.is-sealed.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.is-sealed.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.13 Object.isSealed(O)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js");

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('isSealed', function($isSealed){
  return function isSealed(it){
    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.is.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.is.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.3.10 Object.is(value1, value2)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");
$export($export.S, 'Object', {is: __webpack_require__(/*! ./_same-value */ "./node_modules/core-js/modules/_same-value.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.keys.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.keys.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.14 Object.keys(O)
var toObject = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , $keys    = __webpack_require__(/*! ./_object-keys */ "./node_modules/core-js/modules/_object-keys.js");

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('keys', function(){
  return function keys(it){
    return $keys(toObject(it));
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.prevent-extensions.js":
/*!***********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.prevent-extensions.js ***!
  \***********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.15 Object.preventExtensions(O)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , meta     = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js").onFreeze;

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('preventExtensions', function($preventExtensions){
  return function preventExtensions(it){
    return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it;
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.seal.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.seal.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.2.17 Object.seal(O)
var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , meta     = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js").onFreeze;

__webpack_require__(/*! ./_object-sap */ "./node_modules/core-js/modules/_object-sap.js")('seal', function($seal){
  return function seal(it){
    return $seal && isObject(it) ? $seal(meta(it)) : it;
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.set-prototype-of.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.set-prototype-of.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 19.1.3.19 Object.setPrototypeOf(O, proto)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");
$export($export.S, 'Object', {setPrototypeOf: __webpack_require__(/*! ./_set-proto */ "./node_modules/core-js/modules/_set-proto.js").set});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.object.to-string.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.object.to-string.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 19.1.3.6 Object.prototype.toString()
var classof = __webpack_require__(/*! ./_classof */ "./node_modules/core-js/modules/_classof.js")
  , test    = {};
test[__webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('toStringTag')] = 'z';
if(test + '' != '[object z]'){
  __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")(Object.prototype, 'toString', function toString(){
    return '[object ' + classof(this) + ']';
  }, true);
}

/***/ }),

/***/ "./node_modules/core-js/modules/es6.parse-float.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.parse-float.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export     = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $parseFloat = __webpack_require__(/*! ./_parse-float */ "./node_modules/core-js/modules/_parse-float.js");
// 18.2.4 parseFloat(string)
$export($export.G + $export.F * (parseFloat != $parseFloat), {parseFloat: $parseFloat});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.parse-int.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.parse-int.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $parseInt = __webpack_require__(/*! ./_parse-int */ "./node_modules/core-js/modules/_parse-int.js");
// 18.2.5 parseInt(string, radix)
$export($export.G + $export.F * (parseInt != $parseInt), {parseInt: $parseInt});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.promise.js":
/*!*****************************************************!*\
  !*** ./node_modules/core-js/modules/es6.promise.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var LIBRARY            = __webpack_require__(/*! ./_library */ "./node_modules/core-js/modules/_library.js")
  , global             = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , ctx                = __webpack_require__(/*! ./_ctx */ "./node_modules/core-js/modules/_ctx.js")
  , classof            = __webpack_require__(/*! ./_classof */ "./node_modules/core-js/modules/_classof.js")
  , $export            = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , isObject           = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , aFunction          = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , anInstance         = __webpack_require__(/*! ./_an-instance */ "./node_modules/core-js/modules/_an-instance.js")
  , forOf              = __webpack_require__(/*! ./_for-of */ "./node_modules/core-js/modules/_for-of.js")
  , speciesConstructor = __webpack_require__(/*! ./_species-constructor */ "./node_modules/core-js/modules/_species-constructor.js")
  , task               = __webpack_require__(/*! ./_task */ "./node_modules/core-js/modules/_task.js").set
  , microtask          = __webpack_require__(/*! ./_microtask */ "./node_modules/core-js/modules/_microtask.js")()
  , 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__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('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__(/*! ./_redefine-all */ "./node_modules/core-js/modules/_redefine-all.js")($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__(/*! ./_set-to-string-tag */ "./node_modules/core-js/modules/_set-to-string-tag.js")($Promise, PROMISE);
__webpack_require__(/*! ./_set-species */ "./node_modules/core-js/modules/_set-species.js")(PROMISE);
Wrapper = __webpack_require__(/*! ./_core */ "./node_modules/core-js/modules/_core.js")[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__(/*! ./_iter-detect */ "./node_modules/core-js/modules/_iter-detect.js")(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;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.apply.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.apply.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)
var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , anObject  = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , rApply    = (__webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").Reflect || {}).apply
  , fApply    = Function.apply;
// MS Edge argumentsList argument is optional
$export($export.S + $export.F * !__webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  rApply(function(){});
}), 'Reflect', {
  apply: function apply(target, thisArgument, argumentsList){
    var T = aFunction(target)
      , L = anObject(argumentsList);
    return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.construct.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.construct.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])
var $export    = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , create     = __webpack_require__(/*! ./_object-create */ "./node_modules/core-js/modules/_object-create.js")
  , aFunction  = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , anObject   = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , isObject   = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , fails      = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , bind       = __webpack_require__(/*! ./_bind */ "./node_modules/core-js/modules/_bind.js")
  , rConstruct = (__webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").Reflect || {}).construct;

// MS Edge supports only 2 arguments and argumentsList argument is optional
// FF Nightly sets third argument as `new.target`, but does not create `this` from it
var NEW_TARGET_BUG = fails(function(){
  function F(){}
  return !(rConstruct(function(){}, [], F) instanceof F);
});
var ARGS_BUG = !fails(function(){
  rConstruct(function(){});
});

$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {
  construct: function construct(Target, args /*, newTarget*/){
    aFunction(Target);
    anObject(args);
    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);
    if(ARGS_BUG && !NEW_TARGET_BUG)return rConstruct(Target, args, newTarget);
    if(Target == newTarget){
      // w/o altered newTarget, optimization for 0-4 arguments
      switch(args.length){
        case 0: return new Target;
        case 1: return new Target(args[0]);
        case 2: return new Target(args[0], args[1]);
        case 3: return new Target(args[0], args[1], args[2]);
        case 4: return new Target(args[0], args[1], args[2], args[3]);
      }
      // w/o altered newTarget, lot of arguments case
      var $args = [null];
      $args.push.apply($args, args);
      return new (bind.apply(Target, $args));
    }
    // with altered newTarget, not support built-in constructors
    var proto    = newTarget.prototype
      , instance = create(isObject(proto) ? proto : Object.prototype)
      , result   = Function.apply.call(Target, instance, args);
    return isObject(result) ? result : instance;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.define-property.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.define-property.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)
var dP          = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
  , $export     = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , anObject    = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , toPrimitive = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js");

// MS Edge has broken Reflect.defineProperty - throwing instead of returning false
$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  Reflect.defineProperty(dP.f({}, 1, {value: 1}), 1, {value: 2});
}), 'Reflect', {
  defineProperty: function defineProperty(target, propertyKey, attributes){
    anObject(target);
    propertyKey = toPrimitive(propertyKey, true);
    anObject(attributes);
    try {
      dP.f(target, propertyKey, attributes);
      return true;
    } catch(e){
      return false;
    }
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.delete-property.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.delete-property.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.4 Reflect.deleteProperty(target, propertyKey)
var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , gOPD     = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js").f
  , anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");

$export($export.S, 'Reflect', {
  deleteProperty: function deleteProperty(target, propertyKey){
    var desc = gOPD(anObject(target), propertyKey);
    return desc && !desc.configurable ? false : delete target[propertyKey];
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.enumerate.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.enumerate.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 26.1.5 Reflect.enumerate(target)
var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");
var Enumerate = function(iterated){
  this._t = anObject(iterated); // target
  this._i = 0;                  // next index
  var keys = this._k = []       // keys
    , key;
  for(key in iterated)keys.push(key);
};
__webpack_require__(/*! ./_iter-create */ "./node_modules/core-js/modules/_iter-create.js")(Enumerate, 'Object', function(){
  var that = this
    , keys = that._k
    , key;
  do {
    if(that._i >= keys.length)return {value: undefined, done: true};
  } while(!((key = keys[that._i++]) in that._t));
  return {value: key, done: false};
});

$export($export.S, 'Reflect', {
  enumerate: function enumerate(target){
    return new Enumerate(target);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js":
/*!*********************************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js ***!
  \*********************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)
var gOPD     = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js")
  , $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");

$export($export.S, 'Reflect', {
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey){
    return gOPD.f(anObject(target), propertyKey);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.get-prototype-of.js":
/*!**********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.get-prototype-of.js ***!
  \**********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.8 Reflect.getPrototypeOf(target)
var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , getProto = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");

$export($export.S, 'Reflect', {
  getPrototypeOf: function getPrototypeOf(target){
    return getProto(anObject(target));
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.get.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.get.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.6 Reflect.get(target, propertyKey [, receiver])
var gOPD           = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js")
  , getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , has            = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , isObject       = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , anObject       = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js");

function get(target, propertyKey/*, receiver*/){
  var receiver = arguments.length < 3 ? target : arguments[2]
    , desc, proto;
  if(anObject(target) === receiver)return target[propertyKey];
  if(desc = gOPD.f(target, propertyKey))return has(desc, 'value')
    ? desc.value
    : desc.get !== undefined
      ? desc.get.call(receiver)
      : undefined;
  if(isObject(proto = getPrototypeOf(target)))return get(proto, propertyKey, receiver);
}

$export($export.S, 'Reflect', {get: get});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.has.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.has.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.9 Reflect.has(target, propertyKey)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Reflect', {
  has: function has(target, propertyKey){
    return propertyKey in target;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.is-extensible.js":
/*!*******************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.is-extensible.js ***!
  \*******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.10 Reflect.isExtensible(target)
var $export       = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , anObject      = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , $isExtensible = Object.isExtensible;

$export($export.S, 'Reflect', {
  isExtensible: function isExtensible(target){
    anObject(target);
    return $isExtensible ? $isExtensible(target) : true;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.own-keys.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.own-keys.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.11 Reflect.ownKeys(target)
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Reflect', {ownKeys: __webpack_require__(/*! ./_own-keys */ "./node_modules/core-js/modules/_own-keys.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.prevent-extensions.js":
/*!************************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.prevent-extensions.js ***!
  \************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.12 Reflect.preventExtensions(target)
var $export            = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , anObject           = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , $preventExtensions = Object.preventExtensions;

$export($export.S, 'Reflect', {
  preventExtensions: function preventExtensions(target){
    anObject(target);
    try {
      if($preventExtensions)$preventExtensions(target);
      return true;
    } catch(e){
      return false;
    }
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.set-prototype-of.js":
/*!**********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.set-prototype-of.js ***!
  \**********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.14 Reflect.setPrototypeOf(target, proto)
var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , setProto = __webpack_require__(/*! ./_set-proto */ "./node_modules/core-js/modules/_set-proto.js");

if(setProto)$export($export.S, 'Reflect', {
  setPrototypeOf: function setPrototypeOf(target, proto){
    setProto.check(target, proto);
    try {
      setProto.set(target, proto);
      return true;
    } catch(e){
      return false;
    }
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.reflect.set.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.reflect.set.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])
var dP             = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
  , gOPD           = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js")
  , getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , has            = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , createDesc     = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js")
  , anObject       = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , isObject       = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js");

function set(target, propertyKey, V/*, receiver*/){
  var receiver = arguments.length < 4 ? target : arguments[3]
    , ownDesc  = gOPD.f(anObject(target), propertyKey)
    , existingDescriptor, proto;
  if(!ownDesc){
    if(isObject(proto = getPrototypeOf(target))){
      return set(proto, propertyKey, V, receiver);
    }
    ownDesc = createDesc(0);
  }
  if(has(ownDesc, 'value')){
    if(ownDesc.writable === false || !isObject(receiver))return false;
    existingDescriptor = gOPD.f(receiver, propertyKey) || createDesc(0);
    existingDescriptor.value = V;
    dP.f(receiver, propertyKey, existingDescriptor);
    return true;
  }
  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);
}

$export($export.S, 'Reflect', {set: set});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.regexp.constructor.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.regexp.constructor.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var global            = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ "./node_modules/core-js/modules/_inherit-if-required.js")
  , dP                = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f
  , gOPN              = __webpack_require__(/*! ./_object-gopn */ "./node_modules/core-js/modules/_object-gopn.js").f
  , isRegExp          = __webpack_require__(/*! ./_is-regexp */ "./node_modules/core-js/modules/_is-regexp.js")
  , $flags            = __webpack_require__(/*! ./_flags */ "./node_modules/core-js/modules/_flags.js")
  , $RegExp           = global.RegExp
  , Base              = $RegExp
  , proto             = $RegExp.prototype
  , re1               = /a/g
  , re2               = /a/g
  // "new" creates a new object, old webkit buggy here
  , CORRECT_NEW       = new $RegExp(re1) !== re1;

if(__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && (!CORRECT_NEW || __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  re2[__webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('match')] = false;
  // RegExp constructor can alter flags and IsRegExp works correct with @@match
  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';
}))){
  $RegExp = function RegExp(p, f){
    var tiRE = this instanceof $RegExp
      , piRE = isRegExp(p)
      , fiU  = f === undefined;
    return !tiRE && piRE && p.constructor === $RegExp && fiU ? p
      : inheritIfRequired(CORRECT_NEW
        ? new Base(piRE && !fiU ? p.source : p, f)
        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)
      , tiRE ? this : proto, $RegExp);
  };
  var proxy = function(key){
    key in $RegExp || dP($RegExp, key, {
      configurable: true,
      get: function(){ return Base[key]; },
      set: function(it){ Base[key] = it; }
    });
  };
  for(var keys = gOPN(Base), i = 0; keys.length > i; )proxy(keys[i++]);
  proto.constructor = $RegExp;
  $RegExp.prototype = proto;
  __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")(global, 'RegExp', $RegExp);
}

__webpack_require__(/*! ./_set-species */ "./node_modules/core-js/modules/_set-species.js")('RegExp');

/***/ }),

/***/ "./node_modules/core-js/modules/es6.regexp.flags.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.regexp.flags.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// 21.2.5.3 get RegExp.prototype.flags()
if(__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && /./g.flags != 'g')__webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js").f(RegExp.prototype, 'flags', {
  configurable: true,
  get: __webpack_require__(/*! ./_flags */ "./node_modules/core-js/modules/_flags.js")
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.regexp.match.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.regexp.match.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// @@match logic
__webpack_require__(/*! ./_fix-re-wks */ "./node_modules/core-js/modules/_fix-re-wks.js")('match', 1, function(defined, MATCH, $match){
  // 21.1.3.11 String.prototype.match(regexp)
  return [function match(regexp){
    'use strict';
    var O  = defined(this)
      , fn = regexp == undefined ? undefined : regexp[MATCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
  }, $match];
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.regexp.replace.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.regexp.replace.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// @@replace logic
__webpack_require__(/*! ./_fix-re-wks */ "./node_modules/core-js/modules/_fix-re-wks.js")('replace', 2, function(defined, REPLACE, $replace){
  // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
  return [function replace(searchValue, replaceValue){
    'use strict';
    var O  = defined(this)
      , fn = searchValue == undefined ? undefined : searchValue[REPLACE];
    return fn !== undefined
      ? fn.call(searchValue, O, replaceValue)
      : $replace.call(String(O), searchValue, replaceValue);
  }, $replace];
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.regexp.search.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.regexp.search.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// @@search logic
__webpack_require__(/*! ./_fix-re-wks */ "./node_modules/core-js/modules/_fix-re-wks.js")('search', 1, function(defined, SEARCH, $search){
  // 21.1.3.15 String.prototype.search(regexp)
  return [function search(regexp){
    'use strict';
    var O  = defined(this)
      , fn = regexp == undefined ? undefined : regexp[SEARCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
  }, $search];
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.regexp.split.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.regexp.split.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// @@split logic
__webpack_require__(/*! ./_fix-re-wks */ "./node_modules/core-js/modules/_fix-re-wks.js")('split', 2, function(defined, SPLIT, $split){
  'use strict';
  var isRegExp   = __webpack_require__(/*! ./_is-regexp */ "./node_modules/core-js/modules/_is-regexp.js")
    , _split     = $split
    , $push      = [].push
    , $SPLIT     = 'split'
    , LENGTH     = 'length'
    , LAST_INDEX = 'lastIndex';
  if(
    'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||
    'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||
    'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||
    '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||
    '.'[$SPLIT](/()()/)[LENGTH] > 1 ||
    ''[$SPLIT](/.?/)[LENGTH]
  ){
    var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group
    // based on es5-shim implementation, need to rework it
    $split = function(separator, limit){
      var string = String(this);
      if(separator === undefined && limit === 0)return [];
      // If `separator` is not a regex, use native split
      if(!isRegExp(separator))return _split.call(string, separator, limit);
      var output = [];
      var flags = (separator.ignoreCase ? 'i' : '') +
                  (separator.multiline ? 'm' : '') +
                  (separator.unicode ? 'u' : '') +
                  (separator.sticky ? 'y' : '');
      var lastLastIndex = 0;
      var splitLimit = limit === undefined ? 4294967295 : limit >>> 0;
      // Make `global` and avoid `lastIndex` issues by working with a copy
      var separatorCopy = new RegExp(separator.source, flags + 'g');
      var separator2, match, lastIndex, lastLength, i;
      // Doesn't need flags gy, but they don't hurt
      if(!NPCG)separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
      while(match = separatorCopy.exec(string)){
        // `separatorCopy.lastIndex` is not reliable cross-browser
        lastIndex = match.index + match[0][LENGTH];
        if(lastIndex > lastLastIndex){
          output.push(string.slice(lastLastIndex, match.index));
          // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG
          if(!NPCG && match[LENGTH] > 1)match[0].replace(separator2, function(){
            for(i = 1; i < arguments[LENGTH] - 2; i++)if(arguments[i] === undefined)match[i] = undefined;
          });
          if(match[LENGTH] > 1 && match.index < string[LENGTH])$push.apply(output, match.slice(1));
          lastLength = match[0][LENGTH];
          lastLastIndex = lastIndex;
          if(output[LENGTH] >= splitLimit)break;
        }
        if(separatorCopy[LAST_INDEX] === match.index)separatorCopy[LAST_INDEX]++; // Avoid an infinite loop
      }
      if(lastLastIndex === string[LENGTH]){
        if(lastLength || !separatorCopy.test(''))output.push('');
      } else output.push(string.slice(lastLastIndex));
      return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
    };
  // Chakra, V8
  } else if('0'[$SPLIT](undefined, 0)[LENGTH]){
    $split = function(separator, limit){
      return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit);
    };
  }
  // 21.1.3.17 String.prototype.split(separator, limit)
  return [function split(separator, limit){
    var O  = defined(this)
      , fn = separator == undefined ? undefined : separator[SPLIT];
    return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit);
  }, $split];
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.regexp.to-string.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.regexp.to-string.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

__webpack_require__(/*! ./es6.regexp.flags */ "./node_modules/core-js/modules/es6.regexp.flags.js");
var anObject    = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , $flags      = __webpack_require__(/*! ./_flags */ "./node_modules/core-js/modules/_flags.js")
  , DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js")
  , TO_STRING   = 'toString'
  , $toString   = /./[TO_STRING];

var define = function(fn){
  __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")(RegExp.prototype, TO_STRING, fn, true);
};

// 21.2.5.14 RegExp.prototype.toString()
if(__webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){ return $toString.call({source: 'a', flags: 'b'}) != '/a/b'; })){
  define(function toString(){
    var R = anObject(this);
    return '/'.concat(R.source, '/',
      'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);
  });
// FF44- RegExp#toString has a wrong name
} else if($toString.name != TO_STRING){
  define(function toString(){
    return $toString.call(this);
  });
}

/***/ }),

/***/ "./node_modules/core-js/modules/es6.set.js":
/*!*************************************************!*\
  !*** ./node_modules/core-js/modules/es6.set.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var strong = __webpack_require__(/*! ./_collection-strong */ "./node_modules/core-js/modules/_collection-strong.js");

// 23.2 Set Objects
module.exports = __webpack_require__(/*! ./_collection */ "./node_modules/core-js/modules/_collection.js")('Set', function(get){
  return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.2.3.1 Set.prototype.add(value)
  add: function add(value){
    return strong.def(this, value = value === 0 ? 0 : value, value);
  }
}, strong);

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.anchor.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.anchor.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.2 String.prototype.anchor(name)
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('anchor', function(createHTML){
  return function anchor(name){
    return createHTML(this, 'a', 'name', name);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.big.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.big.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.3 String.prototype.big()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('big', function(createHTML){
  return function big(){
    return createHTML(this, 'big', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.blink.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.blink.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.4 String.prototype.blink()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('blink', function(createHTML){
  return function blink(){
    return createHTML(this, 'blink', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.bold.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.bold.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.5 String.prototype.bold()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('bold', function(createHTML){
  return function bold(){
    return createHTML(this, 'b', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.code-point-at.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.code-point-at.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $at     = __webpack_require__(/*! ./_string-at */ "./node_modules/core-js/modules/_string-at.js")(false);
$export($export.P, 'String', {
  // 21.1.3.3 String.prototype.codePointAt(pos)
  codePointAt: function codePointAt(pos){
    return $at(this, pos);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.ends-with.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.ends-with.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])

var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toLength  = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , context   = __webpack_require__(/*! ./_string-context */ "./node_modules/core-js/modules/_string-context.js")
  , ENDS_WITH = 'endsWith'
  , $endsWith = ''[ENDS_WITH];

$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ "./node_modules/core-js/modules/_fails-is-regexp.js")(ENDS_WITH), 'String', {
  endsWith: function endsWith(searchString /*, endPosition = @length */){
    var that = context(this, searchString, ENDS_WITH)
      , endPosition = arguments.length > 1 ? arguments[1] : undefined
      , len    = toLength(that.length)
      , end    = endPosition === undefined ? len : Math.min(toLength(endPosition), len)
      , search = String(searchString);
    return $endsWith
      ? $endsWith.call(that, search, end)
      : that.slice(end - search.length, end) === search;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.fixed.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.fixed.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.6 String.prototype.fixed()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('fixed', function(createHTML){
  return function fixed(){
    return createHTML(this, 'tt', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.fontcolor.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.fontcolor.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.7 String.prototype.fontcolor(color)
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('fontcolor', function(createHTML){
  return function fontcolor(color){
    return createHTML(this, 'font', 'color', color);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.fontsize.js":
/*!*************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.fontsize.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.8 String.prototype.fontsize(size)
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('fontsize', function(createHTML){
  return function fontsize(size){
    return createHTML(this, 'font', 'size', size);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.from-code-point.js":
/*!********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.from-code-point.js ***!
  \********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toIndex        = __webpack_require__(/*! ./_to-index */ "./node_modules/core-js/modules/_to-index.js")
  , fromCharCode   = String.fromCharCode
  , $fromCodePoint = String.fromCodePoint;

// length should be 1, old FF problem
$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
  // 21.1.2.2 String.fromCodePoint(...codePoints)
  fromCodePoint: function fromCodePoint(x){ // eslint-disable-line no-unused-vars
    var res  = []
      , aLen = arguments.length
      , i    = 0
      , code;
    while(aLen > i){
      code = +arguments[i++];
      if(toIndex(code, 0x10ffff) !== code)throw RangeError(code + ' is not a valid code point');
      res.push(code < 0x10000
        ? fromCharCode(code)
        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
      );
    } return res.join('');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.includes.js":
/*!*************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.includes.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// 21.1.3.7 String.prototype.includes(searchString, position = 0)

var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , context  = __webpack_require__(/*! ./_string-context */ "./node_modules/core-js/modules/_string-context.js")
  , INCLUDES = 'includes';

$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ "./node_modules/core-js/modules/_fails-is-regexp.js")(INCLUDES), 'String', {
  includes: function includes(searchString /*, position = 0 */){
    return !!~context(this, searchString, INCLUDES)
      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.italics.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.italics.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.9 String.prototype.italics()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('italics', function(createHTML){
  return function italics(){
    return createHTML(this, 'i', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.iterator.js":
/*!*************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.iterator.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $at  = __webpack_require__(/*! ./_string-at */ "./node_modules/core-js/modules/_string-at.js")(true);

// 21.1.3.27 String.prototype[@@iterator]()
__webpack_require__(/*! ./_iter-define */ "./node_modules/core-js/modules/_iter-define.js")(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};
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.link.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.link.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.10 String.prototype.link(url)
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('link', function(createHTML){
  return function link(url){
    return createHTML(this, 'a', 'href', url);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.raw.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.raw.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toIObject = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , toLength  = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js");

$export($export.S, 'String', {
  // 21.1.2.4 String.raw(callSite, ...substitutions)
  raw: function raw(callSite){
    var tpl  = toIObject(callSite.raw)
      , len  = toLength(tpl.length)
      , aLen = arguments.length
      , res  = []
      , i    = 0;
    while(len > i){
      res.push(String(tpl[i++]));
      if(i < aLen)res.push(String(arguments[i]));
    } return res.join('');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.repeat.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.repeat.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.P, 'String', {
  // 21.1.3.13 String.prototype.repeat(count)
  repeat: __webpack_require__(/*! ./_string-repeat */ "./node_modules/core-js/modules/_string-repeat.js")
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.small.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.small.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.11 String.prototype.small()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('small', function(createHTML){
  return function small(){
    return createHTML(this, 'small', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.starts-with.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.starts-with.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// 21.1.3.18 String.prototype.startsWith(searchString [, position ])

var $export     = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toLength    = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , context     = __webpack_require__(/*! ./_string-context */ "./node_modules/core-js/modules/_string-context.js")
  , STARTS_WITH = 'startsWith'
  , $startsWith = ''[STARTS_WITH];

$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ "./node_modules/core-js/modules/_fails-is-regexp.js")(STARTS_WITH), 'String', {
  startsWith: function startsWith(searchString /*, position = 0 */){
    var that   = context(this, searchString, STARTS_WITH)
      , index  = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length))
      , search = String(searchString);
    return $startsWith
      ? $startsWith.call(that, search, index)
      : that.slice(index, index + search.length) === search;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.strike.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.strike.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.12 String.prototype.strike()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('strike', function(createHTML){
  return function strike(){
    return createHTML(this, 'strike', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.sub.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.sub.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.13 String.prototype.sub()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('sub', function(createHTML){
  return function sub(){
    return createHTML(this, 'sub', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.sup.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.sup.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// B.2.3.14 String.prototype.sup()
__webpack_require__(/*! ./_string-html */ "./node_modules/core-js/modules/_string-html.js")('sup', function(createHTML){
  return function sup(){
    return createHTML(this, 'sup', '', '');
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.string.trim.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es6.string.trim.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// 21.1.3.25 String.prototype.trim()
__webpack_require__(/*! ./_string-trim */ "./node_modules/core-js/modules/_string-trim.js")('trim', function($trim){
  return function trim(){
    return $trim(this, 3);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.symbol.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/es6.symbol.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// ECMAScript 6 symbols shim
var global         = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , has            = __webpack_require__(/*! ./_has */ "./node_modules/core-js/modules/_has.js")
  , DESCRIPTORS    = __webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js")
  , $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , redefine       = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")
  , META           = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js").KEY
  , $fails         = __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")
  , shared         = __webpack_require__(/*! ./_shared */ "./node_modules/core-js/modules/_shared.js")
  , setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ "./node_modules/core-js/modules/_set-to-string-tag.js")
  , uid            = __webpack_require__(/*! ./_uid */ "./node_modules/core-js/modules/_uid.js")
  , wks            = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")
  , wksExt         = __webpack_require__(/*! ./_wks-ext */ "./node_modules/core-js/modules/_wks-ext.js")
  , wksDefine      = __webpack_require__(/*! ./_wks-define */ "./node_modules/core-js/modules/_wks-define.js")
  , keyOf          = __webpack_require__(/*! ./_keyof */ "./node_modules/core-js/modules/_keyof.js")
  , enumKeys       = __webpack_require__(/*! ./_enum-keys */ "./node_modules/core-js/modules/_enum-keys.js")
  , isArray        = __webpack_require__(/*! ./_is-array */ "./node_modules/core-js/modules/_is-array.js")
  , anObject       = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , toIObject      = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , toPrimitive    = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
  , createDesc     = __webpack_require__(/*! ./_property-desc */ "./node_modules/core-js/modules/_property-desc.js")
  , _create        = __webpack_require__(/*! ./_object-create */ "./node_modules/core-js/modules/_object-create.js")
  , gOPNExt        = __webpack_require__(/*! ./_object-gopn-ext */ "./node_modules/core-js/modules/_object-gopn-ext.js")
  , $GOPD          = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js")
  , $DP            = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js")
  , $keys          = __webpack_require__(/*! ./_object-keys */ "./node_modules/core-js/modules/_object-keys.js")
  , 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__(/*! ./_object-gopn */ "./node_modules/core-js/modules/_object-gopn.js").f = gOPNExt.f = $getOwnPropertyNames;
  __webpack_require__(/*! ./_object-pie */ "./node_modules/core-js/modules/_object-pie.js").f  = $propertyIsEnumerable;
  __webpack_require__(/*! ./_object-gops */ "./node_modules/core-js/modules/_object-gops.js").f = $getOwnPropertySymbols;

  if(DESCRIPTORS && !__webpack_require__(/*! ./_library */ "./node_modules/core-js/modules/_library.js")){
    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__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")($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);

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.array-buffer.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.array-buffer.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export      = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $typed       = __webpack_require__(/*! ./_typed */ "./node_modules/core-js/modules/_typed.js")
  , buffer       = __webpack_require__(/*! ./_typed-buffer */ "./node_modules/core-js/modules/_typed-buffer.js")
  , anObject     = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , toIndex      = __webpack_require__(/*! ./_to-index */ "./node_modules/core-js/modules/_to-index.js")
  , toLength     = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , isObject     = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , ArrayBuffer  = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").ArrayBuffer
  , speciesConstructor = __webpack_require__(/*! ./_species-constructor */ "./node_modules/core-js/modules/_species-constructor.js")
  , $ArrayBuffer = buffer.ArrayBuffer
  , $DataView    = buffer.DataView
  , $isView      = $typed.ABV && ArrayBuffer.isView
  , $slice       = $ArrayBuffer.prototype.slice
  , VIEW         = $typed.VIEW
  , ARRAY_BUFFER = 'ArrayBuffer';

$export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), {ArrayBuffer: $ArrayBuffer});

$export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, {
  // 24.1.3.1 ArrayBuffer.isView(arg)
  isView: function isView(it){
    return $isView && $isView(it) || isObject(it) && VIEW in it;
  }
});

$export($export.P + $export.U + $export.F * __webpack_require__(/*! ./_fails */ "./node_modules/core-js/modules/_fails.js")(function(){
  return !new $ArrayBuffer(2).slice(1, undefined).byteLength;
}), ARRAY_BUFFER, {
  // 24.1.4.3 ArrayBuffer.prototype.slice(start, end)
  slice: function slice(start, end){
    if($slice !== undefined && end === undefined)return $slice.call(anObject(this), start); // FF fix
    var len    = anObject(this).byteLength
      , first  = toIndex(start, len)
      , final  = toIndex(end === undefined ? len : end, len)
      , result = new (speciesConstructor(this, $ArrayBuffer))(toLength(final - first))
      , viewS  = new $DataView(this)
      , viewT  = new $DataView(result)
      , index  = 0;
    while(first < final){
      viewT.setUint8(index++, viewS.getUint8(first++));
    } return result;
  }
});

__webpack_require__(/*! ./_set-species */ "./node_modules/core-js/modules/_set-species.js")(ARRAY_BUFFER);

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.data-view.js":
/*!*************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.data-view.js ***!
  \*************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");
$export($export.G + $export.W + $export.F * !__webpack_require__(/*! ./_typed */ "./node_modules/core-js/modules/_typed.js").ABV, {
  DataView: __webpack_require__(/*! ./_typed-buffer */ "./node_modules/core-js/modules/_typed-buffer.js").DataView
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.float32-array.js":
/*!*****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.float32-array.js ***!
  \*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Float32', 4, function(init){
  return function Float32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.float64-array.js":
/*!*****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.float64-array.js ***!
  \*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Float64', 8, function(init){
  return function Float64Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.int16-array.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.int16-array.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Int16', 2, function(init){
  return function Int16Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.int32-array.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.int32-array.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Int32', 4, function(init){
  return function Int32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.int8-array.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.int8-array.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Int8', 1, function(init){
  return function Int8Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.uint16-array.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.uint16-array.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Uint16', 2, function(init){
  return function Uint16Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.uint32-array.js":
/*!****************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.uint32-array.js ***!
  \****************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Uint32', 4, function(init){
  return function Uint32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.uint8-array.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.uint8-array.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Uint8', 1, function(init){
  return function Uint8Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

/***/ }),

/***/ "./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js":
/*!***********************************************************************!*\
  !*** ./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js ***!
  \***********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_typed-array */ "./node_modules/core-js/modules/_typed-array.js")('Uint8', 1, function(init){
  return function Uint8ClampedArray(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
}, true);

/***/ }),

/***/ "./node_modules/core-js/modules/es6.weak-map.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.weak-map.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var each         = __webpack_require__(/*! ./_array-methods */ "./node_modules/core-js/modules/_array-methods.js")(0)
  , redefine     = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")
  , meta         = __webpack_require__(/*! ./_meta */ "./node_modules/core-js/modules/_meta.js")
  , assign       = __webpack_require__(/*! ./_object-assign */ "./node_modules/core-js/modules/_object-assign.js")
  , weak         = __webpack_require__(/*! ./_collection-weak */ "./node_modules/core-js/modules/_collection-weak.js")
  , isObject     = __webpack_require__(/*! ./_is-object */ "./node_modules/core-js/modules/_is-object.js")
  , getWeak      = meta.getWeak
  , isExtensible = Object.isExtensible
  , uncaughtFrozenStore = weak.ufstore
  , tmp          = {}
  , InternalMap;

var wrapper = function(get){
  return function WeakMap(){
    return get(this, arguments.length > 0 ? arguments[0] : undefined);
  };
};

var methods = {
  // 23.3.3.3 WeakMap.prototype.get(key)
  get: function get(key){
    if(isObject(key)){
      var data = getWeak(key);
      if(data === true)return uncaughtFrozenStore(this).get(key);
      return data ? data[this._i] : undefined;
    }
  },
  // 23.3.3.5 WeakMap.prototype.set(key, value)
  set: function set(key, value){
    return weak.def(this, key, value);
  }
};

// 23.3 WeakMap Objects
var $WeakMap = module.exports = __webpack_require__(/*! ./_collection */ "./node_modules/core-js/modules/_collection.js")('WeakMap', wrapper, methods, weak, true, true);

// IE11 WeakMap frozen keys fix
if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){
  InternalMap = weak.getConstructor(wrapper);
  assign(InternalMap.prototype, methods);
  meta.NEED = true;
  each(['delete', 'has', 'get', 'set'], function(key){
    var proto  = $WeakMap.prototype
      , method = proto[key];
    redefine(proto, key, function(a, b){
      // store frozen objects on internal weakmap shim
      if(isObject(a) && !isExtensible(a)){
        if(!this._f)this._f = new InternalMap;
        var result = this._f[key](a, b);
        return key == 'set' ? this : result;
      // store all the rest on native weakmap
      } return method.call(this, a, b);
    });
  });
}

/***/ }),

/***/ "./node_modules/core-js/modules/es6.weak-set.js":
/*!******************************************************!*\
  !*** ./node_modules/core-js/modules/es6.weak-set.js ***!
  \******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var weak = __webpack_require__(/*! ./_collection-weak */ "./node_modules/core-js/modules/_collection-weak.js");

// 23.4 WeakSet Objects
__webpack_require__(/*! ./_collection */ "./node_modules/core-js/modules/_collection.js")('WeakSet', function(get){
  return function WeakSet(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.4.3.1 WeakSet.prototype.add(value)
  add: function add(value){
    return weak.def(this, value, true);
  }
}, weak, false, true);

/***/ }),

/***/ "./node_modules/core-js/modules/es7.array.includes.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.array.includes.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://github.com/tc39/Array.prototype.includes
var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $includes = __webpack_require__(/*! ./_array-includes */ "./node_modules/core-js/modules/_array-includes.js")(true);

$export($export.P, 'Array', {
  includes: function includes(el /*, fromIndex = 0 */){
    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
  }
});

__webpack_require__(/*! ./_add-to-unscopables */ "./node_modules/core-js/modules/_add-to-unscopables.js")('includes');

/***/ }),

/***/ "./node_modules/core-js/modules/es7.asap.js":
/*!**************************************************!*\
  !*** ./node_modules/core-js/modules/es7.asap.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask
var $export   = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , microtask = __webpack_require__(/*! ./_microtask */ "./node_modules/core-js/modules/_microtask.js")()
  , process   = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js").process
  , isNode    = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js")(process) == 'process';

$export($export.G, {
  asap: function asap(fn){
    var domain = isNode && process.domain;
    microtask(domain ? domain.bind(fn) : fn);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.error.is-error.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.error.is-error.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/ljharb/proposal-is-error
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , cof     = __webpack_require__(/*! ./_cof */ "./node_modules/core-js/modules/_cof.js");

$export($export.S, 'Error', {
  isError: function isError(it){
    return cof(it) === 'Error';
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.map.to-json.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.map.to-json.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.P + $export.R, 'Map', {toJSON: __webpack_require__(/*! ./_collection-to-json */ "./node_modules/core-js/modules/_collection-to-json.js")('Map')});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.math.iaddh.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.math.iaddh.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  iaddh: function iaddh(x0, x1, y0, y1){
    var $x0 = x0 >>> 0
      , $x1 = x1 >>> 0
      , $y0 = y0 >>> 0;
    return $x1 + (y1 >>> 0) + (($x0 & $y0 | ($x0 | $y0) & ~($x0 + $y0 >>> 0)) >>> 31) | 0;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.math.imulh.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.math.imulh.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  imulh: function imulh(u, v){
    var UINT16 = 0xffff
      , $u = +u
      , $v = +v
      , u0 = $u & UINT16
      , v0 = $v & UINT16
      , u1 = $u >> 16
      , v1 = $v >> 16
      , t  = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);
    return u1 * v1 + (t >> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >> 16);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.math.isubh.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.math.isubh.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  isubh: function isubh(x0, x1, y0, y1){
    var $x0 = x0 >>> 0
      , $x1 = x1 >>> 0
      , $y0 = y0 >>> 0;
    return $x1 - (y1 >>> 0) - ((~$x0 & $y0 | ~($x0 ^ $y0) & $x0 - $y0 >>> 0) >>> 31) | 0;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.math.umulh.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.math.umulh.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'Math', {
  umulh: function umulh(u, v){
    var UINT16 = 0xffff
      , $u = +u
      , $v = +v
      , u0 = $u & UINT16
      , v0 = $v & UINT16
      , u1 = $u >>> 16
      , v1 = $v >>> 16
      , t  = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);
    return u1 * v1 + (t >>> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >>> 16);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.object.define-getter.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.object.define-getter.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export         = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toObject        = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , aFunction       = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , $defineProperty = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js");

// B.2.2.2 Object.prototype.__defineGetter__(P, getter)
__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ "./node_modules/core-js/modules/_object-forced-pam.js"), 'Object', {
  __defineGetter__: function __defineGetter__(P, getter){
    $defineProperty.f(toObject(this), P, {get: aFunction(getter), enumerable: true, configurable: true});
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.object.define-setter.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.object.define-setter.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export         = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toObject        = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , aFunction       = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , $defineProperty = __webpack_require__(/*! ./_object-dp */ "./node_modules/core-js/modules/_object-dp.js");

// B.2.2.3 Object.prototype.__defineSetter__(P, setter)
__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ "./node_modules/core-js/modules/_object-forced-pam.js"), 'Object', {
  __defineSetter__: function __defineSetter__(P, setter){
    $defineProperty.f(toObject(this), P, {set: aFunction(setter), enumerable: true, configurable: true});
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.object.entries.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.object.entries.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/tc39/proposal-object-values-entries
var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $entries = __webpack_require__(/*! ./_object-to-array */ "./node_modules/core-js/modules/_object-to-array.js")(true);

$export($export.S, 'Object', {
  entries: function entries(it){
    return $entries(it);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js":
/*!*********************************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js ***!
  \*********************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/tc39/proposal-object-getownpropertydescriptors
var $export        = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , ownKeys        = __webpack_require__(/*! ./_own-keys */ "./node_modules/core-js/modules/_own-keys.js")
  , toIObject      = __webpack_require__(/*! ./_to-iobject */ "./node_modules/core-js/modules/_to-iobject.js")
  , gOPD           = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js")
  , createProperty = __webpack_require__(/*! ./_create-property */ "./node_modules/core-js/modules/_create-property.js");

$export($export.S, 'Object', {
  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object){
    var O       = toIObject(object)
      , getDesc = gOPD.f
      , keys    = ownKeys(O)
      , result  = {}
      , i       = 0
      , key;
    while(keys.length > i)createProperty(result, key = keys[i++], getDesc(O, key));
    return result;
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.object.lookup-getter.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.object.lookup-getter.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export                  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toObject                 = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , toPrimitive              = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
  , getPrototypeOf           = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js").f;

// B.2.2.4 Object.prototype.__lookupGetter__(P)
__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ "./node_modules/core-js/modules/_object-forced-pam.js"), 'Object', {
  __lookupGetter__: function __lookupGetter__(P){
    var O = toObject(this)
      , K = toPrimitive(P, true)
      , D;
    do {
      if(D = getOwnPropertyDescriptor(O, K))return D.get;
    } while(O = getPrototypeOf(O));
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.object.lookup-setter.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.object.lookup-setter.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

var $export                  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , toObject                 = __webpack_require__(/*! ./_to-object */ "./node_modules/core-js/modules/_to-object.js")
  , toPrimitive              = __webpack_require__(/*! ./_to-primitive */ "./node_modules/core-js/modules/_to-primitive.js")
  , getPrototypeOf           = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ "./node_modules/core-js/modules/_object-gopd.js").f;

// B.2.2.5 Object.prototype.__lookupSetter__(P)
__webpack_require__(/*! ./_descriptors */ "./node_modules/core-js/modules/_descriptors.js") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ "./node_modules/core-js/modules/_object-forced-pam.js"), 'Object', {
  __lookupSetter__: function __lookupSetter__(P){
    var O = toObject(this)
      , K = toPrimitive(P, true)
      , D;
    do {
      if(D = getOwnPropertyDescriptor(O, K))return D.set;
    } while(O = getPrototypeOf(O));
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.object.values.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.object.values.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/tc39/proposal-object-values-entries
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $values = __webpack_require__(/*! ./_object-to-array */ "./node_modules/core-js/modules/_object-to-array.js")(false);

$export($export.S, 'Object', {
  values: function values(it){
    return $values(it);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.observable.js":
/*!********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.observable.js ***!
  \********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://github.com/zenparsing/es-observable
var $export     = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , global      = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , core        = __webpack_require__(/*! ./_core */ "./node_modules/core-js/modules/_core.js")
  , microtask   = __webpack_require__(/*! ./_microtask */ "./node_modules/core-js/modules/_microtask.js")()
  , OBSERVABLE  = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")('observable')
  , aFunction   = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , anObject    = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , anInstance  = __webpack_require__(/*! ./_an-instance */ "./node_modules/core-js/modules/_an-instance.js")
  , redefineAll = __webpack_require__(/*! ./_redefine-all */ "./node_modules/core-js/modules/_redefine-all.js")
  , hide        = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , forOf       = __webpack_require__(/*! ./_for-of */ "./node_modules/core-js/modules/_for-of.js")
  , RETURN      = forOf.RETURN;

var getMethod = function(fn){
  return fn == null ? undefined : aFunction(fn);
};

var cleanupSubscription = function(subscription){
  var cleanup = subscription._c;
  if(cleanup){
    subscription._c = undefined;
    cleanup();
  }
};

var subscriptionClosed = function(subscription){
  return subscription._o === undefined;
};

var closeSubscription = function(subscription){
  if(!subscriptionClosed(subscription)){
    subscription._o = undefined;
    cleanupSubscription(subscription);
  }
};

var Subscription = function(observer, subscriber){
  anObject(observer);
  this._c = undefined;
  this._o = observer;
  observer = new SubscriptionObserver(this);
  try {
    var cleanup      = subscriber(observer)
      , subscription = cleanup;
    if(cleanup != null){
      if(typeof cleanup.unsubscribe === 'function')cleanup = function(){ subscription.unsubscribe(); };
      else aFunction(cleanup);
      this._c = cleanup;
    }
  } catch(e){
    observer.error(e);
    return;
  } if(subscriptionClosed(this))cleanupSubscription(this);
};

Subscription.prototype = redefineAll({}, {
  unsubscribe: function unsubscribe(){ closeSubscription(this); }
});

var SubscriptionObserver = function(subscription){
  this._s = subscription;
};

SubscriptionObserver.prototype = redefineAll({}, {
  next: function next(value){
    var subscription = this._s;
    if(!subscriptionClosed(subscription)){
      var observer = subscription._o;
      try {
        var m = getMethod(observer.next);
        if(m)return m.call(observer, value);
      } catch(e){
        try {
          closeSubscription(subscription);
        } finally {
          throw e;
        }
      }
    }
  },
  error: function error(value){
    var subscription = this._s;
    if(subscriptionClosed(subscription))throw value;
    var observer = subscription._o;
    subscription._o = undefined;
    try {
      var m = getMethod(observer.error);
      if(!m)throw value;
      value = m.call(observer, value);
    } catch(e){
      try {
        cleanupSubscription(subscription);
      } finally {
        throw e;
      }
    } cleanupSubscription(subscription);
    return value;
  },
  complete: function complete(value){
    var subscription = this._s;
    if(!subscriptionClosed(subscription)){
      var observer = subscription._o;
      subscription._o = undefined;
      try {
        var m = getMethod(observer.complete);
        value = m ? m.call(observer, value) : undefined;
      } catch(e){
        try {
          cleanupSubscription(subscription);
        } finally {
          throw e;
        }
      } cleanupSubscription(subscription);
      return value;
    }
  }
});

var $Observable = function Observable(subscriber){
  anInstance(this, $Observable, 'Observable', '_f')._f = aFunction(subscriber);
};

redefineAll($Observable.prototype, {
  subscribe: function subscribe(observer){
    return new Subscription(observer, this._f);
  },
  forEach: function forEach(fn){
    var that = this;
    return new (core.Promise || global.Promise)(function(resolve, reject){
      aFunction(fn);
      var subscription = that.subscribe({
        next : function(value){
          try {
            return fn(value);
          } catch(e){
            reject(e);
            subscription.unsubscribe();
          }
        },
        error: reject,
        complete: resolve
      });
    });
  }
});

redefineAll($Observable, {
  from: function from(x){
    var C = typeof this === 'function' ? this : $Observable;
    var method = getMethod(anObject(x)[OBSERVABLE]);
    if(method){
      var observable = anObject(method.call(x));
      return observable.constructor === C ? observable : new C(function(observer){
        return observable.subscribe(observer);
      });
    }
    return new C(function(observer){
      var done = false;
      microtask(function(){
        if(!done){
          try {
            if(forOf(x, false, function(it){
              observer.next(it);
              if(done)return RETURN;
            }) === RETURN)return;
          } catch(e){
            if(done)throw e;
            observer.error(e);
            return;
          } observer.complete();
        }
      });
      return function(){ done = true; };
    });
  },
  of: function of(){
    for(var i = 0, l = arguments.length, items = Array(l); i < l;)items[i] = arguments[i++];
    return new (typeof this === 'function' ? this : $Observable)(function(observer){
      var done = false;
      microtask(function(){
        if(!done){
          for(var i = 0; i < items.length; ++i){
            observer.next(items[i]);
            if(done)return;
          } observer.complete();
        }
      });
      return function(){ done = true; };
    });
  }
});

hide($Observable.prototype, OBSERVABLE, function(){ return this; });

$export($export.G, {Observable: $Observable});

__webpack_require__(/*! ./_set-species */ "./node_modules/core-js/modules/_set-species.js")('Observable');

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.define-metadata.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.define-metadata.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata                  = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject                  = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , toMetaKey                 = metadata.key
  , ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey){
  ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey));
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.delete-metadata.js":
/*!*********************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.delete-metadata.js ***!
  \*********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata               = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject               = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , toMetaKey              = metadata.key
  , getOrCreateMetadataMap = metadata.map
  , store                  = metadata.store;

metadata.exp({deleteMetadata: function deleteMetadata(metadataKey, target /*, targetKey */){
  var targetKey   = arguments.length < 3 ? undefined : toMetaKey(arguments[2])
    , metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false);
  if(metadataMap === undefined || !metadataMap['delete'](metadataKey))return false;
  if(metadataMap.size)return true;
  var targetMetadata = store.get(target);
  targetMetadata['delete'](targetKey);
  return !!targetMetadata.size || store['delete'](target);
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js":
/*!***********************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js ***!
  \***********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var Set                     = __webpack_require__(/*! ./es6.set */ "./node_modules/core-js/modules/es6.set.js")
  , from                    = __webpack_require__(/*! ./_array-from-iterable */ "./node_modules/core-js/modules/_array-from-iterable.js")
  , metadata                = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject                = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , getPrototypeOf          = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , ordinaryOwnMetadataKeys = metadata.keys
  , toMetaKey               = metadata.key;

var ordinaryMetadataKeys = function(O, P){
  var oKeys  = ordinaryOwnMetadataKeys(O, P)
    , parent = getPrototypeOf(O);
  if(parent === null)return oKeys;
  var pKeys  = ordinaryMetadataKeys(parent, P);
  return pKeys.length ? oKeys.length ? from(new Set(oKeys.concat(pKeys))) : pKeys : oKeys;
};

metadata.exp({getMetadataKeys: function getMetadataKeys(target /*, targetKey */){
  return ordinaryMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.get-metadata.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.get-metadata.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata               = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject               = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , getPrototypeOf         = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , ordinaryHasOwnMetadata = metadata.has
  , ordinaryGetOwnMetadata = metadata.get
  , toMetaKey              = metadata.key;

var ordinaryGetMetadata = function(MetadataKey, O, P){
  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
  if(hasOwn)return ordinaryGetOwnMetadata(MetadataKey, O, P);
  var parent = getPrototypeOf(O);
  return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined;
};

metadata.exp({getMetadata: function getMetadata(metadataKey, target /*, targetKey */){
  return ordinaryGetMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js":
/*!***************************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js ***!
  \***************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata                = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject                = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , ordinaryOwnMetadataKeys = metadata.keys
  , toMetaKey               = metadata.key;

metadata.exp({getOwnMetadataKeys: function getOwnMetadataKeys(target /*, targetKey */){
  return ordinaryOwnMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.get-own-metadata.js":
/*!**********************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.get-own-metadata.js ***!
  \**********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata               = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject               = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , ordinaryGetOwnMetadata = metadata.get
  , toMetaKey              = metadata.key;

metadata.exp({getOwnMetadata: function getOwnMetadata(metadataKey, target /*, targetKey */){
  return ordinaryGetOwnMetadata(metadataKey, anObject(target)
    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.has-metadata.js":
/*!******************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.has-metadata.js ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata               = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject               = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , getPrototypeOf         = __webpack_require__(/*! ./_object-gpo */ "./node_modules/core-js/modules/_object-gpo.js")
  , ordinaryHasOwnMetadata = metadata.has
  , toMetaKey              = metadata.key;

var ordinaryHasMetadata = function(MetadataKey, O, P){
  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
  if(hasOwn)return true;
  var parent = getPrototypeOf(O);
  return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false;
};

metadata.exp({hasMetadata: function hasMetadata(metadataKey, target /*, targetKey */){
  return ordinaryHasMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.has-own-metadata.js":
/*!**********************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.has-own-metadata.js ***!
  \**********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata               = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject               = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , ordinaryHasOwnMetadata = metadata.has
  , toMetaKey              = metadata.key;

metadata.exp({hasOwnMetadata: function hasOwnMetadata(metadataKey, target /*, targetKey */){
  return ordinaryHasOwnMetadata(metadataKey, anObject(target)
    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.reflect.metadata.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.reflect.metadata.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var metadata                  = __webpack_require__(/*! ./_metadata */ "./node_modules/core-js/modules/_metadata.js")
  , anObject                  = __webpack_require__(/*! ./_an-object */ "./node_modules/core-js/modules/_an-object.js")
  , aFunction                 = __webpack_require__(/*! ./_a-function */ "./node_modules/core-js/modules/_a-function.js")
  , toMetaKey                 = metadata.key
  , ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({metadata: function metadata(metadataKey, metadataValue){
  return function decorator(target, targetKey){
    ordinaryDefineOwnMetadata(
      metadataKey, metadataValue,
      (targetKey !== undefined ? anObject : aFunction)(target),
      toMetaKey(targetKey)
    );
  };
}});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.set.to-json.js":
/*!*********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.set.to-json.js ***!
  \*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var $export  = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.P + $export.R, 'Set', {toJSON: __webpack_require__(/*! ./_collection-to-json */ "./node_modules/core-js/modules/_collection-to-json.js")('Set')});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.string.at.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/es7.string.at.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://github.com/mathiasbynens/String.prototype.at
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $at     = __webpack_require__(/*! ./_string-at */ "./node_modules/core-js/modules/_string-at.js")(true);

$export($export.P, 'String', {
  at: function at(pos){
    return $at(this, pos);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.string.match-all.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.string.match-all.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://tc39.github.io/String.prototype.matchAll/
var $export     = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , defined     = __webpack_require__(/*! ./_defined */ "./node_modules/core-js/modules/_defined.js")
  , toLength    = __webpack_require__(/*! ./_to-length */ "./node_modules/core-js/modules/_to-length.js")
  , isRegExp    = __webpack_require__(/*! ./_is-regexp */ "./node_modules/core-js/modules/_is-regexp.js")
  , getFlags    = __webpack_require__(/*! ./_flags */ "./node_modules/core-js/modules/_flags.js")
  , RegExpProto = RegExp.prototype;

var $RegExpStringIterator = function(regexp, string){
  this._r = regexp;
  this._s = string;
};

__webpack_require__(/*! ./_iter-create */ "./node_modules/core-js/modules/_iter-create.js")($RegExpStringIterator, 'RegExp String', function next(){
  var match = this._r.exec(this._s);
  return {value: match, done: match === null};
});

$export($export.P, 'String', {
  matchAll: function matchAll(regexp){
    defined(this);
    if(!isRegExp(regexp))throw TypeError(regexp + ' is not a regexp!');
    var S     = String(this)
      , flags = 'flags' in RegExpProto ? String(regexp.flags) : getFlags.call(regexp)
      , rx    = new RegExp(regexp.source, ~flags.indexOf('g') ? flags : 'g' + flags);
    rx.lastIndex = toLength(regexp.lastIndex);
    return new $RegExpStringIterator(rx, S);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.string.pad-end.js":
/*!************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.string.pad-end.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://github.com/tc39/proposal-string-pad-start-end
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $pad    = __webpack_require__(/*! ./_string-pad */ "./node_modules/core-js/modules/_string-pad.js");

$export($export.P, 'String', {
  padEnd: function padEnd(maxLength /*, fillString = ' ' */){
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.string.pad-start.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.string.pad-start.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://github.com/tc39/proposal-string-pad-start-end
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $pad    = __webpack_require__(/*! ./_string-pad */ "./node_modules/core-js/modules/_string-pad.js");

$export($export.P, 'String', {
  padStart: function padStart(maxLength /*, fillString = ' ' */){
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
  }
});

/***/ }),

/***/ "./node_modules/core-js/modules/es7.string.trim-left.js":
/*!**************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.string.trim-left.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
__webpack_require__(/*! ./_string-trim */ "./node_modules/core-js/modules/_string-trim.js")('trimLeft', function($trim){
  return function trimLeft(){
    return $trim(this, 1);
  };
}, 'trimStart');

/***/ }),

/***/ "./node_modules/core-js/modules/es7.string.trim-right.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.string.trim-right.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
__webpack_require__(/*! ./_string-trim */ "./node_modules/core-js/modules/_string-trim.js")('trimRight', function($trim){
  return function trimRight(){
    return $trim(this, 2);
  };
}, 'trimEnd');

/***/ }),

/***/ "./node_modules/core-js/modules/es7.symbol.async-iterator.js":
/*!*******************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.symbol.async-iterator.js ***!
  \*******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_wks-define */ "./node_modules/core-js/modules/_wks-define.js")('asyncIterator');

/***/ }),

/***/ "./node_modules/core-js/modules/es7.symbol.observable.js":
/*!***************************************************************!*\
  !*** ./node_modules/core-js/modules/es7.symbol.observable.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./_wks-define */ "./node_modules/core-js/modules/_wks-define.js")('observable');

/***/ }),

/***/ "./node_modules/core-js/modules/es7.system.global.js":
/*!***********************************************************!*\
  !*** ./node_modules/core-js/modules/es7.system.global.js ***!
  \***********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// https://github.com/ljharb/proposal-global
var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js");

$export($export.S, 'System', {global: __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")});

/***/ }),

/***/ "./node_modules/core-js/modules/web.dom.iterable.js":
/*!**********************************************************!*\
  !*** ./node_modules/core-js/modules/web.dom.iterable.js ***!
  \**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $iterators    = __webpack_require__(/*! ./es6.array.iterator */ "./node_modules/core-js/modules/es6.array.iterator.js")
  , redefine      = __webpack_require__(/*! ./_redefine */ "./node_modules/core-js/modules/_redefine.js")
  , global        = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , hide          = __webpack_require__(/*! ./_hide */ "./node_modules/core-js/modules/_hide.js")
  , Iterators     = __webpack_require__(/*! ./_iterators */ "./node_modules/core-js/modules/_iterators.js")
  , wks           = __webpack_require__(/*! ./_wks */ "./node_modules/core-js/modules/_wks.js")
  , ITERATOR      = wks('iterator')
  , TO_STRING_TAG = wks('toStringTag')
  , ArrayValues   = Iterators.Array;

for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){
  var NAME       = collections[i]
    , Collection = global[NAME]
    , proto      = Collection && Collection.prototype
    , key;
  if(proto){
    if(!proto[ITERATOR])hide(proto, ITERATOR, ArrayValues);
    if(!proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME);
    Iterators[NAME] = ArrayValues;
    for(key in $iterators)if(!proto[key])redefine(proto, key, $iterators[key], true);
  }
}

/***/ }),

/***/ "./node_modules/core-js/modules/web.immediate.js":
/*!*******************************************************!*\
  !*** ./node_modules/core-js/modules/web.immediate.js ***!
  \*******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var $export = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , $task   = __webpack_require__(/*! ./_task */ "./node_modules/core-js/modules/_task.js");
$export($export.G + $export.B, {
  setImmediate:   $task.set,
  clearImmediate: $task.clear
});

/***/ }),

/***/ "./node_modules/core-js/modules/web.timers.js":
/*!****************************************************!*\
  !*** ./node_modules/core-js/modules/web.timers.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// ie9- setTimeout & setInterval additional parameters fix
var global     = __webpack_require__(/*! ./_global */ "./node_modules/core-js/modules/_global.js")
  , $export    = __webpack_require__(/*! ./_export */ "./node_modules/core-js/modules/_export.js")
  , invoke     = __webpack_require__(/*! ./_invoke */ "./node_modules/core-js/modules/_invoke.js")
  , partial    = __webpack_require__(/*! ./_partial */ "./node_modules/core-js/modules/_partial.js")
  , navigator  = global.navigator
  , MSIE       = !!navigator && /MSIE .\./.test(navigator.userAgent); // <- dirty ie9- check
var wrap = function(set){
  return MSIE ? function(fn, time /*, ...args */){
    return set(invoke(
      partial,
      [].slice.call(arguments, 2),
      typeof fn == 'function' ? fn : Function(fn)
    ), time);
  } : set;
};
$export($export.G + $export.B + $export.F * MSIE, {
  setTimeout:  wrap(global.setTimeout),
  setInterval: wrap(global.setInterval)
});

/***/ }),

/***/ "./node_modules/core-js/shim.js":
/*!**************************************!*\
  !*** ./node_modules/core-js/shim.js ***!
  \**************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./modules/es6.symbol */ "./node_modules/core-js/modules/es6.symbol.js");
__webpack_require__(/*! ./modules/es6.object.create */ "./node_modules/core-js/modules/es6.object.create.js");
__webpack_require__(/*! ./modules/es6.object.define-property */ "./node_modules/core-js/modules/es6.object.define-property.js");
__webpack_require__(/*! ./modules/es6.object.define-properties */ "./node_modules/core-js/modules/es6.object.define-properties.js");
__webpack_require__(/*! ./modules/es6.object.get-own-property-descriptor */ "./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js");
__webpack_require__(/*! ./modules/es6.object.get-prototype-of */ "./node_modules/core-js/modules/es6.object.get-prototype-of.js");
__webpack_require__(/*! ./modules/es6.object.keys */ "./node_modules/core-js/modules/es6.object.keys.js");
__webpack_require__(/*! ./modules/es6.object.get-own-property-names */ "./node_modules/core-js/modules/es6.object.get-own-property-names.js");
__webpack_require__(/*! ./modules/es6.object.freeze */ "./node_modules/core-js/modules/es6.object.freeze.js");
__webpack_require__(/*! ./modules/es6.object.seal */ "./node_modules/core-js/modules/es6.object.seal.js");
__webpack_require__(/*! ./modules/es6.object.prevent-extensions */ "./node_modules/core-js/modules/es6.object.prevent-extensions.js");
__webpack_require__(/*! ./modules/es6.object.is-frozen */ "./node_modules/core-js/modules/es6.object.is-frozen.js");
__webpack_require__(/*! ./modules/es6.object.is-sealed */ "./node_modules/core-js/modules/es6.object.is-sealed.js");
__webpack_require__(/*! ./modules/es6.object.is-extensible */ "./node_modules/core-js/modules/es6.object.is-extensible.js");
__webpack_require__(/*! ./modules/es6.object.assign */ "./node_modules/core-js/modules/es6.object.assign.js");
__webpack_require__(/*! ./modules/es6.object.is */ "./node_modules/core-js/modules/es6.object.is.js");
__webpack_require__(/*! ./modules/es6.object.set-prototype-of */ "./node_modules/core-js/modules/es6.object.set-prototype-of.js");
__webpack_require__(/*! ./modules/es6.object.to-string */ "./node_modules/core-js/modules/es6.object.to-string.js");
__webpack_require__(/*! ./modules/es6.function.bind */ "./node_modules/core-js/modules/es6.function.bind.js");
__webpack_require__(/*! ./modules/es6.function.name */ "./node_modules/core-js/modules/es6.function.name.js");
__webpack_require__(/*! ./modules/es6.function.has-instance */ "./node_modules/core-js/modules/es6.function.has-instance.js");
__webpack_require__(/*! ./modules/es6.parse-int */ "./node_modules/core-js/modules/es6.parse-int.js");
__webpack_require__(/*! ./modules/es6.parse-float */ "./node_modules/core-js/modules/es6.parse-float.js");
__webpack_require__(/*! ./modules/es6.number.constructor */ "./node_modules/core-js/modules/es6.number.constructor.js");
__webpack_require__(/*! ./modules/es6.number.to-fixed */ "./node_modules/core-js/modules/es6.number.to-fixed.js");
__webpack_require__(/*! ./modules/es6.number.to-precision */ "./node_modules/core-js/modules/es6.number.to-precision.js");
__webpack_require__(/*! ./modules/es6.number.epsilon */ "./node_modules/core-js/modules/es6.number.epsilon.js");
__webpack_require__(/*! ./modules/es6.number.is-finite */ "./node_modules/core-js/modules/es6.number.is-finite.js");
__webpack_require__(/*! ./modules/es6.number.is-integer */ "./node_modules/core-js/modules/es6.number.is-integer.js");
__webpack_require__(/*! ./modules/es6.number.is-nan */ "./node_modules/core-js/modules/es6.number.is-nan.js");
__webpack_require__(/*! ./modules/es6.number.is-safe-integer */ "./node_modules/core-js/modules/es6.number.is-safe-integer.js");
__webpack_require__(/*! ./modules/es6.number.max-safe-integer */ "./node_modules/core-js/modules/es6.number.max-safe-integer.js");
__webpack_require__(/*! ./modules/es6.number.min-safe-integer */ "./node_modules/core-js/modules/es6.number.min-safe-integer.js");
__webpack_require__(/*! ./modules/es6.number.parse-float */ "./node_modules/core-js/modules/es6.number.parse-float.js");
__webpack_require__(/*! ./modules/es6.number.parse-int */ "./node_modules/core-js/modules/es6.number.parse-int.js");
__webpack_require__(/*! ./modules/es6.math.acosh */ "./node_modules/core-js/modules/es6.math.acosh.js");
__webpack_require__(/*! ./modules/es6.math.asinh */ "./node_modules/core-js/modules/es6.math.asinh.js");
__webpack_require__(/*! ./modules/es6.math.atanh */ "./node_modules/core-js/modules/es6.math.atanh.js");
__webpack_require__(/*! ./modules/es6.math.cbrt */ "./node_modules/core-js/modules/es6.math.cbrt.js");
__webpack_require__(/*! ./modules/es6.math.clz32 */ "./node_modules/core-js/modules/es6.math.clz32.js");
__webpack_require__(/*! ./modules/es6.math.cosh */ "./node_modules/core-js/modules/es6.math.cosh.js");
__webpack_require__(/*! ./modules/es6.math.expm1 */ "./node_modules/core-js/modules/es6.math.expm1.js");
__webpack_require__(/*! ./modules/es6.math.fround */ "./node_modules/core-js/modules/es6.math.fround.js");
__webpack_require__(/*! ./modules/es6.math.hypot */ "./node_modules/core-js/modules/es6.math.hypot.js");
__webpack_require__(/*! ./modules/es6.math.imul */ "./node_modules/core-js/modules/es6.math.imul.js");
__webpack_require__(/*! ./modules/es6.math.log10 */ "./node_modules/core-js/modules/es6.math.log10.js");
__webpack_require__(/*! ./modules/es6.math.log1p */ "./node_modules/core-js/modules/es6.math.log1p.js");
__webpack_require__(/*! ./modules/es6.math.log2 */ "./node_modules/core-js/modules/es6.math.log2.js");
__webpack_require__(/*! ./modules/es6.math.sign */ "./node_modules/core-js/modules/es6.math.sign.js");
__webpack_require__(/*! ./modules/es6.math.sinh */ "./node_modules/core-js/modules/es6.math.sinh.js");
__webpack_require__(/*! ./modules/es6.math.tanh */ "./node_modules/core-js/modules/es6.math.tanh.js");
__webpack_require__(/*! ./modules/es6.math.trunc */ "./node_modules/core-js/modules/es6.math.trunc.js");
__webpack_require__(/*! ./modules/es6.string.from-code-point */ "./node_modules/core-js/modules/es6.string.from-code-point.js");
__webpack_require__(/*! ./modules/es6.string.raw */ "./node_modules/core-js/modules/es6.string.raw.js");
__webpack_require__(/*! ./modules/es6.string.trim */ "./node_modules/core-js/modules/es6.string.trim.js");
__webpack_require__(/*! ./modules/es6.string.iterator */ "./node_modules/core-js/modules/es6.string.iterator.js");
__webpack_require__(/*! ./modules/es6.string.code-point-at */ "./node_modules/core-js/modules/es6.string.code-point-at.js");
__webpack_require__(/*! ./modules/es6.string.ends-with */ "./node_modules/core-js/modules/es6.string.ends-with.js");
__webpack_require__(/*! ./modules/es6.string.includes */ "./node_modules/core-js/modules/es6.string.includes.js");
__webpack_require__(/*! ./modules/es6.string.repeat */ "./node_modules/core-js/modules/es6.string.repeat.js");
__webpack_require__(/*! ./modules/es6.string.starts-with */ "./node_modules/core-js/modules/es6.string.starts-with.js");
__webpack_require__(/*! ./modules/es6.string.anchor */ "./node_modules/core-js/modules/es6.string.anchor.js");
__webpack_require__(/*! ./modules/es6.string.big */ "./node_modules/core-js/modules/es6.string.big.js");
__webpack_require__(/*! ./modules/es6.string.blink */ "./node_modules/core-js/modules/es6.string.blink.js");
__webpack_require__(/*! ./modules/es6.string.bold */ "./node_modules/core-js/modules/es6.string.bold.js");
__webpack_require__(/*! ./modules/es6.string.fixed */ "./node_modules/core-js/modules/es6.string.fixed.js");
__webpack_require__(/*! ./modules/es6.string.fontcolor */ "./node_modules/core-js/modules/es6.string.fontcolor.js");
__webpack_require__(/*! ./modules/es6.string.fontsize */ "./node_modules/core-js/modules/es6.string.fontsize.js");
__webpack_require__(/*! ./modules/es6.string.italics */ "./node_modules/core-js/modules/es6.string.italics.js");
__webpack_require__(/*! ./modules/es6.string.link */ "./node_modules/core-js/modules/es6.string.link.js");
__webpack_require__(/*! ./modules/es6.string.small */ "./node_modules/core-js/modules/es6.string.small.js");
__webpack_require__(/*! ./modules/es6.string.strike */ "./node_modules/core-js/modules/es6.string.strike.js");
__webpack_require__(/*! ./modules/es6.string.sub */ "./node_modules/core-js/modules/es6.string.sub.js");
__webpack_require__(/*! ./modules/es6.string.sup */ "./node_modules/core-js/modules/es6.string.sup.js");
__webpack_require__(/*! ./modules/es6.date.now */ "./node_modules/core-js/modules/es6.date.now.js");
__webpack_require__(/*! ./modules/es6.date.to-json */ "./node_modules/core-js/modules/es6.date.to-json.js");
__webpack_require__(/*! ./modules/es6.date.to-iso-string */ "./node_modules/core-js/modules/es6.date.to-iso-string.js");
__webpack_require__(/*! ./modules/es6.date.to-string */ "./node_modules/core-js/modules/es6.date.to-string.js");
__webpack_require__(/*! ./modules/es6.date.to-primitive */ "./node_modules/core-js/modules/es6.date.to-primitive.js");
__webpack_require__(/*! ./modules/es6.array.is-array */ "./node_modules/core-js/modules/es6.array.is-array.js");
__webpack_require__(/*! ./modules/es6.array.from */ "./node_modules/core-js/modules/es6.array.from.js");
__webpack_require__(/*! ./modules/es6.array.of */ "./node_modules/core-js/modules/es6.array.of.js");
__webpack_require__(/*! ./modules/es6.array.join */ "./node_modules/core-js/modules/es6.array.join.js");
__webpack_require__(/*! ./modules/es6.array.slice */ "./node_modules/core-js/modules/es6.array.slice.js");
__webpack_require__(/*! ./modules/es6.array.sort */ "./node_modules/core-js/modules/es6.array.sort.js");
__webpack_require__(/*! ./modules/es6.array.for-each */ "./node_modules/core-js/modules/es6.array.for-each.js");
__webpack_require__(/*! ./modules/es6.array.map */ "./node_modules/core-js/modules/es6.array.map.js");
__webpack_require__(/*! ./modules/es6.array.filter */ "./node_modules/core-js/modules/es6.array.filter.js");
__webpack_require__(/*! ./modules/es6.array.some */ "./node_modules/core-js/modules/es6.array.some.js");
__webpack_require__(/*! ./modules/es6.array.every */ "./node_modules/core-js/modules/es6.array.every.js");
__webpack_require__(/*! ./modules/es6.array.reduce */ "./node_modules/core-js/modules/es6.array.reduce.js");
__webpack_require__(/*! ./modules/es6.array.reduce-right */ "./node_modules/core-js/modules/es6.array.reduce-right.js");
__webpack_require__(/*! ./modules/es6.array.index-of */ "./node_modules/core-js/modules/es6.array.index-of.js");
__webpack_require__(/*! ./modules/es6.array.last-index-of */ "./node_modules/core-js/modules/es6.array.last-index-of.js");
__webpack_require__(/*! ./modules/es6.array.copy-within */ "./node_modules/core-js/modules/es6.array.copy-within.js");
__webpack_require__(/*! ./modules/es6.array.fill */ "./node_modules/core-js/modules/es6.array.fill.js");
__webpack_require__(/*! ./modules/es6.array.find */ "./node_modules/core-js/modules/es6.array.find.js");
__webpack_require__(/*! ./modules/es6.array.find-index */ "./node_modules/core-js/modules/es6.array.find-index.js");
__webpack_require__(/*! ./modules/es6.array.species */ "./node_modules/core-js/modules/es6.array.species.js");
__webpack_require__(/*! ./modules/es6.array.iterator */ "./node_modules/core-js/modules/es6.array.iterator.js");
__webpack_require__(/*! ./modules/es6.regexp.constructor */ "./node_modules/core-js/modules/es6.regexp.constructor.js");
__webpack_require__(/*! ./modules/es6.regexp.to-string */ "./node_modules/core-js/modules/es6.regexp.to-string.js");
__webpack_require__(/*! ./modules/es6.regexp.flags */ "./node_modules/core-js/modules/es6.regexp.flags.js");
__webpack_require__(/*! ./modules/es6.regexp.match */ "./node_modules/core-js/modules/es6.regexp.match.js");
__webpack_require__(/*! ./modules/es6.regexp.replace */ "./node_modules/core-js/modules/es6.regexp.replace.js");
__webpack_require__(/*! ./modules/es6.regexp.search */ "./node_modules/core-js/modules/es6.regexp.search.js");
__webpack_require__(/*! ./modules/es6.regexp.split */ "./node_modules/core-js/modules/es6.regexp.split.js");
__webpack_require__(/*! ./modules/es6.promise */ "./node_modules/core-js/modules/es6.promise.js");
__webpack_require__(/*! ./modules/es6.map */ "./node_modules/core-js/modules/es6.map.js");
__webpack_require__(/*! ./modules/es6.set */ "./node_modules/core-js/modules/es6.set.js");
__webpack_require__(/*! ./modules/es6.weak-map */ "./node_modules/core-js/modules/es6.weak-map.js");
__webpack_require__(/*! ./modules/es6.weak-set */ "./node_modules/core-js/modules/es6.weak-set.js");
__webpack_require__(/*! ./modules/es6.typed.array-buffer */ "./node_modules/core-js/modules/es6.typed.array-buffer.js");
__webpack_require__(/*! ./modules/es6.typed.data-view */ "./node_modules/core-js/modules/es6.typed.data-view.js");
__webpack_require__(/*! ./modules/es6.typed.int8-array */ "./node_modules/core-js/modules/es6.typed.int8-array.js");
__webpack_require__(/*! ./modules/es6.typed.uint8-array */ "./node_modules/core-js/modules/es6.typed.uint8-array.js");
__webpack_require__(/*! ./modules/es6.typed.uint8-clamped-array */ "./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js");
__webpack_require__(/*! ./modules/es6.typed.int16-array */ "./node_modules/core-js/modules/es6.typed.int16-array.js");
__webpack_require__(/*! ./modules/es6.typed.uint16-array */ "./node_modules/core-js/modules/es6.typed.uint16-array.js");
__webpack_require__(/*! ./modules/es6.typed.int32-array */ "./node_modules/core-js/modules/es6.typed.int32-array.js");
__webpack_require__(/*! ./modules/es6.typed.uint32-array */ "./node_modules/core-js/modules/es6.typed.uint32-array.js");
__webpack_require__(/*! ./modules/es6.typed.float32-array */ "./node_modules/core-js/modules/es6.typed.float32-array.js");
__webpack_require__(/*! ./modules/es6.typed.float64-array */ "./node_modules/core-js/modules/es6.typed.float64-array.js");
__webpack_require__(/*! ./modules/es6.reflect.apply */ "./node_modules/core-js/modules/es6.reflect.apply.js");
__webpack_require__(/*! ./modules/es6.reflect.construct */ "./node_modules/core-js/modules/es6.reflect.construct.js");
__webpack_require__(/*! ./modules/es6.reflect.define-property */ "./node_modules/core-js/modules/es6.reflect.define-property.js");
__webpack_require__(/*! ./modules/es6.reflect.delete-property */ "./node_modules/core-js/modules/es6.reflect.delete-property.js");
__webpack_require__(/*! ./modules/es6.reflect.enumerate */ "./node_modules/core-js/modules/es6.reflect.enumerate.js");
__webpack_require__(/*! ./modules/es6.reflect.get */ "./node_modules/core-js/modules/es6.reflect.get.js");
__webpack_require__(/*! ./modules/es6.reflect.get-own-property-descriptor */ "./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js");
__webpack_require__(/*! ./modules/es6.reflect.get-prototype-of */ "./node_modules/core-js/modules/es6.reflect.get-prototype-of.js");
__webpack_require__(/*! ./modules/es6.reflect.has */ "./node_modules/core-js/modules/es6.reflect.has.js");
__webpack_require__(/*! ./modules/es6.reflect.is-extensible */ "./node_modules/core-js/modules/es6.reflect.is-extensible.js");
__webpack_require__(/*! ./modules/es6.reflect.own-keys */ "./node_modules/core-js/modules/es6.reflect.own-keys.js");
__webpack_require__(/*! ./modules/es6.reflect.prevent-extensions */ "./node_modules/core-js/modules/es6.reflect.prevent-extensions.js");
__webpack_require__(/*! ./modules/es6.reflect.set */ "./node_modules/core-js/modules/es6.reflect.set.js");
__webpack_require__(/*! ./modules/es6.reflect.set-prototype-of */ "./node_modules/core-js/modules/es6.reflect.set-prototype-of.js");
__webpack_require__(/*! ./modules/es7.array.includes */ "./node_modules/core-js/modules/es7.array.includes.js");
__webpack_require__(/*! ./modules/es7.string.at */ "./node_modules/core-js/modules/es7.string.at.js");
__webpack_require__(/*! ./modules/es7.string.pad-start */ "./node_modules/core-js/modules/es7.string.pad-start.js");
__webpack_require__(/*! ./modules/es7.string.pad-end */ "./node_modules/core-js/modules/es7.string.pad-end.js");
__webpack_require__(/*! ./modules/es7.string.trim-left */ "./node_modules/core-js/modules/es7.string.trim-left.js");
__webpack_require__(/*! ./modules/es7.string.trim-right */ "./node_modules/core-js/modules/es7.string.trim-right.js");
__webpack_require__(/*! ./modules/es7.string.match-all */ "./node_modules/core-js/modules/es7.string.match-all.js");
__webpack_require__(/*! ./modules/es7.symbol.async-iterator */ "./node_modules/core-js/modules/es7.symbol.async-iterator.js");
__webpack_require__(/*! ./modules/es7.symbol.observable */ "./node_modules/core-js/modules/es7.symbol.observable.js");
__webpack_require__(/*! ./modules/es7.object.get-own-property-descriptors */ "./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js");
__webpack_require__(/*! ./modules/es7.object.values */ "./node_modules/core-js/modules/es7.object.values.js");
__webpack_require__(/*! ./modules/es7.object.entries */ "./node_modules/core-js/modules/es7.object.entries.js");
__webpack_require__(/*! ./modules/es7.object.define-getter */ "./node_modules/core-js/modules/es7.object.define-getter.js");
__webpack_require__(/*! ./modules/es7.object.define-setter */ "./node_modules/core-js/modules/es7.object.define-setter.js");
__webpack_require__(/*! ./modules/es7.object.lookup-getter */ "./node_modules/core-js/modules/es7.object.lookup-getter.js");
__webpack_require__(/*! ./modules/es7.object.lookup-setter */ "./node_modules/core-js/modules/es7.object.lookup-setter.js");
__webpack_require__(/*! ./modules/es7.map.to-json */ "./node_modules/core-js/modules/es7.map.to-json.js");
__webpack_require__(/*! ./modules/es7.set.to-json */ "./node_modules/core-js/modules/es7.set.to-json.js");
__webpack_require__(/*! ./modules/es7.system.global */ "./node_modules/core-js/modules/es7.system.global.js");
__webpack_require__(/*! ./modules/es7.error.is-error */ "./node_modules/core-js/modules/es7.error.is-error.js");
__webpack_require__(/*! ./modules/es7.math.iaddh */ "./node_modules/core-js/modules/es7.math.iaddh.js");
__webpack_require__(/*! ./modules/es7.math.isubh */ "./node_modules/core-js/modules/es7.math.isubh.js");
__webpack_require__(/*! ./modules/es7.math.imulh */ "./node_modules/core-js/modules/es7.math.imulh.js");
__webpack_require__(/*! ./modules/es7.math.umulh */ "./node_modules/core-js/modules/es7.math.umulh.js");
__webpack_require__(/*! ./modules/es7.reflect.define-metadata */ "./node_modules/core-js/modules/es7.reflect.define-metadata.js");
__webpack_require__(/*! ./modules/es7.reflect.delete-metadata */ "./node_modules/core-js/modules/es7.reflect.delete-metadata.js");
__webpack_require__(/*! ./modules/es7.reflect.get-metadata */ "./node_modules/core-js/modules/es7.reflect.get-metadata.js");
__webpack_require__(/*! ./modules/es7.reflect.get-metadata-keys */ "./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js");
__webpack_require__(/*! ./modules/es7.reflect.get-own-metadata */ "./node_modules/core-js/modules/es7.reflect.get-own-metadata.js");
__webpack_require__(/*! ./modules/es7.reflect.get-own-metadata-keys */ "./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js");
__webpack_require__(/*! ./modules/es7.reflect.has-metadata */ "./node_modules/core-js/modules/es7.reflect.has-metadata.js");
__webpack_require__(/*! ./modules/es7.reflect.has-own-metadata */ "./node_modules/core-js/modules/es7.reflect.has-own-metadata.js");
__webpack_require__(/*! ./modules/es7.reflect.metadata */ "./node_modules/core-js/modules/es7.reflect.metadata.js");
__webpack_require__(/*! ./modules/es7.asap */ "./node_modules/core-js/modules/es7.asap.js");
__webpack_require__(/*! ./modules/es7.observable */ "./node_modules/core-js/modules/es7.observable.js");
__webpack_require__(/*! ./modules/web.timers */ "./node_modules/core-js/modules/web.timers.js");
__webpack_require__(/*! ./modules/web.immediate */ "./node_modules/core-js/modules/web.immediate.js");
__webpack_require__(/*! ./modules/web.dom.iterable */ "./node_modules/core-js/modules/web.dom.iterable.js");
module.exports = __webpack_require__(/*! ./modules/_core */ "./node_modules/core-js/modules/_core.js");

/***/ }),

/***/ "./src/Common/Libraries/Websockets/CloudShareWebSockets/cloudshare-websockets.js":
/*!***************************************************************************************!*\
  !*** ./src/Common/Libraries/Websockets/CloudShareWebSockets/cloudshare-websockets.js ***!
  \***************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CloudShareWebSockets; });
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var CloudShareWebSockets =
/*#__PURE__*/
function () {
  function CloudShareWebSockets(WebSocketClient) {
    _classCallCheck(this, CloudShareWebSockets);

    this._WebSocketClient = WebSocketClient;
  }

  _createClass(CloudShareWebSockets, [{
    key: "listen",
    value: function listen(options) {
      var getOptionsOnReconnect = null;

      if (typeof options.tokenRefresher === "function") {
        getOptionsOnReconnect = this._createGetOptionsOnReconnect(options.tokenRefresher);
      }

      return new this._WebSocketClient({
        protocolAndHost: options.protocolAndHost,
        path: "/websockets/".concat(options.dispatcherName),
        query: {
          token: options.token
        },
        onopen: options.onopen,
        onclose: options.onclose,
        onerror: options.onerror,
        onmessage: this._createOnmessageListener(options.onmessage, options.ontopicListeners),
        noRetry: options.noRetry,
        retryIntervalMs: options.retryIntervalMs,
        getOptionsOnReconnect: getOptionsOnReconnect
      }).connect();
    }
  }, {
    key: "_createOnmessageListener",
    value: function _createOnmessageListener(onmessage, ontopicListeners) {
      var _this = this;

      return function (e) {
        if (onmessage) {
          onmessage(e);
        }

        if (!ontopicListeners) {
          return;
        }

        var message = _this._tryJsonParse(e.data);

        if (!message) {
          console.error("WebsocketsCsws: Invalid message: '".concat(e.data, "'"));
          return;
        }

        var listeners = Object.keys(ontopicListeners).filter(function (topic) {
          return topic === message.topic;
        }).map(function (topic) {
          return ontopicListeners[topic];
        })[0];

        if (!listeners) {
          return;
        }

        if (typeof listeners === "function") {
          listeners(message);
        } else {
          listeners.forEach(function (listener) {
            return listener(message);
          });
        }
      };
    }
  }, {
    key: "_createGetOptionsOnReconnect",
    value: function _createGetOptionsOnReconnect(tokenFunction) {
      return function () {
        return tokenFunction().then(function (token) {
          if (typeof token === "string") {
            return {
              query: {
                token: token
              }
            };
          } else {
            return token;
          }
        });
      };
    }
  }, {
    key: "_tryJsonParse",
    value: function _tryJsonParse(json) {
      try {
        return JSON.parse(json);
      } catch (_) {
        return null;
      }
    }
  }]);

  return CloudShareWebSockets;
}();



/***/ }),

/***/ "./src/Common/Libraries/Websockets/CloudShareWebSockets/index.js":
/*!***********************************************************************!*\
  !*** ./src/Common/Libraries/Websockets/CloudShareWebSockets/index.js ***!
  \***********************************************************************/
/*! exports provided: csws */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "csws", function() { return csws; });
/* harmony import */ var core_js_shim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/shim */ "./node_modules/core-js/shim.js");
/* harmony import */ var core_js_shim__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_shim__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _websocket_client__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./websocket-client */ "./src/Common/Libraries/Websockets/CloudShareWebSockets/websocket-client.js");
/* harmony import */ var _cloudshare_websockets__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./cloudshare-websockets */ "./src/Common/Libraries/Websockets/CloudShareWebSockets/cloudshare-websockets.js");



var csws = new _cloudshare_websockets__WEBPACK_IMPORTED_MODULE_2__["default"](_websocket_client__WEBPACK_IMPORTED_MODULE_1__["default"]);


/***/ }),

/***/ "./src/Common/Libraries/Websockets/CloudShareWebSockets/request.js":
/*!*************************************************************************!*\
  !*** ./src/Common/Libraries/Websockets/CloudShareWebSockets/request.js ***!
  \*************************************************************************/
/*! exports provided: default, createQueryString */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return request; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createQueryString", function() { return createQueryString; });
function request(options) {
  return new Promise(function (resolve) {
    var url = options.host ? "https://" + options.host : "";
    var path = options.path || "";

    if (path[0] !== "/") {
      url += "/" + path;
    } else {
      url += path;
    }

    var body = options.body;

    if (body && typeof body !== "string") {
      body = JSON.stringify(body);
    }

    if (options.query) {
      url += createQueryString(options.query);
    }

    var p = xhr({
      method: options.method || "GET",
      url: url,
      body: body || null
    }).then(function (xhr) {
      if (Math.floor(xhr.status / 100) > 2) {
        throw {
          error: new Error("XHR with status code: " + xhr.status),
          xhr: xhr
        };
      }

      var jsonObject = jsonParseOrNull(xhr.responseText);

      if (jsonObject) {
        return jsonObject;
      }

      return xhr.responseText;
    });
    resolve(p);
  });
}
function createQueryString(obj) {
  var queryString = "";

  if (!obj) {
    return queryString;
  }

  queryString += Object.keys(obj).map(function (paramKey) {
    return "".concat(encodeURIComponent(paramKey), "=").concat(encodeURIComponent(obj[paramKey]));
  }).join("&");

  if (queryString.length > 0) {
    queryString = "?" + queryString;
  }

  return queryString;
}

function jsonParseOrNull(json) {
  try {
    return JSON.parse(json);
  } catch (e) {
    return null;
  }
}

function xhr(options) {
  return new Promise(function (resolve) {
    var xhr = new XMLHttpRequest();
    xhr.withCredentials = true;

    xhr.onreadystatechange = function () {
      if (xhr.readyState == xhr.DONE) {
        resolve(xhr);
      }
    };

    xhr.open(options.method, options.url);

    if (options.body) {
      xhr.setRequestHeader("Content-Type", "application/json");
    }

    xhr.setRequestHeader("Accept", "application/json");
    xhr.send(options.body);
  });
}

/***/ }),

/***/ "./src/Common/Libraries/Websockets/CloudShareWebSockets/websocket-client.js":
/*!**********************************************************************************!*\
  !*** ./src/Common/Libraries/Websockets/CloudShareWebSockets/websocket-client.js ***!
  \**********************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return WebSocketClient; });
/* harmony import */ var _request__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./request */ "./src/Common/Libraries/Websockets/CloudShareWebSockets/request.js");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }


var BASE_RETRY_INTERVAL_MS = 750;
var RETRY_MAX_EXPONENT = 10;

var WebSocketClient =
/*#__PURE__*/
function () {
  function WebSocketClient(options) {
    var _this = this;

    _classCallCheck(this, WebSocketClient);

    this._socket = null;
    this._connecting = false;
    this._connected = false;
    this._retryTimeoutId = null;
    this._options = options;
    this._getOptionsOnReconnect = options.getOptionsOnReconnect;
    this._noRetry = options.noRetry;
    this._retryAttemptCount = 0;
    this._nextRetryIntervalMs = this._getExponentialBackoff();
    this._disconnectResolve = null;
    window.addEventListener("beforeunload", function () {
      _this.disconnect();
    });
  }

  _createClass(WebSocketClient, [{
    key: "connect",
    value: function connect() {
      var _this2 = this;

      if (this._connecting || this._connected) {
        return new Promise(function (resolve) {
          return resolve(_this2);
        });
      }

      this._connecting = true;
      return this._connectToWebSocket();
    }
  }, {
    key: "disconnect",
    value: function disconnect() {
      var _this3 = this;

      return new Promise(function (resolve) {
        if (!_this3._socket || _this3._socket.readyState === _this3._socket.CLOSED) {
          resolve();
        } else {
          _this3._disconnectResolve = resolve;
          _this3._noRetry = true;

          _this3._socket.close();

          _this3._socket = null;
        }
      });
    }
  }, {
    key: "sendText",
    value: function sendText(text) {
      if (!this._socket) {
        return;
      }

      this._socket.send(text);
    }
  }, {
    key: "isConnected",
    value: function isConnected() {
      return this._connected;
    }
  }, {
    key: "_connectToWebSocket",
    value: function _connectToWebSocket() {
      var _this4 = this;

      return new Promise(function (resolve, reject) {
        var url = _this4._optionsToWebSocketsUrl(_this4._options);

        _this4._log("Connecting to: ", url);

        _this4._socket = new window.WebSocket(url);

        _this4._socket.onopen = function (e) {
          _this4._log("Connected to: ", url);

          _this4._connecting = false;
          _this4._connected = true;

          if (_this4._options.onopen) {
            _this4._options.onopen.call(_this4._socket, e);
          }

          resolve(_this4);
        };

        _this4._socket.onclose = function (e) {
          return _this4._onclose(e, url, reject);
        };

        _this4._socket.onerror = function (e) {
          return _this4._onerror(e, url, reject);
        };

        _this4._socket.onmessage = _this4._options.onmessage;
      });
    }
  }, {
    key: "_onclose",
    value: function _onclose(closeEvent, url, reject) {
      this._connecting = false;
      this._connected = false;

      if (!this._noRetry) {
        this._retry();

        if (!closeEvent.wasClean) {
          this._log("Connection failed to: '".concat(url, "', retry in ").concat(this._nextRetryIntervalMs, " ms"), closeEvent);
        } else {
          this._log("Connection closed to: '".concat(url, "', retry in ").concat(this._nextRetryIntervalMs, " ms"), closeEvent);
        }
      } else {
        this._log("Connection closed to: '".concat(url, "'"), closeEvent);

        reject(this);
      }

      if (this._options.onclose) {
        this._options.onclose.call(this._socket, closeEvent);
      }

      if (this._disconnectResolve) {
        this._disconnectResolve();

        this._disconnectResolve = null;
      }
    }
  }, {
    key: "_onerror",
    value: function _onerror(errorEvent, url, reject) {
      this._connecting = false;
      this._connected = false;

      if (!this._noRetry) {
        this._retry();

        this._log("Connection failed to: '".concat(url, "', retry in ").concat(this._nextRetryIntervalMs, " ms"), errorEvent);
      } else {
        this._log("Connection failed to: '".concat(url, "'"), errorEvent);

        reject(this);
      }

      if (this._options.onerror) {
        this._options.onerror.call(this._socket, errorEvent);
      }

      if (this._disconnectResolve) {
        this._disconnectResolve();

        this._disconnectResolve = null;
      }
    }
  }, {
    key: "_retry",
    value: function _retry() {
      var _this5 = this;

      if (!this._socket || this._retryTimeoutId) {
        return -1;
      }

      this._retryAttemptCount += 1;
      this._nextRetryIntervalMs = this._getExponentialBackoff();
      this._retryTimeoutId = setTimeout(function () {
        _this5._retryTimeoutId = null;
        _this5._socket = null;

        if (_this5._getOptionsOnReconnect) {
          _this5._getOptionsOnReconnect().then(function (options) {
            _this5._options.protocolAndHost = options.protocolAndHost || _this5._options.protocolAndHost;
            _this5._options.path = options.path || _this5._options.path;
            _this5._options.query = options.query || _this5._options.query;

            _this5.connect();
          }, function (e) {
            _this5._retry();

            _this5._log("Failed to get connection options before reconnect, retrying in ".concat(_this5._nextRetryIntervalMs, " ms"), e);
          });
        } else {
          _this5.connect();
        }
      }, this._nextRetryIntervalMs);
      return this._nextRetryIntervalMs;
    }
  }, {
    key: "_getExponentialBackoff",
    value: function _getExponentialBackoff() {
      var c = Math.min(this._retryAttemptCount, RETRY_MAX_EXPONENT);
      var r = Math.random() * (Math.pow(2, c) - 1);
      return Math.round(r * BASE_RETRY_INTERVAL_MS);
    }
  }, {
    key: "_optionsToWebSocketsUrl",
    value: function _optionsToWebSocketsUrl(options) {
      var url = options.protocolAndHost;

      if (options.path) {
        url += options.path[0] === "/" ? options.path : "/" + options.path;
      }

      if (options.query) {
        url += Object(_request__WEBPACK_IMPORTED_MODULE_0__["createQueryString"])(options.query);
      }

      return url;
    }
  }, {
    key: "_log",
    value: function _log() {
      var args = Array.prototype.slice.call(arguments);
      args.unshift("WebSockets: ");

      if (console.info) {
        console.info.apply(console, args);
      } else {
        console.log.apply(console, args);
      }
    }
  }]);

  return WebSocketClient;
}();



/***/ })

/******/ });
//# sourceMappingURL=csws.js.map

/***/ }),
/* 26 */
/***/ (function(module, exports) {

// This object will be used as the prototype for Nodes when creating a
// DOM-Level-1-compliant structure.
var NodePrototype = module.exports = {
	get firstChild() {
		var children = this.children;
		return children && children[0] || null;
	},
	get lastChild() {
		var children = this.children;
		return children && children[children.length - 1] || null;
	},
	get nodeType() {
		return nodeTypes[this.type] || nodeTypes.element;
	}
};

var domLvl1 = {
	tagName: "name",
	childNodes: "children",
	parentNode: "parent",
	previousSibling: "prev",
	nextSibling: "next",
	nodeValue: "data"
};

var nodeTypes = {
	element: 1,
	text: 3,
	cdata: 4,
	comment: 8
};

Object.keys(domLvl1).forEach(function(key) {
	var shorthand = domLvl1[key];
	Object.defineProperty(NodePrototype, key, {
		get: function() {
			return this[shorthand] || null;
		},
		set: function(val) {
			this[shorthand] = val;
			return val;
		}
	});
});


/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {

var decodeMap = __webpack_require__(66);

module.exports = decodeCodePoint;

// modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
function decodeCodePoint(codePoint){

	if((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF){
		return "\uFFFD";
	}

	if(codePoint in decodeMap){
		codePoint = decodeMap[codePoint];
	}

	var output = "";

	if(codePoint > 0xFFFF){
		codePoint -= 0x10000;
		output += String.fromCharCode(codePoint >>> 10 & 0x3FF | 0xD800);
		codePoint = 0xDC00 | codePoint & 0x3FF;
	}

	output += String.fromCharCode(codePoint);
	return output;
}


/***/ }),
/* 28 */
/***/ (function(module, exports) {

module.exports = {
	"Aacute": "Á",
	"aacute": "á",
	"Acirc": "Â",
	"acirc": "â",
	"acute": "´",
	"AElig": "Æ",
	"aelig": "æ",
	"Agrave": "À",
	"agrave": "à",
	"amp": "&",
	"AMP": "&",
	"Aring": "Å",
	"aring": "å",
	"Atilde": "Ã",
	"atilde": "ã",
	"Auml": "Ä",
	"auml": "ä",
	"brvbar": "¦",
	"Ccedil": "Ç",
	"ccedil": "ç",
	"cedil": "¸",
	"cent": "¢",
	"copy": "©",
	"COPY": "©",
	"curren": "¤",
	"deg": "°",
	"divide": "÷",
	"Eacute": "É",
	"eacute": "é",
	"Ecirc": "Ê",
	"ecirc": "ê",
	"Egrave": "È",
	"egrave": "è",
	"ETH": "Ð",
	"eth": "ð",
	"Euml": "Ë",
	"euml": "ë",
	"frac12": "½",
	"frac14": "¼",
	"frac34": "¾",
	"gt": ">",
	"GT": ">",
	"Iacute": "Í",
	"iacute": "í",
	"Icirc": "Î",
	"icirc": "î",
	"iexcl": "¡",
	"Igrave": "Ì",
	"igrave": "ì",
	"iquest": "¿",
	"Iuml": "Ï",
	"iuml": "ï",
	"laquo": "«",
	"lt": "<",
	"LT": "<",
	"macr": "¯",
	"micro": "µ",
	"middot": "·",
	"nbsp": " ",
	"not": "¬",
	"Ntilde": "Ñ",
	"ntilde": "ñ",
	"Oacute": "Ó",
	"oacute": "ó",
	"Ocirc": "Ô",
	"ocirc": "ô",
	"Ograve": "Ò",
	"ograve": "ò",
	"ordf": "ª",
	"ordm": "º",
	"Oslash": "Ø",
	"oslash": "ø",
	"Otilde": "Õ",
	"otilde": "õ",
	"Ouml": "Ö",
	"ouml": "ö",
	"para": "¶",
	"plusmn": "±",
	"pound": "£",
	"quot": "\"",
	"QUOT": "\"",
	"raquo": "»",
	"reg": "®",
	"REG": "®",
	"sect": "§",
	"shy": "­",
	"sup1": "¹",
	"sup2": "²",
	"sup3": "³",
	"szlig": "ß",
	"THORN": "Þ",
	"thorn": "þ",
	"times": "×",
	"Uacute": "Ú",
	"uacute": "ú",
	"Ucirc": "Û",
	"ucirc": "û",
	"Ugrave": "Ù",
	"ugrave": "ù",
	"uml": "¨",
	"Uuml": "Ü",
	"uuml": "ü",
	"Yacute": "Ý",
	"yacute": "ý",
	"yen": "¥",
	"yuml": "ÿ"
};

/***/ }),
/* 29 */
/***/ (function(module, exports) {

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A reader which automatically handles the given input stream, returning
 * strictly received packets as array buffers. Note that this object will
 * overwrite any installed event handlers on the given Guacamole.InputStream.
 * 
 * @constructor
 * @param {Guacamole.InputStream} stream The stream that data will be read
 *                                       from.
 */
Guacamole.ArrayBufferReader = function(stream) {

    /**
     * Reference to this Guacamole.InputStream.
     * @private
     */
    var guac_reader = this;

    // Receive blobs as array buffers
    stream.onblob = function(data) {

        // Convert to ArrayBuffer
        var binary = window.atob(data);
        var arrayBuffer = new ArrayBuffer(binary.length);
        var bufferView = new Uint8Array(arrayBuffer);

        for (var i=0; i<binary.length; i++)
            bufferView[i] = binary.charCodeAt(i);

        // Call handler, if present
        if (guac_reader.ondata)
            guac_reader.ondata(arrayBuffer);

    };

    // Simply call onend when end received
    stream.onend = function() {
        if (guac_reader.onend)
            guac_reader.onend();
    };

    /**
     * Fired once for every blob of data received.
     * 
     * @event
     * @param {ArrayBuffer} buffer The data packet received.
     */
    this.ondata = null;

    /**
     * Fired once this stream is finished and no further data will be written.
     * @event
     */
    this.onend = null;

};/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A writer which automatically writes to the given output stream with arbitrary
 * binary data, supplied as ArrayBuffers.
 * 
 * @constructor
 * @param {Guacamole.OutputStream} stream The stream that data will be written
 *                                        to.
 */
Guacamole.ArrayBufferWriter = function(stream) {

    /**
     * Reference to this Guacamole.StringWriter.
     * @private
     */
    var guac_writer = this;

    // Simply call onack for acknowledgements
    stream.onack = function(status) {
        if (guac_writer.onack)
            guac_writer.onack(status);
    };

    /**
     * Encodes the given data as base64, sending it as a blob. The data must
     * be small enough to fit into a single blob instruction.
     * 
     * @private
     * @param {Uint8Array} bytes The data to send.
     */
    function __send_blob(bytes) {

        var binary = "";

        // Produce binary string from bytes in buffer
        for (var i=0; i<bytes.byteLength; i++)
            binary += String.fromCharCode(bytes[i]);

        // Send as base64
        stream.sendBlob(window.btoa(binary));

    }

    /**
     * The maximum length of any blob sent by this Guacamole.ArrayBufferWriter,
     * in bytes. Data sent via
     * [sendData()]{@link Guacamole.ArrayBufferWriter#sendData} which exceeds
     * this length will be split into multiple blobs. As the Guacamole protocol
     * limits the maximum size of any instruction or instruction element to
     * 8192 bytes, and the contents of blobs will be base64-encoded, this value
     * should only be increased with extreme caution.
     *
     * @type {Number}
     * @default {@link Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH}
     */
    this.blobLength = Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH;

    /**
     * Sends the given data.
     * 
     * @param {ArrayBuffer|TypedArray} data The data to send.
     */
    this.sendData = function(data) {

        var bytes = new Uint8Array(data);

        // If small enough to fit into single instruction, send as-is
        if (bytes.length <= guac_writer.blobLength)
            __send_blob(bytes);

        // Otherwise, send as multiple instructions
        else {
            for (var offset=0; offset<bytes.length; offset += guac_writer.blobLength)
                __send_blob(bytes.subarray(offset, offset + guac_writer.blobLength));
        }

    };

    /**
     * Signals that no further text will be sent, effectively closing the
     * stream.
     */
    this.sendEnd = function() {
        stream.sendEnd();
    };

    /**
     * Fired for received data, if acknowledged by the server.
     * @event
     * @param {Guacamole.Status} status The status of the operation.
     */
    this.onack = null;

};

/**
 * The default maximum blob length for new Guacamole.ArrayBufferWriter
 * instances.
 *
 * @constant
 * @type {Number}
 */
Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH = 6048;
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Maintains a singleton instance of the Web Audio API AudioContext class,
 * instantiating the AudioContext only in response to the first call to
 * getAudioContext(), and only if no existing AudioContext instance has been
 * provided via the singleton property. Subsequent calls to getAudioContext()
 * will return the same instance.
 *
 * @namespace
 */
Guacamole.AudioContextFactory = {

    /**
     * A singleton instance of a Web Audio API AudioContext object, or null if
     * no instance has yes been created. This property may be manually set if
     * you wish to supply your own AudioContext instance, but care must be
     * taken to do so as early as possible. Assignments to this property will
     * not retroactively affect the value returned by previous calls to
     * getAudioContext().
     *
     * @type {AudioContext}
     */
    'singleton' : null,

    /**
     * Returns a singleton instance of a Web Audio API AudioContext object.
     *
     * @return {AudioContext}
     *     A singleton instance of a Web Audio API AudioContext object, or null
     *     if the Web Audio API is not supported.
     */
    'getAudioContext' : function getAudioContext() {

        // Fallback to Webkit-specific AudioContext implementation
        var AudioContext = window.AudioContext || window.webkitAudioContext;

        // Get new AudioContext instance if Web Audio API is supported
        if (AudioContext) {
            try {

                // Create new instance if none yet exists
                if (!Guacamole.AudioContextFactory.singleton)
                    Guacamole.AudioContextFactory.singleton = new AudioContext();

                // Return singleton instance
                return Guacamole.AudioContextFactory.singleton;

            }
            catch (e) {
                // Do not use Web Audio API if not allowed by browser
            }
        }

        // Web Audio API not supported
        return null;

    }

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Abstract audio player which accepts, queues and plays back arbitrary audio
 * data. It is up to implementations of this class to provide some means of
 * handling a provided Guacamole.InputStream. Data received along the provided
 * stream is to be played back immediately.
 *
 * @constructor
 */
Guacamole.AudioPlayer = function AudioPlayer() {

    /**
     * Notifies this Guacamole.AudioPlayer that all audio up to the current
     * point in time has been given via the underlying stream, and that any
     * difference in time between queued audio data and the current time can be
     * considered latency.
     */
    this.sync = function sync() {
        // Default implementation - do nothing
    };

};

/**
 * Determines whether the given mimetype is supported by any built-in
 * implementation of Guacamole.AudioPlayer, and thus will be properly handled
 * by Guacamole.AudioPlayer.getInstance().
 *
 * @param {String} mimetype
 *     The mimetype to check.
 *
 * @returns {Boolean}
 *     true if the given mimetype is supported by any built-in
 *     Guacamole.AudioPlayer, false otherwise.
 */
Guacamole.AudioPlayer.isSupportedType = function isSupportedType(mimetype) {

    return Guacamole.RawAudioPlayer.isSupportedType(mimetype);

};

/**
 * Returns a list of all mimetypes supported by any built-in
 * Guacamole.AudioPlayer, in rough order of priority. Beware that only the core
 * mimetypes themselves will be listed. Any mimetype parameters, even required
 * ones, will not be included in the list. For example, "audio/L8" is a
 * supported raw audio mimetype that is supported, but it is invalid without
 * additional parameters. Something like "audio/L8;rate=44100" would be valid,
 * however (see https://tools.ietf.org/html/rfc4856).
 *
 * @returns {String[]}
 *     A list of all mimetypes supported by any built-in Guacamole.AudioPlayer,
 *     excluding any parameters.
 */
Guacamole.AudioPlayer.getSupportedTypes = function getSupportedTypes() {

    return Guacamole.RawAudioPlayer.getSupportedTypes();

};

/**
 * Returns an instance of Guacamole.AudioPlayer providing support for the given
 * audio format. If support for the given audio format is not available, null
 * is returned.
 *
 * @param {Guacamole.InputStream} stream
 *     The Guacamole.InputStream to read audio data from.
 *
 * @param {String} mimetype
 *     The mimetype of the audio data in the provided stream.
 *
 * @return {Guacamole.AudioPlayer}
 *     A Guacamole.AudioPlayer instance supporting the given mimetype and
 *     reading from the given stream, or null if support for the given mimetype
 *     is absent.
 */
Guacamole.AudioPlayer.getInstance = function getInstance(stream, mimetype) {

    // Use raw audio player if possible
    if (Guacamole.RawAudioPlayer.isSupportedType(mimetype))
        return new Guacamole.RawAudioPlayer(stream, mimetype);

    // No support for given mimetype
    return null;

};

/**
 * Implementation of Guacamole.AudioPlayer providing support for raw PCM format
 * audio. This player relies only on the Web Audio API and does not require any
 * browser-level support for its audio formats.
 *
 * @constructor
 * @augments Guacamole.AudioPlayer
 * @param {Guacamole.InputStream} stream
 *     The Guacamole.InputStream to read audio data from.
 *
 * @param {String} mimetype
 *     The mimetype of the audio data in the provided stream, which must be a
 *     "audio/L8" or "audio/L16" mimetype with necessary parameters, such as:
 *     "audio/L16;rate=44100,channels=2".
 */
Guacamole.RawAudioPlayer = function RawAudioPlayer(stream, mimetype) {

    /**
     * The format of audio this player will decode.
     *
     * @private
     * @type {Guacamole.RawAudioFormat}
     */
    var format = Guacamole.RawAudioFormat.parse(mimetype);

    /**
     * An instance of a Web Audio API AudioContext object, or null if the
     * Web Audio API is not supported.
     *
     * @private
     * @type {AudioContext}
     */
    var context = Guacamole.AudioContextFactory.getAudioContext();

    /**
     * The earliest possible time that the next packet could play without
     * overlapping an already-playing packet, in seconds. Note that while this
     * value is in seconds, it is not an integer value and has microsecond
     * resolution.
     *
     * @private
     * @type {Number}
     */
    var nextPacketTime = context.currentTime;

    /**
     * Guacamole.ArrayBufferReader wrapped around the audio input stream
     * provided with this Guacamole.RawAudioPlayer was created.
     *
     * @private
     * @type {Guacamole.ArrayBufferReader}
     */
    var reader = new Guacamole.ArrayBufferReader(stream);

    /**
     * The minimum size of an audio packet split by splitAudioPacket(), in
     * seconds. Audio packets smaller than this will not be split, nor will the
     * split result of a larger packet ever be smaller in size than this
     * minimum.
     *
     * @private
     * @constant
     * @type {Number}
     */
    var MIN_SPLIT_SIZE = 0.02;

    /**
     * The maximum amount of latency to allow between the buffered data stream
     * and the playback position, in seconds. Initially, this is set to
     * roughly one third of a second.
     *
     * @private
     * @type {Number}
     */
    var maxLatency = 0.3;

    /**
     * The type of typed array that will be used to represent each audio packet
     * internally. This will be either Int8Array or Int16Array, depending on
     * whether the raw audio format is 8-bit or 16-bit.
     *
     * @private
     * @constructor
     */
    var SampleArray = (format.bytesPerSample === 1) ? window.Int8Array : window.Int16Array;

    /**
     * The maximum absolute value of any sample within a raw audio packet
     * received by this audio player. This depends only on the size of each
     * sample, and will be 128 for 8-bit audio and 32768 for 16-bit audio.
     *
     * @private
     * @type {Number}
     */
    var maxSampleValue = (format.bytesPerSample === 1) ? 128 : 32768;

    /**
     * The queue of all pending audio packets, as an array of sample arrays.
     * Audio packets which are pending playback will be added to this queue for
     * further manipulation prior to scheduling via the Web Audio API. Once an
     * audio packet leaves this queue and is scheduled via the Web Audio API,
     * no further modifications can be made to that packet.
     *
     * @private
     * @type {SampleArray[]}
     */
    var packetQueue = [];

    /**
     * Given an array of audio packets, returns a single audio packet
     * containing the concatenation of those packets.
     *
     * @private
     * @param {SampleArray[]} packets
     *     The array of audio packets to concatenate.
     *
     * @returns {SampleArray}
     *     A single audio packet containing the concatenation of all given
     *     audio packets. If no packets are provided, this will be undefined.
     */
    var joinAudioPackets = function joinAudioPackets(packets) {

        // Do not bother joining if one or fewer packets are in the queue
        if (packets.length <= 1)
            return packets[0];

        // Determine total sample length of the entire queue
        var totalLength = 0;
        packets.forEach(function addPacketLengths(packet) {
            totalLength += packet.length;
        });

        // Append each packet within queue
        var offset = 0;
        var joined = new SampleArray(totalLength);
        packets.forEach(function appendPacket(packet) {
            joined.set(packet, offset);
            offset += packet.length;
        });

        return joined;

    };

    /**
     * Given a single packet of audio data, splits off an arbitrary length of
     * audio data from the beginning of that packet, returning the split result
     * as an array of two packets. The split location is determined through an
     * algorithm intended to minimize the liklihood of audible clicking between
     * packets. If no such split location is possible, an array containing only
     * the originally-provided audio packet is returned.
     *
     * @private
     * @param {SampleArray} data
     *     The audio packet to split.
     *
     * @returns {SampleArray[]}
     *     An array of audio packets containing the result of splitting the
     *     provided audio packet. If splitting is possible, this array will
     *     contain two packets. If splitting is not possible, this array will
     *     contain only the originally-provided packet.
     */
    var splitAudioPacket = function splitAudioPacket(data) {

        var minValue = Number.MAX_VALUE;
        var optimalSplitLength = data.length;

        // Calculate number of whole samples in the provided audio packet AND
        // in the minimum possible split packet
        var samples = Math.floor(data.length / format.channels);
        var minSplitSamples = Math.floor(format.rate * MIN_SPLIT_SIZE);

        // Calculate the beginning of the "end" of the audio packet
        var start = Math.max(
            format.channels * minSplitSamples,
            format.channels * (samples - minSplitSamples)
        );

        // For all samples at the end of the given packet, find a point where
        // the perceptible volume across all channels is lowest (and thus is
        // the optimal point to split)
        for (var offset = start; offset < data.length; offset += format.channels) {

            // Calculate the sum of all values across all channels (the result
            // will be proportional to the average volume of a sample)
            var totalValue = 0;
            for (var channel = 0; channel < format.channels; channel++) {
                totalValue += Math.abs(data[offset + channel]);
            }

            // If this is the smallest average value thus far, set the split
            // length such that the first packet ends with the current sample
            if (totalValue <= minValue) {
                optimalSplitLength = offset + format.channels;
                minValue = totalValue;
            }

        }

        // If packet is not split, return the supplied packet untouched
        if (optimalSplitLength === data.length)
            return [data];

        // Otherwise, split the packet into two new packets according to the
        // calculated optimal split length
        return [
            new SampleArray(data.buffer.slice(0, optimalSplitLength * format.bytesPerSample)),
            new SampleArray(data.buffer.slice(optimalSplitLength * format.bytesPerSample))
        ];

    };

    /**
     * Pushes the given packet of audio data onto the playback queue. Unlike
     * other private functions within Guacamole.RawAudioPlayer, the type of the
     * ArrayBuffer packet of audio data here need not be specific to the type
     * of audio (as with SampleArray). The ArrayBuffer type provided by a
     * Guacamole.ArrayBufferReader, for example, is sufficient. Any necessary
     * conversions will be performed automatically internally.
     *
     * @private
     * @param {ArrayBuffer} data
     *     A raw packet of audio data that should be pushed onto the audio
     *     playback queue.
     */
    var pushAudioPacket = function pushAudioPacket(data) {
        packetQueue.push(new SampleArray(data));
    };

    /**
     * Shifts off and returns a packet of audio data from the beginning of the
     * playback queue. The length of this audio packet is determined
     * dynamically according to the click-reduction algorithm implemented by
     * splitAudioPacket().
     *
     * @private
     * @returns {SampleArray}
     *     A packet of audio data pulled from the beginning of the playback
     *     queue.
     */
    var shiftAudioPacket = function shiftAudioPacket() {

        // Flatten data in packet queue
        var data = joinAudioPackets(packetQueue);
        if (!data)
            return null;

        // Pull an appropriate amount of data from the front of the queue
        packetQueue = splitAudioPacket(data);
        data = packetQueue.shift();

        return data;

    };

    /**
     * Converts the given audio packet into an AudioBuffer, ready for playback
     * by the Web Audio API. Unlike the raw audio packets received by this
     * audio player, AudioBuffers require floating point samples and are split
     * into isolated planes of channel-specific data.
     *
     * @private
     * @param {SampleArray} data
     *     The raw audio packet that should be converted into a Web Audio API
     *     AudioBuffer.
     *
     * @returns {AudioBuffer}
     *     A new Web Audio API AudioBuffer containing the provided audio data,
     *     converted to the format used by the Web Audio API.
     */
    var toAudioBuffer = function toAudioBuffer(data) {

        // Calculate total number of samples
        var samples = data.length / format.channels;

        // Determine exactly when packet CAN play
        var packetTime = context.currentTime;
        if (nextPacketTime < packetTime)
            nextPacketTime = packetTime;

        // Get audio buffer for specified format
        var audioBuffer = context.createBuffer(format.channels, samples, format.rate);

        // Convert each channel
        for (var channel = 0; channel < format.channels; channel++) {

            var audioData = audioBuffer.getChannelData(channel);

            // Fill audio buffer with data for channel
            var offset = channel;
            for (var i = 0; i < samples; i++) {
                audioData[i] = data[offset] / maxSampleValue;
                offset += format.channels;
            }

        }

        return audioBuffer;

    };

    // Defer playback of received audio packets slightly
    reader.ondata = function playReceivedAudio(data) {

        // Push received samples onto queue
        pushAudioPacket(new SampleArray(data));

        // Shift off an arbitrary packet of audio data from the queue (this may
        // be different in size from the packet just pushed)
        var packet = shiftAudioPacket();
        if (!packet)
            return;

        // Determine exactly when packet CAN play
        var packetTime = context.currentTime;
        if (nextPacketTime < packetTime)
            nextPacketTime = packetTime;

        // Set up buffer source
        var source = context.createBufferSource();
        source.connect(context.destination);

        // Use noteOn() instead of start() if necessary
        if (!source.start)
            source.start = source.noteOn;

        // Schedule packet
        source.buffer = toAudioBuffer(packet);
        source.start(nextPacketTime);

        // Update timeline by duration of scheduled packet
        nextPacketTime += packet.length / format.channels / format.rate;

    };

    /** @override */
    this.sync = function sync() {

        // Calculate elapsed time since last sync
        var now = context.currentTime;

        // Reschedule future playback time such that playback latency is
        // bounded within a reasonable latency threshold
        nextPacketTime = Math.min(nextPacketTime, now + maxLatency);

    };

};

Guacamole.RawAudioPlayer.prototype = new Guacamole.AudioPlayer();

/**
 * Determines whether the given mimetype is supported by
 * Guacamole.RawAudioPlayer.
 *
 * @param {String} mimetype
 *     The mimetype to check.
 *
 * @returns {Boolean}
 *     true if the given mimetype is supported by Guacamole.RawAudioPlayer,
 *     false otherwise.
 */
Guacamole.RawAudioPlayer.isSupportedType = function isSupportedType(mimetype) {

    // No supported types if no Web Audio API
    if (!Guacamole.AudioContextFactory.getAudioContext())
        return false;

    return Guacamole.RawAudioFormat.parse(mimetype) !== null;

};

/**
 * Returns a list of all mimetypes supported by Guacamole.RawAudioPlayer. Only
 * the core mimetypes themselves will be listed. Any mimetype parameters, even
 * required ones, will not be included in the list. For example, "audio/L8" is
 * a raw audio mimetype that may be supported, but it is invalid without
 * additional parameters. Something like "audio/L8;rate=44100" would be valid,
 * however (see https://tools.ietf.org/html/rfc4856).
 *
 * @returns {String[]}
 *     A list of all mimetypes supported by Guacamole.RawAudioPlayer, excluding
 *     any parameters. If the necessary JavaScript APIs for playing raw audio
 *     are absent, this list will be empty.
 */
Guacamole.RawAudioPlayer.getSupportedTypes = function getSupportedTypes() {

    // No supported types if no Web Audio API
    if (!Guacamole.AudioContextFactory.getAudioContext())
        return [];

    // We support 8-bit and 16-bit raw PCM
    return [
        'audio/L8',
        'audio/L16'
    ];

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Abstract audio recorder which streams arbitrary audio data to an underlying
 * Guacamole.OutputStream. It is up to implementations of this class to provide
 * some means of handling this Guacamole.OutputStream. Data produced by the
 * recorder is to be sent along the provided stream immediately.
 *
 * @constructor
 */
Guacamole.AudioRecorder = function AudioRecorder() {

    /**
     * Callback which is invoked when the audio recording process has stopped
     * and the underlying Guacamole stream has been closed normally. Audio will
     * only resume recording if a new Guacamole.AudioRecorder is started. This
     * Guacamole.AudioRecorder instance MAY NOT be reused.
     *
     * @event
     */
    this.onclose = null;

    /**
     * Callback which is invoked when the audio recording process cannot
     * continue due to an error, if it has started at all. The underlying
     * Guacamole stream is automatically closed. Future attempts to record
     * audio should not be made, and this Guacamole.AudioRecorder instance
     * MAY NOT be reused.
     *
     * @event
     */
    this.onerror = null;

};

/**
 * Determines whether the given mimetype is supported by any built-in
 * implementation of Guacamole.AudioRecorder, and thus will be properly handled
 * by Guacamole.AudioRecorder.getInstance().
 *
 * @param {String} mimetype
 *     The mimetype to check.
 *
 * @returns {Boolean}
 *     true if the given mimetype is supported by any built-in
 *     Guacamole.AudioRecorder, false otherwise.
 */
Guacamole.AudioRecorder.isSupportedType = function isSupportedType(mimetype) {

    return Guacamole.RawAudioRecorder.isSupportedType(mimetype);

};

/**
 * Returns a list of all mimetypes supported by any built-in
 * Guacamole.AudioRecorder, in rough order of priority. Beware that only the
 * core mimetypes themselves will be listed. Any mimetype parameters, even
 * required ones, will not be included in the list. For example, "audio/L8" is
 * a supported raw audio mimetype that is supported, but it is invalid without
 * additional parameters. Something like "audio/L8;rate=44100" would be valid,
 * however (see https://tools.ietf.org/html/rfc4856).
 *
 * @returns {String[]}
 *     A list of all mimetypes supported by any built-in
 *     Guacamole.AudioRecorder, excluding any parameters.
 */
Guacamole.AudioRecorder.getSupportedTypes = function getSupportedTypes() {

    return Guacamole.RawAudioRecorder.getSupportedTypes();

};

/**
 * Returns an instance of Guacamole.AudioRecorder providing support for the
 * given audio format. If support for the given audio format is not available,
 * null is returned.
 *
 * @param {Guacamole.OutputStream} stream
 *     The Guacamole.OutputStream to send audio data through.
 *
 * @param {String} mimetype
 *     The mimetype of the audio data to be sent along the provided stream.
 *
 * @return {Guacamole.AudioRecorder}
 *     A Guacamole.AudioRecorder instance supporting the given mimetype and
 *     writing to the given stream, or null if support for the given mimetype
 *     is absent.
 */
Guacamole.AudioRecorder.getInstance = function getInstance(stream, mimetype) {

    // Use raw audio recorder if possible
    if (Guacamole.RawAudioRecorder.isSupportedType(mimetype))
        return new Guacamole.RawAudioRecorder(stream, mimetype);

    // No support for given mimetype
    return null;

};

/**
 * Implementation of Guacamole.AudioRecorder providing support for raw PCM
 * format audio. This recorder relies only on the Web Audio API and does not
 * require any browser-level support for its audio formats.
 *
 * @constructor
 * @augments Guacamole.AudioRecorder
 * @param {Guacamole.OutputStream} stream
 *     The Guacamole.OutputStream to write audio data to.
 *
 * @param {String} mimetype
 *     The mimetype of the audio data to send along the provided stream, which
 *     must be a "audio/L8" or "audio/L16" mimetype with necessary parameters,
 *     such as: "audio/L16;rate=44100,channels=2".
 */
Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {

    /**
     * Reference to this RawAudioRecorder.
     *
     * @private
     * @type {Guacamole.RawAudioRecorder}
     */
    var recorder = this;

    /**
     * The size of audio buffer to request from the Web Audio API when
     * recording or processing audio, in sample-frames. This must be a power of
     * two between 256 and 16384 inclusive, as required by
     * AudioContext.createScriptProcessor().
     *
     * @private
     * @constant
     * @type {Number}
     */
    var BUFFER_SIZE = 2048;

    /**
     * The window size to use when applying Lanczos interpolation, commonly
     * denoted by the variable "a".
     * See: https://en.wikipedia.org/wiki/Lanczos_resampling
     *
     * @private
     * @contant
     * @type Number
     */
    var LANCZOS_WINDOW_SIZE = 3;

    /**
     * The format of audio this recorder will encode.
     *
     * @private
     * @type {Guacamole.RawAudioFormat}
     */
    var format = Guacamole.RawAudioFormat.parse(mimetype);

    /**
     * An instance of a Web Audio API AudioContext object, or null if the
     * Web Audio API is not supported.
     *
     * @private
     * @type {AudioContext}
     */
    var context = Guacamole.AudioContextFactory.getAudioContext();

    /**
     * A function which directly invokes the browser's implementation of
     * navigator.getUserMedia() with all provided parameters.
     *
     * @type Function
     */
    var getUserMedia = (navigator.getUserMedia
            || navigator.webkitGetUserMedia
            || navigator.mozGetUserMedia
            || navigator.msGetUserMedia).bind(navigator);

    /**
     * Guacamole.ArrayBufferWriter wrapped around the audio output stream
     * provided when this Guacamole.RawAudioRecorder was created.
     *
     * @private
     * @type {Guacamole.ArrayBufferWriter}
     */
    var writer = new Guacamole.ArrayBufferWriter(stream);

    /**
     * The type of typed array that will be used to represent each audio packet
     * internally. This will be either Int8Array or Int16Array, depending on
     * whether the raw audio format is 8-bit or 16-bit.
     *
     * @private
     * @constructor
     */
    var SampleArray = (format.bytesPerSample === 1) ? window.Int8Array : window.Int16Array;

    /**
     * The maximum absolute value of any sample within a raw audio packet sent
     * by this audio recorder. This depends only on the size of each sample,
     * and will be 128 for 8-bit audio and 32768 for 16-bit audio.
     *
     * @private
     * @type {Number}
     */
    var maxSampleValue = (format.bytesPerSample === 1) ? 128 : 32768;

    /**
     * The total number of audio samples read from the local audio input device
     * over the life of this audio recorder.
     *
     * @private
     * @type {Number}
     */
    var readSamples = 0;

    /**
     * The total number of audio samples written to the underlying Guacamole
     * connection over the life of this audio recorder.
     *
     * @private
     * @type {Number}
     */
    var writtenSamples = 0;

    /**
     * The audio stream provided by the browser, if allowed. If no stream has
     * yet been received, this will be null.
     *
     * @type MediaStream
     */
    var mediaStream = null;

    /**
     * The source node providing access to the local audio input device.
     *
     * @private
     * @type {MediaStreamAudioSourceNode}
     */
    var source = null;

    /**
     * The script processing node which receives audio input from the media
     * stream source node as individual audio buffers.
     *
     * @private
     * @type {ScriptProcessorNode}
     */
    var processor = null;

    /**
     * The normalized sinc function. The normalized sinc function is defined as
     * 1 for x=0 and sin(PI * x) / (PI * x) for all other values of x.
     *
     * See: https://en.wikipedia.org/wiki/Sinc_function
     *
     * @private
     * @param {Number} x
     *     The point at which the normalized sinc function should be computed.
     *
     * @returns {Number}
     *     The value of the normalized sinc function at x.
     */
    var sinc = function sinc(x) {

        // The value of sinc(0) is defined as 1
        if (x === 0)
            return 1;

        // Otherwise, normlized sinc(x) is sin(PI * x) / (PI * x)
        var piX = Math.PI * x;
        return Math.sin(piX) / piX;

    };

    /**
     * Calculates the value of the Lanczos kernal at point x for a given window
     * size. See: https://en.wikipedia.org/wiki/Lanczos_resampling
     *
     * @private
     * @param {Number} x
     *     The point at which the value of the Lanczos kernel should be
     *     computed.
     *
     * @param {Number} a
     *     The window size to use for the Lanczos kernel.
     *
     * @returns {Number}
     *     The value of the Lanczos kernel at the given point for the given
     *     window size.
     */
    var lanczos = function lanczos(x, a) {

        // Lanczos is sinc(x) * sinc(x / a) for -a < x < a ...
        if (-a < x && x < a)
            return sinc(x) * sinc(x / a);

        // ... and 0 otherwise
        return 0;

    };

    /**
     * Determines the value of the waveform represented by the audio data at
     * the given location. If the value cannot be determined exactly as it does
     * not correspond to an exact sample within the audio data, the value will
     * be derived through interpolating nearby samples.
     *
     * @private
     * @param {Float32Array} audioData
     *     An array of audio data, as returned by AudioBuffer.getChannelData().
     *
     * @param {Number} t
     *     The relative location within the waveform from which the value
     *     should be retrieved, represented as a floating point number between
     *     0 and 1 inclusive, where 0 represents the earliest point in time and
     *     1 represents the latest.
     *
     * @returns {Number}
     *     The value of the waveform at the given location.
     */
    var interpolateSample = function getValueAt(audioData, t) {

        // Convert [0, 1] range to [0, audioData.length - 1]
        var index = (audioData.length - 1) * t;

        // Determine the start and end points for the summation used by the
        // Lanczos interpolation algorithm (see: https://en.wikipedia.org/wiki/Lanczos_resampling)
        var start = Math.floor(index) - LANCZOS_WINDOW_SIZE + 1;
        var end = Math.floor(index) + LANCZOS_WINDOW_SIZE;

        // Calculate the value of the Lanczos interpolation function for the
        // required range
        var sum = 0;
        for (var i = start; i <= end; i++) {
            sum += (audioData[i] || 0) * lanczos(index - i, LANCZOS_WINDOW_SIZE);
        }

        return sum;

    };

    /**
     * Converts the given AudioBuffer into an audio packet, ready for streaming
     * along the underlying output stream. Unlike the raw audio packets used by
     * this audio recorder, AudioBuffers require floating point samples and are
     * split into isolated planes of channel-specific data.
     *
     * @private
     * @param {AudioBuffer} audioBuffer
     *     The Web Audio API AudioBuffer that should be converted to a raw
     *     audio packet.
     *
     * @returns {SampleArray}
     *     A new raw audio packet containing the audio data from the provided
     *     AudioBuffer.
     */
    var toSampleArray = function toSampleArray(audioBuffer) {

        // Track overall amount of data read
        var inSamples = audioBuffer.length;
        readSamples += inSamples;

        // Calculate the total number of samples that should be written as of
        // the audio data just received and adjust the size of the output
        // packet accordingly
        var expectedWrittenSamples = Math.round(readSamples * format.rate / audioBuffer.sampleRate);
        var outSamples = expectedWrittenSamples - writtenSamples;

        // Update number of samples written
        writtenSamples += outSamples;

        // Get array for raw PCM storage
        var data = new SampleArray(outSamples * format.channels);

        // Convert each channel
        for (var channel = 0; channel < format.channels; channel++) {

            var audioData = audioBuffer.getChannelData(channel);

            // Fill array with data from audio buffer channel
            var offset = channel;
            for (var i = 0; i < outSamples; i++) {
                data[offset] = interpolateSample(audioData, i / (outSamples - 1)) * maxSampleValue;
                offset += format.channels;
            }

        }

        return data;

    };

    /**
     * Requests access to the user's microphone and begins capturing audio. All
     * received audio data is resampled as necessary and forwarded to the
     * Guacamole stream underlying this Guacamole.RawAudioRecorder. This
     * function must be invoked ONLY ONCE per instance of
     * Guacamole.RawAudioRecorder.
     *
     * @private
     */
    var beginAudioCapture = function beginAudioCapture() {

        // Attempt to retrieve an audio input stream from the browser
        getUserMedia({ 'audio' : true }, function streamReceived(stream) {

            // Create processing node which receives appropriately-sized audio buffers
            processor = context.createScriptProcessor(BUFFER_SIZE, format.channels, format.channels);
            processor.connect(context.destination);

            // Send blobs when audio buffers are received
            processor.onaudioprocess = function processAudio(e) {
                writer.sendData(toSampleArray(e.inputBuffer).buffer);
            };

            // Connect processing node to user's audio input source
            source = context.createMediaStreamSource(stream);
            source.connect(processor);

            // Save stream for later cleanup
            mediaStream = stream;

        }, function streamDenied() {

            // Simply end stream if audio access is not allowed
            writer.sendEnd();

            // Notify of closure
            if (recorder.onerror)
                recorder.onerror();

        });

    };

    /**
     * Stops capturing audio, if the capture has started, freeing all associated
     * resources. If the capture has not started, this function simply ends the
     * underlying Guacamole stream.
     *
     * @private
     */
    var stopAudioCapture = function stopAudioCapture() {

        // Disconnect media source node from script processor
        if (source)
            source.disconnect();

        // Disconnect associated script processor node
        if (processor)
            processor.disconnect();

        // Stop capture
        if (mediaStream) {
            var tracks = mediaStream.getTracks();
            for (var i = 0; i < tracks.length; i++)
                tracks[i].stop();
        }

        // Remove references to now-unneeded components
        processor = null;
        source = null;
        mediaStream = null;

        // End stream
        writer.sendEnd();

    };

    // Once audio stream is successfully open, request and begin reading audio
    writer.onack = function audioStreamAcknowledged(status) {

        // Begin capture if successful response and not yet started
        if (status.code === Guacamole.Status.Code.SUCCESS && !mediaStream)
            beginAudioCapture();

        // Otherwise stop capture and cease handling any further acks
        else {

            // Stop capturing audio
            stopAudioCapture();
            writer.onack = null;

            // Notify if stream has closed normally
            if (status.code === Guacamole.Status.Code.RESOURCE_CLOSED) {
                if (recorder.onclose)
                    recorder.onclose();
            }

            // Otherwise notify of closure due to error
            else {
                if (recorder.onerror)
                    recorder.onerror();
            }

        }

    };

};

Guacamole.RawAudioRecorder.prototype = new Guacamole.AudioRecorder();

/**
 * Determines whether the given mimetype is supported by
 * Guacamole.RawAudioRecorder.
 *
 * @param {String} mimetype
 *     The mimetype to check.
 *
 * @returns {Boolean}
 *     true if the given mimetype is supported by Guacamole.RawAudioRecorder,
 *     false otherwise.
 */
Guacamole.RawAudioRecorder.isSupportedType = function isSupportedType(mimetype) {

    // No supported types if no Web Audio API
    if (!Guacamole.AudioContextFactory.getAudioContext())
        return false;

    return Guacamole.RawAudioFormat.parse(mimetype) !== null;

};

/**
 * Returns a list of all mimetypes supported by Guacamole.RawAudioRecorder. Only
 * the core mimetypes themselves will be listed. Any mimetype parameters, even
 * required ones, will not be included in the list. For example, "audio/L8" is
 * a raw audio mimetype that may be supported, but it is invalid without
 * additional parameters. Something like "audio/L8;rate=44100" would be valid,
 * however (see https://tools.ietf.org/html/rfc4856).
 *
 * @returns {String[]}
 *     A list of all mimetypes supported by Guacamole.RawAudioRecorder,
 *     excluding any parameters. If the necessary JavaScript APIs for recording
 *     raw audio are absent, this list will be empty.
 */
Guacamole.RawAudioRecorder.getSupportedTypes = function getSupportedTypes() {

    // No supported types if no Web Audio API
    if (!Guacamole.AudioContextFactory.getAudioContext())
        return [];

    // We support 8-bit and 16-bit raw PCM
    return [
        'audio/L8',
        'audio/L16'
    ];

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A reader which automatically handles the given input stream, assembling all
 * received blobs into a single blob by appending them to each other in order.
 * Note that this object will overwrite any installed event handlers on the
 * given Guacamole.InputStream.
 * 
 * @constructor
 * @param {Guacamole.InputStream} stream The stream that data will be read
 *                                       from.
 * @param {String} mimetype The mimetype of the blob being built.
 */
Guacamole.BlobReader = function(stream, mimetype) {

    /**
     * Reference to this Guacamole.InputStream.
     * @private
     */
    var guac_reader = this;

    /**
     * The length of this Guacamole.InputStream in bytes.
     * @private
     */
    var length = 0;

    // Get blob builder
    var blob_builder;
    if      (window.BlobBuilder)       blob_builder = new BlobBuilder();
    else if (window.WebKitBlobBuilder) blob_builder = new WebKitBlobBuilder();
    else if (window.MozBlobBuilder)    blob_builder = new MozBlobBuilder();
    else
        blob_builder = new (function() {

            var blobs = [];

            /** @ignore */
            this.append = function(data) {
                blobs.push(new Blob([data], {"type": mimetype}));
            };

            /** @ignore */
            this.getBlob = function() {
                return new Blob(blobs, {"type": mimetype});
            };

        })();

    // Append received blobs
    stream.onblob = function(data) {

        // Convert to ArrayBuffer
        var binary = window.atob(data);
        var arrayBuffer = new ArrayBuffer(binary.length);
        var bufferView = new Uint8Array(arrayBuffer);

        for (var i=0; i<binary.length; i++)
            bufferView[i] = binary.charCodeAt(i);

        blob_builder.append(arrayBuffer);
        length += arrayBuffer.byteLength;

        // Call handler, if present
        if (guac_reader.onprogress)
            guac_reader.onprogress(arrayBuffer.byteLength);

        // Send success response
        stream.sendAck("OK", 0x0000);

    };

    // Simply call onend when end received
    stream.onend = function() {
        if (guac_reader.onend)
            guac_reader.onend();
    };

    /**
     * Returns the current length of this Guacamole.InputStream, in bytes.
     * @return {Number} The current length of this Guacamole.InputStream.
     */
    this.getLength = function() {
        return length;
    };

    /**
     * Returns the contents of this Guacamole.BlobReader as a Blob.
     * @return {Blob} The contents of this Guacamole.BlobReader.
     */
    this.getBlob = function() {
        return blob_builder.getBlob();
    };

    /**
     * Fired once for every blob of data received.
     * 
     * @event
     * @param {Number} length The number of bytes received.
     */
    this.onprogress = null;

    /**
     * Fired once this stream is finished and no further data will be written.
     * @event
     */
    this.onend = null;

};/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A writer which automatically writes to the given output stream with the
 * contents of provided Blob objects.
 *
 * @constructor
 * @param {Guacamole.OutputStream} stream
 *     The stream that data will be written to.
 */
Guacamole.BlobWriter = function BlobWriter(stream) {

    /**
     * Reference to this Guacamole.BlobWriter.
     *
     * @private
     * @type {Guacamole.BlobWriter}
     */
    var guacWriter = this;

    /**
     * Wrapped Guacamole.ArrayBufferWriter which will be used to send any
     * provided file data.
     *
     * @private
     * @type {Guacamole.ArrayBufferWriter}
     */
    var arrayBufferWriter = new Guacamole.ArrayBufferWriter(stream);

    // Initially, simply call onack for acknowledgements
    arrayBufferWriter.onack = function(status) {
        if (guacWriter.onack)
            guacWriter.onack(status);
    };

    /**
     * Browser-independent implementation of Blob.slice() which uses an end
     * offset to determine the span of the resulting slice, rather than a
     * length.
     *
     * @private
     * @param {Blob} blob
     *     The Blob to slice.
     *
     * @param {Number} start
     *     The starting offset of the slice, in bytes, inclusive.
     *
     * @param {Number} end
     *     The ending offset of the slice, in bytes, exclusive.
     *
     * @returns {Blob}
     *     A Blob containing the data within the given Blob starting at
     *     <code>start</code> and ending at <code>end - 1</code>.
     */
    var slice = function slice(blob, start, end) {

        // Use prefixed implementations if necessary
        var sliceImplementation = (
                blob.slice
             || blob.webkitSlice
             || blob.mozSlice
        ).bind(blob);

        var length = end - start;

        // The old Blob.slice() was length-based (not end-based). Try the
        // length version first, if the two calls are not equivalent.
        if (length !== end) {

            // If the result of the slice() call matches the expected length,
            // trust that result. It must be correct.
            var sliceResult = sliceImplementation(start, length);
            if (sliceResult.size === length)
                return sliceResult;

        }

        // Otherwise, use the most-recent standard: end-based slice()
        return sliceImplementation(start, end);

    };

    /**
     * Sends the contents of the given blob over the underlying stream.
     *
     * @param {Blob} blob
     *     The blob to send.
     */
    this.sendBlob = function sendBlob(blob) {

        var offset = 0;
        var reader = new FileReader();

        /**
         * Reads the next chunk of the blob provided to
         * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The chunk itself
         * is read asynchronously, and will not be available until
         * reader.onload fires.
         *
         * @private
         */
        var readNextChunk = function readNextChunk() {

            // If no further chunks remain, inform of completion and stop
            if (offset >= blob.size) {

                // Fire completion event for completed blob
                if (guacWriter.oncomplete)
                    guacWriter.oncomplete(blob);

                // No further chunks to read
                return;

            }

            // Obtain reference to next chunk as a new blob
            var chunk = slice(blob, offset, offset + arrayBufferWriter.blobLength);
            offset += arrayBufferWriter.blobLength;

            // Attempt to read the blob contents represented by the blob into
            // a new array buffer
            reader.readAsArrayBuffer(chunk);

        };

        // Send each chunk over the stream, continue reading the next chunk
        reader.onload = function chunkLoadComplete() {

            // Send the successfully-read chunk
            arrayBufferWriter.sendData(reader.result);

            // Continue sending more chunks after the latest chunk is
            // acknowledged
            arrayBufferWriter.onack = function sendMoreChunks(status) {

                if (guacWriter.onack)
                    guacWriter.onack(status);

                // Abort transfer if an error occurs
                if (status.isError())
                    return;

                // Inform of blob upload progress via progress events
                if (guacWriter.onprogress)
                    guacWriter.onprogress(blob, offset - arrayBufferWriter.blobLength);

                // Queue the next chunk for reading
                readNextChunk();

            };

        };

        // If an error prevents further reading, inform of error and stop
        reader.onerror = function chunkLoadFailed() {

            // Fire error event, including the context of the error
            if (guacWriter.onerror)
                guacWriter.onerror(blob, offset, reader.error);

        };

        // Begin reading the first chunk
        readNextChunk();

    };

    /**
     * Signals that no further text will be sent, effectively closing the
     * stream.
     */
    this.sendEnd = function sendEnd() {
        arrayBufferWriter.sendEnd();
    };

    /**
     * Fired for received data, if acknowledged by the server.
     *
     * @event
     * @param {Guacamole.Status} status
     *     The status of the operation.
     */
    this.onack = null;

    /**
     * Fired when an error occurs reading a blob passed to
     * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The transfer for the
     * the given blob will cease, but the stream will remain open.
     *
     * @event
     * @param {Blob} blob
     *     The blob that was being read when the error occurred.
     *
     * @param {Number} offset
     *     The offset of the failed read attempt within the blob, in bytes.
     *
     * @param {DOMError} error
     *     The error that occurred.
     */
    this.onerror = null;

    /**
     * Fired for each successfully-read chunk of data as a blob is being sent
     * via [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}.
     *
     * @event
     * @param {Blob} blob
     *     The blob that is being read.
     *
     * @param {Number} offset
     *     The offset of the read that just succeeded.
     */
    this.onprogress = null;

    /**
     * Fired when a blob passed to
     * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob} has finished being
     * sent.
     *
     * @event
     * @param {Blob} blob
     *     The blob that was sent.
     */
    this.oncomplete = null;

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Guacamole protocol client. Given a {@link Guacamole.Tunnel},
 * automatically handles incoming and outgoing Guacamole instructions via the
 * provided tunnel, updating its display using one or more canvas elements.
 * 
 * @constructor
 * @param {Guacamole.Tunnel} tunnel The tunnel to use to send and receive
 *                                  Guacamole instructions.
 */
Guacamole.Client = function(tunnel) {

    var guac_client = this;

    var STATE_IDLE          = 0;
    var STATE_CONNECTING    = 1;
    var STATE_WAITING       = 2;
    var STATE_CONNECTED     = 3;
    var STATE_DISCONNECTING = 4;
    var STATE_DISCONNECTED  = 5;

    var currentState = STATE_IDLE;
    
    var currentTimestamp = 0;
    var pingInterval = null;

    /**
     * Translation from Guacamole protocol line caps to Layer line caps.
     * @private
     */
    var lineCap = {
        0: "butt",
        1: "round",
        2: "square"
    };

    /**
     * Translation from Guacamole protocol line caps to Layer line caps.
     * @private
     */
    var lineJoin = {
        0: "bevel",
        1: "miter",
        2: "round"
    };

    /**
     * The underlying Guacamole display.
     *
     * @private
     * @type {Guacamole.Display}
     */
    var display = new Guacamole.Display();

    /**
     * All available layers and buffers
     *
     * @private
     * @type {Object.<Number, (Guacamole.Display.VisibleLayer|Guacamole.Layer)>}
     */
    var layers = {};
    
    /**
     * All audio players currently in use by the client. Initially, this will
     * be empty, but audio players may be allocated by the server upon request.
     *
     * @private
     * @type {Object.<Number, Guacamole.AudioPlayer>}
     */
    var audioPlayers = {};

    /**
     * All video players currently in use by the client. Initially, this will
     * be empty, but video players may be allocated by the server upon request.
     *
     * @private
     * @type {Object.<Number, Guacamole.VideoPlayer>}
     */
    var videoPlayers = {};

    // No initial parsers
    var parsers = [];

    // No initial streams 
    var streams = [];

    /**
     * All current objects. The index of each object is dictated by the
     * Guacamole server.
     *
     * @private
     * @type {Guacamole.Object[]}
     */
    var objects = [];

    // Pool of available stream indices
    var stream_indices = new Guacamole.IntegerPool();

    // Array of allocated output streams by index
    var output_streams = [];

    function setState(state) {
        if (state != currentState) {
            currentState = state;
            if (guac_client.onstatechange)
                guac_client.onstatechange(currentState);
        }
    }

    function isConnected() {
        return currentState == STATE_CONNECTED
            || currentState == STATE_WAITING;
    }

    /**
     * Produces an opaque representation of Guacamole.Client state which can be
     * later imported through a call to importState(). This object is
     * effectively an independent, compressed snapshot of protocol and display
     * state. Invoking this function implicitly flushes the display.
     *
     * @param {function} callback
     *     Callback which should be invoked once the state object is ready. The
     *     state object will be passed to the callback as the sole parameter.
     *     This callback may be invoked immediately, or later as the display
     *     finishes rendering and becomes ready.
     */
    this.exportState = function exportState(callback) {

        // Start with empty state
        var state = {
            'currentState' : currentState,
            'currentTimestamp' : currentTimestamp,
            'layers' : {}
        };

        var layersSnapshot = {};

        // Make a copy of all current layers (protocol state)
        for (var key in layers) {
            layersSnapshot[key] = layers[key];
        }

        // Populate layers once data is available (display state, requires flush)
        display.flush(function populateLayers() {

            // Export each defined layer/buffer
            for (var key in layersSnapshot) {

                var index = parseInt(key);
                var layer = layersSnapshot[key];
                var canvas = layer.toCanvas();

                // Store layer/buffer dimensions
                var exportLayer = {
                    'width'  : layer.width,
                    'height' : layer.height
                };

                // Store layer/buffer image data, if it can be generated
                if (layer.width && layer.height)
                    exportLayer.url = canvas.toDataURL('image/png');

                // Add layer properties if not a buffer nor the default layer
                if (index > 0) {
                    exportLayer.x = layer.x;
                    exportLayer.y = layer.y;
                    exportLayer.z = layer.z;
                    exportLayer.alpha = layer.alpha;
                    exportLayer.matrix = layer.matrix;
                    exportLayer.parent = getLayerIndex(layer.parent);
                }

                // Store exported layer
                state.layers[key] = exportLayer;

            }

            // Invoke callback now that the state is ready
            callback(state);

        });

    };

    /**
     * Restores Guacamole.Client protocol and display state based on an opaque
     * object from a prior call to exportState(). The Guacamole.Client instance
     * used to export that state need not be the same as this instance.
     *
     * @param {Object} state
     *     An opaque representation of Guacamole.Client state from a prior call
     *     to exportState().
     *
     * @param {function} [callback]
     *     The function to invoke when state has finished being imported. This
     *     may happen immediately, or later as images within the provided state
     *     object are loaded.
     */
    this.importState = function importState(state, callback) {

        var key;
        var index;

        currentState = state.currentState;
        currentTimestamp = state.currentTimestamp;

        // Dispose of all layers
        for (key in layers) {
            index = parseInt(key);
            if (index > 0)
                display.dispose(layers[key]);
        }

        layers = {};

        // Import state of each layer/buffer
        for (key in state.layers) {

            index = parseInt(key);

            var importLayer = state.layers[key];
            var layer = getLayer(index);

            // Reset layer size
            display.resize(layer, importLayer.width, importLayer.height);

            // Initialize new layer if it has associated data
            if (importLayer.url) {
                display.setChannelMask(layer, Guacamole.Layer.SRC);
                display.draw(layer, 0, 0, importLayer.url);
            }

            // Set layer-specific properties if not a buffer nor the default layer
            if (index > 0 && importLayer.parent >= 0) {

                // Apply layer position and set parent
                var parent = getLayer(importLayer.parent);
                display.move(layer, parent, importLayer.x, importLayer.y, importLayer.z);

                // Set layer transparency
                display.shade(layer, importLayer.alpha);

                // Apply matrix transform
                var matrix = importLayer.matrix;
                display.distort(layer,
                    matrix[0], matrix[1], matrix[2],
                    matrix[3], matrix[4], matrix[5]);

            }

        }

        // Flush changes to display
        display.flush(callback);

    };

    /**
     * Returns the underlying display of this Guacamole.Client. The display
     * contains an Element which can be added to the DOM, causing the
     * display to become visible.
     * 
     * @return {Guacamole.Display} The underlying display of this
     *                             Guacamole.Client.
     */
    this.getDisplay = function() {
        return display;
    };

    /**
     * Sends the current size of the screen.
     * 
     * @param {Number} width The width of the screen.
     * @param {Number} height The height of the screen.
     */
    this.sendSize = function(width, height) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("size", width, height);

    };

    /**
     * Sends a key event having the given properties as if the user
     * pressed or released a key.
     * 
     * @param {Boolean} pressed Whether the key is pressed (true) or released
     *                          (false).
     * @param {Number} keysym The keysym of the key being pressed or released.
     */
    this.sendKeyEvent = function(pressed, keysym) {
        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("key", keysym, pressed);
    };

    /**
     * Sends a mouse event having the properties provided by the given mouse
     * state.
     * 
     * @param {Guacamole.Mouse.State} mouseState The state of the mouse to send
     *                                           in the mouse event.
     */
    this.sendMouseState = function(mouseState) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        // Update client-side cursor
        display.moveCursor(
            Math.floor(mouseState.x),
            Math.floor(mouseState.y)
        );

        // Build mask
        var buttonMask = 0;
        if (mouseState.left)   buttonMask |= 1;
        if (mouseState.middle) buttonMask |= 2;
        if (mouseState.right)  buttonMask |= 4;
        if (mouseState.up)     buttonMask |= 8;
        if (mouseState.down)   buttonMask |= 16;

        // Send message
        tunnel.sendMessage("mouse", Math.floor(mouseState.x), Math.floor(mouseState.y), buttonMask);
    };

    /**
     * Sets the clipboard of the remote client to the given text data.
     *
     * @deprecated Use createClipboardStream() instead. 
     * @param {String} data The data to send as the clipboard contents.
     */
    this.setClipboard = function(data) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        // Open stream
        var stream = guac_client.createClipboardStream("text/plain");
        var writer = new Guacamole.StringWriter(stream);

        // Send text chunks
        for (var i=0; i<data.length; i += 4096)
            writer.sendText(data.substring(i, i+4096));

        // Close stream
        writer.sendEnd();

    };

    /**
     * Allocates an available stream index and creates a new
     * Guacamole.OutputStream using that index, associating the resulting
     * stream with this Guacamole.Client. Note that this stream will not yet
     * exist as far as the other end of the Guacamole connection is concerned.
     * Streams exist within the Guacamole protocol only when referenced by an
     * instruction which creates the stream, such as a "clipboard", "file", or
     * "pipe" instruction.
     *
     * @returns {Guacamole.OutputStream}
     *     A new Guacamole.OutputStream with a newly-allocated index and
     *     associated with this Guacamole.Client.
     */
    this.createOutputStream = function createOutputStream() {

        // Allocate index
        var index = stream_indices.next();

        // Return new stream
        var stream = output_streams[index] = new Guacamole.OutputStream(guac_client, index);
        return stream;

    };

    /**
     * Opens a new audio stream for writing, where audio data having the give
     * mimetype will be sent along the returned stream. The instruction
     * necessary to create this stream will automatically be sent.
     *
     * @param {String} mimetype
     *     The mimetype of the audio data that will be sent along the returned
     *     stream.
     *
     * @return {Guacamole.OutputStream}
     *     The created audio stream.
     */
    this.createAudioStream = function(mimetype) {

        // Allocate and associate stream with audio metadata
        var stream = guac_client.createOutputStream();
        tunnel.sendMessage("audio", stream.index, mimetype);
        return stream;

    };

    /**
     * Opens a new file for writing, having the given index, mimetype and
     * filename. The instruction necessary to create this stream will
     * automatically be sent.
     *
     * @param {String} mimetype The mimetype of the file being sent.
     * @param {String} filename The filename of the file being sent.
     * @return {Guacamole.OutputStream} The created file stream.
     */
    this.createFileStream = function(mimetype, filename) {

        // Allocate and associate stream with file metadata
        var stream = guac_client.createOutputStream();
        tunnel.sendMessage("file", stream.index, mimetype, filename);
        return stream;

    };

    /**
     * Opens a new pipe for writing, having the given name and mimetype. The
     * instruction necessary to create this stream will automatically be sent.
     *
     * @param {String} mimetype The mimetype of the data being sent.
     * @param {String} name The name of the pipe.
     * @return {Guacamole.OutputStream} The created file stream.
     */
    this.createPipeStream = function(mimetype, name) {

        // Allocate and associate stream with pipe metadata
        var stream = guac_client.createOutputStream();
        tunnel.sendMessage("pipe", stream.index, mimetype, name);
        return stream;

    };

    /**
     * Opens a new clipboard object for writing, having the given mimetype. The
     * instruction necessary to create this stream will automatically be sent.
     *
     * @param {String} mimetype The mimetype of the data being sent.
     * @param {String} name The name of the pipe.
     * @return {Guacamole.OutputStream} The created file stream.
     */
    this.createClipboardStream = function(mimetype) {

        // Allocate and associate stream with clipboard metadata
        var stream = guac_client.createOutputStream();
        tunnel.sendMessage("clipboard", stream.index, mimetype);
        return stream;

    };

    /**
     * Creates a new output stream associated with the given object and having
     * the given mimetype and name. The legality of a mimetype and name is
     * dictated by the object itself. The instruction necessary to create this
     * stream will automatically be sent.
     *
     * @param {Number} index
     *     The index of the object for which the output stream is being
     *     created.
     *
     * @param {String} mimetype
     *     The mimetype of the data which will be sent to the output stream.
     *
     * @param {String} name
     *     The defined name of an output stream within the given object.
     *
     * @returns {Guacamole.OutputStream}
     *     An output stream which will write blobs to the named output stream
     *     of the given object.
     */
    this.createObjectOutputStream = function createObjectOutputStream(index, mimetype, name) {

        // Allocate and ssociate stream with object metadata
        var stream = guac_client.createOutputStream();
        tunnel.sendMessage("put", index, stream.index, mimetype, name);
        return stream;

    };

    /**
     * Requests read access to the input stream having the given name. If
     * successful, a new input stream will be created.
     *
     * @param {Number} index
     *     The index of the object from which the input stream is being
     *     requested.
     *
     * @param {String} name
     *     The name of the input stream to request.
     */
    this.requestObjectInputStream = function requestObjectInputStream(index, name) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("get", index, name);
    };

    /**
     * Acknowledge receipt of a blob on the stream with the given index.
     * 
     * @param {Number} index The index of the stream associated with the
     *                       received blob.
     * @param {String} message A human-readable message describing the error
     *                         or status.
     * @param {Number} code The error code, if any, or 0 for success.
     */
    this.sendAck = function(index, message, code) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("ack", index, message, code);
    };

    /**
     * Given the index of a file, writes a blob of data to that file.
     * 
     * @param {Number} index The index of the file to write to.
     * @param {String} data Base64-encoded data to write to the file.
     */
    this.sendBlob = function(index, data) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("blob", index, data);
    };

    /**
     * Marks a currently-open stream as complete. The other end of the
     * Guacamole connection will be notified via an "end" instruction that the
     * stream is closed, and the index will be made available for reuse in
     * future streams.
     * 
     * @param {Number} index
     *     The index of the stream to end.
     */
    this.endStream = function(index) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        // Explicitly close stream by sending "end" instruction
        tunnel.sendMessage("end", index);

        // Free associated index and stream if they exist
        if (output_streams[index]) {
            stream_indices.free(index);
            delete output_streams[index];
        }

    };

    /**
     * Fired whenever the state of this Guacamole.Client changes.
     * 
     * @event
     * @param {Number} state The new state of the client.
     */
    this.onstatechange = null;

    /**
     * Fired when the remote client sends a name update.
     * 
     * @event
     * @param {String} name The new name of this client.
     */
    this.onname = null;

    /**
     * Fired when an error is reported by the remote client, and the connection
     * is being closed.
     * 
     * @event
     * @param {Guacamole.Status} status A status object which describes the
     *                                  error.
     */
    this.onerror = null;

    /**
     * Fired when a audio stream is created. The stream provided to this event
     * handler will contain its own event handlers for received data.
     *
     * @event
     * @param {Guacamole.InputStream} stream
     *     The stream that will receive audio data from the server.
     *
     * @param {String} mimetype
     *     The mimetype of the audio data which will be received.
     *
     * @return {Guacamole.AudioPlayer}
     *     An object which implements the Guacamole.AudioPlayer interface and
     *     has been initialied to play the data in the provided stream, or null
     *     if the built-in audio players of the Guacamole client should be
     *     used.
     */
    this.onaudio = null;

    /**
     * Fired when a video stream is created. The stream provided to this event
     * handler will contain its own event handlers for received data.
     *
     * @event
     * @param {Guacamole.InputStream} stream
     *     The stream that will receive video data from the server.
     *
     * @param {Guacamole.Display.VisibleLayer} layer
     *     The destination layer on which the received video data should be
     *     played. It is the responsibility of the Guacamole.VideoPlayer
     *     implementation to play the received data within this layer.
     *
     * @param {String} mimetype
     *     The mimetype of the video data which will be received.
     *
     * @return {Guacamole.VideoPlayer}
     *     An object which implements the Guacamole.VideoPlayer interface and
     *     has been initialied to play the data in the provided stream, or null
     *     if the built-in video players of the Guacamole client should be
     *     used.
     */
    this.onvideo = null;

    /**
     * Fired when the clipboard of the remote client is changing.
     * 
     * @event
     * @param {Guacamole.InputStream} stream The stream that will receive
     *                                       clipboard data from the server.
     * @param {String} mimetype The mimetype of the data which will be received.
     */
    this.onclipboard = null;

    /**
     * Fired when a file stream is created. The stream provided to this event
     * handler will contain its own event handlers for received data.
     * 
     * @event
     * @param {Guacamole.InputStream} stream The stream that will receive data
     *                                       from the server.
     * @param {String} mimetype The mimetype of the file received.
     * @param {String} filename The name of the file received.
     */
    this.onfile = null;

    /**
     * Fired when a filesystem object is created. The object provided to this
     * event handler will contain its own event handlers and functions for
     * requesting and handling data.
     *
     * @event
     * @param {Guacamole.Object} object
     *     The created filesystem object.
     *
     * @param {String} name
     *     The name of the filesystem.
     */
    this.onfilesystem = null;

    /**
     * Fired when a pipe stream is created. The stream provided to this event
     * handler will contain its own event handlers for received data;
     * 
     * @event
     * @param {Guacamole.InputStream} stream The stream that will receive data
     *                                       from the server.
     * @param {String} mimetype The mimetype of the data which will be received.
     * @param {String} name The name of the pipe.
     */
    this.onpipe = null;

    /**
     * Fired whenever a sync instruction is received from the server, indicating
     * that the server is finished processing any input from the client and
     * has sent any results.
     * 
     * @event
     * @param {Number} timestamp The timestamp associated with the sync
     *                           instruction.
     */
    this.onsync = null;

    /**
     * Returns the layer with the given index, creating it if necessary.
     * Positive indices refer to visible layers, an index of zero refers to
     * the default layer, and negative indices refer to buffers.
     *
     * @private
     * @param {Number} index
     *     The index of the layer to retrieve.
     *
     * @return {Guacamole.Display.VisibleLayer|Guacamole.Layer}
     *     The layer having the given index.
     */
    var getLayer = function getLayer(index) {

        // Get layer, create if necessary
        var layer = layers[index];
        if (!layer) {

            // Create layer based on index
            if (index === 0)
                layer = display.getDefaultLayer();
            else if (index > 0)
                layer = display.createLayer();
            else
                layer = display.createBuffer();
                
            // Add new layer
            layers[index] = layer;

        }

        return layer;

    };

    /**
     * Returns the index passed to getLayer() when the given layer was created.
     * Positive indices refer to visible layers, an index of zero refers to the
     * default layer, and negative indices refer to buffers.
     *
     * @param {Guacamole.Display.VisibleLayer|Guacamole.Layer} layer
     *     The layer whose index should be determined.
     *
     * @returns {Number}
     *     The index of the given layer, or null if no such layer is associated
     *     with this client.
     */
    var getLayerIndex = function getLayerIndex(layer) {

        // Avoid searching if there clearly is no such layer
        if (!layer)
            return null;

        // Search through each layer, returning the index of the given layer
        // once found
        for (var key in layers) {
            if (layer === layers[key])
                return parseInt(key);
        }

        // Otherwise, no such index
        return null;

    };

    function getParser(index) {

        var parser = parsers[index];

        // If parser not yet created, create it, and tie to the
        // oninstruction handler of the tunnel.
        if (parser == null) {
            parser = parsers[index] = new Guacamole.Parser();
            parser.oninstruction = tunnel.oninstruction;
        }

        return parser;

    }

    /**
     * Handlers for all defined layer properties.
     * @private
     */
    var layerPropertyHandlers = {

        "miter-limit": function(layer, value) {
            display.setMiterLimit(layer, parseFloat(value));
        }

    };
    
    /**
     * Handlers for all instruction opcodes receivable by a Guacamole protocol
     * client.
     * @private
     */
    var instructionHandlers = {

        "ack": function(parameters) {

            var stream_index = parseInt(parameters[0]);
            var reason = parameters[1];
            var code = parseInt(parameters[2]);

            // Get stream
            var stream = output_streams[stream_index];
            if (stream) {

                // Signal ack if handler defined
                if (stream.onack)
                    stream.onack(new Guacamole.Status(code, reason));

                // If code is an error, invalidate stream if not already
                // invalidated by onack handler
                if (code >= 0x0100 && output_streams[stream_index] === stream) {
                    stream_indices.free(stream_index);
                    delete output_streams[stream_index];
                }

            }

        },

        "arc": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var x = parseInt(parameters[1]);
            var y = parseInt(parameters[2]);
            var radius = parseInt(parameters[3]);
            var startAngle = parseFloat(parameters[4]);
            var endAngle = parseFloat(parameters[5]);
            var negative = parseInt(parameters[6]);

            display.arc(layer, x, y, radius, startAngle, endAngle, negative != 0);

        },

        "audio": function(parameters) {

            var stream_index = parseInt(parameters[0]);
            var mimetype = parameters[1];

            // Create stream 
            var stream = streams[stream_index] =
                    new Guacamole.InputStream(guac_client, stream_index);

            // Get player instance via callback
            var audioPlayer = null;
            if (guac_client.onaudio)
                audioPlayer = guac_client.onaudio(stream, mimetype);

            // If unsuccessful, try to use a default implementation
            if (!audioPlayer)
                audioPlayer = Guacamole.AudioPlayer.getInstance(stream, mimetype);

            // If we have successfully retrieved an audio player, send success response
            if (audioPlayer) {
                audioPlayers[stream_index] = audioPlayer;
                guac_client.sendAck(stream_index, "OK", 0x0000);
            }

            // Otherwise, mimetype must be unsupported
            else
                guac_client.sendAck(stream_index, "BAD TYPE", 0x030F);

        },

        "blob": function(parameters) {

            // Get stream 
            var stream_index = parseInt(parameters[0]);
            var data = parameters[1];
            var stream = streams[stream_index];

            // Write data
            if (stream && stream.onblob)
                stream.onblob(data);

        },

        "body" : function handleBody(parameters) {

            // Get object
            var objectIndex = parseInt(parameters[0]);
            var object = objects[objectIndex];

            var streamIndex = parseInt(parameters[1]);
            var mimetype = parameters[2];
            var name = parameters[3];

            // Create stream if handler defined
            if (object && object.onbody) {
                var stream = streams[streamIndex] = new Guacamole.InputStream(guac_client, streamIndex);
                object.onbody(stream, mimetype, name);
            }

            // Otherwise, unsupported
            else
                guac_client.sendAck(streamIndex, "Receipt of body unsupported", 0x0100);

        },

        "cfill": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var r = parseInt(parameters[2]);
            var g = parseInt(parameters[3]);
            var b = parseInt(parameters[4]);
            var a = parseInt(parameters[5]);

            display.setChannelMask(layer, channelMask);
            display.fillColor(layer, r, g, b, a);

        },

        "clip": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));

            display.clip(layer);

        },

        "clipboard": function(parameters) {

            var stream_index = parseInt(parameters[0]);
            var mimetype = parameters[1];

            // Create stream 
            if (guac_client.onclipboard) {
                var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
                guac_client.onclipboard(stream, mimetype);
            }

            // Otherwise, unsupported
            else
                guac_client.sendAck(stream_index, "Clipboard unsupported", 0x0100);

        },

        "close": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));

            display.close(layer);

        },

        "copy": function(parameters) {

            var srcL = getLayer(parseInt(parameters[0]));
            var srcX = parseInt(parameters[1]);
            var srcY = parseInt(parameters[2]);
            var srcWidth = parseInt(parameters[3]);
            var srcHeight = parseInt(parameters[4]);
            var channelMask = parseInt(parameters[5]);
            var dstL = getLayer(parseInt(parameters[6]));
            var dstX = parseInt(parameters[7]);
            var dstY = parseInt(parameters[8]);

            display.setChannelMask(dstL, channelMask);
            display.copy(srcL, srcX, srcY, srcWidth, srcHeight, 
                         dstL, dstX, dstY);

        },

        "cstroke": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var cap = lineCap[parseInt(parameters[2])];
            var join = lineJoin[parseInt(parameters[3])];
            var thickness = parseInt(parameters[4]);
            var r = parseInt(parameters[5]);
            var g = parseInt(parameters[6]);
            var b = parseInt(parameters[7]);
            var a = parseInt(parameters[8]);

            display.setChannelMask(layer, channelMask);
            display.strokeColor(layer, cap, join, thickness, r, g, b, a);

        },

        "cursor": function(parameters) {

            var cursorHotspotX = parseInt(parameters[0]);
            var cursorHotspotY = parseInt(parameters[1]);
            var srcL = getLayer(parseInt(parameters[2]));
            var srcX = parseInt(parameters[3]);
            var srcY = parseInt(parameters[4]);
            var srcWidth = parseInt(parameters[5]);
            var srcHeight = parseInt(parameters[6]);

            display.setCursor(cursorHotspotX, cursorHotspotY,
                              srcL, srcX, srcY, srcWidth, srcHeight);

        },

        "curve": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var cp1x = parseInt(parameters[1]);
            var cp1y = parseInt(parameters[2]);
            var cp2x = parseInt(parameters[3]);
            var cp2y = parseInt(parameters[4]);
            var x = parseInt(parameters[5]);
            var y = parseInt(parameters[6]);

            display.curveTo(layer, cp1x, cp1y, cp2x, cp2y, x, y);

        },

        "disconnect" : function handleDisconnect(parameters) {

            // Explicitly tear down connection
            guac_client.disconnect();

        },

        "dispose": function(parameters) {
            
            var layer_index = parseInt(parameters[0]);

            // If visible layer, remove from parent
            if (layer_index > 0) {

                // Remove from parent
                var layer = getLayer(layer_index);
                display.dispose(layer);

                // Delete reference
                delete layers[layer_index];

            }

            // If buffer, just delete reference
            else if (layer_index < 0)
                delete layers[layer_index];

            // Attempting to dispose the root layer currently has no effect.

        },

        "distort": function(parameters) {

            var layer_index = parseInt(parameters[0]);
            var a = parseFloat(parameters[1]);
            var b = parseFloat(parameters[2]);
            var c = parseFloat(parameters[3]);
            var d = parseFloat(parameters[4]);
            var e = parseFloat(parameters[5]);
            var f = parseFloat(parameters[6]);

            // Only valid for visible layers (not buffers)
            if (layer_index >= 0) {
                var layer = getLayer(layer_index);
                display.distort(layer, a, b, c, d, e, f);
            }

        },
 
        "error": function(parameters) {

            var reason = parameters[0];
            var code = parseInt(parameters[1]);

            // Call handler if defined
            if (guac_client.onerror)
                guac_client.onerror(new Guacamole.Status(code, reason));

            guac_client.disconnect();

        },

        "end": function(parameters) {

            var stream_index = parseInt(parameters[0]);

            // Get stream
            var stream = streams[stream_index];
            if (stream) {

                // Signal end of stream if handler defined
                if (stream.onend)
                    stream.onend();

                // Invalidate stream
                delete streams[stream_index];

            }

        },

        "file": function(parameters) {

            var stream_index = parseInt(parameters[0]);
            var mimetype = parameters[1];
            var filename = parameters[2];

            // Create stream 
            if (guac_client.onfile) {
                var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
                guac_client.onfile(stream, mimetype, filename);
            }

            // Otherwise, unsupported
            else
                guac_client.sendAck(stream_index, "File transfer unsupported", 0x0100);

        },

        "filesystem" : function handleFilesystem(parameters) {

            var objectIndex = parseInt(parameters[0]);
            var name = parameters[1];

            // Create object, if supported
            if (guac_client.onfilesystem) {
                var object = objects[objectIndex] = new Guacamole.Object(guac_client, objectIndex);
                guac_client.onfilesystem(object, name);
            }

            // If unsupported, simply ignore the availability of the filesystem

        },

        "identity": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));

            display.setTransform(layer, 1, 0, 0, 1, 0, 0);

        },

        "img": function(parameters) {

            var stream_index = parseInt(parameters[0]);
            var channelMask = parseInt(parameters[1]);
            var layer = getLayer(parseInt(parameters[2]));
            var mimetype = parameters[3];
            var x = parseInt(parameters[4]);
            var y = parseInt(parameters[5]);

            // Create stream
            var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
            var reader = new Guacamole.DataURIReader(stream, mimetype);

            // Draw image when stream is complete
            reader.onend = function drawImageBlob() {
                display.setChannelMask(layer, channelMask);
                display.draw(layer, x, y, reader.getURI());
            };

        },

        "jpeg": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var x = parseInt(parameters[2]);
            var y = parseInt(parameters[3]);
            var data = parameters[4];

            display.setChannelMask(layer, channelMask);
            display.draw(layer, x, y, "data:image/jpeg;base64," + data);

        },

        "lfill": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var srcLayer = getLayer(parseInt(parameters[2]));

            display.setChannelMask(layer, channelMask);
            display.fillLayer(layer, srcLayer);

        },

        "line": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var x = parseInt(parameters[1]);
            var y = parseInt(parameters[2]);

            display.lineTo(layer, x, y);

        },

        "lstroke": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var srcLayer = getLayer(parseInt(parameters[2]));

            display.setChannelMask(layer, channelMask);
            display.strokeLayer(layer, srcLayer);

        },

        "mouse" : function handleMouse(parameters) {

            var x = parseInt(parameters[0]);
            var y = parseInt(parameters[1]);

            // Display and move software cursor to received coordinates
            display.showCursor(true);
            display.moveCursor(x, y);

        },

        "move": function(parameters) {
            
            var layer_index = parseInt(parameters[0]);
            var parent_index = parseInt(parameters[1]);
            var x = parseInt(parameters[2]);
            var y = parseInt(parameters[3]);
            var z = parseInt(parameters[4]);

            // Only valid for non-default layers
            if (layer_index > 0 && parent_index >= 0) {
                var layer = getLayer(layer_index);
                var parent = getLayer(parent_index);
                display.move(layer, parent, x, y, z);
            }

        },

        "name": function(parameters) {
            if (guac_client.onname) guac_client.onname(parameters[0]);
        },

        "nest": function(parameters) {
            var parser = getParser(parseInt(parameters[0]));
            parser.receive(parameters[1]);
        },

        "pipe": function(parameters) {

            var stream_index = parseInt(parameters[0]);
            var mimetype = parameters[1];
            var name = parameters[2];

            // Create stream 
            if (guac_client.onpipe) {
                var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
                guac_client.onpipe(stream, mimetype, name);
            }

            // Otherwise, unsupported
            else
                guac_client.sendAck(stream_index, "Named pipes unsupported", 0x0100);

        },

        "png": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var x = parseInt(parameters[2]);
            var y = parseInt(parameters[3]);
            var data = parameters[4];

            display.setChannelMask(layer, channelMask);
            display.draw(layer, x, y, "data:image/png;base64," + data);

        },

        "pop": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));

            display.pop(layer);

        },

        "push": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));

            display.push(layer);

        },
 
        "rect": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var x = parseInt(parameters[1]);
            var y = parseInt(parameters[2]);
            var w = parseInt(parameters[3]);
            var h = parseInt(parameters[4]);

            display.rect(layer, x, y, w, h);

        },
        
        "reset": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));

            display.reset(layer);

        },
        
        "set": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var name = parameters[1];
            var value = parameters[2];

            // Call property handler if defined
            var handler = layerPropertyHandlers[name];
            if (handler)
                handler(layer, value);

        },

        "shade": function(parameters) {
            
            var layer_index = parseInt(parameters[0]);
            var a = parseInt(parameters[1]);

            // Only valid for visible layers (not buffers)
            if (layer_index >= 0) {
                var layer = getLayer(layer_index);
                display.shade(layer, a);
            }

        },

        "size": function(parameters) {

            var layer_index = parseInt(parameters[0]);
            var layer = getLayer(layer_index);
            var width = parseInt(parameters[1]);
            var height = parseInt(parameters[2]);

            display.resize(layer, width, height);

        },
        
        "start": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var x = parseInt(parameters[1]);
            var y = parseInt(parameters[2]);

            display.moveTo(layer, x, y);

        },

        "sync": function(parameters) {

            var timestamp = parseInt(parameters[0]);

            // Flush display, send sync when done
            display.flush(function displaySyncComplete() {

                // Synchronize all audio players
                for (var index in audioPlayers) {
                    var audioPlayer = audioPlayers[index];
                    if (audioPlayer)
                        audioPlayer.sync();
                }

                // Send sync response to server
                if (timestamp !== currentTimestamp) {
                    tunnel.sendMessage("sync", timestamp);
                    currentTimestamp = timestamp;
                }

            });

            // If received first update, no longer waiting.
            if (currentState === STATE_WAITING)
                setState(STATE_CONNECTED);

            // Call sync handler if defined
            if (guac_client.onsync)
                guac_client.onsync(timestamp);

        },

        "transfer": function(parameters) {

            var srcL = getLayer(parseInt(parameters[0]));
            var srcX = parseInt(parameters[1]);
            var srcY = parseInt(parameters[2]);
            var srcWidth = parseInt(parameters[3]);
            var srcHeight = parseInt(parameters[4]);
            var function_index = parseInt(parameters[5]);
            var dstL = getLayer(parseInt(parameters[6]));
            var dstX = parseInt(parameters[7]);
            var dstY = parseInt(parameters[8]);

            /* SRC */
            if (function_index === 0x3)
                display.put(srcL, srcX, srcY, srcWidth, srcHeight, 
                    dstL, dstX, dstY);

            /* Anything else that isn't a NO-OP */
            else if (function_index !== 0x5)
                display.transfer(srcL, srcX, srcY, srcWidth, srcHeight, 
                    dstL, dstX, dstY, Guacamole.Client.DefaultTransferFunction[function_index]);

        },

        "transform": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var a = parseFloat(parameters[1]);
            var b = parseFloat(parameters[2]);
            var c = parseFloat(parameters[3]);
            var d = parseFloat(parameters[4]);
            var e = parseFloat(parameters[5]);
            var f = parseFloat(parameters[6]);

            display.transform(layer, a, b, c, d, e, f);

        },

        "undefine" : function handleUndefine(parameters) {

            // Get object
            var objectIndex = parseInt(parameters[0]);
            var object = objects[objectIndex];

            // Signal end of object definition
            if (object && object.onundefine)
                object.onundefine();

        },

        "video": function(parameters) {

            var stream_index = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var mimetype = parameters[2];

            // Create stream
            var stream = streams[stream_index] =
                    new Guacamole.InputStream(guac_client, stream_index);

            // Get player instance via callback
            var videoPlayer = null;
            if (guac_client.onvideo)
                videoPlayer = guac_client.onvideo(stream, layer, mimetype);

            // If unsuccessful, try to use a default implementation
            if (!videoPlayer)
                videoPlayer = Guacamole.VideoPlayer.getInstance(stream, layer, mimetype);

            // If we have successfully retrieved an video player, send success response
            if (videoPlayer) {
                videoPlayers[stream_index] = videoPlayer;
                guac_client.sendAck(stream_index, "OK", 0x0000);
            }

            // Otherwise, mimetype must be unsupported
            else
                guac_client.sendAck(stream_index, "BAD TYPE", 0x030F);

        }

    };

    tunnel.oninstruction = function(opcode, parameters) {

        var handler = instructionHandlers[opcode];
        if (handler)
            handler(parameters);

    };

    /**
     * Sends a disconnect instruction to the server and closes the tunnel.
     */
    this.disconnect = function() {

        // Only attempt disconnection not disconnected.
        if (currentState != STATE_DISCONNECTED
                && currentState != STATE_DISCONNECTING) {

            setState(STATE_DISCONNECTING);

            // Stop ping
            if (pingInterval)
                window.clearInterval(pingInterval);

            // Send disconnect message and disconnect
            tunnel.sendMessage("disconnect");
            tunnel.disconnect();
            setState(STATE_DISCONNECTED);

        }

    };
    
    /**
     * Connects the underlying tunnel of this Guacamole.Client, passing the
     * given arbitrary data to the tunnel during the connection process.
     *
     * @param data Arbitrary connection data to be sent to the underlying
     *             tunnel during the connection process.
     * @throws {Guacamole.Status} If an error occurs during connection.
     */
    this.connect = function(data) {

        setState(STATE_CONNECTING);

        try {
            tunnel.connect(data);
        }
        catch (status) {
            setState(STATE_IDLE);
            throw status;
        }

        // Ping every 5 seconds (ensure connection alive)
        pingInterval = window.setInterval(function() {
            tunnel.sendMessage("nop");
        }, 5000);

        setState(STATE_WAITING);
    };

};

/**
 * Map of all Guacamole binary raster operations to transfer functions.
 * @private
 */
Guacamole.Client.DefaultTransferFunction = {

    /* BLACK */
    0x0: function (src, dst) {
        dst.red = dst.green = dst.blue = 0x00;
    },

    /* WHITE */
    0xF: function (src, dst) {
        dst.red = dst.green = dst.blue = 0xFF;
    },

    /* SRC */
    0x3: function (src, dst) {
        dst.red   = src.red;
        dst.green = src.green;
        dst.blue  = src.blue;
        dst.alpha = src.alpha;
    },

    /* DEST (no-op) */
    0x5: function (src, dst) {
        // Do nothing
    },

    /* Invert SRC */
    0xC: function (src, dst) {
        dst.red   = 0xFF & ~src.red;
        dst.green = 0xFF & ~src.green;
        dst.blue  = 0xFF & ~src.blue;
        dst.alpha =  src.alpha;
    },
    
    /* Invert DEST */
    0xA: function (src, dst) {
        dst.red   = 0xFF & ~dst.red;
        dst.green = 0xFF & ~dst.green;
        dst.blue  = 0xFF & ~dst.blue;
    },

    /* AND */
    0x1: function (src, dst) {
        dst.red   =  ( src.red   &  dst.red);
        dst.green =  ( src.green &  dst.green);
        dst.blue  =  ( src.blue  &  dst.blue);
    },

    /* NAND */
    0xE: function (src, dst) {
        dst.red   = 0xFF & ~( src.red   &  dst.red);
        dst.green = 0xFF & ~( src.green &  dst.green);
        dst.blue  = 0xFF & ~( src.blue  &  dst.blue);
    },

    /* OR */
    0x7: function (src, dst) {
        dst.red   =  ( src.red   |  dst.red);
        dst.green =  ( src.green |  dst.green);
        dst.blue  =  ( src.blue  |  dst.blue);
    },

    /* NOR */
    0x8: function (src, dst) {
        dst.red   = 0xFF & ~( src.red   |  dst.red);
        dst.green = 0xFF & ~( src.green |  dst.green);
        dst.blue  = 0xFF & ~( src.blue  |  dst.blue);
    },

    /* XOR */
    0x6: function (src, dst) {
        dst.red   =  ( src.red   ^  dst.red);
        dst.green =  ( src.green ^  dst.green);
        dst.blue  =  ( src.blue  ^  dst.blue);
    },

    /* XNOR */
    0x9: function (src, dst) {
        dst.red   = 0xFF & ~( src.red   ^  dst.red);
        dst.green = 0xFF & ~( src.green ^  dst.green);
        dst.blue  = 0xFF & ~( src.blue  ^  dst.blue);
    },

    /* AND inverted source */
    0x4: function (src, dst) {
        dst.red   =  0xFF & (~src.red   &  dst.red);
        dst.green =  0xFF & (~src.green &  dst.green);
        dst.blue  =  0xFF & (~src.blue  &  dst.blue);
    },

    /* OR inverted source */
    0xD: function (src, dst) {
        dst.red   =  0xFF & (~src.red   |  dst.red);
        dst.green =  0xFF & (~src.green |  dst.green);
        dst.blue  =  0xFF & (~src.blue  |  dst.blue);
    },

    /* AND inverted destination */
    0x2: function (src, dst) {
        dst.red   =  0xFF & ( src.red   & ~dst.red);
        dst.green =  0xFF & ( src.green & ~dst.green);
        dst.blue  =  0xFF & ( src.blue  & ~dst.blue);
    },

    /* OR inverted destination */
    0xB: function (src, dst) {
        dst.red   =  0xFF & ( src.red   | ~dst.red);
        dst.green =  0xFF & ( src.green | ~dst.green);
        dst.blue  =  0xFF & ( src.blue  | ~dst.blue);
    }

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A reader which automatically handles the given input stream, returning
 * received blobs as a single data URI built over the course of the stream.
 * Note that this object will overwrite any installed event handlers on the
 * given Guacamole.InputStream.
 * 
 * @constructor
 * @param {Guacamole.InputStream} stream
 *     The stream that data will be read from.
 */
Guacamole.DataURIReader = function(stream, mimetype) {

    /**
     * Reference to this Guacamole.DataURIReader.
     * @private
     */
    var guac_reader = this;

    /**
     * Current data URI.
     *
     * @private
     * @type {String}
     */
    var uri = 'data:' + mimetype + ';base64,';

    // Receive blobs as array buffers
    stream.onblob = function dataURIReaderBlob(data) {

        // Currently assuming data will ALWAYS be safe to simply append. This
        // will not be true if the received base64 data encodes a number of
        // bytes that isn't a multiple of three (as base64 expands in a ratio
        // of exactly 3:4).
        uri += data;

    };

    // Simply call onend when end received
    stream.onend = function dataURIReaderEnd() {
        if (guac_reader.onend)
            guac_reader.onend();
    };

    /**
     * Returns the data URI of all data received through the underlying stream
     * thus far.
     *
     * @returns {String}
     *     The data URI of all data received through the underlying stream thus
     *     far.
     */
    this.getURI = function getURI() {
        return uri;
    };

    /**
     * Fired once this stream is finished and no further data will be written.
     *
     * @event
     */
    this.onend = null;

};/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * The Guacamole display. The display does not deal with the Guacamole
 * protocol, and instead implements a set of graphical operations which
 * embody the set of operations present in the protocol. The order operations
 * are executed is guaranteed to be in the same order as their corresponding
 * functions are called.
 * 
 * @constructor
 */
Guacamole.Display = function() {

    /**
     * Reference to this Guacamole.Display.
     * @private
     */
    var guac_display = this;

    var displayWidth = 0;
    var displayHeight = 0;
    var displayScale = 1;

    // Create display
    var display = document.createElement("div");
    display.style.position = "relative";
    display.style.width = displayWidth + "px";
    display.style.height = displayHeight + "px";

    // Ensure transformations on display originate at 0,0
    display.style.transformOrigin =
    display.style.webkitTransformOrigin =
    display.style.MozTransformOrigin =
    display.style.OTransformOrigin =
    display.style.msTransformOrigin =
        "0 0";

    // Create default layer
    var default_layer = new Guacamole.Display.VisibleLayer(displayWidth, displayHeight);

    // Create cursor layer
    var cursor = new Guacamole.Display.VisibleLayer(0, 0);
    cursor.setChannelMask(Guacamole.Layer.SRC);

    // Add default layer and cursor to display
    display.appendChild(default_layer.getElement());
    display.appendChild(cursor.getElement());

    // Create bounding div 
    var bounds = document.createElement("div");
    bounds.style.position = "relative";
    bounds.style.width = (displayWidth*displayScale) + "px";
    bounds.style.height = (displayHeight*displayScale) + "px";

    // Add display to bounds
    bounds.appendChild(display);

    /**
     * The X coordinate of the hotspot of the mouse cursor. The hotspot is
     * the relative location within the image of the mouse cursor at which
     * each click occurs.
     * 
     * @type {Number}
     */
    this.cursorHotspotX = 0;

    /**
     * The Y coordinate of the hotspot of the mouse cursor. The hotspot is
     * the relative location within the image of the mouse cursor at which
     * each click occurs.
     * 
     * @type {Number}
     */
    this.cursorHotspotY = 0;

    /**
     * The current X coordinate of the local mouse cursor. This is not
     * necessarily the location of the actual mouse - it refers only to
     * the location of the cursor image within the Guacamole display, as
     * last set by moveCursor().
     * 
     * @type {Number}
     */
    this.cursorX = 0;

    /**
     * The current X coordinate of the local mouse cursor. This is not
     * necessarily the location of the actual mouse - it refers only to
     * the location of the cursor image within the Guacamole display, as
     * last set by moveCursor().
     * 
     * @type {Number}
     */
    this.cursorY = 0;

    /**
     * Fired when the default layer (and thus the entire Guacamole display)
     * is resized.
     * 
     * @event
     * @param {Number} width The new width of the Guacamole display.
     * @param {Number} height The new height of the Guacamole display.
     */
    this.onresize = null;

    /**
     * Fired whenever the local cursor image is changed. This can be used to
     * implement special handling of the client-side cursor, or to override
     * the default use of a software cursor layer.
     * 
     * @event
     * @param {HTMLCanvasElement} canvas The cursor image.
     * @param {Number} x The X-coordinate of the cursor hotspot.
     * @param {Number} y The Y-coordinate of the cursor hotspot.
     */
    this.oncursor = null;

    /**
     * The queue of all pending Tasks. Tasks will be run in order, with new
     * tasks added at the end of the queue and old tasks removed from the
     * front of the queue (FIFO). These tasks will eventually be grouped
     * into a Frame.
     * @private
     * @type {Task[]}
     */
    var tasks = [];

    /**
     * The queue of all frames. Each frame is a pairing of an array of tasks
     * and a callback which must be called when the frame is rendered.
     * @private
     * @type {Frame[]}
     */
    var frames = [];

    /**
     * Flushes all pending frames.
     * @private
     */
    function __flush_frames() {

        var rendered_frames = 0;

        // Draw all pending frames, if ready
        while (rendered_frames < frames.length) {

            var frame = frames[rendered_frames];
            if (!frame.isReady())
                break;

            frame.flush();
            rendered_frames++;

        } 

        // Remove rendered frames from array
        frames.splice(0, rendered_frames);

    }

    /**
     * An ordered list of tasks which must be executed atomically. Once
     * executed, an associated (and optional) callback will be called.
     *
     * @private
     * @constructor
     * @param {function} callback The function to call when this frame is
     *                            rendered.
     * @param {Task[]} tasks The set of tasks which must be executed to render
     *                       this frame.
     */
    function Frame(callback, tasks) {

        /**
         * Returns whether this frame is ready to be rendered. This function
         * returns true if and only if ALL underlying tasks are unblocked.
         * 
         * @returns {Boolean} true if all underlying tasks are unblocked,
         *                    false otherwise.
         */
        this.isReady = function() {

            // Search for blocked tasks
            for (var i=0; i < tasks.length; i++) {
                if (tasks[i].blocked)
                    return false;
            }

            // If no blocked tasks, the frame is ready
            return true;

        };

        /**
         * Renders this frame, calling the associated callback, if any, after
         * the frame is complete. This function MUST only be called when no
         * blocked tasks exist. Calling this function with blocked tasks
         * will result in undefined behavior.
         */
        this.flush = function() {

            // Draw all pending tasks.
            for (var i=0; i < tasks.length; i++)
                tasks[i].execute();

            // Call callback
            if (callback) callback();

        };

    }

    /**
     * A container for an task handler. Each operation which must be ordered
     * is associated with a Task that goes into a task queue. Tasks in this
     * queue are executed in order once their handlers are set, while Tasks 
     * without handlers block themselves and any following Tasks from running.
     *
     * @constructor
     * @private
     * @param {function} taskHandler The function to call when this task 
     *                               runs, if any.
     * @param {boolean} blocked Whether this task should start blocked.
     */
    function Task(taskHandler, blocked) {
       
        var task = this;
       
        /**
         * Whether this Task is blocked.
         * 
         * @type {boolean}
         */
        this.blocked = blocked;

        /**
         * Unblocks this Task, allowing it to run.
         */
        this.unblock = function() {
            if (task.blocked) {
                task.blocked = false;
                __flush_frames();
            }
        };

        /**
         * Calls the handler associated with this task IMMEDIATELY. This
         * function does not track whether this task is marked as blocked.
         * Enforcing the blocked status of tasks is up to the caller.
         */
        this.execute = function() {
            if (taskHandler) taskHandler();
        };

    }

    /**
     * Schedules a task for future execution. The given handler will execute
     * immediately after all previous tasks upon frame flush, unless this
     * task is blocked. If any tasks is blocked, the entire frame will not
     * render (and no tasks within will execute) until all tasks are unblocked.
     * 
     * @private
     * @param {function} handler The function to call when possible, if any.
     * @param {boolean} blocked Whether the task should start blocked.
     * @returns {Task} The Task created and added to the queue for future
     *                 running.
     */
    function scheduleTask(handler, blocked) {
        var task = new Task(handler, blocked);
        tasks.push(task);
        return task;
    }

    /**
     * Returns the element which contains the Guacamole display.
     * 
     * @return {Element} The element containing the Guacamole display.
     */
    this.getElement = function() {
        return bounds;
    };

    /**
     * Returns the width of this display.
     * 
     * @return {Number} The width of this display;
     */
    this.getWidth = function() {
        return displayWidth;
    };

    /**
     * Returns the height of this display.
     * 
     * @return {Number} The height of this display;
     */
    this.getHeight = function() {
        return displayHeight;
    };

    /**
     * Returns the default layer of this display. Each Guacamole display always
     * has at least one layer. Other layers can optionally be created within
     * this layer, but the default layer cannot be removed and is the absolute
     * ancestor of all other layers.
     * 
     * @return {Guacamole.Display.VisibleLayer} The default layer.
     */
    this.getDefaultLayer = function() {
        return default_layer;
    };

    /**
     * Returns the cursor layer of this display. Each Guacamole display contains
     * a layer for the image of the mouse cursor. This layer is a special case
     * and exists above all other layers, similar to the hardware mouse cursor.
     * 
     * @return {Guacamole.Display.VisibleLayer} The cursor layer.
     */
    this.getCursorLayer = function() {
        return cursor;
    };

    /**
     * Creates a new layer. The new layer will be a direct child of the default
     * layer, but can be moved to be a child of any other layer. Layers returned
     * by this function are visible.
     * 
     * @return {Guacamole.Display.VisibleLayer} The newly-created layer.
     */
    this.createLayer = function() {
        var layer = new Guacamole.Display.VisibleLayer(displayWidth, displayHeight);
        layer.move(default_layer, 0, 0, 0);
        return layer;
    };

    /**
     * Creates a new buffer. Buffers are invisible, off-screen surfaces. They
     * are implemented in the same manner as layers, but do not provide the
     * same nesting semantics.
     * 
     * @return {Guacamole.Layer} The newly-created buffer.
     */
    this.createBuffer = function() {
        var buffer = new Guacamole.Layer(0, 0);
        buffer.autosize = 1;
        return buffer;
    };

    /**
     * Flush all pending draw tasks, if possible, as a new frame. If the entire
     * frame is not ready, the flush will wait until all required tasks are
     * unblocked.
     * 
     * @param {function} callback The function to call when this frame is
     *                            flushed. This may happen immediately, or
     *                            later when blocked tasks become unblocked.
     */
    this.flush = function(callback) {

        // Add frame, reset tasks
        frames.push(new Frame(callback, tasks));
        tasks = [];

        // Attempt flush
        __flush_frames();

    };

    /**
     * Sets the hotspot and image of the mouse cursor displayed within the
     * Guacamole display.
     * 
     * @param {Number} hotspotX The X coordinate of the cursor hotspot.
     * @param {Number} hotspotY The Y coordinate of the cursor hotspot.
     * @param {Guacamole.Layer} layer The source layer containing the data which
     *                                should be used as the mouse cursor image.
     * @param {Number} srcx The X coordinate of the upper-left corner of the
     *                      rectangle within the source layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcy The Y coordinate of the upper-left corner of the
     *                      rectangle within the source layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcw The width of the rectangle within the source layer's
     *                      coordinate space to copy data from.
     * @param {Number} srch The height of the rectangle within the source
     *                      layer's coordinate space to copy data from.

     */
    this.setCursor = function(hotspotX, hotspotY, layer, srcx, srcy, srcw, srch) {
        scheduleTask(function __display_set_cursor() {

            // Set hotspot
            guac_display.cursorHotspotX = hotspotX;
            guac_display.cursorHotspotY = hotspotY;

            // Reset cursor size
            cursor.resize(srcw, srch);

            // Draw cursor to cursor layer
            cursor.copy(layer, srcx, srcy, srcw, srch, 0, 0);
            guac_display.moveCursor(guac_display.cursorX, guac_display.cursorY);

            // Fire cursor change event
            if (guac_display.oncursor)
                guac_display.oncursor(cursor.toCanvas(), hotspotX, hotspotY);

        });
    };

    /**
     * Sets whether the software-rendered cursor is shown. This cursor differs
     * from the hardware cursor in that it is built into the Guacamole.Display,
     * and relies on its own Guacamole layer to render.
     *
     * @param {Boolean} [shown=true] Whether to show the software cursor.
     */
    this.showCursor = function(shown) {

        var element = cursor.getElement();
        var parent = element.parentNode;

        // Remove from DOM if hidden
        if (shown === false) {
            if (parent)
                parent.removeChild(element);
        }

        // Otherwise, ensure cursor is child of display
        else if (parent !== display)
            display.appendChild(element);

    };

    /**
     * Sets the location of the local cursor to the given coordinates. For the
     * sake of responsiveness, this function performs its action immediately.
     * Cursor motion is not maintained within atomic frames.
     * 
     * @param {Number} x The X coordinate to move the cursor to.
     * @param {Number} y The Y coordinate to move the cursor to.
     */
    this.moveCursor = function(x, y) {

        // Move cursor layer
        cursor.translate(x - guac_display.cursorHotspotX,
                         y - guac_display.cursorHotspotY);

        // Update stored position
        guac_display.cursorX = x;
        guac_display.cursorY = y;

    };

    /**
     * Changes the size of the given Layer to the given width and height.
     * Resizing is only attempted if the new size provided is actually different
     * from the current size.
     * 
     * @param {Guacamole.Layer} layer The layer to resize.
     * @param {Number} width The new width.
     * @param {Number} height The new height.
     */
    this.resize = function(layer, width, height) {
        scheduleTask(function __display_resize() {

            layer.resize(width, height);

            // Resize display if default layer is resized
            if (layer === default_layer) {

                // Update (set) display size
                displayWidth = width;
                displayHeight = height;
                display.style.width = displayWidth + "px";
                display.style.height = displayHeight + "px";

                // Update bounds size
                bounds.style.width = (displayWidth*displayScale) + "px";
                bounds.style.height = (displayHeight*displayScale) + "px";

                // Notify of resize
                if (guac_display.onresize)
                    guac_display.onresize(width, height);

            }

        });
    };

    /**
     * Draws the specified image at the given coordinates. The image specified
     * must already be loaded.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     * @param {Image} image The image to draw. Note that this is an Image
     *                      object - not a URL.
     */
    this.drawImage = function(layer, x, y, image) {
        scheduleTask(function __display_drawImage() {
            layer.drawImage(x, y, image);
        });
    };

    /**
     * Draws the image contained within the specified Blob at the given
     * coordinates. The Blob specified must already be populated with image
     * data.
     *
     * @param {Guacamole.Layer} layer
     *     The layer to draw upon.
     *
     * @param {Number} x
     *     The destination X coordinate.
     *
     * @param {Number} y
     *     The destination Y coordinate.
     *
     * @param {Blob} blob
     *     The Blob containing the image data to draw.
     */
    this.drawBlob = function(layer, x, y, blob) {

        // Create URL for blob
        var url = URL.createObjectURL(blob);

        // Draw and free blob URL when ready
        var task = scheduleTask(function __display_drawBlob() {

            // Draw the image only if it loaded without errors
            if (image.width && image.height)
                layer.drawImage(x, y, image);

            // Blob URL no longer needed
            URL.revokeObjectURL(url);

        }, true);

        // Load image from URL
        var image = new Image();
        image.onload = task.unblock;
        image.onerror = task.unblock;
        image.src = url;

    };

    /**
     * Draws the image at the specified URL at the given coordinates. The image
     * will be loaded automatically, and this and any future operations will
     * wait for the image to finish loading.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     * @param {String} url The URL of the image to draw.
     */
    this.draw = function(layer, x, y, url) {

        var task = scheduleTask(function __display_draw() {

            // Draw the image only if it loaded without errors
            if (image.width && image.height)
                layer.drawImage(x, y, image);

        }, true);

        var image = new Image();
        image.onload = task.unblock;
        image.onerror = task.unblock;
        image.src = url;

    };

    /**
     * Plays the video at the specified URL within this layer. The video
     * will be loaded automatically, and this and any future operations will
     * wait for the video to finish loading. Future operations will not be
     * executed until the video finishes playing.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {String} mimetype The mimetype of the video to play.
     * @param {Number} duration The duration of the video in milliseconds.
     * @param {String} url The URL of the video to play.
     */
    this.play = function(layer, mimetype, duration, url) {

        // Start loading the video
        var video = document.createElement("video");
        video.type = mimetype;
        video.src = url;

        // Start copying frames when playing
        video.addEventListener("play", function() {
            
            function render_callback() {
                layer.drawImage(0, 0, video);
                if (!video.ended)
                    window.setTimeout(render_callback, 20);
            }
            
            render_callback();
            
        }, false);

        scheduleTask(video.play);

    };

    /**
     * Transfer a rectangle of image data from one Layer to this Layer using the
     * specified transfer function.
     * 
     * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
     * @param {Number} srcx The X coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcy The Y coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcw The width of the rectangle within the source Layer's
     *                      coordinate space to copy data from.
     * @param {Number} srch The height of the rectangle within the source
     *                      Layer's coordinate space to copy data from.
     * @param {Guacamole.Layer} dstLayer The layer to draw upon.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     * @param {Function} transferFunction The transfer function to use to
     *                                    transfer data from source to
     *                                    destination.
     */
    this.transfer = function(srcLayer, srcx, srcy, srcw, srch, dstLayer, x, y, transferFunction) {
        scheduleTask(function __display_transfer() {
            dstLayer.transfer(srcLayer, srcx, srcy, srcw, srch, x, y, transferFunction);
        });
    };

    /**
     * Put a rectangle of image data from one Layer to this Layer directly
     * without performing any alpha blending. Simply copy the data.
     * 
     * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
     * @param {Number} srcx The X coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcy The Y coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcw The width of the rectangle within the source Layer's
     *                      coordinate space to copy data from.
     * @param {Number} srch The height of the rectangle within the source
     *                      Layer's coordinate space to copy data from.
     * @param {Guacamole.Layer} dstLayer The layer to draw upon.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     */
    this.put = function(srcLayer, srcx, srcy, srcw, srch, dstLayer, x, y) {
        scheduleTask(function __display_put() {
            dstLayer.put(srcLayer, srcx, srcy, srcw, srch, x, y);
        });
    };

    /**
     * Copy a rectangle of image data from one Layer to this Layer. This
     * operation will copy exactly the image data that will be drawn once all
     * operations of the source Layer that were pending at the time this
     * function was called are complete. This operation will not alter the
     * size of the source Layer even if its autosize property is set to true.
     * 
     * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
     * @param {Number} srcx The X coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcy The Y coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcw The width of the rectangle within the source Layer's
     *                      coordinate space to copy data from.
     * @param {Number} srch The height of the rectangle within the source
     *                      Layer's coordinate space to copy data from.
     * @param {Guacamole.Layer} dstLayer The layer to draw upon.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     */
    this.copy = function(srcLayer, srcx, srcy, srcw, srch, dstLayer, x, y) {
        scheduleTask(function __display_copy() {
            dstLayer.copy(srcLayer, srcx, srcy, srcw, srch, x, y);
        });
    };

    /**
     * Starts a new path at the specified point.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} x The X coordinate of the point to draw.
     * @param {Number} y The Y coordinate of the point to draw.
     */
    this.moveTo = function(layer, x, y) {
        scheduleTask(function __display_moveTo() {
            layer.moveTo(x, y);
        });
    };

    /**
     * Add the specified line to the current path.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} x The X coordinate of the endpoint of the line to draw.
     * @param {Number} y The Y coordinate of the endpoint of the line to draw.
     */
    this.lineTo = function(layer, x, y) {
        scheduleTask(function __display_lineTo() {
            layer.lineTo(x, y);
        });
    };

    /**
     * Add the specified arc to the current path.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} x The X coordinate of the center of the circle which
     *                   will contain the arc.
     * @param {Number} y The Y coordinate of the center of the circle which
     *                   will contain the arc.
     * @param {Number} radius The radius of the circle.
     * @param {Number} startAngle The starting angle of the arc, in radians.
     * @param {Number} endAngle The ending angle of the arc, in radians.
     * @param {Boolean} negative Whether the arc should be drawn in order of
     *                           decreasing angle.
     */
    this.arc = function(layer, x, y, radius, startAngle, endAngle, negative) {
        scheduleTask(function __display_arc() {
            layer.arc(x, y, radius, startAngle, endAngle, negative);
        });
    };

    /**
     * Starts a new path at the specified point.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} cp1x The X coordinate of the first control point.
     * @param {Number} cp1y The Y coordinate of the first control point.
     * @param {Number} cp2x The X coordinate of the second control point.
     * @param {Number} cp2y The Y coordinate of the second control point.
     * @param {Number} x The X coordinate of the endpoint of the curve.
     * @param {Number} y The Y coordinate of the endpoint of the curve.
     */
    this.curveTo = function(layer, cp1x, cp1y, cp2x, cp2y, x, y) {
        scheduleTask(function __display_curveTo() {
            layer.curveTo(cp1x, cp1y, cp2x, cp2y, x, y);
        });
    };

    /**
     * Closes the current path by connecting the end point with the start
     * point (if any) with a straight line.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     */
    this.close = function(layer) {
        scheduleTask(function __display_close() {
            layer.close();
        });
    };

    /**
     * Add the specified rectangle to the current path.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} x The X coordinate of the upper-left corner of the
     *                   rectangle to draw.
     * @param {Number} y The Y coordinate of the upper-left corner of the
     *                   rectangle to draw.
     * @param {Number} w The width of the rectangle to draw.
     * @param {Number} h The height of the rectangle to draw.
     */
    this.rect = function(layer, x, y, w, h) {
        scheduleTask(function __display_rect() {
            layer.rect(x, y, w, h);
        });
    };

    /**
     * Clip all future drawing operations by the current path. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as fillColor()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {Guacamole.Layer} layer The layer to affect.
     */
    this.clip = function(layer) {
        scheduleTask(function __display_clip() {
            layer.clip();
        });
    };

    /**
     * Stroke the current path with the specified color. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {String} cap The line cap style. Can be "round", "square",
     *                     or "butt".
     * @param {String} join The line join style. Can be "round", "bevel",
     *                      or "miter".
     * @param {Number} thickness The line thickness in pixels.
     * @param {Number} r The red component of the color to fill.
     * @param {Number} g The green component of the color to fill.
     * @param {Number} b The blue component of the color to fill.
     * @param {Number} a The alpha component of the color to fill.
     */
    this.strokeColor = function(layer, cap, join, thickness, r, g, b, a) {
        scheduleTask(function __display_strokeColor() {
            layer.strokeColor(cap, join, thickness, r, g, b, a);
        });
    };

    /**
     * Fills the current path with the specified color. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Number} r The red component of the color to fill.
     * @param {Number} g The green component of the color to fill.
     * @param {Number} b The blue component of the color to fill.
     * @param {Number} a The alpha component of the color to fill.
     */
    this.fillColor = function(layer, r, g, b, a) {
        scheduleTask(function __display_fillColor() {
            layer.fillColor(r, g, b, a);
        });
    };

    /**
     * Stroke the current path with the image within the specified layer. The
     * image data will be tiled infinitely within the stroke. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {String} cap The line cap style. Can be "round", "square",
     *                     or "butt".
     * @param {String} join The line join style. Can be "round", "bevel",
     *                      or "miter".
     * @param {Number} thickness The line thickness in pixels.
     * @param {Guacamole.Layer} srcLayer The layer to use as a repeating pattern
     *                                   within the stroke.
     */
    this.strokeLayer = function(layer, cap, join, thickness, srcLayer) {
        scheduleTask(function __display_strokeLayer() {
            layer.strokeLayer(cap, join, thickness, srcLayer);
        });
    };

    /**
     * Fills the current path with the image within the specified layer. The
     * image data will be tiled infinitely within the stroke. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     * @param {Guacamole.Layer} srcLayer The layer to use as a repeating pattern
     *                                   within the fill.
     */
    this.fillLayer = function(layer, srcLayer) {
        scheduleTask(function __display_fillLayer() {
            layer.fillLayer(srcLayer);
        });
    };

    /**
     * Push current layer state onto stack.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     */
    this.push = function(layer) {
        scheduleTask(function __display_push() {
            layer.push();
        });
    };

    /**
     * Pop layer state off stack.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     */
    this.pop = function(layer) {
        scheduleTask(function __display_pop() {
            layer.pop();
        });
    };

    /**
     * Reset the layer, clearing the stack, the current path, and any transform
     * matrix.
     * 
     * @param {Guacamole.Layer} layer The layer to draw upon.
     */
    this.reset = function(layer) {
        scheduleTask(function __display_reset() {
            layer.reset();
        });
    };

    /**
     * Sets the given affine transform (defined with six values from the
     * transform's matrix).
     * 
     * @param {Guacamole.Layer} layer The layer to modify.
     * @param {Number} a The first value in the affine transform's matrix.
     * @param {Number} b The second value in the affine transform's matrix.
     * @param {Number} c The third value in the affine transform's matrix.
     * @param {Number} d The fourth value in the affine transform's matrix.
     * @param {Number} e The fifth value in the affine transform's matrix.
     * @param {Number} f The sixth value in the affine transform's matrix.
     */
    this.setTransform = function(layer, a, b, c, d, e, f) {
        scheduleTask(function __display_setTransform() {
            layer.setTransform(a, b, c, d, e, f);
        });
    };

    /**
     * Applies the given affine transform (defined with six values from the
     * transform's matrix).
     * 
     * @param {Guacamole.Layer} layer The layer to modify.
     * @param {Number} a The first value in the affine transform's matrix.
     * @param {Number} b The second value in the affine transform's matrix.
     * @param {Number} c The third value in the affine transform's matrix.
     * @param {Number} d The fourth value in the affine transform's matrix.
     * @param {Number} e The fifth value in the affine transform's matrix.
     * @param {Number} f The sixth value in the affine transform's matrix.
     */
    this.transform = function(layer, a, b, c, d, e, f) {
        scheduleTask(function __display_transform() {
            layer.transform(a, b, c, d, e, f);
        });
    };

    /**
     * Sets the channel mask for future operations on this Layer.
     * 
     * The channel mask is a Guacamole-specific compositing operation identifier
     * with a single bit representing each of four channels (in order): source
     * image where destination transparent, source where destination opaque,
     * destination where source transparent, and destination where source
     * opaque.
     * 
     * @param {Guacamole.Layer} layer The layer to modify.
     * @param {Number} mask The channel mask for future operations on this
     *                      Layer.
     */
    this.setChannelMask = function(layer, mask) {
        scheduleTask(function __display_setChannelMask() {
            layer.setChannelMask(mask);
        });
    };

    /**
     * Sets the miter limit for stroke operations using the miter join. This
     * limit is the maximum ratio of the size of the miter join to the stroke
     * width. If this ratio is exceeded, the miter will not be drawn for that
     * joint of the path.
     * 
     * @param {Guacamole.Layer} layer The layer to modify.
     * @param {Number} limit The miter limit for stroke operations using the
     *                       miter join.
     */
    this.setMiterLimit = function(layer, limit) {
        scheduleTask(function __display_setMiterLimit() {
            layer.setMiterLimit(limit);
        });
    };

    /**
     * Removes the given layer container entirely, such that it is no longer
     * contained within its parent layer, if any.
     *
     * @param {Guacamole.Display.VisibleLayer} layer
     *     The layer being removed from its parent.
     */
    this.dispose = function dispose(layer) {
        scheduleTask(function disposeLayer() {
            layer.dispose();
        });
    };

    /**
     * Applies the given affine transform (defined with six values from the
     * transform's matrix) to the given layer.
     *
     * @param {Guacamole.Display.VisibleLayer} layer
     *     The layer being distorted.
     *
     * @param {Number} a
     *     The first value in the affine transform's matrix.
     *
     * @param {Number} b
     *     The second value in the affine transform's matrix.
     *
     * @param {Number} c
     *     The third value in the affine transform's matrix.
     *
     * @param {Number} d
     *     The fourth value in the affine transform's matrix.
     *
     * @param {Number} e
     *     The fifth value in the affine transform's matrix.
     *
     * @param {Number} f
     *     The sixth value in the affine transform's matrix.
     */
    this.distort = function distort(layer, a, b, c, d, e, f) {
        scheduleTask(function distortLayer() {
            layer.distort(a, b, c, d, e, f);
        });
    };

    /**
     * Moves the upper-left corner of the given layer to the given X and Y
     * coordinate, sets the Z stacking order, and reparents the layer
     * to the given parent layer.
     *
     * @param {Guacamole.Display.VisibleLayer} layer
     *     The layer being moved.
     *
     * @param {Guacamole.Display.VisibleLayer} parent
     *     The parent to set.
     *
     * @param {Number} x
     *     The X coordinate to move to.
     *
     * @param {Number} y
     *     The Y coordinate to move to.
     *
     * @param {Number} z
     *     The Z coordinate to move to.
     */
    this.move = function move(layer, parent, x, y, z) {
        scheduleTask(function moveLayer() {
            layer.move(parent, x, y, z);
        });
    };

    /**
     * Sets the opacity of the given layer to the given value, where 255 is
     * fully opaque and 0 is fully transparent.
     *
     * @param {Guacamole.Display.VisibleLayer} layer
     *     The layer whose opacity should be set.
     *
     * @param {Number} alpha
     *     The opacity to set.
     */
    this.shade = function shade(layer, alpha) {
        scheduleTask(function shadeLayer() {
            layer.shade(alpha);
        });
    };

    /**
     * Sets the scale of the client display element such that it renders at
     * a relatively smaller or larger size, without affecting the true
     * resolution of the display.
     *
     * @param {Number} scale The scale to resize to, where 1.0 is normal
     *                       size (1:1 scale).
     */
    this.scale = function(scale) {

        display.style.transform =
        display.style.WebkitTransform =
        display.style.MozTransform =
        display.style.OTransform =
        display.style.msTransform =

            "scale(" + scale + "," + scale + ")";

        displayScale = scale;

        // Update bounds size
        bounds.style.width = (displayWidth*displayScale) + "px";
        bounds.style.height = (displayHeight*displayScale) + "px";

    };

    /**
     * Returns the scale of the display.
     *
     * @return {Number} The scale of the display.
     */
    this.getScale = function() {
        return displayScale;
    };

    /**
     * Returns a canvas element containing the entire display, with all child
     * layers composited within.
     *
     * @return {HTMLCanvasElement} A new canvas element containing a copy of
     *                             the display.
     */
    this.flatten = function() {
       
        // Get destination canvas
        var canvas = document.createElement("canvas");
        canvas.width = default_layer.width;
        canvas.height = default_layer.height;

        var context = canvas.getContext("2d");

        // Returns sorted array of children
        function get_children(layer) {

            // Build array of children
            var children = [];
            for (var index in layer.children)
                children.push(layer.children[index]);

            // Sort
            children.sort(function children_comparator(a, b) {

                // Compare based on Z order
                var diff = a.z - b.z;
                if (diff !== 0)
                    return diff;

                // If Z order identical, use document order
                var a_element = a.getElement();
                var b_element = b.getElement();
                var position = b_element.compareDocumentPosition(a_element);

                if (position & Node.DOCUMENT_POSITION_PRECEDING) return -1;
                if (position & Node.DOCUMENT_POSITION_FOLLOWING) return  1;

                // Otherwise, assume same
                return 0;

            });

            // Done
            return children;

        }

        // Draws the contents of the given layer at the given coordinates
        function draw_layer(layer, x, y) {

            // Draw layer
            if (layer.width > 0 && layer.height > 0) {

                // Save and update alpha
                var initial_alpha = context.globalAlpha;
                context.globalAlpha *= layer.alpha / 255.0;

                // Copy data
                context.drawImage(layer.getCanvas(), x, y);

                // Draw all children
                var children = get_children(layer);
                for (var i=0; i<children.length; i++) {
                    var child = children[i];
                    draw_layer(child, x + child.x, y + child.y);
                }

                // Restore alpha
                context.globalAlpha = initial_alpha;

            }

        }

        // Draw default layer and all children
        draw_layer(default_layer, 0, 0);

        // Return new canvas copy
        return canvas;
        
    };

};

/**
 * Simple container for Guacamole.Layer, allowing layers to be easily
 * repositioned and nested. This allows certain operations to be accelerated
 * through DOM manipulation, rather than raster operations.
 * 
 * @constructor
 * @augments Guacamole.Layer
 * @param {Number} width The width of the Layer, in pixels. The canvas element
 *                       backing this Layer will be given this width.
 * @param {Number} height The height of the Layer, in pixels. The canvas element
 *                        backing this Layer will be given this height.
 */
Guacamole.Display.VisibleLayer = function(width, height) {

    Guacamole.Layer.apply(this, [width, height]);

    /**
     * Reference to this layer.
     * @private
     */
    var layer = this;

    /**
     * Identifier which uniquely identifies this layer. This is COMPLETELY
     * UNRELATED to the index of the underlying layer, which is specific
     * to the Guacamole protocol, and not relevant at this level.
     * 
     * @private
     * @type {Number}
     */
    this.__unique_id = Guacamole.Display.VisibleLayer.__next_id++;

    /**
     * The opacity of the layer container, where 255 is fully opaque and 0 is
     * fully transparent.
     */
    this.alpha = 0xFF;

    /**
     * X coordinate of the upper-left corner of this layer container within
     * its parent, in pixels.
     * @type {Number}
     */
    this.x = 0;

    /**
     * Y coordinate of the upper-left corner of this layer container within
     * its parent, in pixels.
     * @type {Number}
     */
    this.y = 0;

    /**
     * Z stacking order of this layer relative to other sibling layers.
     * @type {Number}
     */
    this.z = 0;

    /**
     * The affine transformation applied to this layer container. Each element
     * corresponds to a value from the transformation matrix, with the first
     * three values being the first row, and the last three values being the
     * second row. There are six values total.
     * 
     * @type {Number[]}
     */
    this.matrix = [1, 0, 0, 1, 0, 0];

    /**
     * The parent layer container of this layer, if any.
     * @type {Guacamole.Display.VisibleLayer}
     */
    this.parent = null;

    /**
     * Set of all children of this layer, indexed by layer index. This object
     * will have one property per child.
     */
    this.children = {};

    // Set layer position
    var canvas = layer.getCanvas();
    canvas.style.position = "absolute";
    canvas.style.left = "0px";
    canvas.style.top = "0px";

    // Create div with given size
    var div = document.createElement("div");
    div.appendChild(canvas);
    div.style.width = width + "px";
    div.style.height = height + "px";
    div.style.position = "absolute";
    div.style.left = "0px";
    div.style.top = "0px";
    div.style.overflow = "hidden";

    /**
     * Superclass resize() function.
     * @private
     */
    var __super_resize = this.resize;

    this.resize = function(width, height) {

        // Resize containing div
        div.style.width = width + "px";
        div.style.height = height + "px";

        __super_resize(width, height);

    };
  
    /**
     * Returns the element containing the canvas and any other elements
     * associated with this layer.
     * @returns {Element} The element containing this layer's canvas.
     */
    this.getElement = function() {
        return div;
    };

    /**
     * The translation component of this layer's transform.
     * @private
     */
    var translate = "translate(0px, 0px)"; // (0, 0)

    /**
     * The arbitrary matrix component of this layer's transform.
     * @private
     */
    var matrix = "matrix(1, 0, 0, 1, 0, 0)"; // Identity

    /**
     * Moves the upper-left corner of this layer to the given X and Y
     * coordinate.
     * 
     * @param {Number} x The X coordinate to move to.
     * @param {Number} y The Y coordinate to move to.
     */
    this.translate = function(x, y) {

        layer.x = x;
        layer.y = y;

        // Generate translation
        translate = "translate("
                        + x + "px,"
                        + y + "px)";

        // Set layer transform 
        div.style.transform =
        div.style.WebkitTransform =
        div.style.MozTransform =
        div.style.OTransform =
        div.style.msTransform =

            translate + " " + matrix;

    };

    /**
     * Moves the upper-left corner of this VisibleLayer to the given X and Y
     * coordinate, sets the Z stacking order, and reparents this VisibleLayer
     * to the given VisibleLayer.
     * 
     * @param {Guacamole.Display.VisibleLayer} parent The parent to set.
     * @param {Number} x The X coordinate to move to.
     * @param {Number} y The Y coordinate to move to.
     * @param {Number} z The Z coordinate to move to.
     */
    this.move = function(parent, x, y, z) {

        // Set parent if necessary
        if (layer.parent !== parent) {

            // Maintain relationship
            if (layer.parent)
                delete layer.parent.children[layer.__unique_id];
            layer.parent = parent;
            parent.children[layer.__unique_id] = layer;

            // Reparent element
            var parent_element = parent.getElement();
            parent_element.appendChild(div);

        }

        // Set location
        layer.translate(x, y);
        layer.z = z;
        div.style.zIndex = z;

    };

    /**
     * Sets the opacity of this layer to the given value, where 255 is fully
     * opaque and 0 is fully transparent.
     * 
     * @param {Number} a The opacity to set.
     */
    this.shade = function(a) {
        layer.alpha = a;
        div.style.opacity = a/255.0;
    };

    /**
     * Removes this layer container entirely, such that it is no longer
     * contained within its parent layer, if any.
     */
    this.dispose = function() {

        // Remove from parent container
        if (layer.parent) {
            delete layer.parent.children[layer.__unique_id];
            layer.parent = null;
        }

        // Remove from parent element
        if (div.parentNode)
            div.parentNode.removeChild(div);
        
    };

    /**
     * Applies the given affine transform (defined with six values from the
     * transform's matrix).
     * 
     * @param {Number} a The first value in the affine transform's matrix.
     * @param {Number} b The second value in the affine transform's matrix.
     * @param {Number} c The third value in the affine transform's matrix.
     * @param {Number} d The fourth value in the affine transform's matrix.
     * @param {Number} e The fifth value in the affine transform's matrix.
     * @param {Number} f The sixth value in the affine transform's matrix.
     */
    this.distort = function(a, b, c, d, e, f) {

        // Store matrix
        layer.matrix = [a, b, c, d, e, f];

        // Generate matrix transformation
        matrix =

            /* a c e
             * b d f
             * 0 0 1
             */
    
            "matrix(" + a + "," + b + "," + c + "," + d + "," + e + "," + f + ")";

        // Set layer transform 
        div.style.transform =
        div.style.WebkitTransform =
        div.style.MozTransform =
        div.style.OTransform =
        div.style.msTransform =

            translate + " " + matrix;

    };

};

/**
 * The next identifier to be assigned to the layer container. This identifier
 * uniquely identifies each VisibleLayer, but is unrelated to the index of
 * the layer, which exists at the protocol/client level only.
 * 
 * @private
 * @type {Number}
 */
Guacamole.Display.VisibleLayer.__next_id = 0;
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * An input stream abstraction used by the Guacamole client to facilitate
 * transfer of files or other binary data.
 * 
 * @constructor
 * @param {Guacamole.Client} client The client owning this stream.
 * @param {Number} index The index of this stream.
 */
Guacamole.InputStream = function(client, index) {

    /**
     * Reference to this stream.
     * @private
     */
    var guac_stream = this;

    /**
     * The index of this stream.
     * @type {Number}
     */
    this.index = index;

    /**
     * Called when a blob of data is received.
     * 
     * @event
     * @param {String} data The received base64 data.
     */
    this.onblob = null;

    /**
     * Called when this stream is closed.
     * 
     * @event
     */
    this.onend = null;

    /**
     * Acknowledges the receipt of a blob.
     * 
     * @param {String} message A human-readable message describing the error
     *                         or status.
     * @param {Number} code The error code, if any, or 0 for success.
     */
    this.sendAck = function(message, code) {
        client.sendAck(guac_stream.index, message, code);
    };

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Integer pool which returns consistently increasing integers while integers
 * are in use, and previously-used integers when possible.
 * @constructor 
 */
Guacamole.IntegerPool = function() {

    /**
     * Reference to this integer pool.
     *
     * @private
     */
    var guac_pool = this;

    /**
     * Array of available integers.
     *
     * @private
     * @type {Number[]}
     */
    var pool = [];

    /**
     * The next integer to return if no more integers remain.
     * @type {Number}
     */
    this.next_int = 0;

    /**
     * Returns the next available integer in the pool. If possible, a previously
     * used integer will be returned.
     * 
     * @return {Number} The next available integer.
     */
    this.next = function() {

        // If free'd integers exist, return one of those
        if (pool.length > 0)
            return pool.shift();

        // Otherwise, return a new integer
        return guac_pool.next_int++;

    };

    /**
     * Frees the given integer, allowing it to be reused.
     * 
     * @param {Number} integer The integer to free.
     */
    this.free = function(integer) {
        pool.push(integer);
    };

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A reader which automatically handles the given input stream, assembling all
 * received blobs into a JavaScript object by appending them to each other, in
 * order, and decoding the result as JSON. Note that this object will overwrite
 * any installed event handlers on the given Guacamole.InputStream.
 * 
 * @constructor
 * @param {Guacamole.InputStream} stream
 *     The stream that JSON will be read from.
 */
Guacamole.JSONReader = function guacamoleJSONReader(stream) {

    /**
     * Reference to this Guacamole.JSONReader.
     *
     * @private
     * @type {Guacamole.JSONReader}
     */
    var guacReader = this;

    /**
     * Wrapped Guacamole.StringReader.
     *
     * @private
     * @type {Guacamole.StringReader}
     */
    var stringReader = new Guacamole.StringReader(stream);

    /**
     * All JSON read thus far.
     *
     * @private
     * @type {String}
     */
    var json = '';

    /**
     * Returns the current length of this Guacamole.JSONReader, in characters.
     *
     * @return {Number}
     *     The current length of this Guacamole.JSONReader.
     */
    this.getLength = function getLength() {
        return json.length;
    };

    /**
     * Returns the contents of this Guacamole.JSONReader as a JavaScript
     * object.
     *
     * @return {Object}
     *     The contents of this Guacamole.JSONReader, as parsed from the JSON
     *     contents of the input stream.
     */
    this.getJSON = function getJSON() {
        return JSON.parse(json);
    };

    // Append all received text
    stringReader.ontext = function ontext(text) {

        // Append received text
        json += text;

        // Call handler, if present
        if (guacReader.onprogress)
            guacReader.onprogress(text.length);

    };

    // Simply call onend when end received
    stringReader.onend = function onend() {
        if (guacReader.onend)
            guacReader.onend();
    };

    /**
     * Fired once for every blob of data received.
     * 
     * @event
     * @param {Number} length
     *     The number of characters received.
     */
    this.onprogress = null;

    /**
     * Fired once this stream is finished and no further data will be written.
     *
     * @event
     */
    this.onend = null;

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Provides cross-browser and cross-keyboard keyboard for a specific element.
 * Browser and keyboard layout variation is abstracted away, providing events
 * which represent keys as their corresponding X11 keysym.
 * 
 * @constructor
 * @param {Element} element The Element to use to provide keyboard events.
 */
Guacamole.Keyboard = function(element) {

    /**
     * Reference to this Guacamole.Keyboard.
     * @private
     */
    var guac_keyboard = this;

    /**
     * Fired whenever the user presses a key with the element associated
     * with this Guacamole.Keyboard in focus.
     * 
     * @event
     * @param {Number} keysym The keysym of the key being pressed.
     * @return {Boolean} true if the key event should be allowed through to the
     *                   browser, false otherwise.
     */
    this.onkeydown = null;

    /**
     * Fired whenever the user releases a key with the element associated
     * with this Guacamole.Keyboard in focus.
     * 
     * @event
     * @param {Number} keysym The keysym of the key being released.
     */
    this.onkeyup = null;

    /**
     * A key event having a corresponding timestamp. This event is non-specific.
     * Its subclasses should be used instead when recording specific key
     * events.
     *
     * @private
     * @constructor
     */
    var KeyEvent = function() {

        /**
         * Reference to this key event.
         */
        var key_event = this;

        /**
         * An arbitrary timestamp in milliseconds, indicating this event's
         * position in time relative to other events.
         *
         * @type {Number}
         */
        this.timestamp = new Date().getTime();

        /**
         * Whether the default action of this key event should be prevented.
         *
         * @type {Boolean}
         */
        this.defaultPrevented = false;

        /**
         * The keysym of the key associated with this key event, as determined
         * by a best-effort guess using available event properties and keyboard
         * state.
         *
         * @type {Number}
         */
        this.keysym = null;

        /**
         * Whether the keysym value of this key event is known to be reliable.
         * If false, the keysym may still be valid, but it's only a best guess,
         * and future key events may be a better source of information.
         *
         * @type {Boolean}
         */
        this.reliable = false;

        /**
         * Returns the number of milliseconds elapsed since this event was
         * received.
         *
         * @return {Number} The number of milliseconds elapsed since this
         *                  event was received.
         */
        this.getAge = function() {
            return new Date().getTime() - key_event.timestamp;
        };

    };

    /**
     * Information related to the pressing of a key, which need not be a key
     * associated with a printable character. The presence or absence of any
     * information within this object is browser-dependent.
     *
     * @private
     * @constructor
     * @augments Guacamole.Keyboard.KeyEvent
     * @param {Number} keyCode The JavaScript key code of the key pressed.
     * @param {String} keyIdentifier The legacy DOM3 "keyIdentifier" of the key
     *                               pressed, as defined at:
     *                               http://www.w3.org/TR/2009/WD-DOM-Level-3-Events-20090908/#events-Events-KeyboardEvent
     * @param {String} key The standard name of the key pressed, as defined at:
     *                     http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
     * @param {Number} location The location on the keyboard corresponding to
     *                          the key pressed, as defined at:
     *                          http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
     */
    var KeydownEvent = function(keyCode, keyIdentifier, key, location) {

        // We extend KeyEvent
        KeyEvent.apply(this);

        /**
         * The JavaScript key code of the key pressed.
         *
         * @type {Number}
         */
        this.keyCode = keyCode;

        /**
         * The legacy DOM3 "keyIdentifier" of the key pressed, as defined at:
         * http://www.w3.org/TR/2009/WD-DOM-Level-3-Events-20090908/#events-Events-KeyboardEvent
         *
         * @type {String}
         */
        this.keyIdentifier = keyIdentifier;

        /**
         * The standard name of the key pressed, as defined at:
         * http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
         * 
         * @type {String}
         */
        this.key = key;

        /**
         * The location on the keyboard corresponding to the key pressed, as
         * defined at:
         * http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
         * 
         * @type {Number}
         */
        this.location = location;

        // If key is known from keyCode or DOM3 alone, use that
        this.keysym =  keysym_from_key_identifier(key, location)
                    || keysym_from_keycode(keyCode, location);

        // DOM3 and keyCode are reliable sources if the corresponding key is
        // not a printable key
        if (this.keysym && !isPrintable(this.keysym))
            this.reliable = true;

        // Use legacy keyIdentifier as a last resort, if it looks sane
        if (!this.keysym && key_identifier_sane(keyCode, keyIdentifier))
            this.keysym = keysym_from_key_identifier(keyIdentifier, location, guac_keyboard.modifiers.shift);

        // Determine whether default action for Alt+combinations must be prevented
        var prevent_alt =  !guac_keyboard.modifiers.ctrl
                        && !(navigator && navigator.platform && navigator.platform.match(/^mac/i));

        // Determine whether default action for Ctrl+combinations must be prevented
        var prevent_ctrl = !guac_keyboard.modifiers.alt;

        // We must rely on the (potentially buggy) keyIdentifier if preventing
        // the default action is important
        if ((prevent_ctrl && guac_keyboard.modifiers.ctrl)
         || (prevent_alt  && guac_keyboard.modifiers.alt)
         || guac_keyboard.modifiers.meta
         || guac_keyboard.modifiers.hyper)
            this.reliable = true;

        // Record most recently known keysym by associated key code
        recentKeysym[keyCode] = this.keysym;

    };

    KeydownEvent.prototype = new KeyEvent();

    /**
     * Information related to the pressing of a key, which MUST be
     * associated with a printable character. The presence or absence of any
     * information within this object is browser-dependent.
     *
     * @private
     * @constructor
     * @augments Guacamole.Keyboard.KeyEvent
     * @param {Number} charCode The Unicode codepoint of the character that
     *                          would be typed by the key pressed.
     */
    var KeypressEvent = function(charCode) {

        // We extend KeyEvent
        KeyEvent.apply(this);

        /**
         * The Unicode codepoint of the character that would be typed by the
         * key pressed.
         *
         * @type {Number}
         */
        this.charCode = charCode;

        // Pull keysym from char code
        this.keysym = keysym_from_charcode(charCode);

        // Keypress is always reliable
        this.reliable = true;

    };

    KeypressEvent.prototype = new KeyEvent();

    /**
     * Information related to the pressing of a key, which need not be a key
     * associated with a printable character. The presence or absence of any
     * information within this object is browser-dependent.
     *
     * @private
     * @constructor
     * @augments Guacamole.Keyboard.KeyEvent
     * @param {Number} keyCode The JavaScript key code of the key released.
     * @param {String} keyIdentifier The legacy DOM3 "keyIdentifier" of the key
     *                               released, as defined at:
     *                               http://www.w3.org/TR/2009/WD-DOM-Level-3-Events-20090908/#events-Events-KeyboardEvent
     * @param {String} key The standard name of the key released, as defined at:
     *                     http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
     * @param {Number} location The location on the keyboard corresponding to
     *                          the key released, as defined at:
     *                          http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
     */
    var KeyupEvent = function(keyCode, keyIdentifier, key, location) {

        // We extend KeyEvent
        KeyEvent.apply(this);

        /**
         * The JavaScript key code of the key released.
         *
         * @type {Number}
         */
        this.keyCode = keyCode;

        /**
         * The legacy DOM3 "keyIdentifier" of the key released, as defined at:
         * http://www.w3.org/TR/2009/WD-DOM-Level-3-Events-20090908/#events-Events-KeyboardEvent
         *
         * @type {String}
         */
        this.keyIdentifier = keyIdentifier;

        /**
         * The standard name of the key released, as defined at:
         * http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
         * 
         * @type {String}
         */
        this.key = key;

        /**
         * The location on the keyboard corresponding to the key released, as
         * defined at:
         * http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
         * 
         * @type {Number}
         */
        this.location = location;

        // If key is known from keyCode or DOM3 alone, use that
        this.keysym =  recentKeysym[keyCode]
                    || keysym_from_keycode(keyCode, location)
                    || keysym_from_key_identifier(key, location); // keyCode is still more reliable for keyup when dead keys are in use

        // Keyup is as reliable as it will ever be
        this.reliable = true;

    };

    KeyupEvent.prototype = new KeyEvent();

    /**
     * An array of recorded events, which can be instances of the private
     * KeydownEvent, KeypressEvent, and KeyupEvent classes.
     *
     * @private
     * @type {KeyEvent[]}
     */
    var eventLog = [];

    /**
     * Map of known JavaScript keycodes which do not map to typable characters
     * to their X11 keysym equivalents.
     * @private
     */
    var keycodeKeysyms = {
        8:   [0xFF08], // backspace
        9:   [0xFF09], // tab
        12:  [0xFF0B, 0xFF0B, 0xFF0B, 0xFFB5], // clear       / KP 5
        13:  [0xFF0D], // enter
        16:  [0xFFE1, 0xFFE1, 0xFFE2], // shift
        17:  [0xFFE3, 0xFFE3, 0xFFE4], // ctrl
        18:  [0xFFE9, 0xFFE9, 0xFE03], // alt
        19:  [0xFF13], // pause/break
        20:  [0xFFE5], // caps lock
        27:  [0xFF1B], // escape
        32:  [0x0020], // space
        33:  [0xFF55, 0xFF55, 0xFF55, 0xFFB9], // page up     / KP 9
        34:  [0xFF56, 0xFF56, 0xFF56, 0xFFB3], // page down   / KP 3
        35:  [0xFF57, 0xFF57, 0xFF57, 0xFFB1], // end         / KP 1
        36:  [0xFF50, 0xFF50, 0xFF50, 0xFFB7], // home        / KP 7
        37:  [0xFF51, 0xFF51, 0xFF51, 0xFFB4], // left arrow  / KP 4
        38:  [0xFF52, 0xFF52, 0xFF52, 0xFFB8], // up arrow    / KP 8
        39:  [0xFF53, 0xFF53, 0xFF53, 0xFFB6], // right arrow / KP 6
        40:  [0xFF54, 0xFF54, 0xFF54, 0xFFB2], // down arrow  / KP 2
        45:  [0xFF63, 0xFF63, 0xFF63, 0xFFB0], // insert      / KP 0
        46:  [0xFFFF, 0xFFFF, 0xFFFF, 0xFFAE], // delete      / KP decimal
        91:  [0xFFEB], // left window key (hyper_l)
        92:  [0xFF67], // right window key (menu key?)
        93:  null,     // select key
        96:  [0xFFB0], // KP 0
        97:  [0xFFB1], // KP 1
        98:  [0xFFB2], // KP 2
        99:  [0xFFB3], // KP 3
        100: [0xFFB4], // KP 4
        101: [0xFFB5], // KP 5
        102: [0xFFB6], // KP 6
        103: [0xFFB7], // KP 7
        104: [0xFFB8], // KP 8
        105: [0xFFB9], // KP 9
        106: [0xFFAA], // KP multiply
        107: [0xFFAB], // KP add
        109: [0xFFAD], // KP subtract
        110: [0xFFAE], // KP decimal
        111: [0xFFAF], // KP divide
        112: [0xFFBE], // f1
        113: [0xFFBF], // f2
        114: [0xFFC0], // f3
        115: [0xFFC1], // f4
        116: [0xFFC2], // f5
        117: [0xFFC3], // f6
        118: [0xFFC4], // f7
        119: [0xFFC5], // f8
        120: [0xFFC6], // f9
        121: [0xFFC7], // f10
        122: [0xFFC8], // f11
        123: [0xFFC9], // f12
        144: [0xFF7F], // num lock
        145: [0xFF14], // scroll lock
        225: [0xFE03]  // altgraph (iso_level3_shift)
    };

    /**
     * Map of known JavaScript keyidentifiers which do not map to typable
     * characters to their unshifted X11 keysym equivalents.
     * @private
     */
    var keyidentifier_keysym = {
        "Again": [0xFF66],
        "AllCandidates": [0xFF3D],
        "Alphanumeric": [0xFF30],
        "Alt": [0xFFE9, 0xFFE9, 0xFE03],
        "Attn": [0xFD0E],
        "AltGraph": [0xFE03],
        "ArrowDown": [0xFF54],
        "ArrowLeft": [0xFF51],
        "ArrowRight": [0xFF53],
        "ArrowUp": [0xFF52],
        "Backspace": [0xFF08],
        "CapsLock": [0xFFE5],
        "Cancel": [0xFF69],
        "Clear": [0xFF0B],
        "Convert": [0xFF21],
        "Copy": [0xFD15],
        "Crsel": [0xFD1C],
        "CrSel": [0xFD1C],
        "CodeInput": [0xFF37],
        "Compose": [0xFF20],
        "Control": [0xFFE3, 0xFFE3, 0xFFE4],
        "ContextMenu": [0xFF67],
        "DeadGrave": [0xFE50],
        "DeadAcute": [0xFE51],
        "DeadCircumflex": [0xFE52],
        "DeadTilde": [0xFE53],
        "DeadMacron": [0xFE54],
        "DeadBreve": [0xFE55],
        "DeadAboveDot": [0xFE56],
        "DeadUmlaut": [0xFE57],
        "DeadAboveRing": [0xFE58],
        "DeadDoubleacute": [0xFE59],
        "DeadCaron": [0xFE5A],
        "DeadCedilla": [0xFE5B],
        "DeadOgonek": [0xFE5C],
        "DeadIota": [0xFE5D],
        "DeadVoicedSound": [0xFE5E],
        "DeadSemivoicedSound": [0xFE5F],
        "Delete": [0xFFFF],
        "Down": [0xFF54],
        "End": [0xFF57],
        "Enter": [0xFF0D],
        "EraseEof": [0xFD06],
        "Escape": [0xFF1B],
        "Execute": [0xFF62],
        "Exsel": [0xFD1D],
        "ExSel": [0xFD1D],
        "F1": [0xFFBE],
        "F2": [0xFFBF],
        "F3": [0xFFC0],
        "F4": [0xFFC1],
        "F5": [0xFFC2],
        "F6": [0xFFC3],
        "F7": [0xFFC4],
        "F8": [0xFFC5],
        "F9": [0xFFC6],
        "F10": [0xFFC7],
        "F11": [0xFFC8],
        "F12": [0xFFC9],
        "F13": [0xFFCA],
        "F14": [0xFFCB],
        "F15": [0xFFCC],
        "F16": [0xFFCD],
        "F17": [0xFFCE],
        "F18": [0xFFCF],
        "F19": [0xFFD0],
        "F20": [0xFFD1],
        "F21": [0xFFD2],
        "F22": [0xFFD3],
        "F23": [0xFFD4],
        "F24": [0xFFD5],
        "Find": [0xFF68],
        "GroupFirst": [0xFE0C],
        "GroupLast": [0xFE0E],
        "GroupNext": [0xFE08],
        "GroupPrevious": [0xFE0A],
        "FullWidth": null,
        "HalfWidth": null,
        "HangulMode": [0xFF31],
        "Hankaku": [0xFF29],
        "HanjaMode": [0xFF34],
        "Help": [0xFF6A],
        "Hiragana": [0xFF25],
        "HiraganaKatakana": [0xFF27],
        "Home": [0xFF50],
        "Hyper": [0xFFED, 0xFFED, 0xFFEE],
        "Insert": [0xFF63],
        "JapaneseHiragana": [0xFF25],
        "JapaneseKatakana": [0xFF26],
        "JapaneseRomaji": [0xFF24],
        "JunjaMode": [0xFF38],
        "KanaMode": [0xFF2D],
        "KanjiMode": [0xFF21],
        "Katakana": [0xFF26],
        "Left": [0xFF51],
        "Meta": [0xFFE7, 0xFFE7, 0xFFE8],
        "ModeChange": [0xFF7E],
        "NumLock": [0xFF7F],
        "PageDown": [0xFF56],
        "PageUp": [0xFF55],
        "Pause": [0xFF13],
        "Play": [0xFD16],
        "PreviousCandidate": [0xFF3E],
        "PrintScreen": [0xFD1D],
        "Redo": [0xFF66],
        "Right": [0xFF53],
        "RomanCharacters": null,
        "Scroll": [0xFF14],
        "Select": [0xFF60],
        "Separator": [0xFFAC],
        "Shift": [0xFFE1, 0xFFE1, 0xFFE2],
        "SingleCandidate": [0xFF3C],
        "Super": [0xFFEB, 0xFFEB, 0xFFEC],
        "Tab": [0xFF09],
        "Up": [0xFF52],
        "Undo": [0xFF65],
        "Win": [0xFFEB],
        "Zenkaku": [0xFF28],
        "ZenkakuHankaku": [0xFF2A]
    };

    /**
     * All keysyms which should not repeat when held down.
     * @private
     */
    var no_repeat = {
        0xFE03: true, // ISO Level 3 Shift (AltGr)
        0xFFE1: true, // Left shift
        0xFFE2: true, // Right shift
        0xFFE3: true, // Left ctrl 
        0xFFE4: true, // Right ctrl 
        0xFFE7: true, // Left meta 
        0xFFE8: true, // Right meta 
        0xFFE9: true, // Left alt
        0xFFEA: true, // Right alt
        0xFFEB: true, // Left hyper
        0xFFEC: true  // Right hyper
    };

    /**
     * All modifiers and their states.
     */
    this.modifiers = new Guacamole.Keyboard.ModifierState();
        
    /**
     * The state of every key, indexed by keysym. If a particular key is
     * pressed, the value of pressed for that keysym will be true. If a key
     * is not currently pressed, it will not be defined. 
     */
    this.pressed = {};

    /**
     * The last result of calling the onkeydown handler for each key, indexed
     * by keysym. This is used to prevent/allow default actions for key events,
     * even when the onkeydown handler cannot be called again because the key
     * is (theoretically) still pressed.
     *
     * @private
     */
    var last_keydown_result = {};

    /**
     * The keysym most recently associated with a given keycode when keydown
     * fired. This object maps keycodes to keysyms.
     *
     * @private
     * @type {Object.<Number, Number>}
     */
    var recentKeysym = {};

    /**
     * Timeout before key repeat starts.
     * @private
     */
    var key_repeat_timeout = null;

    /**
     * Interval which presses and releases the last key pressed while that
     * key is still being held down.
     * @private
     */
    var key_repeat_interval = null;

    /**
     * Given an array of keysyms indexed by location, returns the keysym
     * for the given location, or the keysym for the standard location if
     * undefined.
     * 
     * @private
     * @param {Number[]} keysyms
     *     An array of keysyms, where the index of the keysym in the array is
     *     the location value.
     *
     * @param {Number} location
     *     The location on the keyboard corresponding to the key pressed, as
     *     defined at: http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
     */
    var get_keysym = function get_keysym(keysyms, location) {

        if (!keysyms)
            return null;

        return keysyms[location] || keysyms[0];
    };

    /**
     * Returns true if the given keysym corresponds to a printable character,
     * false otherwise.
     *
     * @param {Number} keysym
     *     The keysym to check.
     *
     * @returns {Boolean}
     *     true if the given keysym corresponds to a printable character,
     *     false otherwise.
     */
    var isPrintable = function isPrintable(keysym) {

        // Keysyms with Unicode equivalents are printable
        return (keysym >= 0x00 && keysym <= 0xFF)
            || (keysym & 0xFFFF0000) === 0x01000000;

    };

    function keysym_from_key_identifier(identifier, location, shifted) {

        if (!identifier)
            return null;

        var typedCharacter;

        // If identifier is U+xxxx, decode Unicode character 
        var unicodePrefixLocation = identifier.indexOf("U+");
        if (unicodePrefixLocation >= 0) {
            var hex = identifier.substring(unicodePrefixLocation+2);
            typedCharacter = String.fromCharCode(parseInt(hex, 16));
        }

        // If single character and not keypad, use that as typed character
        else if (identifier.length === 1 && location !== 3)
            typedCharacter = identifier;

        // Otherwise, look up corresponding keysym
        else
            return get_keysym(keyidentifier_keysym[identifier], location);

        // Alter case if necessary
        if (shifted === true)
            typedCharacter = typedCharacter.toUpperCase();
        else if (shifted === false)
            typedCharacter = typedCharacter.toLowerCase();

        // Get codepoint
        var codepoint = typedCharacter.charCodeAt(0);
        return keysym_from_charcode(codepoint);

    }

    function isControlCharacter(codepoint) {
        return codepoint <= 0x1F || (codepoint >= 0x7F && codepoint <= 0x9F);
    }

    function keysym_from_charcode(codepoint) {

        // Keysyms for control characters
        if (isControlCharacter(codepoint)) return 0xFF00 | codepoint;

        // Keysyms for ASCII chars
        if (codepoint >= 0x0000 && codepoint <= 0x00FF)
            return codepoint;

        // Keysyms for Unicode
        if (codepoint >= 0x0100 && codepoint <= 0x10FFFF)
            return 0x01000000 | codepoint;

        return null;

    }

    function keysym_from_keycode(keyCode, location) {
        return get_keysym(keycodeKeysyms[keyCode], location);
    }

    /**
     * Heuristically detects if the legacy keyIdentifier property of
     * a keydown/keyup event looks incorrectly derived. Chrome, and
     * presumably others, will produce the keyIdentifier by assuming
     * the keyCode is the Unicode codepoint for that key. This is not
     * correct in all cases.
     *
     * @private
     * @param {Number} keyCode
     *     The keyCode from a browser keydown/keyup event.
     *
     * @param {String} keyIdentifier
     *     The legacy keyIdentifier from a browser keydown/keyup event.
     *
     * @returns {Boolean}
     *     true if the keyIdentifier looks sane, false if the keyIdentifier
     *     appears incorrectly derived or is missing entirely.
     */
    var key_identifier_sane = function key_identifier_sane(keyCode, keyIdentifier) {

        // Missing identifier is not sane
        if (!keyIdentifier)
            return false;

        // Assume non-Unicode keyIdentifier values are sane
        var unicodePrefixLocation = keyIdentifier.indexOf("U+");
        if (unicodePrefixLocation === -1)
            return true;

        // If the Unicode codepoint isn't identical to the keyCode,
        // then the identifier is likely correct
        var codepoint = parseInt(keyIdentifier.substring(unicodePrefixLocation+2), 16);
        if (keyCode !== codepoint)
            return true;

        // The keyCodes for A-Z and 0-9 are actually identical to their
        // Unicode codepoints
        if ((keyCode >= 65 && keyCode <= 90) || (keyCode >= 48 && keyCode <= 57))
            return true;

        // The keyIdentifier does NOT appear sane
        return false;

    };

    /**
     * Marks a key as pressed, firing the keydown event if registered. Key
     * repeat for the pressed key will start after a delay if that key is
     * not a modifier. The return value of this function depends on the
     * return value of the keydown event handler, if any.
     * 
     * @param {Number} keysym The keysym of the key to press.
     * @return {Boolean} true if event should NOT be canceled, false otherwise.
     */
    this.press = function(keysym) {

        // Don't bother with pressing the key if the key is unknown
        if (keysym === null) return;

        // Only press if released
        if (!guac_keyboard.pressed[keysym]) {

            // Mark key as pressed
            guac_keyboard.pressed[keysym] = true;

            // Send key event
            if (guac_keyboard.onkeydown) {
                var result = guac_keyboard.onkeydown(keysym);
                last_keydown_result[keysym] = result;

                // Stop any current repeat
                window.clearTimeout(key_repeat_timeout);
                window.clearInterval(key_repeat_interval);

                // Repeat after a delay as long as pressed
                if (!no_repeat[keysym])
                    key_repeat_timeout = window.setTimeout(function() {
                        key_repeat_interval = window.setInterval(function() {
                            guac_keyboard.onkeyup(keysym);
                            guac_keyboard.onkeydown(keysym);
                        }, 50);
                    }, 500);

                return result;
            }
        }

        // Return the last keydown result by default, resort to false if unknown
        return last_keydown_result[keysym] || false;

    };

    /**
     * Marks a key as released, firing the keyup event if registered.
     * 
     * @param {Number} keysym The keysym of the key to release.
     */
    this.release = function(keysym) {

        // Only release if pressed
        if (guac_keyboard.pressed[keysym]) {
            
            // Mark key as released
            delete guac_keyboard.pressed[keysym];

            // Stop repeat
            window.clearTimeout(key_repeat_timeout);
            window.clearInterval(key_repeat_interval);

            // Send key event
            if (keysym !== null && guac_keyboard.onkeyup)
                guac_keyboard.onkeyup(keysym);

        }

    };

    /**
     * Resets the state of this keyboard, releasing all keys, and firing keyup
     * events for each released key.
     */
    this.reset = function() {

        // Release all pressed keys
        for (var keysym in guac_keyboard.pressed)
            guac_keyboard.release(parseInt(keysym));

        // Clear event log
        eventLog = [];

    };

    /**
     * Given a keyboard event, updates the local modifier state and remote
     * key state based on the modifier flags within the event. This function
     * pays no attention to keycodes.
     *
     * @private
     * @param {KeyboardEvent} e
     *     The keyboard event containing the flags to update.
     */
    var update_modifier_state = function update_modifier_state(e) {

        // Get state
        var state = Guacamole.Keyboard.ModifierState.fromKeyboardEvent(e);

        // Release alt if implicitly released
        if (guac_keyboard.modifiers.alt && state.alt === false) {
            guac_keyboard.release(0xFFE9); // Left alt
            guac_keyboard.release(0xFFEA); // Right alt
            guac_keyboard.release(0xFE03); // AltGr
        }

        // Release shift if implicitly released
        if (guac_keyboard.modifiers.shift && state.shift === false) {
            guac_keyboard.release(0xFFE1); // Left shift
            guac_keyboard.release(0xFFE2); // Right shift
        }

        // Release ctrl if implicitly released
        if (guac_keyboard.modifiers.ctrl && state.ctrl === false) {
            guac_keyboard.release(0xFFE3); // Left ctrl 
            guac_keyboard.release(0xFFE4); // Right ctrl 
        }

        // Release meta if implicitly released
        if (guac_keyboard.modifiers.meta && state.meta === false) {
            guac_keyboard.release(0xFFE7); // Left meta 
            guac_keyboard.release(0xFFE8); // Right meta 
        }

        // Release hyper if implicitly released
        if (guac_keyboard.modifiers.hyper && state.hyper === false) {
            guac_keyboard.release(0xFFEB); // Left hyper
            guac_keyboard.release(0xFFEC); // Right hyper
        }

        // Update state
        guac_keyboard.modifiers = state;

    };

    /**
     * Reads through the event log, removing events from the head of the log
     * when the corresponding true key presses are known (or as known as they
     * can be).
     * 
     * @private
     * @return {Boolean} Whether the default action of the latest event should
     *                   be prevented.
     */
    function interpret_events() {

        // Do not prevent default if no event could be interpreted
        var handled_event = interpret_event();
        if (!handled_event)
            return false;

        // Interpret as much as possible
        var last_event;
        do {
            last_event = handled_event;
            handled_event = interpret_event();
        } while (handled_event !== null);

        return last_event.defaultPrevented;

    }

    /**
     * Releases Ctrl+Alt, if both are currently pressed and the given keysym
     * looks like a key that may require AltGr.
     *
     * @private
     * @param {Number} keysym The key that was just pressed.
     */
    var release_simulated_altgr = function release_simulated_altgr(keysym) {

        // Both Ctrl+Alt must be pressed if simulated AltGr is in use
        if (!guac_keyboard.modifiers.ctrl || !guac_keyboard.modifiers.alt)
            return;

        // Assume [A-Z] never require AltGr
        if (keysym >= 0x0041 && keysym <= 0x005A)
            return;

        // Assume [a-z] never require AltGr
        if (keysym >= 0x0061 && keysym <= 0x007A)
            return;

        // Release Ctrl+Alt if the keysym is printable
        if (keysym <= 0xFF || (keysym & 0xFF000000) === 0x01000000) {
            guac_keyboard.release(0xFFE3); // Left ctrl 
            guac_keyboard.release(0xFFE4); // Right ctrl 
            guac_keyboard.release(0xFFE9); // Left alt
            guac_keyboard.release(0xFFEA); // Right alt
        }

    };

    /**
     * Reads through the event log, interpreting the first event, if possible,
     * and returning that event. If no events can be interpreted, due to a
     * total lack of events or the need for more events, null is returned. Any
     * interpreted events are automatically removed from the log.
     * 
     * @private
     * @return {KeyEvent}
     *     The first key event in the log, if it can be interpreted, or null
     *     otherwise.
     */
    var interpret_event = function interpret_event() {

        // Peek at first event in log
        var first = eventLog[0];
        if (!first)
            return null;

        // Keydown event
        if (first instanceof KeydownEvent) {

            var keysym = null;
            var accepted_events = [];

            // If event itself is reliable, no need to wait for other events
            if (first.reliable) {
                keysym = first.keysym;
                accepted_events = eventLog.splice(0, 1);
            }

            // If keydown is immediately followed by a keypress, use the indicated character
            else if (eventLog[1] instanceof KeypressEvent) {
                keysym = eventLog[1].keysym;
                accepted_events = eventLog.splice(0, 2);
            }

            // If keydown is immediately followed by anything else, then no
            // keypress can possibly occur to clarify this event, and we must
            // handle it now
            else if (eventLog[1]) {
                keysym = first.keysym;
                accepted_events = eventLog.splice(0, 1);
            }

            // Fire a key press if valid events were found
            if (accepted_events.length > 0) {

                if (keysym) {

                    // Fire event
                    release_simulated_altgr(keysym);
                    var defaultPrevented = !guac_keyboard.press(keysym);
                    recentKeysym[first.keyCode] = keysym;

                    // If a key is pressed while meta is held down, the keyup will
                    // never be sent in Chrome, so send it now. (bug #108404)
                    if (guac_keyboard.modifiers.meta && keysym !== 0xFFE7 && keysym !== 0xFFE8)
                        guac_keyboard.release(keysym);

                    // Record whether default was prevented
                    for (var i=0; i<accepted_events.length; i++)
                        accepted_events[i].defaultPrevented = defaultPrevented;

                }

                return first;

            }

        } // end if keydown

        // Keyup event
        else if (first instanceof KeyupEvent) {

            // Release specific key if known
            var keysym = first.keysym;
            if (keysym) {
                guac_keyboard.release(keysym);
                first.defaultPrevented = true;
            }

            // Otherwise, fall back to releasing all keys
            else {
                guac_keyboard.reset();
                return first;
            }

            return eventLog.shift();

        } // end if keyup

        // Ignore any other type of event (keypress by itself is invalid)
        else
            return eventLog.shift();

        // No event interpreted
        return null;

    };

    /**
     * Returns the keyboard location of the key associated with the given
     * keyboard event. The location differentiates key events which otherwise
     * have the same keycode, such as left shift vs. right shift.
     *
     * @private
     * @param {KeyboardEvent} e
     *     A JavaScript keyboard event, as received through the DOM via a
     *     "keydown", "keyup", or "keypress" handler.
     *
     * @returns {Number}
     *     The location of the key event on the keyboard, as defined at:
     *     http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent
     */
    var getEventLocation = function getEventLocation(e) {

        // Use standard location, if possible
        if ('location' in e)
            return e.location;

        // Failing that, attempt to use deprecated keyLocation
        if ('keyLocation' in e)
            return e.keyLocation;

        // If no location is available, assume left side
        return 0;

    };

    // When key pressed
    element.addEventListener("keydown", function(e) {

        // Only intercept if handler set
        if (!guac_keyboard.onkeydown) return;

        var keyCode;
        if (window.event) keyCode = window.event.keyCode;
        else if (e.which) keyCode = e.which;

        // Fix modifier states
        update_modifier_state(e);

        // Ignore (but do not prevent) the "composition" keycode sent by some
        // browsers when an IME is in use (see: http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html)
        if (keyCode === 229)
            return;

        // Log event
        var keydownEvent = new KeydownEvent(keyCode, e.keyIdentifier, e.key, getEventLocation(e));
        eventLog.push(keydownEvent);

        // Interpret as many events as possible, prevent default if indicated
        if (interpret_events())
            e.preventDefault();

    }, true);

    // When key pressed
    element.addEventListener("keypress", function(e) {

        // Only intercept if handler set
        if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;

        var charCode;
        if (window.event) charCode = window.event.keyCode;
        else if (e.which) charCode = e.which;

        // Fix modifier states
        update_modifier_state(e);

        // Log event
        var keypressEvent = new KeypressEvent(charCode);
        eventLog.push(keypressEvent);

        // Interpret as many events as possible, prevent default if indicated
        if (interpret_events())
            e.preventDefault();

    }, true);

    // When key released
    element.addEventListener("keyup", function(e) {

        // Only intercept if handler set
        if (!guac_keyboard.onkeyup) return;

        e.preventDefault();

        var keyCode;
        if (window.event) keyCode = window.event.keyCode;
        else if (e.which) keyCode = e.which;
        
        // Fix modifier states
        update_modifier_state(e);

        // Log event, call for interpretation
        var keyupEvent = new KeyupEvent(keyCode, e.keyIdentifier, e.key, getEventLocation(e));
        eventLog.push(keyupEvent);
        interpret_events();

    }, true);

};

/**
 * The state of all supported keyboard modifiers.
 * @constructor
 */
Guacamole.Keyboard.ModifierState = function() {
    
    /**
     * Whether shift is currently pressed.
     * @type {Boolean}
     */
    this.shift = false;
    
    /**
     * Whether ctrl is currently pressed.
     * @type {Boolean}
     */
    this.ctrl = false;
    
    /**
     * Whether alt is currently pressed.
     * @type {Boolean}
     */
    this.alt = false;
    
    /**
     * Whether meta (apple key) is currently pressed.
     * @type {Boolean}
     */
    this.meta = false;

    /**
     * Whether hyper (windows key) is currently pressed.
     * @type {Boolean}
     */
    this.hyper = false;
    
};

/**
 * Returns the modifier state applicable to the keyboard event given.
 * 
 * @param {KeyboardEvent} e The keyboard event to read.
 * @returns {Guacamole.Keyboard.ModifierState} The current state of keyboard
 *                                             modifiers.
 */
Guacamole.Keyboard.ModifierState.fromKeyboardEvent = function(e) {
    
    var state = new Guacamole.Keyboard.ModifierState();

    // Assign states from old flags
    state.shift = e.shiftKey;
    state.ctrl  = e.ctrlKey;
    state.alt   = e.altKey;
    state.meta  = e.metaKey;

    // Use DOM3 getModifierState() for others
    if (e.getModifierState) {
        state.hyper = e.getModifierState("OS")
                   || e.getModifierState("Super")
                   || e.getModifierState("Hyper")
                   || e.getModifierState("Win");
    }

    return state;
    
};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Abstract ordered drawing surface. Each Layer contains a canvas element and
 * provides simple drawing instructions for drawing to that canvas element,
 * however unlike the canvas element itself, drawing operations on a Layer are
 * guaranteed to run in order, even if such an operation must wait for an image
 * to load before completing.
 * 
 * @constructor
 * 
 * @param {Number} width The width of the Layer, in pixels. The canvas element
 *                       backing this Layer will be given this width.
 *                       
 * @param {Number} height The height of the Layer, in pixels. The canvas element
 *                        backing this Layer will be given this height.
 */
Guacamole.Layer = function(width, height) {

    /**
     * Reference to this Layer.
     * @private
     */
    var layer = this;

    /**
     * The number of pixels the width or height of a layer must change before
     * the underlying canvas is resized. The underlying canvas will be kept at
     * dimensions which are integer multiples of this factor.
     *
     * @private
     * @constant
     * @type Number
     */
    var CANVAS_SIZE_FACTOR = 64;

    /**
     * The canvas element backing this Layer.
     * @private
     */
    var canvas = document.createElement("canvas");

    /**
     * The 2D display context of the canvas element backing this Layer.
     * @private
     */
    var context = canvas.getContext("2d");
    context.save();

    /**
     * Whether the layer has not yet been drawn to. Once any draw operation
     * which affects the underlying canvas is invoked, this flag will be set to
     * false.
     *
     * @private
     * @type Boolean
     */
    var empty = true;

    /**
     * Whether a new path should be started with the next path drawing
     * operations.
     * @private
     */
    var pathClosed = true;

    /**
     * The number of states on the state stack.
     * 
     * Note that there will ALWAYS be one element on the stack, but that
     * element is not exposed. It is only used to reset the layer to its
     * initial state.
     * 
     * @private
     */
    var stackSize = 0;

    /**
     * Map of all Guacamole channel masks to HTML5 canvas composite operation
     * names. Not all channel mask combinations are currently implemented.
     * @private
     */
    var compositeOperation = {
     /* 0x0 NOT IMPLEMENTED */
        0x1: "destination-in",
        0x2: "destination-out",
     /* 0x3 NOT IMPLEMENTED */
        0x4: "source-in",
     /* 0x5 NOT IMPLEMENTED */
        0x6: "source-atop",
     /* 0x7 NOT IMPLEMENTED */
        0x8: "source-out",
        0x9: "destination-atop",
        0xA: "xor",
        0xB: "destination-over",
        0xC: "copy",
     /* 0xD NOT IMPLEMENTED */
        0xE: "source-over",
        0xF: "lighter"
    };

    /**
     * Resizes the canvas element backing this Layer. This function should only
     * be used internally.
     * 
     * @private
     * @param {Number} [newWidth=0]
     *     The new width to assign to this Layer.
     *
     * @param {Number} [newHeight=0]
     *     The new height to assign to this Layer.
     */
    var resize = function resize(newWidth, newHeight) {

        // Default size to zero
        newWidth = newWidth || 0;
        newHeight = newHeight || 0;

        // Calculate new dimensions of internal canvas
        var canvasWidth  = Math.ceil(newWidth  / CANVAS_SIZE_FACTOR) * CANVAS_SIZE_FACTOR;
        var canvasHeight = Math.ceil(newHeight / CANVAS_SIZE_FACTOR) * CANVAS_SIZE_FACTOR;

        // Resize only if canvas dimensions are actually changing
        if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {

            // Copy old data only if relevant and non-empty
            var oldData = null;
            if (!empty && canvas.width !== 0 && canvas.height !== 0) {

                // Create canvas and context for holding old data
                oldData = document.createElement("canvas");
                oldData.width = Math.min(layer.width, newWidth);
                oldData.height = Math.min(layer.height, newHeight);

                var oldDataContext = oldData.getContext("2d");

                // Copy image data from current
                oldDataContext.drawImage(canvas,
                        0, 0, oldData.width, oldData.height,
                        0, 0, oldData.width, oldData.height);

            }

            // Preserve composite operation
            var oldCompositeOperation = context.globalCompositeOperation;

            // Resize canvas
            canvas.width = canvasWidth;
            canvas.height = canvasHeight;

            // Redraw old data, if any
            if (oldData)
                context.drawImage(oldData,
                    0, 0, oldData.width, oldData.height,
                    0, 0, oldData.width, oldData.height);

            // Restore composite operation
            context.globalCompositeOperation = oldCompositeOperation;

            // Acknowledge reset of stack (happens on resize of canvas)
            stackSize = 0;
            context.save();

        }

        // If the canvas size is not changing, manually force state reset
        else
            layer.reset();

        // Assign new layer dimensions
        layer.width = newWidth;
        layer.height = newHeight;

    };

    /**
     * Given the X and Y coordinates of the upper-left corner of a rectangle
     * and the rectangle's width and height, resize the backing canvas element
     * as necessary to ensure that the rectangle fits within the canvas
     * element's coordinate space. This function will only make the canvas
     * larger. If the rectangle already fits within the canvas element's
     * coordinate space, the canvas is left unchanged.
     * 
     * @private
     * @param {Number} x The X coordinate of the upper-left corner of the
     *                   rectangle to fit.
     * @param {Number} y The Y coordinate of the upper-left corner of the
     *                   rectangle to fit.
     * @param {Number} w The width of the the rectangle to fit.
     * @param {Number} h The height of the the rectangle to fit.
     */
    function fitRect(x, y, w, h) {
        
        // Calculate bounds
        var opBoundX = w + x;
        var opBoundY = h + y;
        
        // Determine max width
        var resizeWidth;
        if (opBoundX > layer.width)
            resizeWidth = opBoundX;
        else
            resizeWidth = layer.width;

        // Determine max height
        var resizeHeight;
        if (opBoundY > layer.height)
            resizeHeight = opBoundY;
        else
            resizeHeight = layer.height;

        // Resize if necessary
        layer.resize(resizeWidth, resizeHeight);

    }

    /**
     * Set to true if this Layer should resize itself to accomodate the
     * dimensions of any drawing operation, and false (the default) otherwise.
     * 
     * Note that setting this property takes effect immediately, and thus may
     * take effect on operations that were started in the past but have not
     * yet completed. If you wish the setting of this flag to only modify
     * future operations, you will need to make the setting of this flag an
     * operation with sync().
     * 
     * @example
     * // Set autosize to true for all future operations
     * layer.sync(function() {
     *     layer.autosize = true;
     * });
     * 
     * @type {Boolean}
     * @default false
     */
    this.autosize = false;

    /**
     * The current width of this layer.
     * @type {Number}
     */
    this.width = width;

    /**
     * The current height of this layer.
     * @type {Number}
     */
    this.height = height;

    /**
     * Returns the canvas element backing this Layer. Note that the dimensions
     * of the canvas may not exactly match those of the Layer, as resizing a
     * canvas while maintaining its state is an expensive operation.
     *
     * @returns {HTMLCanvasElement}
     *     The canvas element backing this Layer.
     */
    this.getCanvas = function getCanvas() {
        return canvas;
    };

    /**
     * Returns a new canvas element containing the same image as this Layer.
     * Unlike getCanvas(), the canvas element returned is guaranteed to have
     * the exact same dimensions as the Layer.
     *
     * @returns {HTMLCanvasElement}
     *     A new canvas element containing a copy of the image content this
     *     Layer.
     */
    this.toCanvas = function toCanvas() {

        // Create new canvas having same dimensions
        var canvas = document.createElement('canvas');
        canvas.width = layer.width;
        canvas.height = layer.height;

        // Copy image contents to new canvas
        var context = canvas.getContext('2d');
        context.drawImage(layer.getCanvas(), 0, 0);

        return canvas;

    };

    /**
     * Changes the size of this Layer to the given width and height. Resizing
     * is only attempted if the new size provided is actually different from
     * the current size.
     * 
     * @param {Number} newWidth The new width to assign to this Layer.
     * @param {Number} newHeight The new height to assign to this Layer.
     */
    this.resize = function(newWidth, newHeight) {
        if (newWidth !== layer.width || newHeight !== layer.height)
            resize(newWidth, newHeight);
    };

    /**
     * Draws the specified image at the given coordinates. The image specified
     * must already be loaded.
     * 
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     * @param {Image} image The image to draw. Note that this is an Image
     *                      object - not a URL.
     */
    this.drawImage = function(x, y, image) {
        if (layer.autosize) fitRect(x, y, image.width, image.height);
        context.drawImage(image, x, y);
        empty = false;
    };

    /**
     * Transfer a rectangle of image data from one Layer to this Layer using the
     * specified transfer function.
     * 
     * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
     * @param {Number} srcx The X coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcy The Y coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcw The width of the rectangle within the source Layer's
     *                      coordinate space to copy data from.
     * @param {Number} srch The height of the rectangle within the source
     *                      Layer's coordinate space to copy data from.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     * @param {Function} transferFunction The transfer function to use to
     *                                    transfer data from source to
     *                                    destination.
     */
    this.transfer = function(srcLayer, srcx, srcy, srcw, srch, x, y, transferFunction) {

        var srcCanvas = srcLayer.getCanvas();

        // If entire rectangle outside source canvas, stop
        if (srcx >= srcCanvas.width || srcy >= srcCanvas.height) return;

        // Otherwise, clip rectangle to area
        if (srcx + srcw > srcCanvas.width)
            srcw = srcCanvas.width - srcx;

        if (srcy + srch > srcCanvas.height)
            srch = srcCanvas.height - srcy;

        // Stop if nothing to draw.
        if (srcw === 0 || srch === 0) return;

        if (layer.autosize) fitRect(x, y, srcw, srch);

        // Get image data from src and dst
        var src = srcLayer.getCanvas().getContext("2d").getImageData(srcx, srcy, srcw, srch);
        var dst = context.getImageData(x , y, srcw, srch);

        // Apply transfer for each pixel
        for (var i=0; i<srcw*srch*4; i+=4) {

            // Get source pixel environment
            var src_pixel = new Guacamole.Layer.Pixel(
                src.data[i],
                src.data[i+1],
                src.data[i+2],
                src.data[i+3]
            );
                
            // Get destination pixel environment
            var dst_pixel = new Guacamole.Layer.Pixel(
                dst.data[i],
                dst.data[i+1],
                dst.data[i+2],
                dst.data[i+3]
            );

            // Apply transfer function
            transferFunction(src_pixel, dst_pixel);

            // Save pixel data
            dst.data[i  ] = dst_pixel.red;
            dst.data[i+1] = dst_pixel.green;
            dst.data[i+2] = dst_pixel.blue;
            dst.data[i+3] = dst_pixel.alpha;

        }

        // Draw image data
        context.putImageData(dst, x, y);
        empty = false;

    };

    /**
     * Put a rectangle of image data from one Layer to this Layer directly
     * without performing any alpha blending. Simply copy the data.
     * 
     * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
     * @param {Number} srcx The X coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcy The Y coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcw The width of the rectangle within the source Layer's
     *                      coordinate space to copy data from.
     * @param {Number} srch The height of the rectangle within the source
     *                      Layer's coordinate space to copy data from.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     */
    this.put = function(srcLayer, srcx, srcy, srcw, srch, x, y) {

        var srcCanvas = srcLayer.getCanvas();

        // If entire rectangle outside source canvas, stop
        if (srcx >= srcCanvas.width || srcy >= srcCanvas.height) return;

        // Otherwise, clip rectangle to area
        if (srcx + srcw > srcCanvas.width)
            srcw = srcCanvas.width - srcx;

        if (srcy + srch > srcCanvas.height)
            srch = srcCanvas.height - srcy;

        // Stop if nothing to draw.
        if (srcw === 0 || srch === 0) return;

        if (layer.autosize) fitRect(x, y, srcw, srch);

        // Get image data from src and dst
        var src = srcLayer.getCanvas().getContext("2d").getImageData(srcx, srcy, srcw, srch);
        context.putImageData(src, x, y);
        empty = false;

    };

    /**
     * Copy a rectangle of image data from one Layer to this Layer. This
     * operation will copy exactly the image data that will be drawn once all
     * operations of the source Layer that were pending at the time this
     * function was called are complete. This operation will not alter the
     * size of the source Layer even if its autosize property is set to true.
     * 
     * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
     * @param {Number} srcx The X coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcy The Y coordinate of the upper-left corner of the
     *                      rectangle within the source Layer's coordinate
     *                      space to copy data from.
     * @param {Number} srcw The width of the rectangle within the source Layer's
     *                      coordinate space to copy data from.
     * @param {Number} srch The height of the rectangle within the source
     *                      Layer's coordinate space to copy data from.
     * @param {Number} x The destination X coordinate.
     * @param {Number} y The destination Y coordinate.
     */
    this.copy = function(srcLayer, srcx, srcy, srcw, srch, x, y) {

        var srcCanvas = srcLayer.getCanvas();

        // If entire rectangle outside source canvas, stop
        if (srcx >= srcCanvas.width || srcy >= srcCanvas.height) return;

        // Otherwise, clip rectangle to area
        if (srcx + srcw > srcCanvas.width)
            srcw = srcCanvas.width - srcx;

        if (srcy + srch > srcCanvas.height)
            srch = srcCanvas.height - srcy;

        // Stop if nothing to draw.
        if (srcw === 0 || srch === 0) return;

        if (layer.autosize) fitRect(x, y, srcw, srch);
        context.drawImage(srcCanvas, srcx, srcy, srcw, srch, x, y, srcw, srch);
        empty = false;

    };

    /**
     * Starts a new path at the specified point.
     * 
     * @param {Number} x The X coordinate of the point to draw.
     * @param {Number} y The Y coordinate of the point to draw.
     */
    this.moveTo = function(x, y) {
        
        // Start a new path if current path is closed
        if (pathClosed) {
            context.beginPath();
            pathClosed = false;
        }
        
        if (layer.autosize) fitRect(x, y, 0, 0);
        context.moveTo(x, y);

    };

    /**
     * Add the specified line to the current path.
     * 
     * @param {Number} x The X coordinate of the endpoint of the line to draw.
     * @param {Number} y The Y coordinate of the endpoint of the line to draw.
     */
    this.lineTo = function(x, y) {
        
        // Start a new path if current path is closed
        if (pathClosed) {
            context.beginPath();
            pathClosed = false;
        }
        
        if (layer.autosize) fitRect(x, y, 0, 0);
        context.lineTo(x, y);
        
    };

    /**
     * Add the specified arc to the current path.
     * 
     * @param {Number} x The X coordinate of the center of the circle which
     *                   will contain the arc.
     * @param {Number} y The Y coordinate of the center of the circle which
     *                   will contain the arc.
     * @param {Number} radius The radius of the circle.
     * @param {Number} startAngle The starting angle of the arc, in radians.
     * @param {Number} endAngle The ending angle of the arc, in radians.
     * @param {Boolean} negative Whether the arc should be drawn in order of
     *                           decreasing angle.
     */
    this.arc = function(x, y, radius, startAngle, endAngle, negative) {
        
        // Start a new path if current path is closed
        if (pathClosed) {
            context.beginPath();
            pathClosed = false;
        }
        
        if (layer.autosize) fitRect(x, y, 0, 0);
        context.arc(x, y, radius, startAngle, endAngle, negative);
        
    };

    /**
     * Starts a new path at the specified point.
     * 
     * @param {Number} cp1x The X coordinate of the first control point.
     * @param {Number} cp1y The Y coordinate of the first control point.
     * @param {Number} cp2x The X coordinate of the second control point.
     * @param {Number} cp2y The Y coordinate of the second control point.
     * @param {Number} x The X coordinate of the endpoint of the curve.
     * @param {Number} y The Y coordinate of the endpoint of the curve.
     */
    this.curveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
        
        // Start a new path if current path is closed
        if (pathClosed) {
            context.beginPath();
            pathClosed = false;
        }
        
        if (layer.autosize) fitRect(x, y, 0, 0);
        context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
        
    };

    /**
     * Closes the current path by connecting the end point with the start
     * point (if any) with a straight line.
     */
    this.close = function() {
        context.closePath();
        pathClosed = true;
    };

    /**
     * Add the specified rectangle to the current path.
     * 
     * @param {Number} x The X coordinate of the upper-left corner of the
     *                   rectangle to draw.
     * @param {Number} y The Y coordinate of the upper-left corner of the
     *                   rectangle to draw.
     * @param {Number} w The width of the rectangle to draw.
     * @param {Number} h The height of the rectangle to draw.
     */
    this.rect = function(x, y, w, h) {
            
        // Start a new path if current path is closed
        if (pathClosed) {
            context.beginPath();
            pathClosed = false;
        }
        
        if (layer.autosize) fitRect(x, y, w, h);
        context.rect(x, y, w, h);
        
    };

    /**
     * Clip all future drawing operations by the current path. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as fillColor()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     */
    this.clip = function() {

        // Set new clipping region
        context.clip();

        // Path now implicitly closed
        pathClosed = true;

    };

    /**
     * Stroke the current path with the specified color. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {String} cap The line cap style. Can be "round", "square",
     *                     or "butt".
     * @param {String} join The line join style. Can be "round", "bevel",
     *                      or "miter".
     * @param {Number} thickness The line thickness in pixels.
     * @param {Number} r The red component of the color to fill.
     * @param {Number} g The green component of the color to fill.
     * @param {Number} b The blue component of the color to fill.
     * @param {Number} a The alpha component of the color to fill.
     */
    this.strokeColor = function(cap, join, thickness, r, g, b, a) {

        // Stroke with color
        context.lineCap = cap;
        context.lineJoin = join;
        context.lineWidth = thickness;
        context.strokeStyle = "rgba(" + r + "," + g + "," + b + "," + a/255.0 + ")";
        context.stroke();
        empty = false;

        // Path now implicitly closed
        pathClosed = true;

    };

    /**
     * Fills the current path with the specified color. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {Number} r The red component of the color to fill.
     * @param {Number} g The green component of the color to fill.
     * @param {Number} b The blue component of the color to fill.
     * @param {Number} a The alpha component of the color to fill.
     */
    this.fillColor = function(r, g, b, a) {

        // Fill with color
        context.fillStyle = "rgba(" + r + "," + g + "," + b + "," + a/255.0 + ")";
        context.fill();
        empty = false;

        // Path now implicitly closed
        pathClosed = true;

    };

    /**
     * Stroke the current path with the image within the specified layer. The
     * image data will be tiled infinitely within the stroke. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {String} cap The line cap style. Can be "round", "square",
     *                     or "butt".
     * @param {String} join The line join style. Can be "round", "bevel",
     *                      or "miter".
     * @param {Number} thickness The line thickness in pixels.
     * @param {Guacamole.Layer} srcLayer The layer to use as a repeating pattern
     *                                   within the stroke.
     */
    this.strokeLayer = function(cap, join, thickness, srcLayer) {

        // Stroke with image data
        context.lineCap = cap;
        context.lineJoin = join;
        context.lineWidth = thickness;
        context.strokeStyle = context.createPattern(
            srcLayer.getCanvas(),
            "repeat"
        );
        context.stroke();
        empty = false;

        // Path now implicitly closed
        pathClosed = true;

    };

    /**
     * Fills the current path with the image within the specified layer. The
     * image data will be tiled infinitely within the stroke. The current path
     * is implicitly closed. The current path can continue to be reused
     * for other operations (such as clip()) but a new path will be started
     * once a path drawing operation (path() or rect()) is used.
     * 
     * @param {Guacamole.Layer} srcLayer The layer to use as a repeating pattern
     *                                   within the fill.
     */
    this.fillLayer = function(srcLayer) {

        // Fill with image data 
        context.fillStyle = context.createPattern(
            srcLayer.getCanvas(),
            "repeat"
        );
        context.fill();
        empty = false;

        // Path now implicitly closed
        pathClosed = true;

    };

    /**
     * Push current layer state onto stack.
     */
    this.push = function() {

        // Save current state onto stack
        context.save();
        stackSize++;

    };

    /**
     * Pop layer state off stack.
     */
    this.pop = function() {

        // Restore current state from stack
        if (stackSize > 0) {
            context.restore();
            stackSize--;
        }

    };

    /**
     * Reset the layer, clearing the stack, the current path, and any transform
     * matrix.
     */
    this.reset = function() {

        // Clear stack
        while (stackSize > 0) {
            context.restore();
            stackSize--;
        }

        // Restore to initial state
        context.restore();
        context.save();

        // Clear path
        context.beginPath();
        pathClosed = false;

    };

    /**
     * Sets the given affine transform (defined with six values from the
     * transform's matrix).
     * 
     * @param {Number} a The first value in the affine transform's matrix.
     * @param {Number} b The second value in the affine transform's matrix.
     * @param {Number} c The third value in the affine transform's matrix.
     * @param {Number} d The fourth value in the affine transform's matrix.
     * @param {Number} e The fifth value in the affine transform's matrix.
     * @param {Number} f The sixth value in the affine transform's matrix.
     */
    this.setTransform = function(a, b, c, d, e, f) {
        context.setTransform(
            a, b, c,
            d, e, f
          /*0, 0, 1*/
        );
    };

    /**
     * Applies the given affine transform (defined with six values from the
     * transform's matrix).
     * 
     * @param {Number} a The first value in the affine transform's matrix.
     * @param {Number} b The second value in the affine transform's matrix.
     * @param {Number} c The third value in the affine transform's matrix.
     * @param {Number} d The fourth value in the affine transform's matrix.
     * @param {Number} e The fifth value in the affine transform's matrix.
     * @param {Number} f The sixth value in the affine transform's matrix.
     */
    this.transform = function(a, b, c, d, e, f) {
        context.transform(
            a, b, c,
            d, e, f
          /*0, 0, 1*/
        );
    };

    /**
     * Sets the channel mask for future operations on this Layer.
     * 
     * The channel mask is a Guacamole-specific compositing operation identifier
     * with a single bit representing each of four channels (in order): source
     * image where destination transparent, source where destination opaque,
     * destination where source transparent, and destination where source
     * opaque.
     * 
     * @param {Number} mask The channel mask for future operations on this
     *                      Layer.
     */
    this.setChannelMask = function(mask) {
        context.globalCompositeOperation = compositeOperation[mask];
    };

    /**
     * Sets the miter limit for stroke operations using the miter join. This
     * limit is the maximum ratio of the size of the miter join to the stroke
     * width. If this ratio is exceeded, the miter will not be drawn for that
     * joint of the path.
     * 
     * @param {Number} limit The miter limit for stroke operations using the
     *                       miter join.
     */
    this.setMiterLimit = function(limit) {
        context.miterLimit = limit;
    };

    // Initialize canvas dimensions
    resize(width, height);

    // Explicitly render canvas below other elements in the layer (such as
    // child layers). Chrome and others may fail to render layers properly
    // without this.
    canvas.style.zIndex = -1;

};

/**
 * Channel mask for the composite operation "rout".
 */
Guacamole.Layer.ROUT  = 0x2;

/**
 * Channel mask for the composite operation "atop".
 */
Guacamole.Layer.ATOP  = 0x6;

/**
 * Channel mask for the composite operation "xor".
 */
Guacamole.Layer.XOR   = 0xA;

/**
 * Channel mask for the composite operation "rover".
 */
Guacamole.Layer.ROVER = 0xB;

/**
 * Channel mask for the composite operation "over".
 */
Guacamole.Layer.OVER  = 0xE;

/**
 * Channel mask for the composite operation "plus".
 */
Guacamole.Layer.PLUS  = 0xF;

/**
 * Channel mask for the composite operation "rin".
 * Beware that WebKit-based browsers may leave the contents of the destionation
 * layer where the source layer is transparent, despite the definition of this
 * operation.
 */
Guacamole.Layer.RIN   = 0x1;

/**
 * Channel mask for the composite operation "in".
 * Beware that WebKit-based browsers may leave the contents of the destionation
 * layer where the source layer is transparent, despite the definition of this
 * operation.
 */
Guacamole.Layer.IN    = 0x4;

/**
 * Channel mask for the composite operation "out".
 * Beware that WebKit-based browsers may leave the contents of the destionation
 * layer where the source layer is transparent, despite the definition of this
 * operation.
 */
Guacamole.Layer.OUT   = 0x8;

/**
 * Channel mask for the composite operation "ratop".
 * Beware that WebKit-based browsers may leave the contents of the destionation
 * layer where the source layer is transparent, despite the definition of this
 * operation.
 */
Guacamole.Layer.RATOP = 0x9;

/**
 * Channel mask for the composite operation "src".
 * Beware that WebKit-based browsers may leave the contents of the destionation
 * layer where the source layer is transparent, despite the definition of this
 * operation.
 */
Guacamole.Layer.SRC   = 0xC;

/**
 * Represents a single pixel of image data. All components have a minimum value
 * of 0 and a maximum value of 255.
 * 
 * @constructor
 * 
 * @param {Number} r The red component of this pixel.
 * @param {Number} g The green component of this pixel.
 * @param {Number} b The blue component of this pixel.
 * @param {Number} a The alpha component of this pixel.
 */
Guacamole.Layer.Pixel = function(r, g, b, a) {

    /**
     * The red component of this pixel, where 0 is the minimum value,
     * and 255 is the maximum.
     */
    this.red   = r;

    /**
     * The green component of this pixel, where 0 is the minimum value,
     * and 255 is the maximum.
     */
    this.green = g;

    /**
     * The blue component of this pixel, where 0 is the minimum value,
     * and 255 is the maximum.
     */
    this.blue  = b;

    /**
     * The alpha component of this pixel, where 0 is the minimum value,
     * and 255 is the maximum.
     */
    this.alpha = a;

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Provides cross-browser mouse events for a given element. The events of
 * the given element are automatically populated with handlers that translate
 * mouse events into a non-browser-specific event provided by the
 * Guacamole.Mouse instance.
 * 
 * @constructor
 * @param {Element} element The Element to use to provide mouse events.
 */
Guacamole.Mouse = function(element) {

    /**
     * Reference to this Guacamole.Mouse.
     * @private
     */
    var guac_mouse = this;

    /**
     * The number of mousemove events to require before re-enabling mouse
     * event handling after receiving a touch event.
     */
    this.touchMouseThreshold = 3;

    /**
     * The minimum amount of pixels scrolled required for a single scroll button
     * click.
     */
    this.scrollThreshold = 53;

    /**
     * The number of pixels to scroll per line.
     */
    this.PIXELS_PER_LINE = 18;

    /**
     * The number of pixels to scroll per page.
     */
    this.PIXELS_PER_PAGE = this.PIXELS_PER_LINE * 16;

    /**
     * The current mouse state. The properties of this state are updated when
     * mouse events fire. This state object is also passed in as a parameter to
     * the handler of any mouse events.
     * 
     * @type {Guacamole.Mouse.State}
     */
    this.currentState = new Guacamole.Mouse.State(
        0, 0, 
        false, false, false, false, false
    );

    /**
     * Fired whenever the user presses a mouse button down over the element
     * associated with this Guacamole.Mouse.
     * 
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmousedown = null;

    /**
     * Fired whenever the user releases a mouse button down over the element
     * associated with this Guacamole.Mouse.
     * 
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmouseup = null;

    /**
     * Fired whenever the user moves the mouse over the element associated with
     * this Guacamole.Mouse.
     * 
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmousemove = null;

    /**
     * Fired whenever the mouse leaves the boundaries of the element associated
     * with this Guacamole.Mouse.
     * 
     * @event
     */
	this.onmouseout = null;

    /**
     * Counter of mouse events to ignore. This decremented by mousemove, and
     * while non-zero, mouse events will have no effect.
     * @private
     */
    var ignore_mouse = 0;

    /**
     * Cumulative scroll delta amount. This value is accumulated through scroll
     * events and results in scroll button clicks if it exceeds a certain
     * threshold.
     *
     * @private
     */
    var scroll_delta = 0;

    function cancelEvent(e) {
        e.stopPropagation();
        if (e.preventDefault) e.preventDefault();
        e.returnValue = false;
    }

    // Block context menu so right-click gets sent properly
    element.addEventListener("contextmenu", function(e) {
        cancelEvent(e);
    }, false);

    element.addEventListener("mousemove", function(e) {

        cancelEvent(e);

        // If ignoring events, decrement counter
        if (ignore_mouse) {
            ignore_mouse--;
            return;
        }

        guac_mouse.currentState.fromClientPosition(element, e.clientX, e.clientY);

        if (guac_mouse.onmousemove)
            guac_mouse.onmousemove(guac_mouse.currentState);

    }, false);

    element.addEventListener("mousedown", function(e) {

        cancelEvent(e);

        // Do not handle if ignoring events
        if (ignore_mouse)
            return;

        switch (e.button) {
            case 0:
                guac_mouse.currentState.left = true;
                break;
            case 1:
                guac_mouse.currentState.middle = true;
                break;
            case 2:
                guac_mouse.currentState.right = true;
                break;
        }

        if (guac_mouse.onmousedown)
            guac_mouse.onmousedown(guac_mouse.currentState);

    }, false);

    element.addEventListener("mouseup", function(e) {

        cancelEvent(e);

        // Do not handle if ignoring events
        if (ignore_mouse)
            return;

        switch (e.button) {
            case 0:
                guac_mouse.currentState.left = false;
                break;
            case 1:
                guac_mouse.currentState.middle = false;
                break;
            case 2:
                guac_mouse.currentState.right = false;
                break;
        }

        if (guac_mouse.onmouseup)
            guac_mouse.onmouseup(guac_mouse.currentState);

    }, false);

    element.addEventListener("mouseout", function(e) {

        // Get parent of the element the mouse pointer is leaving
       	if (!e) e = window.event;

        // Check that mouseout is due to actually LEAVING the element
        var target = e.relatedTarget || e.toElement;
        while (target) {
            if (target === element)
                return;
            target = target.parentNode;
        }

        cancelEvent(e);

        // Release all buttons
        if (guac_mouse.currentState.left
            || guac_mouse.currentState.middle
            || guac_mouse.currentState.right) {

            guac_mouse.currentState.left = false;
            guac_mouse.currentState.middle = false;
            guac_mouse.currentState.right = false;

            if (guac_mouse.onmouseup)
                guac_mouse.onmouseup(guac_mouse.currentState);
        }

        // Fire onmouseout event
        if (guac_mouse.onmouseout)
            guac_mouse.onmouseout();

    }, false);

    // Override selection on mouse event element.
    element.addEventListener("selectstart", function(e) {
        cancelEvent(e);
    }, false);

    // Ignore all pending mouse events when touch events are the apparent source
    function ignorePendingMouseEvents() { ignore_mouse = guac_mouse.touchMouseThreshold; }

    element.addEventListener("touchmove",  ignorePendingMouseEvents, false);
    element.addEventListener("touchstart", ignorePendingMouseEvents, false);
    element.addEventListener("touchend",   ignorePendingMouseEvents, false);

    // Scroll wheel support
    function mousewheel_handler(e) {

        // Determine approximate scroll amount (in pixels)
        var delta = e.deltaY || -e.wheelDeltaY || -e.wheelDelta;

        // If successfully retrieved scroll amount, convert to pixels if not
        // already in pixels
        if (delta) {

            // Convert to pixels if delta was lines
            if (e.deltaMode === 1)
                delta = e.deltaY * guac_mouse.PIXELS_PER_LINE;

            // Convert to pixels if delta was pages
            else if (e.deltaMode === 2)
                delta = e.deltaY * guac_mouse.PIXELS_PER_PAGE;

        }

        // Otherwise, assume legacy mousewheel event and line scrolling
        else
            delta = e.detail * guac_mouse.PIXELS_PER_LINE;
        
        // Update overall delta
        scroll_delta += delta;

        // Up
        if (scroll_delta <= -guac_mouse.scrollThreshold) {

            // Repeatedly click the up button until insufficient delta remains
            do {

                if (guac_mouse.onmousedown) {
                    guac_mouse.currentState.up = true;
                    guac_mouse.onmousedown(guac_mouse.currentState);
                }

                if (guac_mouse.onmouseup) {
                    guac_mouse.currentState.up = false;
                    guac_mouse.onmouseup(guac_mouse.currentState);
                }

                scroll_delta += guac_mouse.scrollThreshold;

            } while (scroll_delta <= -guac_mouse.scrollThreshold);

            // Reset delta
            scroll_delta = 0;

        }

        // Down
        if (scroll_delta >= guac_mouse.scrollThreshold) {

            // Repeatedly click the down button until insufficient delta remains
            do {

                if (guac_mouse.onmousedown) {
                    guac_mouse.currentState.down = true;
                    guac_mouse.onmousedown(guac_mouse.currentState);
                }

                if (guac_mouse.onmouseup) {
                    guac_mouse.currentState.down = false;
                    guac_mouse.onmouseup(guac_mouse.currentState);
                }

                scroll_delta -= guac_mouse.scrollThreshold;

            } while (scroll_delta >= guac_mouse.scrollThreshold);

            // Reset delta
            scroll_delta = 0;

        }

        cancelEvent(e);

    }

    element.addEventListener('DOMMouseScroll', mousewheel_handler, false);
    element.addEventListener('mousewheel',     mousewheel_handler, false);
    element.addEventListener('wheel',          mousewheel_handler, false);

    /**
     * Whether the browser supports CSS3 cursor styling, including hotspot
     * coordinates.
     *
     * @private
     * @type {Boolean}
     */
    var CSS3_CURSOR_SUPPORTED = (function() {

        var div = document.createElement("div");

        // If no cursor property at all, then no support
        if (!("cursor" in div.style))
            return false;

        try {
            // Apply simple 1x1 PNG
            div.style.cursor = "url(data:image/png;base64,"
                             + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
                             + "AQMAAAAl21bKAAAAA1BMVEX///+nxBvI"
                             + "AAAACklEQVQI12NgAAAAAgAB4iG8MwAA"
                             + "AABJRU5ErkJggg==) 0 0, auto";
        }
        catch (e) {
            return false;
        }

        // Verify cursor property is set to URL with hotspot
        return /\burl\([^()]*\)\s+0\s+0\b/.test(div.style.cursor || "");

    })();

    /**
     * Changes the local mouse cursor to the given canvas, having the given
     * hotspot coordinates. This affects styling of the element backing this
     * Guacamole.Mouse only, and may fail depending on browser support for
     * setting the mouse cursor.
     * 
     * If setting the local cursor is desired, it is up to the implementation
     * to do something else, such as use the software cursor built into
     * Guacamole.Display, if the local cursor cannot be set.
     *
     * @param {HTMLCanvasElement} canvas The cursor image.
     * @param {Number} x The X-coordinate of the cursor hotspot.
     * @param {Number} y The Y-coordinate of the cursor hotspot.
     * @return {Boolean} true if the cursor was successfully set, false if the
     *                   cursor could not be set for any reason.
     */
    this.setCursor = function(canvas, x, y) {

        // Attempt to set via CSS3 cursor styling
        if (CSS3_CURSOR_SUPPORTED) {
            var dataURL = canvas.toDataURL('image/png');
            element.style.cursor = "url(" + dataURL + ") " + x + " " + y + ", auto";
            return true;
        }

        // Otherwise, setting cursor failed
        return false;

    };

};

/**
 * Simple container for properties describing the state of a mouse.
 * 
 * @constructor
 * @param {Number} x The X position of the mouse pointer in pixels.
 * @param {Number} y The Y position of the mouse pointer in pixels.
 * @param {Boolean} left Whether the left mouse button is pressed. 
 * @param {Boolean} middle Whether the middle mouse button is pressed. 
 * @param {Boolean} right Whether the right mouse button is pressed. 
 * @param {Boolean} up Whether the up mouse button is pressed (the fourth
 *                     button, usually part of a scroll wheel). 
 * @param {Boolean} down Whether the down mouse button is pressed (the fifth
 *                       button, usually part of a scroll wheel). 
 */
Guacamole.Mouse.State = function(x, y, left, middle, right, up, down) {

    /**
     * Reference to this Guacamole.Mouse.State.
     * @private
     */
    var guac_state = this;

    /**
     * The current X position of the mouse pointer.
     * @type {Number}
     */
    this.x = x;

    /**
     * The current Y position of the mouse pointer.
     * @type {Number}
     */
    this.y = y;

    /**
     * Whether the left mouse button is currently pressed.
     * @type {Boolean}
     */
    this.left = left;

    /**
     * Whether the middle mouse button is currently pressed.
     * @type {Boolean}
     */
    this.middle = middle;

    /**
     * Whether the right mouse button is currently pressed.
     * @type {Boolean}
     */
    this.right = right;

    /**
     * Whether the up mouse button is currently pressed. This is the fourth
     * mouse button, associated with upward scrolling of the mouse scroll
     * wheel.
     * @type {Boolean}
     */
    this.up = up;

    /**
     * Whether the down mouse button is currently pressed. This is the fifth 
     * mouse button, associated with downward scrolling of the mouse scroll
     * wheel.
     * @type {Boolean}
     */
    this.down = down;

    /**
     * Updates the position represented within this state object by the given
     * element and clientX/clientY coordinates (commonly available within event
     * objects). Position is translated from clientX/clientY (relative to
     * viewport) to element-relative coordinates.
     * 
     * @param {Element} element The element the coordinates should be relative
     *                          to.
     * @param {Number} clientX The X coordinate to translate, viewport-relative.
     * @param {Number} clientY The Y coordinate to translate, viewport-relative.
     */
    this.fromClientPosition = function(element, clientX, clientY) {
    
        guac_state.x = clientX - element.offsetLeft;
        guac_state.y = clientY - element.offsetTop;

        // This is all JUST so we can get the mouse position within the element
        var parent = element.offsetParent;
        while (parent && !(parent === document.body)) {
            guac_state.x -= parent.offsetLeft - parent.scrollLeft;
            guac_state.y -= parent.offsetTop  - parent.scrollTop;

            parent = parent.offsetParent;
        }

        // Element ultimately depends on positioning within document body,
        // take document scroll into account. 
        if (parent) {
            var documentScrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
            var documentScrollTop = document.body.scrollTop || document.documentElement.scrollTop;

            guac_state.x -= parent.offsetLeft - documentScrollLeft;
            guac_state.y -= parent.offsetTop  - documentScrollTop;
        }

    };

};

/**
 * Provides cross-browser relative touch event translation for a given element.
 * 
 * Touch events are translated into mouse events as if the touches occurred
 * on a touchpad (drag to push the mouse pointer, tap to click).
 * 
 * @constructor
 * @param {Element} element The Element to use to provide touch events.
 */
Guacamole.Mouse.Touchpad = function(element) {

    /**
     * Reference to this Guacamole.Mouse.Touchpad.
     * @private
     */
    var guac_touchpad = this;

    /**
     * The distance a two-finger touch must move per scrollwheel event, in
     * pixels.
     */
    this.scrollThreshold = 20 * (window.devicePixelRatio || 1);

    /**
     * The maximum number of milliseconds to wait for a touch to end for the
     * gesture to be considered a click.
     */
    this.clickTimingThreshold = 250;

    /**
     * The maximum number of pixels to allow a touch to move for the gesture to
     * be considered a click.
     */
    this.clickMoveThreshold = 10 * (window.devicePixelRatio || 1);

    /**
     * The current mouse state. The properties of this state are updated when
     * mouse events fire. This state object is also passed in as a parameter to
     * the handler of any mouse events.
     * 
     * @type {Guacamole.Mouse.State}
     */
    this.currentState = new Guacamole.Mouse.State(
        0, 0, 
        false, false, false, false, false
    );

    /**
     * Fired whenever a mouse button is effectively pressed. This can happen
     * as part of a "click" gesture initiated by the user by tapping one
     * or more fingers over the touchpad element, as part of a "scroll"
     * gesture initiated by dragging two fingers up or down, etc.
     * 
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmousedown = null;

    /**
     * Fired whenever a mouse button is effectively released. This can happen
     * as part of a "click" gesture initiated by the user by tapping one
     * or more fingers over the touchpad element, as part of a "scroll"
     * gesture initiated by dragging two fingers up or down, etc.
     * 
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmouseup = null;

    /**
     * Fired whenever the user moves the mouse by dragging their finger over
     * the touchpad element.
     * 
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmousemove = null;

    var touch_count = 0;
    var last_touch_x = 0;
    var last_touch_y = 0;
    var last_touch_time = 0;
    var pixels_moved = 0;

    var touch_buttons = {
        1: "left",
        2: "right",
        3: "middle"
    };

    var gesture_in_progress = false;
    var click_release_timeout = null;

    element.addEventListener("touchend", function(e) {
        
        e.preventDefault();
            
        // If we're handling a gesture AND this is the last touch
        if (gesture_in_progress && e.touches.length === 0) {
            
            var time = new Date().getTime();

            // Get corresponding mouse button
            var button = touch_buttons[touch_count];

            // If mouse already down, release anad clear timeout
            if (guac_touchpad.currentState[button]) {

                // Fire button up event
                guac_touchpad.currentState[button] = false;
                if (guac_touchpad.onmouseup)
                    guac_touchpad.onmouseup(guac_touchpad.currentState);

                // Clear timeout, if set
                if (click_release_timeout) {
                    window.clearTimeout(click_release_timeout);
                    click_release_timeout = null;
                }

            }

            // If single tap detected (based on time and distance)
            if (time - last_touch_time <= guac_touchpad.clickTimingThreshold
                    && pixels_moved < guac_touchpad.clickMoveThreshold) {

                // Fire button down event
                guac_touchpad.currentState[button] = true;
                if (guac_touchpad.onmousedown)
                    guac_touchpad.onmousedown(guac_touchpad.currentState);

                // Delay mouse up - mouse up should be canceled if
                // touchstart within timeout.
                click_release_timeout = window.setTimeout(function() {
                    
                    // Fire button up event
                    guac_touchpad.currentState[button] = false;
                    if (guac_touchpad.onmouseup)
                        guac_touchpad.onmouseup(guac_touchpad.currentState);
                    
                    // Gesture now over
                    gesture_in_progress = false;

                }, guac_touchpad.clickTimingThreshold);

            }

            // If we're not waiting to see if this is a click, stop gesture
            if (!click_release_timeout)
                gesture_in_progress = false;

        }

    }, false);

    element.addEventListener("touchstart", function(e) {

        e.preventDefault();

        // Track number of touches, but no more than three
        touch_count = Math.min(e.touches.length, 3);

        // Clear timeout, if set
        if (click_release_timeout) {
            window.clearTimeout(click_release_timeout);
            click_release_timeout = null;
        }

        // Record initial touch location and time for touch movement
        // and tap gestures
        if (!gesture_in_progress) {

            // Stop mouse events while touching
            gesture_in_progress = true;

            // Record touch location and time
            var starting_touch = e.touches[0];
            last_touch_x = starting_touch.clientX;
            last_touch_y = starting_touch.clientY;
            last_touch_time = new Date().getTime();
            pixels_moved = 0;

        }

    }, false);

    element.addEventListener("touchmove", function(e) {

        e.preventDefault();

        // Get change in touch location
        var touch = e.touches[0];
        var delta_x = touch.clientX - last_touch_x;
        var delta_y = touch.clientY - last_touch_y;

        // Track pixels moved
        pixels_moved += Math.abs(delta_x) + Math.abs(delta_y);

        // If only one touch involved, this is mouse move
        if (touch_count === 1) {

            // Calculate average velocity in Manhatten pixels per millisecond
            var velocity = pixels_moved / (new Date().getTime() - last_touch_time);

            // Scale mouse movement relative to velocity
            var scale = 1 + velocity;

            // Update mouse location
            guac_touchpad.currentState.x += delta_x*scale;
            guac_touchpad.currentState.y += delta_y*scale;

            // Prevent mouse from leaving screen

            if (guac_touchpad.currentState.x < 0)
                guac_touchpad.currentState.x = 0;
            else if (guac_touchpad.currentState.x >= element.offsetWidth)
                guac_touchpad.currentState.x = element.offsetWidth - 1;

            if (guac_touchpad.currentState.y < 0)
                guac_touchpad.currentState.y = 0;
            else if (guac_touchpad.currentState.y >= element.offsetHeight)
                guac_touchpad.currentState.y = element.offsetHeight - 1;

            // Fire movement event, if defined
            if (guac_touchpad.onmousemove)
                guac_touchpad.onmousemove(guac_touchpad.currentState);

            // Update touch location
            last_touch_x = touch.clientX;
            last_touch_y = touch.clientY;

        }

        // Interpret two-finger swipe as scrollwheel
        else if (touch_count === 2) {

            // If change in location passes threshold for scroll
            if (Math.abs(delta_y) >= guac_touchpad.scrollThreshold) {

                // Decide button based on Y movement direction
                var button;
                if (delta_y > 0) button = "down";
                else             button = "up";

                // Fire button down event
                guac_touchpad.currentState[button] = true;
                if (guac_touchpad.onmousedown)
                    guac_touchpad.onmousedown(guac_touchpad.currentState);

                // Fire button up event
                guac_touchpad.currentState[button] = false;
                if (guac_touchpad.onmouseup)
                    guac_touchpad.onmouseup(guac_touchpad.currentState);

                // Only update touch location after a scroll has been
                // detected
                last_touch_x = touch.clientX;
                last_touch_y = touch.clientY;

            }

        }

    }, false);

};

/**
 * Provides cross-browser absolute touch event translation for a given element.
 *
 * Touch events are translated into mouse events as if the touches occurred
 * on a touchscreen (tapping anywhere on the screen clicks at that point,
 * long-press to right-click).
 *
 * @constructor
 * @param {Element} element The Element to use to provide touch events.
 */
Guacamole.Mouse.Touchscreen = function(element) {

    /**
     * Reference to this Guacamole.Mouse.Touchscreen.
     * @private
     */
    var guac_touchscreen = this;

    /**
     * Whether a gesture is known to be in progress. If false, touch events
     * will be ignored.
     *
     * @private
     */
    var gesture_in_progress = false;

    /**
     * The start X location of a gesture.
     * @private
     */
    var gesture_start_x = null;

    /**
     * The start Y location of a gesture.
     * @private
     */
    var gesture_start_y = null;

    /**
     * The timeout associated with the delayed, cancellable click release.
     *
     * @private
     */
    var click_release_timeout = null;

    /**
     * The timeout associated with long-press for right click.
     *
     * @private
     */
    var long_press_timeout = null;

    /**
     * The distance a two-finger touch must move per scrollwheel event, in
     * pixels.
     */
    this.scrollThreshold = 20 * (window.devicePixelRatio || 1);

    /**
     * The maximum number of milliseconds to wait for a touch to end for the
     * gesture to be considered a click.
     */
    this.clickTimingThreshold = 250;

    /**
     * The maximum number of pixels to allow a touch to move for the gesture to
     * be considered a click.
     */
    this.clickMoveThreshold = 16 * (window.devicePixelRatio || 1);

    /**
     * The amount of time a press must be held for long press to be
     * detected.
     */
    this.longPressThreshold = 500;

    /**
     * The current mouse state. The properties of this state are updated when
     * mouse events fire. This state object is also passed in as a parameter to
     * the handler of any mouse events.
     *
     * @type {Guacamole.Mouse.State}
     */
    this.currentState = new Guacamole.Mouse.State(
        0, 0,
        false, false, false, false, false
    );

    /**
     * Fired whenever a mouse button is effectively pressed. This can happen
     * as part of a "mousedown" gesture initiated by the user by pressing one
     * finger over the touchscreen element, as part of a "scroll" gesture
     * initiated by dragging two fingers up or down, etc.
     *
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmousedown = null;

    /**
     * Fired whenever a mouse button is effectively released. This can happen
     * as part of a "mouseup" gesture initiated by the user by removing the
     * finger pressed against the touchscreen element, or as part of a "scroll"
     * gesture initiated by dragging two fingers up or down, etc.
     *
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmouseup = null;

    /**
     * Fired whenever the user moves the mouse by dragging their finger over
     * the touchscreen element. Note that unlike Guacamole.Mouse.Touchpad,
     * dragging a finger over the touchscreen element will always cause
     * the mouse button to be effectively down, as if clicking-and-dragging.
     *
     * @event
     * @param {Guacamole.Mouse.State} state The current mouse state.
     */
	this.onmousemove = null;

    /**
     * Presses the given mouse button, if it isn't already pressed. Valid
     * button values are "left", "middle", "right", "up", and "down".
     *
     * @private
     * @param {String} button The mouse button to press.
     */
    function press_button(button) {
        if (!guac_touchscreen.currentState[button]) {
            guac_touchscreen.currentState[button] = true;
            if (guac_touchscreen.onmousedown)
                guac_touchscreen.onmousedown(guac_touchscreen.currentState);
        }
    }

    /**
     * Releases the given mouse button, if it isn't already released. Valid
     * button values are "left", "middle", "right", "up", and "down".
     *
     * @private
     * @param {String} button The mouse button to release.
     */
    function release_button(button) {
        if (guac_touchscreen.currentState[button]) {
            guac_touchscreen.currentState[button] = false;
            if (guac_touchscreen.onmouseup)
                guac_touchscreen.onmouseup(guac_touchscreen.currentState);
        }
    }

    /**
     * Clicks (presses and releases) the given mouse button. Valid button
     * values are "left", "middle", "right", "up", and "down".
     *
     * @private
     * @param {String} button The mouse button to click.
     */
    function click_button(button) {
        press_button(button);
        release_button(button);
    }

    /**
     * Moves the mouse to the given coordinates. These coordinates must be
     * relative to the browser window, as they will be translated based on
     * the touch event target's location within the browser window.
     *
     * @private
     * @param {Number} x The X coordinate of the mouse pointer.
     * @param {Number} y The Y coordinate of the mouse pointer.
     */
    function move_mouse(x, y) {
        guac_touchscreen.currentState.fromClientPosition(element, x, y);
        if (guac_touchscreen.onmousemove)
            guac_touchscreen.onmousemove(guac_touchscreen.currentState);
    }

    /**
     * Returns whether the given touch event exceeds the movement threshold for
     * clicking, based on where the touch gesture began.
     *
     * @private
     * @param {TouchEvent} e The touch event to check.
     * @return {Boolean} true if the movement threshold is exceeded, false
     *                   otherwise.
     */
    function finger_moved(e) {
        var touch = e.touches[0] || e.changedTouches[0];
        var delta_x = touch.clientX - gesture_start_x;
        var delta_y = touch.clientY - gesture_start_y;
        return Math.sqrt(delta_x*delta_x + delta_y*delta_y) >= guac_touchscreen.clickMoveThreshold;
    }

    /**
     * Begins a new gesture at the location of the first touch in the given
     * touch event.
     * 
     * @private
     * @param {TouchEvent} e The touch event beginning this new gesture.
     */
    function begin_gesture(e) {
        var touch = e.touches[0];
        gesture_in_progress = true;
        gesture_start_x = touch.clientX;
        gesture_start_y = touch.clientY;
    }

    /**
     * End the current gesture entirely. Wait for all touches to be done before
     * resuming gesture detection.
     * 
     * @private
     */
    function end_gesture() {
        window.clearTimeout(click_release_timeout);
        window.clearTimeout(long_press_timeout);
        gesture_in_progress = false;
    }

    element.addEventListener("touchend", function(e) {

        // Do not handle if no gesture
        if (!gesture_in_progress)
            return;

        // Ignore if more than one touch
        if (e.touches.length !== 0 || e.changedTouches.length !== 1) {
            end_gesture();
            return;
        }

        // Long-press, if any, is over
        window.clearTimeout(long_press_timeout);

        // Always release mouse button if pressed
        release_button("left");

        // If finger hasn't moved enough to cancel the click
        if (!finger_moved(e)) {

            e.preventDefault();

            // If not yet pressed, press and start delay release
            if (!guac_touchscreen.currentState.left) {

                var touch = e.changedTouches[0];
                move_mouse(touch.clientX, touch.clientY);
                press_button("left");

                // Release button after a delay, if not canceled
                click_release_timeout = window.setTimeout(function() {
                    release_button("left");
                    end_gesture();
                }, guac_touchscreen.clickTimingThreshold);

            }

        } // end if finger not moved

    }, false);

    element.addEventListener("touchstart", function(e) {

        // Ignore if more than one touch
        if (e.touches.length !== 1) {
            end_gesture();
            return;
        }

        e.preventDefault();

        // New touch begins a new gesture
        begin_gesture(e);

        // Keep button pressed if tap after left click
        window.clearTimeout(click_release_timeout);

        // Click right button if this turns into a long-press
        long_press_timeout = window.setTimeout(function() {
            var touch = e.touches[0];
            move_mouse(touch.clientX, touch.clientY);
            click_button("right");
            end_gesture();
        }, guac_touchscreen.longPressThreshold);

    }, false);

    element.addEventListener("touchmove", function(e) {

        // Do not handle if no gesture
        if (!gesture_in_progress)
            return;

        // Cancel long press if finger moved
        if (finger_moved(e))
            window.clearTimeout(long_press_timeout);

        // Ignore if more than one touch
        if (e.touches.length !== 1) {
            end_gesture();
            return;
        }

        // Update mouse position if dragging
        if (guac_touchscreen.currentState.left) {

            e.preventDefault();

            // Update state
            var touch = e.touches[0];
            move_mouse(touch.clientX, touch.clientY);

        }

    }, false);

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * The namespace used by the Guacamole JavaScript API. Absolutely all classes
 * defined by the Guacamole JavaScript API will be within this namespace.
 *
 * @namespace
 */
var Guacamole = Guacamole || {};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * An object used by the Guacamole client to house arbitrarily-many named
 * input and output streams.
 * 
 * @constructor
 * @param {Guacamole.Client} client
 *     The client owning this object.
 *
 * @param {Number} index
 *     The index of this object.
 */
Guacamole.Object = function guacamoleObject(client, index) {

    /**
     * Reference to this Guacamole.Object.
     *
     * @private
     * @type {Guacamole.Object}
     */
    var guacObject = this;

    /**
     * Map of stream name to corresponding queue of callbacks. The queue of
     * callbacks is guaranteed to be in order of request.
     *
     * @private
     * @type {Object.<String, Function[]>}
     */
    var bodyCallbacks = {};

    /**
     * Removes and returns the callback at the head of the callback queue for
     * the stream having the given name. If no such callbacks exist, null is
     * returned.
     *
     * @private
     * @param {String} name
     *     The name of the stream to retrieve a callback for.
     *
     * @returns {Function}
     *     The next callback associated with the stream having the given name,
     *     or null if no such callback exists.
     */
    var dequeueBodyCallback = function dequeueBodyCallback(name) {

        // If no callbacks defined, simply return null
        var callbacks = bodyCallbacks[name];
        if (!callbacks)
            return null;

        // Otherwise, pull off first callback, deleting the queue if empty
        var callback = callbacks.shift();
        if (callbacks.length === 0)
            delete bodyCallbacks[name];

        // Return found callback
        return callback;

    };

    /**
     * Adds the given callback to the tail of the callback queue for the stream
     * having the given name.
     *
     * @private
     * @param {String} name
     *     The name of the stream to associate with the given callback.
     *
     * @param {Function} callback
     *     The callback to add to the queue of the stream with the given name.
     */
    var enqueueBodyCallback = function enqueueBodyCallback(name, callback) {

        // Get callback queue by name, creating first if necessary
        var callbacks = bodyCallbacks[name];
        if (!callbacks) {
            callbacks = [];
            bodyCallbacks[name] = callbacks;
        }

        // Add callback to end of queue
        callbacks.push(callback);

    };

    /**
     * The index of this object.
     *
     * @type {Number}
     */
    this.index = index;

    /**
     * Called when this object receives the body of a requested input stream.
     * By default, all objects will invoke the callbacks provided to their
     * requestInputStream() functions based on the name of the stream
     * requested. This behavior can be overridden by specifying a different
     * handler here.
     *
     * @event
     * @param {Guacamole.InputStream} inputStream
     *     The input stream of the received body.
     *
     * @param {String} mimetype
     *     The mimetype of the data being received.
     *
     * @param {String} name
     *     The name of the stream whose body has been received.
     */
    this.onbody = function defaultBodyHandler(inputStream, mimetype, name) {

        // Call queued callback for the received body, if any
        var callback = dequeueBodyCallback(name);
        if (callback)
            callback(inputStream, mimetype);

    };

    /**
     * Called when this object is being undefined. Once undefined, no further
     * communication involving this object may occur.
     * 
     * @event
     */
    this.onundefine = null;

    /**
     * Requests read access to the input stream having the given name. If
     * successful, a new input stream will be created.
     *
     * @param {String} name
     *     The name of the input stream to request.
     *
     * @param {Function} [bodyCallback]
     *     The callback to invoke when the body of the requested input stream
     *     is received. This callback will be provided a Guacamole.InputStream
     *     and its mimetype as its two only arguments. If the onbody handler of
     *     this object is overridden, this callback will not be invoked.
     */
    this.requestInputStream = function requestInputStream(name, bodyCallback) {

        // Queue body callback if provided
        if (bodyCallback)
            enqueueBodyCallback(name, bodyCallback);

        // Send request for input stream
        client.requestObjectInputStream(guacObject.index, name);

    };

    /**
     * Creates a new output stream associated with this object and having the
     * given mimetype and name. The legality of a mimetype and name is dictated
     * by the object itself.
     *
     * @param {String} mimetype
     *     The mimetype of the data which will be sent to the output stream.
     *
     * @param {String} name
     *     The defined name of an output stream within this object.
     *
     * @returns {Guacamole.OutputStream}
     *     An output stream which will write blobs to the named output stream
     *     of this object.
     */
    this.createOutputStream = function createOutputStream(mimetype, name) {
        return client.createObjectOutputStream(guacObject.index, mimetype, name);
    };

};

/**
 * The reserved name denoting the root stream of any object. The contents of
 * the root stream MUST be a JSON map of stream name to mimetype.
 *
 * @constant
 * @type {String}
 */
Guacamole.Object.ROOT_STREAM = '/';

/**
 * The mimetype of a stream containing JSON which maps available stream names
 * to their corresponding mimetype. The root stream of a Guacamole.Object MUST
 * have this mimetype.
 *
 * @constant
 * @type {String}
 */
Guacamole.Object.STREAM_INDEX_MIMETYPE = 'application/vnd.glyptodon.guacamole.stream-index+json';
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Dynamic on-screen keyboard. Given the layout object for an on-screen
 * keyboard, this object will construct a clickable on-screen keyboard with its
 * own key events.
 *
 * @constructor
 * @param {Guacamole.OnScreenKeyboard.Layout} layout
 *     The layout of the on-screen keyboard to display.
 */
Guacamole.OnScreenKeyboard = function(layout) {

    /**
     * Reference to this Guacamole.OnScreenKeyboard.
     *
     * @private
     * @type {Guacamole.OnScreenKeyboard}
     */
    var osk = this;

    /**
     * Map of currently-set modifiers to the keysym associated with their
     * original press. When the modifier is cleared, this keysym must be
     * released.
     *
     * @private
     * @type {Object.<String, Number>}
     */
    var modifierKeysyms = {};

    /**
     * Map of all key names to their current pressed states. If a key is not
     * pressed, it may not be in this map at all, but all pressed keys will
     * have a corresponding mapping to true.
     *
     * @private
     * @type {Object.<String, Boolean>}
     */
    var pressed = {};

    /**
     * All scalable elements which are part of the on-screen keyboard. Each
     * scalable element is carefully controlled to ensure the interface layout
     * and sizing remains constant, even on browsers that would otherwise
     * experience rounding error due to unit conversions.
     *
     * @private
     * @type {ScaledElement[]}
     */
    var scaledElements = [];

    /**
     * Adds a CSS class to an element.
     * 
     * @private
     * @function
     * @param {Element} element
     *     The element to add a class to.
     *
     * @param {String} classname
     *     The name of the class to add.
     */
    var addClass = function addClass(element, classname) {

        // If classList supported, use that
        if (element.classList)
            element.classList.add(classname);

        // Otherwise, simply append the class
        else
            element.className += " " + classname;

    };

    /**
     * Removes a CSS class from an element.
     * 
     * @private
     * @function
     * @param {Element} element
     *     The element to remove a class from.
     *
     * @param {String} classname
     *     The name of the class to remove.
     */
    var removeClass = function removeClass(element, classname) {

        // If classList supported, use that
        if (element.classList)
            element.classList.remove(classname);

        // Otherwise, manually filter out classes with given name
        else {
            element.className = element.className.replace(/([^ ]+)[ ]*/g,
                function removeMatchingClasses(match, testClassname) {

                    // If same class, remove
                    if (testClassname === classname)
                        return "";

                    // Otherwise, allow
                    return match;
                    
                }
            );
        }

    };

    /**
     * Counter of mouse events to ignore. This decremented by mousemove, and
     * while non-zero, mouse events will have no effect.
     *
     * @private
     * @type {Number}
     */
    var ignoreMouse = 0;

    /**
     * Ignores all pending mouse events when touch events are the apparent
     * source. Mouse events are ignored until at least touchMouseThreshold
     * mouse events occur without corresponding touch events.
     *
     * @private
     */
    var ignorePendingMouseEvents = function ignorePendingMouseEvents() {
        ignoreMouse = osk.touchMouseThreshold;
    };

    /**
     * An element whose dimensions are maintained according to an arbitrary
     * scale. The conversion factor for these arbitrary units to pixels is
     * provided later via a call to scale().
     *
     * @private
     * @constructor
     * @param {Element} element
     *     The element whose scale should be maintained.
     *
     * @param {Number} width
     *     The width of the element, in arbitrary units, relative to other
     *     ScaledElements.
     *
     * @param {Number} height
     *     The height of the element, in arbitrary units, relative to other
     *     ScaledElements.
     *     
     * @param {Boolean} [scaleFont=false]
     *     Whether the line height and font size should be scaled as well.
     */
    var ScaledElement = function ScaledElement(element, width, height, scaleFont) {

        /**
         * The width of this ScaledElement, in arbitrary units, relative to
         * other ScaledElements.
         *
         * @type {Number}
         */
         this.width = width;

        /**
         * The height of this ScaledElement, in arbitrary units, relative to
         * other ScaledElements.
         *
         * @type {Number}
         */
         this.height = height;
 
        /**
         * Resizes the associated element, updating its dimensions according to
         * the given pixels per unit.
         *
         * @param {Number} pixels
         *     The number of pixels to assign per arbitrary unit.
         */
        this.scale = function(pixels) {

            // Scale element width/height
            element.style.width  = (width  * pixels) + "px";
            element.style.height = (height * pixels) + "px";

            // Scale font, if requested
            if (scaleFont) {
                element.style.lineHeight = (height * pixels) + "px";
                element.style.fontSize   = pixels + "px";
            }

        };

    };

    /**
     * Returns whether all modifiers having the given names are currently
     * active.
     *
     * @private
     * @param {String[]} names
     *     The names of all modifiers to test.
     *
     * @returns {Boolean}
     *     true if all specified modifiers are pressed, false otherwise.
     */
    var modifiersPressed = function modifiersPressed(names) {

        // If any required modifiers are not pressed, return false
        for (var i=0; i < names.length; i++) {

            // Test whether current modifier is pressed
            var name = names[i];
            if (!(name in modifierKeysyms))
                return false;

        }

        // Otherwise, all required modifiers are pressed
        return true;

    };

    /**
     * Returns the single matching Key object associated with the key of the
     * given name, where that Key object's requirements (such as pressed
     * modifiers) are all currently satisfied.
     *
     * @private
     * @param {String} keyName
     *     The name of the key to retrieve.
     *
     * @returns {Guacamole.OnScreenKeyboard.Key}
     *     The Key object associated with the given name, where that object's
     *     requirements are all currently satisfied, or null if no such Key
     *     can be found.
     */
    var getActiveKey = function getActiveKey(keyName) {

        // Get key array for given name
        var keys = osk.keys[keyName];
        if (!keys)
            return null;

        // Find last matching key
        for (var i = keys.length - 1; i >= 0; i--) {

            // Get candidate key
            var candidate = keys[i];

            // If all required modifiers are pressed, use that key
            if (modifiersPressed(candidate.requires))
                return candidate;

        }

        // No valid key
        return null;

    };

    /**
     * Presses the key having the given name, updating the associated key
     * element with the "guac-keyboard-pressed" CSS class. If the key is
     * already pressed, this function has no effect.
     *
     * @private
     * @param {String} keyName
     *     The name of the key to press.
     *
     * @param {String} keyElement
     *     The element associated with the given key.
     */
    var press = function press(keyName, keyElement) {

        // Press key if not yet pressed
        if (!pressed[keyName]) {

            addClass(keyElement, "guac-keyboard-pressed");

            // Get current key based on modifier state
            var key = getActiveKey(keyName);

            // Update modifier state
            if (key.modifier) {

                // Construct classname for modifier
                var modifierClass = "guac-keyboard-modifier-" + getCSSName(key.modifier);

                // Retrieve originally-pressed keysym, if modifier was already pressed
                var originalKeysym = modifierKeysyms[key.modifier];

                // Activate modifier if not pressed
                if (!originalKeysym) {
                    
                    addClass(keyboard, modifierClass);
                    modifierKeysyms[key.modifier] = key.keysym;
                    
                    // Send key event
                    if (osk.onkeydown)
                        osk.onkeydown(key.keysym);

                }

                // Deactivate if not pressed
                else {

                    removeClass(keyboard, modifierClass);
                    delete modifierKeysyms[key.modifier];
                    
                    // Send key event
                    if (osk.onkeyup)
                        osk.onkeyup(originalKeysym);

                }

            }

            // If not modifier, send key event now
            else if (osk.onkeydown)
                osk.onkeydown(key.keysym);

            // Mark key as pressed
            pressed[keyName] = true;

        }

    };

    /**
     * Releases the key having the given name, removing the
     * "guac-keyboard-pressed" CSS class from the associated element. If the
     * key is already released, this function has no effect.
     *
     * @private
     * @param {String} keyName
     *     The name of the key to release.
     *
     * @param {String} keyElement
     *     The element associated with the given key.
     */
    var release = function release(keyName, keyElement) {

        // Release key if currently pressed
        if (pressed[keyName]) {

            removeClass(keyElement, "guac-keyboard-pressed");

            // Get current key based on modifier state
            var key = getActiveKey(keyName);

            // Send key event if not a modifier key
            if (!key.modifier && osk.onkeyup)
                osk.onkeyup(key.keysym);

            // Mark key as released
            pressed[keyName] = false;

        }

    };

    // Create keyboard
    var keyboard = document.createElement("div");
    keyboard.className = "guac-keyboard";

    // Do not allow selection or mouse movement to propagate/register.
    keyboard.onselectstart =
    keyboard.onmousemove   =
    keyboard.onmouseup     =
    keyboard.onmousedown   = function handleMouseEvents(e) {

        // If ignoring events, decrement counter
        if (ignoreMouse)
            ignoreMouse--;

        e.stopPropagation();
        return false;

    };

    /**
     * The number of mousemove events to require before re-enabling mouse
     * event handling after receiving a touch event.
     *
     * @type {Number}
     */
    this.touchMouseThreshold = 3;

    /**
     * Fired whenever the user presses a key on this Guacamole.OnScreenKeyboard.
     * 
     * @event
     * @param {Number} keysym The keysym of the key being pressed.
     */
    this.onkeydown = null;

    /**
     * Fired whenever the user releases a key on this Guacamole.OnScreenKeyboard.
     * 
     * @event
     * @param {Number} keysym The keysym of the key being released.
     */
    this.onkeyup = null;

    /**
     * The keyboard layout provided at time of construction.
     *
     * @type {Guacamole.OnScreenKeyboard.Layout}
     */
    this.layout = new Guacamole.OnScreenKeyboard.Layout(layout);

    /**
     * Returns the element containing the entire on-screen keyboard.
     * @returns {Element} The element containing the entire on-screen keyboard.
     */
    this.getElement = function() {
        return keyboard;
    };

    /**
     * Resizes all elements within this Guacamole.OnScreenKeyboard such that
     * the width is close to but does not exceed the specified width. The
     * height of the keyboard is determined based on the width.
     * 
     * @param {Number} width The width to resize this Guacamole.OnScreenKeyboard
     *                       to, in pixels.
     */
    this.resize = function(width) {

        // Get pixel size of a unit
        var unit = Math.floor(width * 10 / osk.layout.width) / 10;

        // Resize all scaled elements
        for (var i=0; i<scaledElements.length; i++) {
            var scaledElement = scaledElements[i];
            scaledElement.scale(unit);
        }

    };

    /**
     * Given the name of a key and its corresponding definition, which may be
     * an array of keys objects, a number (keysym), a string (key title), or a
     * single key object, returns an array of key objects, deriving any missing
     * properties as needed, and ensuring the key name is defined.
     *
     * @private
     * @param {String} name
     *     The name of the key being coerced into an array of Key objects.
     *
     * @param {Number|String|Guacamole.OnScreenKeyboard.Key|Guacamole.OnScreenKeyboard.Key[]} object
     *     The object defining the behavior of the key having the given name,
     *     which may be the title of the key (a string), the keysym (a number),
     *     a single Key object, or an array of Key objects.
     *     
     * @returns {Guacamole.OnScreenKeyboard.Key[]}
     *     An array of all keys associated with the given name.
     */
    var asKeyArray = function asKeyArray(name, object) {

        // If already an array, just coerce into a true Key[] 
        if (object instanceof Array) {
            var keys = [];
            for (var i=0; i < object.length; i++) {
                keys.push(new Guacamole.OnScreenKeyboard.Key(object[i], name));
            }
            return keys;
        }

        // Derive key object from keysym if that's all we have
        if (typeof object === 'number') {
            return [new Guacamole.OnScreenKeyboard.Key({
                name   : name,
                keysym : object
            })];
        }

        // Derive key object from title if that's all we have
        if (typeof object === 'string') {
            return [new Guacamole.OnScreenKeyboard.Key({
                name  : name,
                title : object
            })];
        }

        // Otherwise, assume it's already a key object, just not an array
        return [new Guacamole.OnScreenKeyboard.Key(object, name)];

    };

    /**
     * Converts the rather forgiving key mapping allowed by
     * Guacamole.OnScreenKeyboard.Layout into a rigorous mapping of key name
     * to key definition, where the key definition is always an array of Key
     * objects.
     *
     * @private
     * @param {Object.<String, Number|String|Guacamole.OnScreenKeyboard.Key|Guacamole.OnScreenKeyboard.Key[]>} keys
     *     A mapping of key name to key definition, where the key definition is
     *     the title of the key (a string), the keysym (a number), a single
     *     Key object, or an array of Key objects.
     *
     * @returns {Object.<String, Guacamole.OnScreenKeyboard.Key[]>}
     *     A more-predictable mapping of key name to key definition, where the
     *     key definition is always simply an array of Key objects.
     */
    var getKeys = function getKeys(keys) {

        var keyArrays = {};

        // Coerce all keys into individual key arrays
        for (var name in layout.keys) {
            keyArrays[name] = asKeyArray(name, keys[name]);
        }

        return keyArrays;

    };

    /**
     * Map of all key names to their corresponding set of keys. Each key name
     * may correspond to multiple keys due to the effect of modifiers.
     *
     * @type {Object.<String, Guacamole.OnScreenKeyboard.Key[]>}
     */
    this.keys = getKeys(layout.keys);

    /**
     * Given an arbitrary string representing the name of some component of the
     * on-screen keyboard, returns a string formatted for use as a CSS class
     * name. The result will be lowercase. Word boundaries previously denoted
     * by CamelCase will be replaced by individual hyphens, as will all
     * contiguous non-alphanumeric characters.
     *
     * @private
     * @param {String} name
     *     An arbitrary string representing the name of some component of the
     *     on-screen keyboard.
     *
     * @returns {String}
     *     A string formatted for use as a CSS class name.
     */
    var getCSSName = function getCSSName(name) {

        // Convert name from possibly-CamelCase to hyphenated lowercase
        var cssName = name
               .replace(/([a-z])([A-Z])/g, '$1-$2')
               .replace(/[^A-Za-z0-9]+/g, '-')
               .toLowerCase();

        return cssName;

    };

    /**
     * Appends DOM elements to the given element as dictated by the layout
     * structure object provided. If a name is provided, an additional CSS
     * class, prepended with "guac-keyboard-", will be added to the top-level
     * element.
     * 
     * If the layout structure object is an array, all elements within that
     * array will be recursively appended as children of a group, and the
     * top-level element will be given the CSS class "guac-keyboard-group".
     *
     * If the layout structure object is an object, all properties within that
     * object will be recursively appended as children of a group, and the
     * top-level element will be given the CSS class "guac-keyboard-group". The
     * name of each property will be applied as the name of each child object
     * for the sake of CSS. Each property will be added in sorted order.
     *
     * If the layout structure object is a string, the key having that name
     * will be appended. The key will be given the CSS class
     * "guac-keyboard-key" and "guac-keyboard-key-NAME", where NAME is the name
     * of the key. If the name of the key is a single character, this will
     * first be transformed into the C-style hexadecimal literal for the
     * Unicode codepoint of that character. For example, the key "A" would
     * become "guac-keyboard-key-0x41".
     * 
     * If the layout structure object is a number, a gap of that size will be
     * inserted. The gap will be given the CSS class "guac-keyboard-gap", and
     * will be scaled according to the same size units as each key.
     *
     * @private
     * @param {Element} element
     *     The element to append elements to.
     *
     * @param {Array|Object|String|Number} object
     *     The layout structure object to use when constructing the elements to
     *     append.
     *
     * @param {String} [name]
     *     The name of the top-level element being appended, if any.
     */
    var appendElements = function appendElements(element, object, name) {

        var i;

        // Create div which will become the group or key
        var div = document.createElement('div');

        // Add class based on name, if name given
        if (name)
            addClass(div, 'guac-keyboard-' + getCSSName(name));

        // If an array, append each element
        if (object instanceof Array) {

            // Add group class
            addClass(div, 'guac-keyboard-group');

            // Append all elements of array
            for (i=0; i < object.length; i++)
                appendElements(div, object[i]);

        }

        // If an object, append each property value
        else if (object instanceof Object) {

            // Add group class
            addClass(div, 'guac-keyboard-group');

            // Append all children, sorted by name
            var names = Object.keys(object).sort();
            for (i=0; i < names.length; i++) {
                var name = names[i];
                appendElements(div, object[name], name);
            }

        }

        // If a number, create as a gap 
        else if (typeof object === 'number') {

            // Add gap class
            addClass(div, 'guac-keyboard-gap');

            // Maintain scale
            scaledElements.push(new ScaledElement(div, object, object));

        }

        // If a string, create as a key
        else if (typeof object === 'string') {

            // If key name is only one character, use codepoint for name
            var keyName = object;
            if (keyName.length === 1)
                keyName = '0x' + keyName.charCodeAt(0).toString(16);

            // Add key container class
            addClass(div, 'guac-keyboard-key-container');

            // Create key element which will contain all possible caps
            var keyElement = document.createElement('div');
            keyElement.className = 'guac-keyboard-key '
                                 + 'guac-keyboard-key-' + getCSSName(keyName);

            // Add all associated keys as caps within DOM
            var keys = osk.keys[object];
            if (keys) {
                for (i=0; i < keys.length; i++) {

                    // Get current key
                    var key = keys[i];

                    // Create cap element for key
                    var capElement = document.createElement('div');
                    capElement.className   = 'guac-keyboard-cap';
                    capElement.textContent = key.title;

                    // Add classes for any requirements
                    for (var j=0; j < key.requires.length; j++) {
                        var requirement = key.requires[j];
                        addClass(capElement, 'guac-keyboard-requires-' + getCSSName(requirement));
                        addClass(keyElement, 'guac-keyboard-uses-'     + getCSSName(requirement));
                    }

                    // Add cap to key within DOM
                    keyElement.appendChild(capElement);

                }
            }

            // Add key to DOM, maintain scale
            div.appendChild(keyElement);
            scaledElements.push(new ScaledElement(div, osk.layout.keyWidths[object] || 1, 1, true));

            /**
             * Handles a touch event which results in the pressing of an OSK
             * key. Touch events will result in mouse events being ignored for
             * touchMouseThreshold events.
             *
             * @private
             * @param {TouchEvent} e
             *     The touch event being handled.
             */
            var touchPress = function touchPress(e) {
                e.preventDefault();
                ignoreMouse = osk.touchMouseThreshold;
                press(object, keyElement);
            };

            /**
             * Handles a touch event which results in the release of an OSK
             * key. Touch events will result in mouse events being ignored for
             * touchMouseThreshold events.
             *
             * @private
             * @param {TouchEvent} e
             *     The touch event being handled.
             */
            var touchRelease = function touchRelease(e) {
                e.preventDefault();
                ignoreMouse = osk.touchMouseThreshold;
                release(object, keyElement);
            };

            /**
             * Handles a mouse event which results in the pressing of an OSK
             * key. If mouse events are currently being ignored, this handler
             * does nothing.
             *
             * @private
             * @param {MouseEvent} e
             *     The touch event being handled.
             */
            var mousePress = function mousePress(e) {
                e.preventDefault();
                if (ignoreMouse === 0)
                    press(object, keyElement);
            };

            /**
             * Handles a mouse event which results in the release of an OSK
             * key. If mouse events are currently being ignored, this handler
             * does nothing.
             *
             * @private
             * @param {MouseEvent} e
             *     The touch event being handled.
             */
            var mouseRelease = function mouseRelease(e) {
                e.preventDefault();
                if (ignoreMouse === 0)
                    release(object, keyElement);
            };

            // Handle touch events on key
            keyElement.addEventListener("touchstart", touchPress,   true);
            keyElement.addEventListener("touchend",   touchRelease, true);

            // Handle mouse events on key
            keyElement.addEventListener("mousedown", mousePress,   true);
            keyElement.addEventListener("mouseup",   mouseRelease, true);
            keyElement.addEventListener("mouseout",  mouseRelease, true);

        } // end if object is key name

        // Add newly-created group/key
        element.appendChild(div);

    };

    // Create keyboard layout in DOM
    appendElements(keyboard, layout.layout);

};

/**
 * Represents an entire on-screen keyboard layout, including all available
 * keys, their behaviors, and their relative position and sizing.
 *
 * @constructor
 * @param {Guacamole.OnScreenKeyboard.Layout|Object} template
 *     The object whose identically-named properties will be used to initialize
 *     the properties of this layout.
 */
Guacamole.OnScreenKeyboard.Layout = function(template) {

    /**
     * The language of keyboard layout, such as "en_US". This property is for
     * informational purposes only, but it is recommend to conform to the
     * [language code]_[country code] format.
     *
     * @type {String}
     */
    this.language = template.language;

    /**
     * The type of keyboard layout, such as "qwerty". This property is for
     * informational purposes only, and does not conform to any standard.
     *
     * @type {String}
     */
    this.type = template.type;

    /**
     * Map of key name to corresponding keysym, title, or key object. If only
     * the keysym or title is provided, the key object will be created
     * implicitly. In all cases, the name property of the key object will be
     * taken from the name given in the mapping.
     *
     * @type {Object.<String, Number|String|Guacamole.OnScreenKeyboard.Key|Guacamole.OnScreenKeyboard.Key[]>}
     */
    this.keys = template.keys;

    /**
     * Arbitrarily nested, arbitrarily grouped key names. The contents of the
     * layout will be traversed to produce an identically-nested grouping of
     * keys in the DOM tree. All strings will be transformed into their
     * corresponding sets of keys, while all objects and arrays will be
     * transformed into named groups and anonymous groups respectively. Any
     * numbers present will be transformed into gaps of that size, scaled
     * according to the same units as each key.
     *
     * @type {Object}
     */
    this.layout = template.layout;

    /**
     * The width of the entire keyboard, in arbitrary units. The width of each
     * key is relative to this width, as both width values are assumed to be in
     * the same units. The conversion factor between these units and pixels is
     * derived later via a call to resize() on the Guacamole.OnScreenKeyboard.
     *
     * @type {Number}
     */
    this.width = template.width;

    /**
     * The width of each key, in arbitrary units, relative to other keys in
     * this layout. The true pixel size of each key will be determined by the
     * overall size of the keyboard. If not defined here, the width of each
     * key will default to 1.
     *
     * @type {Object.<String, Number>}
     */
    this.keyWidths = template.keyWidths || {};

};

/**
 * Represents a single key, or a single possible behavior of a key. Each key
 * on the on-screen keyboard must have at least one associated
 * Guacamole.OnScreenKeyboard.Key, whether that key is explicitly defined or
 * implied, and may have multiple Guacamole.OnScreenKeyboard.Key if behavior
 * depends on modifier states.
 *
 * @constructor
 * @param {Guacamole.OnScreenKeyboard.Key|Object} template
 *     The object whose identically-named properties will be used to initialize
 *     the properties of this key.
 *     
 * @param {String} [name]
 *     The name to use instead of any name provided within the template, if
 *     any. If omitted, the name within the template will be used, assuming the
 *     template contains a name.
 */
Guacamole.OnScreenKeyboard.Key = function(template, name) {

    /**
     * The unique name identifying this key within the keyboard layout.
     *
     * @type {String}
     */
    this.name = name || template.name;

    /**
     * The human-readable title that will be displayed to the user within the
     * key. If not provided, this will be derived from the key name.
     *
     * @type {String}
     */
    this.title = template.title || this.name;

    /**
     * The keysym to be pressed/released when this key is pressed/released. If
     * not provided, this will be derived from the title if the title is a
     * single character.
     *
     * @type {Number}
     */
    this.keysym = template.keysym || (function deriveKeysym(title) {

        // Do not derive keysym if title is not exactly one character
        if (!title || title.length !== 1)
            return null;

        // For characters between U+0000 and U+00FF, the keysym is the codepoint
        var charCode = title.charCodeAt(0);
        if (charCode >= 0x0000 && charCode <= 0x00FF)
            return charCode;

        // For characters between U+0100 and U+10FFFF, the keysym is the codepoint or'd with 0x01000000
        if (charCode >= 0x0100 && charCode <= 0x10FFFF)
            return 0x01000000 | charCode;

        // Unable to derive keysym
        return null;

    })(this.title);

    /**
     * The name of the modifier set when the key is pressed and cleared when
     * this key is released, if any. The names of modifiers are distinct from
     * the names of keys; both the "RightShift" and "LeftShift" keys may set
     * the "shift" modifier, for example. By default, the key will affect no
     * modifiers.
     * 
     * @type {String}
     */
    this.modifier = template.modifier;

    /**
     * An array containing the names of each modifier required for this key to
     * have an effect. For example, a lowercase letter may require nothing,
     * while an uppercase letter would require "shift", assuming the Shift key
     * is named "shift" within the layout. By default, the key will require
     * no modifiers.
     *
     * @type {String[]}
     */
    this.requires = template.requires || [];

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Abstract stream which can receive data.
 * 
 * @constructor
 * @param {Guacamole.Client} client The client owning this stream.
 * @param {Number} index The index of this stream.
 */
Guacamole.OutputStream = function(client, index) {

    /**
     * Reference to this stream.
     * @private
     */
    var guac_stream = this;

    /**
     * The index of this stream.
     * @type {Number}
     */
    this.index = index;

    /**
     * Fired whenever an acknowledgement is received from the server, indicating
     * that a stream operation has completed, or an error has occurred.
     * 
     * @event
     * @param {Guacamole.Status} status The status of the operation.
     */
    this.onack = null;

    /**
     * Writes the given base64-encoded data to this stream as a blob.
     * 
     * @param {String} data The base64-encoded data to send.
     */
    this.sendBlob = function(data) {
        client.sendBlob(guac_stream.index, data);
    };

    /**
     * Closes this stream.
     */
    this.sendEnd = function() {
        client.endStream(guac_stream.index);
    };

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Simple Guacamole protocol parser that invokes an oninstruction event when
 * full instructions are available from data received via receive().
 * 
 * @constructor
 */
Guacamole.Parser = function() {

    /**
     * Reference to this parser.
     * @private
     */
    var parser = this;

    /**
     * Current buffer of received data. This buffer grows until a full
     * element is available. After a full element is available, that element
     * is flushed into the element buffer.
     * 
     * @private
     */
    var buffer = "";

    /**
     * Buffer of all received, complete elements. After an entire instruction
     * is read, this buffer is flushed, and a new instruction begins.
     * 
     * @private
     */
    var element_buffer = [];

    // The location of the last element's terminator
    var element_end = -1;

    // Where to start the next length search or the next element
    var start_index = 0;

    /**
     * Appends the given instruction data packet to the internal buffer of
     * this Guacamole.Parser, executing all completed instructions at
     * the beginning of this buffer, if any.
     *
     * @param {String} packet The instruction data to receive.
     */
    this.receive = function(packet) {

        // Truncate buffer as necessary
        if (start_index > 4096 && element_end >= start_index) {

            buffer = buffer.substring(start_index);

            // Reset parse relative to truncation
            element_end -= start_index;
            start_index = 0;

        }

        // Append data to buffer
        buffer += packet;

        // While search is within currently received data
        while (element_end < buffer.length) {

            // If we are waiting for element data
            if (element_end >= start_index) {

                // We now have enough data for the element. Parse.
                var element = buffer.substring(start_index, element_end);
                var terminator = buffer.substring(element_end, element_end+1);

                // Add element to array
                element_buffer.push(element);

                // If last element, handle instruction
                if (terminator == ";") {

                    // Get opcode
                    var opcode = element_buffer.shift();

                    // Call instruction handler.
                    if (parser.oninstruction != null)
                        parser.oninstruction(opcode, element_buffer);

                    // Clear elements
                    element_buffer.length = 0;

                }
                else if (terminator != ',')
                    throw new Error("Illegal terminator.");

                // Start searching for length at character after
                // element terminator
                start_index = element_end + 1;

            }

            // Search for end of length
            var length_end = buffer.indexOf(".", start_index);
            if (length_end != -1) {

                // Parse length
                var length = parseInt(buffer.substring(element_end+1, length_end));
                if (length == NaN)
                    throw new Error("Non-numeric character in element length.");

                // Calculate start of element
                start_index = length_end + 1;

                // Calculate location of element terminator
                element_end = start_index + length;

            }
            
            // If no period yet, continue search when more data
            // is received
            else {
                start_index = buffer.length;
                break;
            }

        } // end parse loop

    };

    /**
     * Fired once for every complete Guacamole instruction received, in order.
     * 
     * @event
     * @param {String} opcode The Guacamole instruction opcode.
     * @param {Array} parameters The parameters provided for the instruction,
     *                           if any.
     */
    this.oninstruction = null;

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A description of the format of raw PCM audio, such as that used by
 * Guacamole.RawAudioPlayer and Guacamole.RawAudioRecorder. This object
 * describes the number of bytes per sample, the number of channels, and the
 * overall sample rate.
 *
 * @constructor
 * @param {Guacamole.RawAudioFormat|Object} template
 *     The object whose properties should be copied into the corresponding
 *     properties of the new Guacamole.RawAudioFormat.
 */
Guacamole.RawAudioFormat = function RawAudioFormat(template) {

    /**
     * The number of bytes in each sample of audio data. This value is
     * independent of the number of channels.
     *
     * @type {Number}
     */
    this.bytesPerSample = template.bytesPerSample;

    /**
     * The number of audio channels (ie: 1 for mono, 2 for stereo).
     *
     * @type {Number}
     */
    this.channels = template.channels;

    /**
     * The number of samples per second, per channel.
     *
     * @type {Number}
     */
    this.rate = template.rate;

};

/**
 * Parses the given mimetype, returning a new Guacamole.RawAudioFormat
 * which describes the type of raw audio data represented by that mimetype. If
 * the mimetype is not a supported raw audio data mimetype, null is returned.
 *
 * @param {String} mimetype
 *     The audio mimetype to parse.
 *
 * @returns {Guacamole.RawAudioFormat}
 *     A new Guacamole.RawAudioFormat which describes the type of raw
 *     audio data represented by the given mimetype, or null if the given
 *     mimetype is not supported.
 */
Guacamole.RawAudioFormat.parse = function parseFormat(mimetype) {

    var bytesPerSample;

    // Rate is absolutely required - if null is still present later, the
    // mimetype must not be supported
    var rate = null;

    // Default for both "audio/L8" and "audio/L16" is one channel
    var channels = 1;

    // "audio/L8" has one byte per sample
    if (mimetype.substring(0, 9) === 'audio/L8;') {
        mimetype = mimetype.substring(9);
        bytesPerSample = 1;
    }

    // "audio/L16" has two bytes per sample
    else if (mimetype.substring(0, 10) === 'audio/L16;') {
        mimetype = mimetype.substring(10);
        bytesPerSample = 2;
    }

    // All other types are unsupported
    else
        return null;

    // Parse all parameters
    var parameters = mimetype.split(',');
    for (var i = 0; i < parameters.length; i++) {

        var parameter = parameters[i];

        // All parameters must have an equals sign separating name from value
        var equals = parameter.indexOf('=');
        if (equals === -1)
            return null;

        // Parse name and value from parameter string
        var name  = parameter.substring(0, equals);
        var value = parameter.substring(equals+1);

        // Handle each supported parameter
        switch (name) {

            // Number of audio channels
            case 'channels':
                channels = parseInt(value);
                break;

            // Sample rate
            case 'rate':
                rate = parseInt(value);
                break;

            // All other parameters are unsupported
            default:
                return null;

        }

    };

    // The rate parameter is required
    if (rate === null)
        return null;

    // Return parsed format details
    return new Guacamole.RawAudioFormat({
        bytesPerSample : bytesPerSample,
        channels       : channels,
        rate           : rate
    });

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A recording of a Guacamole session. Given a {@link Guacamole.Tunnel}, the
 * Guacamole.SessionRecording automatically handles incoming Guacamole
 * instructions, storing them for playback. Playback of the recording may be
 * controlled through function calls to the Guacamole.SessionRecording, even
 * while the recording has not yet finished being created or downloaded.
 *
 * @constructor
 * @param {Guacamole.Tunnel} tunnel
 *     The Guacamole.Tunnel from which the instructions of the recording should
 *     be read.
 */
Guacamole.SessionRecording = function SessionRecording(tunnel) {

    /**
     * Reference to this Guacamole.SessionRecording.
     *
     * @private
     * @type {Guacamole.SessionRecording}
     */
    var recording = this;

    /**
     * The minimum number of characters which must have been read between
     * keyframes.
     *
     * @private
     * @constant
     * @type {Number}
     */
    var KEYFRAME_CHAR_INTERVAL = 16384;

    /**
     * The minimum number of milliseconds which must elapse between keyframes.
     *
     * @private
     * @constant
     * @type {Number}
     */
    var KEYFRAME_TIME_INTERVAL = 5000;

    /**
     * All frames parsed from the provided tunnel.
     *
     * @private
     * @type {Guacamole.SessionRecording._Frame[]}
     */
    var frames = [];

    /**
     * All instructions which have been read since the last frame was added to
     * the frames array.
     *
     * @private
     * @type {Guacamole.SessionRecording._Frame.Instruction[]}
     */
    var instructions = [];

    /**
     * The approximate number of characters which have been read from the
     * provided tunnel since the last frame was flagged for use as a keyframe.
     *
     * @private
     * @type {Number}
     */
    var charactersSinceLastKeyframe = 0;

    /**
     * The timestamp of the last frame which was flagged for use as a keyframe.
     * If no timestamp has yet been flagged, this will be 0.
     *
     * @private
     * @type {Number}
     */
    var lastKeyframeTimestamp = 0;

    /**
     * Tunnel which feeds arbitrary instructions to the client used by this
     * Guacamole.SessionRecording for playback of the session recording.
     *
     * @private
     * @type {Guacamole.SessionRecording._PlaybackTunnel}
     */
    var playbackTunnel = new Guacamole.SessionRecording._PlaybackTunnel();

    /**
     * Guacamole.Client instance used for visible playback of the session
     * recording.
     *
     * @private
     * @type {Guacamole.Client}
     */
    var playbackClient = new Guacamole.Client(playbackTunnel);

    /**
     * The current frame rendered within the playback client. If no frame is
     * yet rendered, this will be -1.
     *
     * @private
     * @type {Number}
     */
    var currentFrame = -1;

    /**
     * The timestamp of the frame when playback began, in milliseconds. If
     * playback is not in progress, this will be null.
     *
     * @private
     * @type {Number}
     */
    var startVideoTimestamp = null;

    /**
     * The real-world timestamp when playback began, in milliseconds. If
     * playback is not in progress, this will be null.
     *
     * @private
     * @type {Number}
     */
    var startRealTimestamp = null;

    /**
     * The ID of the timeout which will play the next frame, if playback is in
     * progress. If playback is not in progress, the ID stored here (if any)
     * will not be valid.
     *
     * @private
     * @type {Number}
     */
    var playbackTimeout = null;

    // Start playback client connected
    playbackClient.connect();

    // Hide cursor unless mouse position is received
    playbackClient.getDisplay().showCursor(false);

    // Read instructions from provided tunnel, extracting each frame
    tunnel.oninstruction = function handleInstruction(opcode, args) {

        // Store opcode and arguments for received instruction
        var instruction = new Guacamole.SessionRecording._Frame.Instruction(opcode, args.slice());
        instructions.push(instruction);
        charactersSinceLastKeyframe += instruction.getSize();

        // Once a sync is received, store all instructions since the last
        // frame as a new frame
        if (opcode === 'sync') {

            // Parse frame timestamp from sync instruction
            var timestamp = parseInt(args[0]);

            // Add a new frame containing the instructions read since last frame
            var frame = new Guacamole.SessionRecording._Frame(timestamp, instructions);
            frames.push(frame);

            // This frame should eventually become a keyframe if enough data
            // has been processed and enough recording time has elapsed, or if
            // this is the absolute first frame
            if (frames.length === 1 || (charactersSinceLastKeyframe >= KEYFRAME_CHAR_INTERVAL
                    && timestamp - lastKeyframeTimestamp >= KEYFRAME_TIME_INTERVAL)) {
                frame.keyframe = true;
                lastKeyframeTimestamp = timestamp;
                charactersSinceLastKeyframe = 0;
            }

            // Clear set of instructions in preparation for next frame
            instructions = [];

            // Notify that additional content is available
            if (recording.onprogress)
                recording.onprogress(recording.getDuration());

        }

    };

    /**
     * Converts the given absolute timestamp to a timestamp which is relative
     * to the first frame in the recording.
     *
     * @private
     * @param {Number} timestamp
     *     The timestamp to convert to a relative timestamp.
     *
     * @returns {Number}
     *     The difference in milliseconds between the given timestamp and the
     *     first frame of the recording, or zero if no frames yet exist.
     */
    var toRelativeTimestamp = function toRelativeTimestamp(timestamp) {

        // If no frames yet exist, all timestamps are zero
        if (frames.length === 0)
            return 0;

        // Calculate timestamp relative to first frame
        return timestamp - frames[0].timestamp;

    };

    /**
     * Searches through the given region of frames for the frame having a
     * relative timestamp closest to the timestamp given.
     *
     * @private
     * @param {Number} minIndex
     *     The index of the first frame in the region (the frame having the
     *     smallest timestamp).
     *
     * @param {Number} maxIndex
     *     The index of the last frame in the region (the frame having the
     *     largest timestamp).
     *
     * @param {Number} timestamp
     *     The relative timestamp to search for, where zero denotes the first
     *     frame in the recording.
     *
     * @returns {Number}
     *     The index of the frame having a relative timestamp closest to the
     *     given value.
     */
    var findFrame = function findFrame(minIndex, maxIndex, timestamp) {

        // Do not search if the region contains only one element
        if (minIndex === maxIndex)
            return minIndex;

        // Split search region into two halves
        var midIndex = Math.floor((minIndex + maxIndex) / 2);
        var midTimestamp = toRelativeTimestamp(frames[midIndex].timestamp);

        // If timestamp is within lesser half, search again within that half
        if (timestamp < midTimestamp && midIndex > minIndex)
            return findFrame(minIndex, midIndex - 1, timestamp);

        // If timestamp is within greater half, search again within that half
        if (timestamp > midTimestamp && midIndex < maxIndex)
            return findFrame(midIndex + 1, maxIndex, timestamp);

        // Otherwise, we lucked out and found a frame with exactly the
        // desired timestamp
        return midIndex;

    };

    /**
     * Replays the instructions associated with the given frame, sending those
     * instructions to the playback client.
     *
     * @private
     * @param {Number} index
     *     The index of the frame within the frames array which should be
     *     replayed.
     */
    var replayFrame = function replayFrame(index) {

        var frame = frames[index];

        // Replay all instructions within the retrieved frame
        for (var i = 0; i < frame.instructions.length; i++) {
            var instruction = frame.instructions[i];
            playbackTunnel.receiveInstruction(instruction.opcode, instruction.args);
        }

        // Store client state if frame is flagged as a keyframe
        if (frame.keyframe && !frame.clientState) {
            playbackClient.exportState(function storeClientState(state) {
                frame.clientState = state;
            });
        }

    };

    /**
     * Moves the playback position to the given frame, resetting the state of
     * the playback client and replaying frames as necessary.
     *
     * @private
     * @param {Number} index
     *     The index of the frame which should become the new playback
     *     position.
     */
    var seekToFrame = function seekToFrame(index) {

        var startIndex;

        // Back up until startIndex represents current state
        for (startIndex = index; startIndex >= 0; startIndex--) {

            var frame = frames[startIndex];

            // If we've reached the current frame, startIndex represents
            // current state by definition
            if (startIndex === currentFrame)
                break;

            // If frame has associated absolute state, make that frame the
            // current state
            if (frame.clientState) {
                playbackClient.importState(frame.clientState);
                break;
            }

        }

        // Advance to frame index after current state
        startIndex++;

        // Replay any applicable incremental frames
        for (; startIndex <= index; startIndex++)
            replayFrame(startIndex);

        // Current frame is now at requested index
        currentFrame = index;

        // Notify of changes in position
        if (recording.onseek)
            recording.onseek(recording.getPosition());

    };

    /**
     * Advances playback to the next frame in the frames array and schedules
     * playback of the frame following that frame based on their associated
     * timestamps. If no frames exist after the next frame, playback is paused.
     *
     * @private
     */
    var continuePlayback = function continuePlayback() {

        // Advance to next frame
        seekToFrame(currentFrame + 1);

        // If frames remain after advancing, schedule next frame
        if (currentFrame + 1 < frames.length) {

            // Pull the upcoming frame
            var next = frames[currentFrame + 1];

            // Calculate the real timestamp corresponding to when the next
            // frame begins
            var nextRealTimestamp = next.timestamp - startVideoTimestamp + startRealTimestamp;

            // Calculate the relative delay between the current time and
            // the next frame start
            var delay = Math.max(nextRealTimestamp - new Date().getTime(), 0);

            // Advance to next frame after enough time has elapsed
            playbackTimeout = window.setTimeout(function frameDelayElapsed() {
                continuePlayback();
            }, delay);

        }

        // Otherwise stop playback
        else
            recording.pause();

    };

    /**
     * Fired when new frames have become available while the recording is
     * being downloaded.
     *
     * @event
     * @param {Number} duration
     *     The new duration of the recording, in milliseconds.
     */
    this.onprogress = null;

    /**
     * Fired whenever playback of the recording has started.
     *
     * @event
     */
    this.onplay = null;

    /**
     * Fired whenever playback of the recording has been paused. This may
     * happen when playback is explicitly paused with a call to pause(), or
     * when playback is implicitly paused due to reaching the end of the
     * recording.
     *
     * @event
     */
    this.onpause = null;

    /**
     * Fired whenever the playback position within the recording changes.
     *
     * @event
     * @param {Number} position
     *     The new position within the recording, in milliseconds.
     */
    this.onseek = null;

    /**
     * Connects the underlying tunnel, beginning download of the Guacamole
     * session. Playback of the Guacamole session cannot occur until at least
     * one frame worth of instructions has been downloaded.
     *
     * @param {String} data
     *     The data to send to the tunnel when connecting.
     */
    this.connect = function connect(data) {
        tunnel.connect(data);
    };

    /**
     * Disconnects the underlying tunnel, stopping further download of the
     * Guacamole session.
     */
    this.disconnect = function disconnect() {
        tunnel.disconnect();
    };

    /**
     * Returns the underlying display of the Guacamole.Client used by this
     * Guacamole.SessionRecording for playback. The display contains an Element
     * which can be added to the DOM, causing the display (and thus playback of
     * the recording) to become visible.
     *
     * @return {Guacamole.Display}
     *     The underlying display of the Guacamole.Client used by this
     *     Guacamole.SessionRecording for playback.
     */
    this.getDisplay = function getDisplay() {
        return playbackClient.getDisplay();
    };

    /**
     * Returns whether playback is currently in progress.
     *
     * @returns {Boolean}
     *     true if playback is currently in progress, false otherwise.
     */
    this.isPlaying = function isPlaying() {
        return !!startVideoTimestamp;
    };

    /**
     * Returns the current playback position within the recording, in
     * milliseconds, where zero is the start of the recording.
     *
     * @returns {Number}
     *     The current playback position within the recording, in milliseconds.
     */
    this.getPosition = function getPosition() {

        // Position is simply zero if playback has not started at all
        if (currentFrame === -1)
            return 0;

        // Return current position as a millisecond timestamp relative to the
        // start of the recording
        return toRelativeTimestamp(frames[currentFrame].timestamp);

    };

    /**
     * Returns the duration of this recording, in milliseconds. If the
     * recording is still being downloaded, this value will gradually increase.
     *
     * @returns {Number}
     *     The duration of this recording, in milliseconds.
     */
    this.getDuration = function getDuration() {

        // If no frames yet exist, duration is zero
        if (frames.length === 0)
            return 0;

        // Recording duration is simply the timestamp of the last frame
        return toRelativeTimestamp(frames[frames.length - 1].timestamp);

    };

    /**
     * Begins continuous playback of the recording downloaded thus far.
     * Playback of the recording will continue until pause() is invoked or
     * until no further frames exist. Playback is initially paused when a
     * Guacamole.SessionRecording is created, and must be explicitly started
     * through a call to this function. If playback is already in progress,
     * this function has no effect.
     */
    this.play = function play() {

        // If playback is not already in progress and frames remain,
        // begin playback
        if (!recording.isPlaying() && currentFrame + 1 < frames.length) {

            // Notify that playback is starting
            if (recording.onplay)
                recording.onplay();

            // Store timestamp of playback start for relative scheduling of
            // future frames
            var next = frames[currentFrame + 1];
            startVideoTimestamp = next.timestamp;
            startRealTimestamp = new Date().getTime();

            // Begin playback of video
            continuePlayback();

        }

    };

    /**
     * Seeks to the given position within the recording. If the recording is
     * currently being played back, playback will continue after the seek is
     * performed. If the recording is currently paused, playback will be
     * paused after the seek is performed.
     *
     * @param {Number} position
     *     The position within the recording to seek to, in milliseconds.
     */
    this.seek = function seek(position) {

        // Do not seek if no frames exist
        if (frames.length === 0)
            return;

        // Pause playback, preserving playback state
        var originallyPlaying = recording.isPlaying();
        recording.pause();

        // Perform seek
        seekToFrame(findFrame(0, frames.length - 1, position));

        // Restore playback state
        if (originallyPlaying)
            recording.play();

    };

    /**
     * Pauses playback of the recording, if playback is currently in progress.
     * If playback is not in progress, this function has no effect. Playback is
     * initially paused when a Guacamole.SessionRecording is created, and must
     * be explicitly started through a call to play().
     */
    this.pause = function pause() {

        // Stop playback only if playback is in progress
        if (recording.isPlaying()) {

            // Notify that playback is stopping
            if (recording.onpause)
                recording.onpause();

            // Stop playback
            window.clearTimeout(playbackTimeout);
            startVideoTimestamp = null;
            startRealTimestamp = null;

        }

    };

};

/**
 * A single frame of Guacamole session data. Each frame is made up of the set
 * of instructions used to generate that frame, and the timestamp as dictated
 * by the "sync" instruction terminating the frame. Optionally, a frame may
 * also be associated with a snapshot of Guacamole client state, such that the
 * frame can be rendered without replaying all previous frames.
 *
 * @private
 * @constructor
 * @param {Number} timestamp
 *     The timestamp of this frame, as dictated by the "sync" instruction which
 *     terminates the frame.
 *
 * @param {Guacamole.SessionRecording._Frame.Instruction[]} instructions
 *     All instructions which are necessary to generate this frame relative to
 *     the previous frame in the Guacamole session.
 */
Guacamole.SessionRecording._Frame = function _Frame(timestamp, instructions) {

    /**
     * Whether this frame should be used as a keyframe if possible. This value
     * is purely advisory. The stored clientState must eventually be manually
     * set for the frame to be used as a keyframe. By default, frames are not
     * keyframes.
     *
     * @type {Boolean}
     * @default false
     */
    this.keyframe = false;

    /**
     * The timestamp of this frame, as dictated by the "sync" instruction which
     * terminates the frame.
     *
     * @type {Number}
     */
    this.timestamp = timestamp;

    /**
     * All instructions which are necessary to generate this frame relative to
     * the previous frame in the Guacamole session.
     *
     * @type {Guacamole.SessionRecording._Frame.Instruction[]}
     */
    this.instructions = instructions;

    /**
     * A snapshot of client state after this frame was rendered, as returned by
     * a call to exportState(). If no such snapshot has been taken, this will
     * be null.
     *
     * @type {Object}
     * @default null
     */
    this.clientState = null;

};

/**
 * A Guacamole protocol instruction. Each Guacamole protocol instruction is
 * made up of an opcode and set of arguments.
 *
 * @private
 * @constructor
 * @param {String} opcode
 *     The opcode of this Guacamole instruction.
 *
 * @param {String[]} args
 *     All arguments associated with this Guacamole instruction.
 */
Guacamole.SessionRecording._Frame.Instruction = function Instruction(opcode, args) {

    /**
     * Reference to this Guacamole.SessionRecording._Frame.Instruction.
     *
     * @private
     * @type {Guacamole.SessionRecording._Frame.Instruction}
     */
    var instruction = this;

    /**
     * The opcode of this Guacamole instruction.
     *
     * @type {String}
     */
    this.opcode = opcode;

    /**
     * All arguments associated with this Guacamole instruction.
     *
     * @type {String[]}
     */
    this.args = args;

    /**
     * Returns the approximate number of characters which make up this
     * instruction. This value is only approximate as it excludes the length
     * prefixes and various delimiters used by the Guacamole protocol; only
     * the content of the opcode and each argument is taken into account.
     *
     * @returns {Number}
     *     The approximate size of this instruction, in characters.
     */
    this.getSize = function getSize() {

        // Init with length of opcode
        var size = instruction.opcode.length;

        // Add length of all arguments
        for (var i = 0; i < instruction.args.length; i++)
            size += instruction.args[i].length;

        return size;

    };

};

/**
 * A read-only Guacamole.Tunnel implementation which streams instructions
 * received through explicit calls to its receiveInstruction() function.
 *
 * @private
 * @constructor
 * @augments {Guacamole.Tunnel}
 */
Guacamole.SessionRecording._PlaybackTunnel = function _PlaybackTunnel() {

    /**
     * Reference to this Guacamole.SessionRecording._PlaybackTunnel.
     *
     * @private
     * @type {Guacamole.SessionRecording._PlaybackTunnel}
     */
    var tunnel = this;

    this.connect = function connect(data) {
        // Do nothing
    };

    this.sendMessage = function sendMessage(elements) {
        // Do nothing
    };

    this.disconnect = function disconnect() {
        // Do nothing
    };

    /**
     * Invokes this tunnel's oninstruction handler, notifying users of this
     * tunnel (such as a Guacamole.Client instance) that an instruction has
     * been received. If the oninstruction handler has not been set, this
     * function has no effect.
     *
     * @param {String} opcode
     *     The opcode of the Guacamole instruction.
     *
     * @param {String[]} args
     *     All arguments associated with this Guacamole instruction.
     */
    this.receiveInstruction = function receiveInstruction(opcode, args) {
        if (tunnel.oninstruction)
            tunnel.oninstruction(opcode, args);
    };

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A Guacamole status. Each Guacamole status consists of a status code, defined
 * by the protocol, and an optional human-readable message, usually only
 * included for debugging convenience.
 *
 * @constructor
 * @param {Number} code
 *     The Guacamole status code, as defined by Guacamole.Status.Code.
 *
 * @param {String} [message]
 *     An optional human-readable message.
 */
Guacamole.Status = function(code, message) {

    /**
     * Reference to this Guacamole.Status.
     * @private
     */
    var guac_status = this;

    /**
     * The Guacamole status code.
     * @see Guacamole.Status.Code
     * @type {Number}
     */
    this.code = code;

    /**
     * An arbitrary human-readable message associated with this status, if any.
     * The human-readable message is not required, and is generally provided
     * for debugging purposes only. For user feedback, it is better to translate
     * the Guacamole status code into a message.
     * 
     * @type {String}
     */
    this.message = message;

    /**
     * Returns whether this status represents an error.
     * @returns {Boolean} true if this status represents an error, false
     *                    otherwise.
     */
    this.isError = function() {
        return guac_status.code < 0 || guac_status.code > 0x00FF;
    };

};

/**
 * Enumeration of all Guacamole status codes.
 */
Guacamole.Status.Code = {

    /**
     * The operation succeeded.
     *
     * @type {Number}
     */
    "SUCCESS": 0x0000,

    /**
     * The requested operation is unsupported.
     *
     * @type {Number}
     */
    "UNSUPPORTED": 0x0100,

    /**
     * The operation could not be performed due to an internal failure.
     *
     * @type {Number}
     */
    "SERVER_ERROR": 0x0200,

    /**
     * The operation could not be performed as the server is busy.
     *
     * @type {Number}
     */
    "SERVER_BUSY": 0x0201,

    /**
     * The operation could not be performed because the upstream server is not
     * responding.
     *
     * @type {Number}
     */
    "UPSTREAM_TIMEOUT": 0x0202,

    /**
     * The operation was unsuccessful due to an error or otherwise unexpected
     * condition of the upstream server.
     *
     * @type {Number}
     */
    "UPSTREAM_ERROR": 0x0203,

    /**
     * The operation could not be performed as the requested resource does not
     * exist.
     *
     * @type {Number}
     */
    "RESOURCE_NOT_FOUND": 0x0204,

    /**
     * The operation could not be performed as the requested resource is
     * already in use.
     *
     * @type {Number}
     */
    "RESOURCE_CONFLICT": 0x0205,

    /**
     * The operation could not be performed as the requested resource is now
     * closed.
     *
     * @type {Number}
     */
    "RESOURCE_CLOSED": 0x0206,

    /**
     * The operation could not be performed because the upstream server does
     * not appear to exist.
     *
     * @type {Number}
     */
    "UPSTREAM_NOT_FOUND": 0x0207,

    /**
     * The operation could not be performed because the upstream server is not
     * available to service the request.
     *
     * @type {Number}
     */
    "UPSTREAM_UNAVAILABLE": 0x0208,

    /**
     * The session within the upstream server has ended because it conflicted
     * with another session.
     *
     * @type {Number}
     */
    "SESSION_CONFLICT": 0x0209,

    /**
     * The session within the upstream server has ended because it appeared to
     * be inactive.
     *
     * @type {Number}
     */
    "SESSION_TIMEOUT": 0x020A,

    /**
     * The session within the upstream server has been forcibly terminated.
     *
     * @type {Number}
     */
    "SESSION_CLOSED": 0x020B,

    /**
     * The operation could not be performed because bad parameters were given.
     *
     * @type {Number}
     */
    "CLIENT_BAD_REQUEST": 0x0300,

    /**
     * Permission was denied to perform the operation, as the user is not yet
     * authorized (not yet logged in, for example).
     *
     * @type {Number}
     */
    "CLIENT_UNAUTHORIZED": 0x0301,

    /**
     * Permission was denied to perform the operation, and this permission will
     * not be granted even if the user is authorized.
     *
     * @type {Number}
     */
    "CLIENT_FORBIDDEN": 0x0303,

    /**
     * The client took too long to respond.
     *
     * @type {Number}
     */
    "CLIENT_TIMEOUT": 0x0308,

    /**
     * The client sent too much data.
     *
     * @type {Number}
     */
    "CLIENT_OVERRUN": 0x030D,

    /**
     * The client sent data of an unsupported or unexpected type.
     *
     * @type {Number}
     */
    "CLIENT_BAD_TYPE": 0x030F,

    /**
     * The operation failed because the current client is already using too
     * many resources.
     *
     * @type {Number}
     */
    "CLIENT_TOO_MANY": 0x031D

};
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A reader which automatically handles the given input stream, returning
 * strictly text data. Note that this object will overwrite any installed event
 * handlers on the given Guacamole.InputStream.
 * 
 * @constructor
 * @param {Guacamole.InputStream} stream The stream that data will be read
 *                                       from.
 */
Guacamole.StringReader = function(stream) {

    /**
     * Reference to this Guacamole.InputStream.
     * @private
     */
    var guac_reader = this;

    /**
     * Wrapped Guacamole.ArrayBufferReader.
     * @private
     * @type {Guacamole.ArrayBufferReader}
     */
    var array_reader = new Guacamole.ArrayBufferReader(stream);

    /**
     * The number of bytes remaining for the current codepoint.
     *
     * @private
     * @type {Number}
     */
    var bytes_remaining = 0;

    /**
     * The current codepoint value, as calculated from bytes read so far.
     *
     * @private
     * @type {Number}
     */
    var codepoint = 0;

    /**
     * Decodes the given UTF-8 data into a Unicode string. The data may end in
     * the middle of a multibyte character.
     * 
     * @private
     * @param {ArrayBuffer} buffer Arbitrary UTF-8 data.
     * @return {String} A decoded Unicode string.
     */
    function __decode_utf8(buffer) {

        var text = "";

        var bytes = new Uint8Array(buffer);
        for (var i=0; i<bytes.length; i++) {

            // Get current byte
            var value = bytes[i];

            // Start new codepoint if nothing yet read
            if (bytes_remaining === 0) {

                // 1 byte (0xxxxxxx)
                if ((value | 0x7F) === 0x7F)
                    text += String.fromCharCode(value);

                // 2 byte (110xxxxx)
                else if ((value | 0x1F) === 0xDF) {
                    codepoint = value & 0x1F;
                    bytes_remaining = 1;
                }

                // 3 byte (1110xxxx)
                else if ((value | 0x0F )=== 0xEF) {
                    codepoint = value & 0x0F;
                    bytes_remaining = 2;
                }

                // 4 byte (11110xxx)
                else if ((value | 0x07) === 0xF7) {
                    codepoint = value & 0x07;
                    bytes_remaining = 3;
                }

                // Invalid byte
                else
                    text += "\uFFFD";

            }

            // Continue existing codepoint (10xxxxxx)
            else if ((value | 0x3F) === 0xBF) {

                codepoint = (codepoint << 6) | (value & 0x3F);
                bytes_remaining--;

                // Write codepoint if finished
                if (bytes_remaining === 0)
                    text += String.fromCharCode(codepoint);

            }

            // Invalid byte
            else {
                bytes_remaining = 0;
                text += "\uFFFD";
            }

        }

        return text;

    }

    // Receive blobs as strings
    array_reader.ondata = function(buffer) {

        // Decode UTF-8
        var text = __decode_utf8(buffer);

        // Call handler, if present
        if (guac_reader.ontext)
            guac_reader.ontext(text);

    };

    // Simply call onend when end received
    array_reader.onend = function() {
        if (guac_reader.onend)
            guac_reader.onend();
    };

    /**
     * Fired once for every blob of text data received.
     * 
     * @event
     * @param {String} text The data packet received.
     */
    this.ontext = null;

    /**
     * Fired once this stream is finished and no further data will be written.
     * @event
     */
    this.onend = null;

};/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A writer which automatically writes to the given output stream with text
 * data.
 * 
 * @constructor
 * @param {Guacamole.OutputStream} stream The stream that data will be written
 *                                        to.
 */
Guacamole.StringWriter = function(stream) {

    /**
     * Reference to this Guacamole.StringWriter.
     * @private
     */
    var guac_writer = this;

    /**
     * Wrapped Guacamole.ArrayBufferWriter.
     * @private
     * @type {Guacamole.ArrayBufferWriter}
     */
    var array_writer = new Guacamole.ArrayBufferWriter(stream);

    /**
     * Internal buffer for UTF-8 output.
     * @private
     */
    var buffer = new Uint8Array(8192);

    /**
     * The number of bytes currently in the buffer.
     * @private
     */
    var length = 0;

    // Simply call onack for acknowledgements
    array_writer.onack = function(status) {
        if (guac_writer.onack)
            guac_writer.onack(status);
    };

    /**
     * Expands the size of the underlying buffer by the given number of bytes,
     * updating the length appropriately.
     * 
     * @private
     * @param {Number} bytes The number of bytes to add to the underlying
     *                       buffer.
     */
    function __expand(bytes) {

        // Resize buffer if more space needed
        if (length+bytes >= buffer.length) {
            var new_buffer = new Uint8Array((length+bytes)*2);
            new_buffer.set(buffer);
            buffer = new_buffer;
        }

        length += bytes;

    }

    /**
     * Appends a single Unicode character to the current buffer, resizing the
     * buffer if necessary. The character will be encoded as UTF-8.
     * 
     * @private
     * @param {Number} codepoint The codepoint of the Unicode character to
     *                           append.
     */
    function __append_utf8(codepoint) {

        var mask;
        var bytes;

        // 1 byte
        if (codepoint <= 0x7F) {
            mask = 0x00;
            bytes = 1;
        }

        // 2 byte
        else if (codepoint <= 0x7FF) {
            mask = 0xC0;
            bytes = 2;
        }

        // 3 byte
        else if (codepoint <= 0xFFFF) {
            mask = 0xE0;
            bytes = 3;
        }

        // 4 byte
        else if (codepoint <= 0x1FFFFF) {
            mask = 0xF0;
            bytes = 4;
        }

        // If invalid codepoint, append replacement character
        else {
            __append_utf8(0xFFFD);
            return;
        }

        // Offset buffer by size
        __expand(bytes);
        var offset = length - 1;

        // Add trailing bytes, if any
        for (var i=1; i<bytes; i++) {
            buffer[offset--] = 0x80 | (codepoint & 0x3F);
            codepoint >>= 6;
        }

        // Set initial byte
        buffer[offset] = mask | codepoint;

    }

    /**
     * Encodes the given string as UTF-8, returning an ArrayBuffer containing
     * the resulting bytes.
     * 
     * @private
     * @param {String} text The string to encode as UTF-8.
     * @return {Uint8Array} The encoded UTF-8 data.
     */
    function __encode_utf8(text) {

        // Fill buffer with UTF-8
        for (var i=0; i<text.length; i++) {
            var codepoint = text.charCodeAt(i);
            __append_utf8(codepoint);
        }

        // Flush buffer
        if (length > 0) {
            var out_buffer = buffer.subarray(0, length);
            length = 0;
            return out_buffer;
        }

    }

    /**
     * Sends the given text.
     * 
     * @param {String} text The text to send.
     */
    this.sendText = function(text) {
        if (text.length)
            array_writer.sendData(__encode_utf8(text));
    };

    /**
     * Signals that no further text will be sent, effectively closing the
     * stream.
     */
    this.sendEnd = function() {
        array_writer.sendEnd();
    };

    /**
     * Fired for received data, if acknowledged by the server.
     * @event
     * @param {Guacamole.Status} status The status of the operation.
     */
    this.onack = null;

};/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Core object providing abstract communication for Guacamole. This object
 * is a null implementation whose functions do nothing. Guacamole applications
 * should use {@link Guacamole.HTTPTunnel} instead, or implement their own tunnel based
 * on this one.
 * 
 * @constructor
 * @see Guacamole.HTTPTunnel
 */
Guacamole.Tunnel = function() {

    /**
     * Connect to the tunnel with the given optional data. This data is
     * typically used for authentication. The format of data accepted is
     * up to the tunnel implementation.
     * 
     * @param {String} data The data to send to the tunnel when connecting.
     */
    this.connect = function(data) {};
    
    /**
     * Disconnect from the tunnel.
     */
    this.disconnect = function() {};
    
    /**
     * Send the given message through the tunnel to the service on the other
     * side. All messages are guaranteed to be received in the order sent.
     * 
     * @param {...*} elements
     *     The elements of the message to send to the service on the other side
     *     of the tunnel.
     */
    this.sendMessage = function(elements) {};

    /**
     * The current state of this tunnel.
     * 
     * @type {Number}
     */
    this.state = Guacamole.Tunnel.State.CONNECTING;

    /**
     * The maximum amount of time to wait for data to be received, in
     * milliseconds. If data is not received within this amount of time,
     * the tunnel is closed with an error. The default value is 15000.
     * 
     * @type {Number}
     */
    this.receiveTimeout = 15000;

    /**
     * The UUID uniquely identifying this tunnel. If not yet known, this will
     * be null.
     *
     * @type {String}
     */
    this.uuid = null;

    /**
     * Fired whenever an error is encountered by the tunnel.
     * 
     * @event
     * @param {Guacamole.Status} status A status object which describes the
     *                                  error.
     */
    this.onerror = null;

    /**
     * Fired whenever the state of the tunnel changes.
     * 
     * @event
     * @param {Number} state The new state of the client.
     */
    this.onstatechange = null;

    /**
     * Fired once for every complete Guacamole instruction received, in order.
     * 
     * @event
     * @param {String} opcode The Guacamole instruction opcode.
     * @param {Array} parameters The parameters provided for the instruction,
     *                           if any.
     */
    this.oninstruction = null;

};

/**
 * The Guacamole protocol instruction opcode reserved for arbitrary internal
 * use by tunnel implementations. The value of this opcode is guaranteed to be
 * the empty string (""). Tunnel implementations may use this opcode for any
 * purpose. It is currently used by the HTTP tunnel to mark the end of the HTTP
 * response, and by the WebSocket tunnel to transmit the tunnel UUID.
 *
 * @constant
 * @type {String}
 */
Guacamole.Tunnel.INTERNAL_DATA_OPCODE = '';

/**
 * All possible tunnel states.
 */
Guacamole.Tunnel.State = {

    /**
     * A connection is in pending. It is not yet known whether connection was
     * successful.
     * 
     * @type {Number}
     */
    "CONNECTING": 0,

    /**
     * Connection was successful, and data is being received.
     * 
     * @type {Number}
     */
    "OPEN": 1,

    /**
     * The connection is closed. Connection may not have been successful, the
     * tunnel may have been explicitly closed by either side, or an error may
     * have occurred.
     * 
     * @type {Number}
     */
    "CLOSED": 2

};

/**
 * Guacamole Tunnel implemented over HTTP via XMLHttpRequest.
 * 
 * @constructor
 * @augments Guacamole.Tunnel
 *
 * @param {String} tunnelURL
 *     The URL of the HTTP tunneling service.
 *
 * @param {Boolean} [crossDomain=false]
 *     Whether tunnel requests will be cross-domain, and thus must use CORS
 *     mechanisms and headers. By default, it is assumed that tunnel requests
 *     will be made to the same domain.
 */
Guacamole.HTTPTunnel = function(tunnelURL, crossDomain) {

    /**
     * Reference to this HTTP tunnel.
     * @private
     */
    var tunnel = this;

    var TUNNEL_CONNECT = tunnelURL + "?connect";
    var TUNNEL_READ    = tunnelURL + "?read:";
    var TUNNEL_WRITE   = tunnelURL + "?write:";

    var POLLING_ENABLED     = 1;
    var POLLING_DISABLED    = 0;

    // Default to polling - will be turned off automatically if not needed
    var pollingMode = POLLING_ENABLED;

    var sendingMessages = false;
    var outputMessageBuffer = "";

    // If requests are expected to be cross-domain, the cookie that the HTTP
    // tunnel depends on will only be sent if withCredentials is true
    var withCredentials = !!crossDomain;

    /**
     * The current receive timeout ID, if any.
     * @private
     */
    var receive_timeout = null;

    /**
     * Initiates a timeout which, if data is not received, causes the tunnel
     * to close with an error.
     * 
     * @private
     */
    function reset_timeout() {

        // Get rid of old timeout (if any)
        window.clearTimeout(receive_timeout);

        // Set new timeout
        receive_timeout = window.setTimeout(function () {
            close_tunnel(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_TIMEOUT, "Server timeout."));
        }, tunnel.receiveTimeout);

    }

    /**
     * Closes this tunnel, signaling the given status and corresponding
     * message, which will be sent to the onerror handler if the status is
     * an error status.
     * 
     * @private
     * @param {Guacamole.Status} status The status causing the connection to
     *                                  close;
     */
    function close_tunnel(status) {

        // Ignore if already closed
        if (tunnel.state === Guacamole.Tunnel.State.CLOSED)
            return;

        // If connection closed abnormally, signal error.
        if (status.code !== Guacamole.Status.Code.SUCCESS && tunnel.onerror) {

            // Ignore RESOURCE_NOT_FOUND if we've already connected, as that
            // only signals end-of-stream for the HTTP tunnel.
            if (tunnel.state === Guacamole.Tunnel.State.CONNECTING
                    || status.code !== Guacamole.Status.Code.RESOURCE_NOT_FOUND)
                tunnel.onerror(status);

        }

        // Mark as closed
        tunnel.state = Guacamole.Tunnel.State.CLOSED;

        // Reset output message buffer
        sendingMessages = false;

        if (tunnel.onstatechange)
            tunnel.onstatechange(tunnel.state);

    }


    this.sendMessage = function() {

        // Do not attempt to send messages if not connected
        if (tunnel.state !== Guacamole.Tunnel.State.OPEN)
            return;

        // Do not attempt to send empty messages
        if (arguments.length === 0)
            return;

        /**
         * Converts the given value to a length/string pair for use as an
         * element in a Guacamole instruction.
         * 
         * @private
         * @param value The value to convert.
         * @return {String} The converted value. 
         */
        function getElement(value) {
            var string = new String(value);
            return string.length + "." + string; 
        }

        // Initialized message with first element
        var message = getElement(arguments[0]);

        // Append remaining elements
        for (var i=1; i<arguments.length; i++)
            message += "," + getElement(arguments[i]);

        // Final terminator
        message += ";";

        // Add message to buffer
        outputMessageBuffer += message;

        // Send if not currently sending
        if (!sendingMessages)
            sendPendingMessages();

    };

    function sendPendingMessages() {

        // Do not attempt to send messages if not connected
        if (tunnel.state !== Guacamole.Tunnel.State.OPEN)
            return;

        if (outputMessageBuffer.length > 0) {

            sendingMessages = true;

            var message_xmlhttprequest = new XMLHttpRequest();
            message_xmlhttprequest.open("POST", TUNNEL_WRITE + tunnel.uuid);
            message_xmlhttprequest.withCredentials = withCredentials;
            message_xmlhttprequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");

            // Once response received, send next queued event.
            message_xmlhttprequest.onreadystatechange = function() {
                if (message_xmlhttprequest.readyState === 4) {

                    // If an error occurs during send, handle it
                    if (message_xmlhttprequest.status !== 200)
                        handleHTTPTunnelError(message_xmlhttprequest);

                    // Otherwise, continue the send loop
                    else
                        sendPendingMessages();

                }
            };

            message_xmlhttprequest.send(outputMessageBuffer);
            outputMessageBuffer = ""; // Clear buffer

        }
        else
            sendingMessages = false;

    }

    function handleHTTPTunnelError(xmlhttprequest) {

        var code = parseInt(xmlhttprequest.getResponseHeader("Guacamole-Status-Code"));
        var message = xmlhttprequest.getResponseHeader("Guacamole-Error-Message");

        close_tunnel(new Guacamole.Status(code, message));

    }

    function handleResponse(xmlhttprequest) {

        var interval = null;
        var nextRequest = null;

        var dataUpdateEvents = 0;

        // The location of the last element's terminator
        var elementEnd = -1;

        // Where to start the next length search or the next element
        var startIndex = 0;

        // Parsed elements
        var elements = new Array();

        function parseResponse() {

            // Do not handle responses if not connected
            if (tunnel.state !== Guacamole.Tunnel.State.OPEN) {
                
                // Clean up interval if polling
                if (interval !== null)
                    clearInterval(interval);
                
                return;
            }

            // Do not parse response yet if not ready
            if (xmlhttprequest.readyState < 2) return;

            // Attempt to read status
            var status;
            try { status = xmlhttprequest.status; }

            // If status could not be read, assume successful.
            catch (e) { status = 200; }

            // Start next request as soon as possible IF request was successful
            if (!nextRequest && status === 200)
                nextRequest = makeRequest();

            // Parse stream when data is received and when complete.
            if (xmlhttprequest.readyState === 3 ||
                xmlhttprequest.readyState === 4) {

                reset_timeout();

                // Also poll every 30ms (some browsers don't repeatedly call onreadystatechange for new data)
                if (pollingMode === POLLING_ENABLED) {
                    if (xmlhttprequest.readyState === 3 && !interval)
                        interval = setInterval(parseResponse, 30);
                    else if (xmlhttprequest.readyState === 4 && interval)
                        clearInterval(interval);
                }

                // If canceled, stop transfer
                if (xmlhttprequest.status === 0) {
                    tunnel.disconnect();
                    return;
                }

                // Halt on error during request
                else if (xmlhttprequest.status !== 200) {
                    handleHTTPTunnelError(xmlhttprequest);
                    return;
                }

                // Attempt to read in-progress data
                var current;
                try { current = xmlhttprequest.responseText; }

                // Do not attempt to parse if data could not be read
                catch (e) { return; }

                // While search is within currently received data
                while (elementEnd < current.length) {

                    // If we are waiting for element data
                    if (elementEnd >= startIndex) {

                        // We now have enough data for the element. Parse.
                        var element = current.substring(startIndex, elementEnd);
                        var terminator = current.substring(elementEnd, elementEnd+1);

                        // Add element to array
                        elements.push(element);

                        // If last element, handle instruction
                        if (terminator === ";") {

                            // Get opcode
                            var opcode = elements.shift();

                            // Call instruction handler.
                            if (tunnel.oninstruction)
                                tunnel.oninstruction(opcode, elements);

                            // Clear elements
                            elements.length = 0;

                        }

                        // Start searching for length at character after
                        // element terminator
                        startIndex = elementEnd + 1;

                    }

                    // Search for end of length
                    var lengthEnd = current.indexOf(".", startIndex);
                    if (lengthEnd !== -1) {

                        // Parse length
                        var length = parseInt(current.substring(elementEnd+1, lengthEnd));

                        // If we're done parsing, handle the next response.
                        if (length === 0) {

                            // Clean up interval if polling
                            if (interval)
                                clearInterval(interval);
                           
                            // Clean up object
                            xmlhttprequest.onreadystatechange = null;
                            xmlhttprequest.abort();

                            // Start handling next request
                            if (nextRequest)
                                handleResponse(nextRequest);

                            // Done parsing
                            break;

                        }

                        // Calculate start of element
                        startIndex = lengthEnd + 1;

                        // Calculate location of element terminator
                        elementEnd = startIndex + length;

                    }
                    
                    // If no period yet, continue search when more data
                    // is received
                    else {
                        startIndex = current.length;
                        break;
                    }

                } // end parse loop

            }

        }

        // If response polling enabled, attempt to detect if still
        // necessary (via wrapping parseResponse())
        if (pollingMode === POLLING_ENABLED) {
            xmlhttprequest.onreadystatechange = function() {

                // If we receive two or more readyState==3 events,
                // there is no need to poll.
                if (xmlhttprequest.readyState === 3) {
                    dataUpdateEvents++;
                    if (dataUpdateEvents >= 2) {
                        pollingMode = POLLING_DISABLED;
                        xmlhttprequest.onreadystatechange = parseResponse;
                    }
                }

                parseResponse();
            };
        }

        // Otherwise, just parse
        else
            xmlhttprequest.onreadystatechange = parseResponse;

        parseResponse();

    }

    /**
     * Arbitrary integer, unique for each tunnel read request.
     * @private
     */
    var request_id = 0;

    function makeRequest() {

        // Make request, increment request ID
        var xmlhttprequest = new XMLHttpRequest();
        xmlhttprequest.open("GET", TUNNEL_READ + tunnel.uuid + ":" + (request_id++));
        xmlhttprequest.withCredentials = withCredentials;
        xmlhttprequest.send(null);

        return xmlhttprequest;

    }

    this.connect = function(data) {

        // Start waiting for connect
        reset_timeout();

        // Start tunnel and connect
        var connect_xmlhttprequest = new XMLHttpRequest();
        connect_xmlhttprequest.onreadystatechange = function() {

            if (connect_xmlhttprequest.readyState !== 4)
                return;

            // If failure, throw error
            if (connect_xmlhttprequest.status !== 200) {
                handleHTTPTunnelError(connect_xmlhttprequest);
                return;
            }

            reset_timeout();

            // Get UUID from response
            tunnel.uuid = connect_xmlhttprequest.responseText;

            tunnel.state = Guacamole.Tunnel.State.OPEN;
            if (tunnel.onstatechange)
                tunnel.onstatechange(tunnel.state);

            // Start reading data
            handleResponse(makeRequest());

        };

        connect_xmlhttprequest.open("POST", TUNNEL_CONNECT, true);
        connect_xmlhttprequest.withCredentials = withCredentials;
        connect_xmlhttprequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
        connect_xmlhttprequest.send(data);

    };

    this.disconnect = function() {
        close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SUCCESS, "Manually closed."));
    };

};

Guacamole.HTTPTunnel.prototype = new Guacamole.Tunnel();

/**
 * Guacamole Tunnel implemented over WebSocket via XMLHttpRequest.
 * 
 * @constructor
 * @augments Guacamole.Tunnel
 * @param {String} tunnelURL The URL of the WebSocket tunneling service.
 */
Guacamole.WebSocketTunnel = function(tunnelURL) {

    /**
     * Reference to this WebSocket tunnel.
     * @private
     */
    var tunnel = this;

    /**
     * The WebSocket used by this tunnel.
     * @private
     */
    var socket = null;

    /**
     * The current receive timeout ID, if any.
     * @private
     */
    var receive_timeout = null;

    /**
     * The WebSocket protocol corresponding to the protocol used for the current
     * location.
     * @private
     */
    var ws_protocol = {
        "http:":  "ws:",
        "https:": "wss:"
    };

    // Transform current URL to WebSocket URL

    // If not already a websocket URL
    if (   tunnelURL.substring(0, 3) !== "ws:"
        && tunnelURL.substring(0, 4) !== "wss:") {

        var protocol = ws_protocol[window.location.protocol];

        // If absolute URL, convert to absolute WS URL
        if (tunnelURL.substring(0, 1) === "/")
            tunnelURL =
                protocol
                + "//" + window.location.host
                + tunnelURL;

        // Otherwise, construct absolute from relative URL
        else {

            // Get path from pathname
            var slash = window.location.pathname.lastIndexOf("/");
            var path  = window.location.pathname.substring(0, slash + 1);

            // Construct absolute URL
            tunnelURL =
                protocol
                + "//" + window.location.host
                + path
                + tunnelURL;

        }

    }

    /**
     * Initiates a timeout which, if data is not received, causes the tunnel
     * to close with an error.
     * 
     * @private
     */
    function reset_timeout() {

        // Get rid of old timeout (if any)
        window.clearTimeout(receive_timeout);

        // Set new timeout
        receive_timeout = window.setTimeout(function () {
            close_tunnel(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_TIMEOUT, "Server timeout."));
        }, tunnel.receiveTimeout);

    }

    /**
     * Closes this tunnel, signaling the given status and corresponding
     * message, which will be sent to the onerror handler if the status is
     * an error status.
     * 
     * @private
     * @param {Guacamole.Status} status The status causing the connection to
     *                                  close;
     */
    function close_tunnel(status) {

        // Ignore if already closed
        if (tunnel.state === Guacamole.Tunnel.State.CLOSED)
            return;

        // If connection closed abnormally, signal error.
        if (status.code !== Guacamole.Status.Code.SUCCESS && tunnel.onerror)
            tunnel.onerror(status);

        // Mark as closed
        tunnel.state = Guacamole.Tunnel.State.CLOSED;
        if (tunnel.onstatechange)
            tunnel.onstatechange(tunnel.state);

        socket.close();

    }

    this.sendMessage = function(elements) {

        // Do not attempt to send messages if not connected
        if (tunnel.state !== Guacamole.Tunnel.State.OPEN)
            return;

        // Do not attempt to send empty messages
        if (arguments.length === 0)
            return;

        /**
         * Converts the given value to a length/string pair for use as an
         * element in a Guacamole instruction.
         * 
         * @private
         * @param value The value to convert.
         * @return {String} The converted value. 
         */
        function getElement(value) {
            var string = new String(value);
            return string.length + "." + string; 
        }

        // Initialized message with first element
        var message = getElement(arguments[0]);

        // Append remaining elements
        for (var i=1; i<arguments.length; i++)
            message += "," + getElement(arguments[i]);

        // Final terminator
        message += ";";

        socket.send(message);

    };

    this.connect = function(data) {

        reset_timeout();

        // Connect socket
        socket = new WebSocket(tunnelURL + "?" + data, "guacamole");

        socket.onopen = function(event) {
            reset_timeout();
        };

        socket.onclose = function(event) {
            close_tunnel(new Guacamole.Status(parseInt(event.reason), event.reason));
        };
        
        socket.onerror = function(event) {
            close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SERVER_ERROR, event.data));
        };

        socket.onmessage = function(event) {

            reset_timeout();

            var message = event.data;
            var startIndex = 0;
            var elementEnd;

            var elements = [];

            do {

                // Search for end of length
                var lengthEnd = message.indexOf(".", startIndex);
                if (lengthEnd !== -1) {

                    // Parse length
                    var length = parseInt(message.substring(elementEnd+1, lengthEnd));

                    // Calculate start of element
                    startIndex = lengthEnd + 1;

                    // Calculate location of element terminator
                    elementEnd = startIndex + length;

                }
                
                // If no period, incomplete instruction.
                else
                    close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SERVER_ERROR, "Incomplete instruction."));

                // We now have enough data for the element. Parse.
                var element = message.substring(startIndex, elementEnd);
                var terminator = message.substring(elementEnd, elementEnd+1);

                // Add element to array
                elements.push(element);

                // If last element, handle instruction
                if (terminator === ";") {

                    // Get opcode
                    var opcode = elements.shift();

                    // Update state and UUID when first instruction received
                    if (tunnel.state !== Guacamole.Tunnel.State.OPEN) {

                        // Associate tunnel UUID if received
                        if (opcode === Guacamole.Tunnel.INTERNAL_DATA_OPCODE)
                            tunnel.uuid = elements[0];

                        // Tunnel is now open and UUID is available
                        tunnel.state = Guacamole.Tunnel.State.OPEN;
                        if (tunnel.onstatechange)
                            tunnel.onstatechange(tunnel.state);

                    }

                    // Call instruction handler.
                    if (opcode !== Guacamole.Tunnel.INTERNAL_DATA_OPCODE && tunnel.oninstruction)
                        tunnel.oninstruction(opcode, elements);

                    // Clear elements
                    elements.length = 0;

                }

                // Start searching for length at character after
                // element terminator
                startIndex = elementEnd + 1;

            } while (startIndex < message.length);

        };

    };

    this.disconnect = function() {
        close_tunnel(new Guacamole.Status(Guacamole.Status.Code.SUCCESS, "Manually closed."));
    };

};

Guacamole.WebSocketTunnel.prototype = new Guacamole.Tunnel();

/**
 * Guacamole Tunnel which cycles between all specified tunnels until
 * no tunnels are left. Another tunnel is used if an error occurs but
 * no instructions have been received. If an instruction has been
 * received, or no tunnels remain, the error is passed directly out
 * through the onerror handler (if defined).
 * 
 * @constructor
 * @augments Guacamole.Tunnel
 * @param {...*} tunnelChain
 *     The tunnels to use, in order of priority.
 */
Guacamole.ChainedTunnel = function(tunnelChain) {

    /**
     * Reference to this chained tunnel.
     * @private
     */
    var chained_tunnel = this;

    /**
     * Data passed in via connect(), to be used for
     * wrapped calls to other tunnels' connect() functions.
     * @private
     */
    var connect_data;

    /**
     * Array of all tunnels passed to this ChainedTunnel through the
     * constructor arguments.
     * @private
     */
    var tunnels = [];

    /**
     * The tunnel committed via commit_tunnel(), if any, or null if no tunnel
     * has yet been committed.
     *
     * @private
     * @type {Guacamole.Tunnel}
     */
    var committedTunnel = null;

    // Load all tunnels into array
    for (var i=0; i<arguments.length; i++)
        tunnels.push(arguments[i]);

    /**
     * Sets the current tunnel.
     * 
     * @private
     * @param {Guacamole.Tunnel} tunnel The tunnel to set as the current tunnel.
     */
    function attach(tunnel) {

        // Set own functions to tunnel's functions
        chained_tunnel.disconnect  = tunnel.disconnect;
        chained_tunnel.sendMessage = tunnel.sendMessage;

        /**
         * Fails the currently-attached tunnel, attaching a new tunnel if
         * possible.
         *
         * @private
         * @param {Guacamole.Status} [status]
         *     An object representing the failure that occured in the
         *     currently-attached tunnel, if known.
         *
         * @return {Guacamole.Tunnel}
         *     The next tunnel, or null if there are no more tunnels to try or
         *     if no more tunnels should be tried.
         */
        var failTunnel = function failTunnel(status) {

            // Do not attempt to continue using next tunnel on server timeout
            if (status && status.code === Guacamole.Status.Code.UPSTREAM_TIMEOUT) {
                tunnels = [];
                return null;
            }

            // Get next tunnel
            var next_tunnel = tunnels.shift();

            // If there IS a next tunnel, try using it.
            if (next_tunnel) {
                tunnel.onerror = null;
                tunnel.oninstruction = null;
                tunnel.onstatechange = null;
                attach(next_tunnel);
            }

            return next_tunnel;

        };

        /**
         * Use the current tunnel from this point forward. Do not try any more
         * tunnels, even if the current tunnel fails.
         * 
         * @private
         */
        function commit_tunnel() {
            tunnel.onstatechange = chained_tunnel.onstatechange;
            tunnel.oninstruction = chained_tunnel.oninstruction;
            tunnel.onerror = chained_tunnel.onerror;
            chained_tunnel.uuid = tunnel.uuid;
            committedTunnel = tunnel;
        }

        // Wrap own onstatechange within current tunnel
        tunnel.onstatechange = function(state) {

            switch (state) {

                // If open, use this tunnel from this point forward.
                case Guacamole.Tunnel.State.OPEN:
                    commit_tunnel();
                    if (chained_tunnel.onstatechange)
                        chained_tunnel.onstatechange(state);
                    break;

                // If closed, mark failure, attempt next tunnel
                case Guacamole.Tunnel.State.CLOSED:
                    if (!failTunnel() && chained_tunnel.onstatechange)
                        chained_tunnel.onstatechange(state);
                    break;
                
            }

        };

        // Wrap own oninstruction within current tunnel
        tunnel.oninstruction = function(opcode, elements) {

            // Accept current tunnel
            commit_tunnel();

            // Invoke handler
            if (chained_tunnel.oninstruction)
                chained_tunnel.oninstruction(opcode, elements);

        };

        // Attach next tunnel on error
        tunnel.onerror = function(status) {

            // Mark failure, attempt next tunnel
            if (!failTunnel(status) && chained_tunnel.onerror)
                chained_tunnel.onerror(status);

        };

        // Attempt connection
        tunnel.connect(connect_data);
        
    }

    this.connect = function(data) {
       
        // Remember connect data
        connect_data = data;

        // Get committed tunnel if exists or the first tunnel on the list
        var next_tunnel = committedTunnel ? committedTunnel : tunnels.shift();

        // Attach first tunnel
        if (next_tunnel)
            attach(next_tunnel);

        // If there IS no first tunnel, error
        else if (chained_tunnel.onerror)
            chained_tunnel.onerror(Guacamole.Status.Code.SERVER_ERROR, "No tunnels to try.");

    };
    
};

Guacamole.ChainedTunnel.prototype = new Guacamole.Tunnel();

/**
 * Guacamole Tunnel which replays a Guacamole protocol dump from a static file
 * received via HTTP. Instructions within the file are parsed and handled as
 * quickly as possible, while the file is being downloaded.
 *
 * @constructor
 * @augments Guacamole.Tunnel
 * @param {String} url
 *     The URL of a Guacamole protocol dump.
 *
 * @param {Boolean} [crossDomain=false]
 *     Whether tunnel requests will be cross-domain, and thus must use CORS
 *     mechanisms and headers. By default, it is assumed that tunnel requests
 *     will be made to the same domain.
 */
Guacamole.StaticHTTPTunnel = function StaticHTTPTunnel(url, crossDomain) {

    /**
     * Reference to this Guacamole.StaticHTTPTunnel.
     *
     * @private
     */
    var tunnel = this;

    /**
     * The current, in-progress HTTP request. If no request is currently in
     * progress, this will be null.
     *
     * @private
     * @type {XMLHttpRequest}
     */
    var xhr = null;

    /**
     * Changes the stored numeric state of this tunnel, firing the onstatechange
     * event if the new state is different and a handler has been defined.
     *
     * @private
     * @param {Number} state
     *     The new state of this tunnel.
     */
    var setState = function setState(state) {

        // Notify only if state changes
        if (state !== tunnel.state) {
            tunnel.state = state;
            if (tunnel.onstatechange)
                tunnel.onstatechange(state);
        }

    };

    /**
     * Returns the Guacamole protocol status code which most closely
     * represents the given HTTP status code.
     *
     * @private
     * @param {Number} httpStatus
     *     The HTTP status code to translate into a Guacamole protocol status
     *     code.
     *
     * @returns {Number}
     *     The Guacamole protocol status code which most closely represents the
     *     given HTTP status code.
     */
    var getGuacamoleStatusCode = function getGuacamoleStatusCode(httpStatus) {

        // Translate status codes with known equivalents
        switch (httpStatus) {

            // HTTP 400 - Bad request
            case 400:
                return Guacamole.Status.Code.CLIENT_BAD_REQUEST;

            // HTTP 403 - Forbidden
            case 403:
                return Guacamole.Status.Code.CLIENT_FORBIDDEN;

            // HTTP 404 - Resource not found
            case 404:
                return Guacamole.Status.Code.RESOURCE_NOT_FOUND;

            // HTTP 429 - Too many requests
            case 429:
                return Guacamole.Status.Code.CLIENT_TOO_MANY;

            // HTTP 503 - Server unavailable
            case 503:
                return Guacamole.Status.Code.SERVER_BUSY;

        }

        // Default all other codes to generic internal error
        return Guacamole.Status.Code.SERVER_ERROR;

    };

    this.sendMessage = function sendMessage(elements) {
        // Do nothing
    };

    this.connect = function connect(data) {

        // Ensure any existing connection is killed
        tunnel.disconnect();

        // Connection is now starting
        setState(Guacamole.Tunnel.State.CONNECTING);

        // Start a new connection
        xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.withCredentials = !!crossDomain;
        xhr.responseType = 'text';
        xhr.send(null);

        var offset = 0;

        // Create Guacamole protocol parser specifically for this connection
        var parser = new Guacamole.Parser();

        // Invoke tunnel's oninstruction handler for each parsed instruction
        parser.oninstruction = function instructionReceived(opcode, args) {
            if (tunnel.oninstruction)
                tunnel.oninstruction(opcode, args);
        };

        // Continuously parse received data
        xhr.onreadystatechange = function readyStateChanged() {

            // Parse while data is being received
            if (xhr.readyState === 3 || xhr.readyState === 4) {

                // Connection is open
                setState(Guacamole.Tunnel.State.OPEN);

                var buffer = xhr.responseText;
                var length = buffer.length;

                // Parse only the portion of data which is newly received
                if (offset < length) {
                    parser.receive(buffer.substring(offset));
                    offset = length;
                }

            }

            // Clean up and close when done
            if (xhr.readyState === 4)
                tunnel.disconnect();

        };

        // Reset state and close upon error
        xhr.onerror = function httpError() {

            // Fail if file could not be downloaded via HTTP
            if (tunnel.onerror)
                tunnel.onerror(new Guacamole.Status(getGuacamoleStatusCode(xhr.status), xhr.statusText));

            tunnel.disconnect();
        };

    };

    this.disconnect = function disconnect() {

        // Abort and dispose of XHR if a request is in progress
        if (xhr) {
            xhr.abort();
            xhr = null;
        }

        // Connection is now closed
        setState(Guacamole.Tunnel.State.CLOSED);

    };

};

Guacamole.StaticHTTPTunnel.prototype = new Guacamole.Tunnel();
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * The unique ID of this version of the Guacamole JavaScript API. This ID will
 * be the version string of the guacamole-common-js Maven project, and can be
 * used in downstream applications as a sanity check that the proper version
 * of the APIs is being used (in case an older version is cached, for example).
 *
 * @type {String}
 */
Guacamole.API_VERSION = "0.9.12-incubating";
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * Abstract video player which accepts, queues and plays back arbitrary video
 * data. It is up to implementations of this class to provide some means of
 * handling a provided Guacamole.InputStream and rendering the received data to
 * the provided Guacamole.Display.VisibleLayer. Data received along the
 * provided stream is to be played back immediately.
 *
 * @constructor
 */
Guacamole.VideoPlayer = function VideoPlayer() {

    /**
     * Notifies this Guacamole.VideoPlayer that all video up to the current
     * point in time has been given via the underlying stream, and that any
     * difference in time between queued video data and the current time can be
     * considered latency.
     */
    this.sync = function sync() {
        // Default implementation - do nothing
    };

};

/**
 * Determines whether the given mimetype is supported by any built-in
 * implementation of Guacamole.VideoPlayer, and thus will be properly handled
 * by Guacamole.VideoPlayer.getInstance().
 *
 * @param {String} mimetype
 *     The mimetype to check.
 *
 * @returns {Boolean}
 *     true if the given mimetype is supported by any built-in
 *     Guacamole.VideoPlayer, false otherwise.
 */
Guacamole.VideoPlayer.isSupportedType = function isSupportedType(mimetype) {

    // There are currently no built-in video players (and therefore no
    // supported types)
    return false;

};

/**
 * Returns a list of all mimetypes supported by any built-in
 * Guacamole.VideoPlayer, in rough order of priority. Beware that only the core
 * mimetypes themselves will be listed. Any mimetype parameters, even required
 * ones, will not be included in the list.
 *
 * @returns {String[]}
 *     A list of all mimetypes supported by any built-in Guacamole.VideoPlayer,
 *     excluding any parameters.
 */
Guacamole.VideoPlayer.getSupportedTypes = function getSupportedTypes() {

    // There are currently no built-in video players (and therefore no
    // supported types)
    return [];

};

/**
 * Returns an instance of Guacamole.VideoPlayer providing support for the given
 * video format. If support for the given video format is not available, null
 * is returned.
 *
 * @param {Guacamole.InputStream} stream
 *     The Guacamole.InputStream to read video data from.
 *
 * @param {Guacamole.Display.VisibleLayer} layer
 *     The destination layer in which this Guacamole.VideoPlayer should play
 *     the received video data.
 *
 * @param {String} mimetype
 *     The mimetype of the video data in the provided stream.
 *
 * @return {Guacamole.VideoPlayer}
 *     A Guacamole.VideoPlayer instance supporting the given mimetype and
 *     reading from the given stream, or null if support for the given mimetype
 *     is absent.
 */
Guacamole.VideoPlayer.getInstance = function getInstance(stream, layer, mimetype) {

    // There are currently no built-in video players
    return null;

};


/*** EXPORTS FROM exports-loader ***/
module.exports = Guacamole;

/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {

var Tokenizer = __webpack_require__(31);

/*
	Options:

	xmlMode: Disables the special behavior for script/style tags (false by default)
	lowerCaseAttributeNames: call .toLowerCase for each attribute name (true if xmlMode is `false`)
	lowerCaseTags: call .toLowerCase for each tag name (true if xmlMode is `false`)
*/

/*
	Callbacks:

	oncdataend,
	oncdatastart,
	onclosetag,
	oncomment,
	oncommentend,
	onerror,
	onopentag,
	onprocessinginstruction,
	onreset,
	ontext
*/

var formTags = {
	input: true,
	option: true,
	optgroup: true,
	select: true,
	button: true,
	datalist: true,
	textarea: true
};

var openImpliesClose = {
	tr      : { tr:true, th:true, td:true },
	th      : { th:true },
	td      : { thead:true, th:true, td:true },
	body    : { head:true, link:true, script:true },
	li      : { li:true },
	p       : { p:true },
	h1      : { p:true },
	h2      : { p:true },
	h3      : { p:true },
	h4      : { p:true },
	h5      : { p:true },
	h6      : { p:true },
	select  : formTags,
	input   : formTags,
	output  : formTags,
	button  : formTags,
	datalist: formTags,
	textarea: formTags,
	option  : { option:true },
	optgroup: { optgroup:true }
};

var voidElements = {
	__proto__: null,
	area: true,
	base: true,
	basefont: true,
	br: true,
	col: true,
	command: true,
	embed: true,
	frame: true,
	hr: true,
	img: true,
	input: true,
	isindex: true,
	keygen: true,
	link: true,
	meta: true,
	param: true,
	source: true,
	track: true,
	wbr: true,

	//common self closing svg elements
	path: true,
	circle: true,
	ellipse: true,
	line: true,
	rect: true,
	use: true,
	stop: true,
	polyline: true,
	polygon: true
};

var re_nameEnd = /\s|\//;

function Parser(cbs, options){
	this._options = options || {};
	this._cbs = cbs || {};

	this._tagname = "";
	this._attribname = "";
	this._attribvalue = "";
	this._attribs = null;
	this._stack = [];

	this.startIndex = 0;
	this.endIndex = null;

	this._lowerCaseTagNames = "lowerCaseTags" in this._options ?
									!!this._options.lowerCaseTags :
									!this._options.xmlMode;
	this._lowerCaseAttributeNames = "lowerCaseAttributeNames" in this._options ?
									!!this._options.lowerCaseAttributeNames :
									!this._options.xmlMode;

	if(this._options.Tokenizer) {
		Tokenizer = this._options.Tokenizer;
	}
	this._tokenizer = new Tokenizer(this._options, this);

	if(this._cbs.onparserinit) this._cbs.onparserinit(this);
}

__webpack_require__(1)(Parser, __webpack_require__(9).EventEmitter);

Parser.prototype._updatePosition = function(initialOffset){
	if(this.endIndex === null){
		if(this._tokenizer._sectionStart <= initialOffset){
			this.startIndex = 0;
		} else {
			this.startIndex = this._tokenizer._sectionStart - initialOffset;
		}
	}
	else this.startIndex = this.endIndex + 1;
	this.endIndex = this._tokenizer.getAbsoluteIndex();
};

//Tokenizer event handlers
Parser.prototype.ontext = function(data){
	this._updatePosition(1);
	this.endIndex--;

	if(this._cbs.ontext) this._cbs.ontext(data);
};

Parser.prototype.onopentagname = function(name){
	if(this._lowerCaseTagNames){
		name = name.toLowerCase();
	}

	this._tagname = name;

	if(!this._options.xmlMode && name in openImpliesClose) {
		for(
			var el;
			(el = this._stack[this._stack.length - 1]) in openImpliesClose[name];
			this.onclosetag(el)
		);
	}

	if(this._options.xmlMode || !(name in voidElements)){
		this._stack.push(name);
	}

	if(this._cbs.onopentagname) this._cbs.onopentagname(name);
	if(this._cbs.onopentag) this._attribs = {};
};

Parser.prototype.onopentagend = function(){
	this._updatePosition(1);

	if(this._attribs){
		if(this._cbs.onopentag) this._cbs.onopentag(this._tagname, this._attribs);
		this._attribs = null;
	}

	if(!this._options.xmlMode && this._cbs.onclosetag && this._tagname in voidElements){
		this._cbs.onclosetag(this._tagname);
	}

	this._tagname = "";
};

Parser.prototype.onclosetag = function(name){
	this._updatePosition(1);

	if(this._lowerCaseTagNames){
		name = name.toLowerCase();
	}

	if(this._stack.length && (!(name in voidElements) || this._options.xmlMode)){
		var pos = this._stack.lastIndexOf(name);
		if(pos !== -1){
			if(this._cbs.onclosetag){
				pos = this._stack.length - pos;
				while(pos--) this._cbs.onclosetag(this._stack.pop());
			}
			else this._stack.length = pos;
		} else if(name === "p" && !this._options.xmlMode){
			this.onopentagname(name);
			this._closeCurrentTag();
		}
	} else if(!this._options.xmlMode && (name === "br" || name === "p")){
		this.onopentagname(name);
		this._closeCurrentTag();
	}
};

Parser.prototype.onselfclosingtag = function(){
	if(this._options.xmlMode || this._options.recognizeSelfClosing){
		this._closeCurrentTag();
	} else {
		this.onopentagend();
	}
};

Parser.prototype._closeCurrentTag = function(){
	var name = this._tagname;

	this.onopentagend();

	//self-closing tags will be on the top of the stack
	//(cheaper check than in onclosetag)
	if(this._stack[this._stack.length - 1] === name){
		if(this._cbs.onclosetag){
			this._cbs.onclosetag(name);
		}
		this._stack.pop();
	}
};

Parser.prototype.onattribname = function(name){
	if(this._lowerCaseAttributeNames){
		name = name.toLowerCase();
	}
	this._attribname = name;
};

Parser.prototype.onattribdata = function(value){
	this._attribvalue += value;
};

Parser.prototype.onattribend = function(){
	if(this._cbs.onattribute) this._cbs.onattribute(this._attribname, this._attribvalue);
	if(
		this._attribs &&
		!Object.prototype.hasOwnProperty.call(this._attribs, this._attribname)
	){
		this._attribs[this._attribname] = this._attribvalue;
	}
	this._attribname = "";
	this._attribvalue = "";
};

Parser.prototype._getInstructionName = function(value){
	var idx = value.search(re_nameEnd),
	    name = idx < 0 ? value : value.substr(0, idx);

	if(this._lowerCaseTagNames){
		name = name.toLowerCase();
	}

	return name;
};

Parser.prototype.ondeclaration = function(value){
	if(this._cbs.onprocessinginstruction){
		var name = this._getInstructionName(value);
		this._cbs.onprocessinginstruction("!" + name, "!" + value);
	}
};

Parser.prototype.onprocessinginstruction = function(value){
	if(this._cbs.onprocessinginstruction){
		var name = this._getInstructionName(value);
		this._cbs.onprocessinginstruction("?" + name, "?" + value);
	}
};

Parser.prototype.oncomment = function(value){
	this._updatePosition(4);

	if(this._cbs.oncomment) this._cbs.oncomment(value);
	if(this._cbs.oncommentend) this._cbs.oncommentend();
};

Parser.prototype.oncdata = function(value){
	this._updatePosition(1);

	if(this._options.xmlMode || this._options.recognizeCDATA){
		if(this._cbs.oncdatastart) this._cbs.oncdatastart();
		if(this._cbs.ontext) this._cbs.ontext(value);
		if(this._cbs.oncdataend) this._cbs.oncdataend();
	} else {
		this.oncomment("[CDATA[" + value + "]]");
	}
};

Parser.prototype.onerror = function(err){
	if(this._cbs.onerror) this._cbs.onerror(err);
};

Parser.prototype.onend = function(){
	if(this._cbs.onclosetag){
		for(
			var i = this._stack.length;
			i > 0;
			this._cbs.onclosetag(this._stack[--i])
		);
	}
	if(this._cbs.onend) this._cbs.onend();
};


//Resets the parser to a blank state, ready to parse a new HTML document
Parser.prototype.reset = function(){
	if(this._cbs.onreset) this._cbs.onreset();
	this._tokenizer.reset();

	this._tagname = "";
	this._attribname = "";
	this._attribs = null;
	this._stack = [];

	if(this._cbs.onparserinit) this._cbs.onparserinit(this);
};

//Parses a complete HTML document and pushes it to the handler
Parser.prototype.parseComplete = function(data){
	this.reset();
	this.end(data);
};

Parser.prototype.write = function(chunk){
	this._tokenizer.write(chunk);
};

Parser.prototype.end = function(chunk){
	this._tokenizer.end(chunk);
};

Parser.prototype.pause = function(){
	this._tokenizer.pause();
};

Parser.prototype.resume = function(){
	this._tokenizer.resume();
};

//alias for backwards compat
Parser.prototype.parseChunk = Parser.prototype.write;
Parser.prototype.done = Parser.prototype.end;

module.exports = Parser;


/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = Tokenizer;

var decodeCodePoint = __webpack_require__(27),
    entityMap = __webpack_require__(18),
    legacyMap = __webpack_require__(28),
    xmlMap    = __webpack_require__(19),

    i = 0,

    TEXT                      = i++,
    BEFORE_TAG_NAME           = i++, //after <
    IN_TAG_NAME               = i++,
    IN_SELF_CLOSING_TAG       = i++,
    BEFORE_CLOSING_TAG_NAME   = i++,
    IN_CLOSING_TAG_NAME       = i++,
    AFTER_CLOSING_TAG_NAME    = i++,

    //attributes
    BEFORE_ATTRIBUTE_NAME     = i++,
    IN_ATTRIBUTE_NAME         = i++,
    AFTER_ATTRIBUTE_NAME      = i++,
    BEFORE_ATTRIBUTE_VALUE    = i++,
    IN_ATTRIBUTE_VALUE_DQ     = i++, // "
    IN_ATTRIBUTE_VALUE_SQ     = i++, // '
    IN_ATTRIBUTE_VALUE_NQ     = i++,

    //declarations
    BEFORE_DECLARATION        = i++, // !
    IN_DECLARATION            = i++,

    //processing instructions
    IN_PROCESSING_INSTRUCTION = i++, // ?

    //comments
    BEFORE_COMMENT            = i++,
    IN_COMMENT                = i++,
    AFTER_COMMENT_1           = i++,
    AFTER_COMMENT_2           = i++,

    //cdata
    BEFORE_CDATA_1            = i++, // [
    BEFORE_CDATA_2            = i++, // C
    BEFORE_CDATA_3            = i++, // D
    BEFORE_CDATA_4            = i++, // A
    BEFORE_CDATA_5            = i++, // T
    BEFORE_CDATA_6            = i++, // A
    IN_CDATA                  = i++, // [
    AFTER_CDATA_1             = i++, // ]
    AFTER_CDATA_2             = i++, // ]

    //special tags
    BEFORE_SPECIAL            = i++, //S
    BEFORE_SPECIAL_END        = i++,   //S

    BEFORE_SCRIPT_1           = i++, //C
    BEFORE_SCRIPT_2           = i++, //R
    BEFORE_SCRIPT_3           = i++, //I
    BEFORE_SCRIPT_4           = i++, //P
    BEFORE_SCRIPT_5           = i++, //T
    AFTER_SCRIPT_1            = i++, //C
    AFTER_SCRIPT_2            = i++, //R
    AFTER_SCRIPT_3            = i++, //I
    AFTER_SCRIPT_4            = i++, //P
    AFTER_SCRIPT_5            = i++, //T

    BEFORE_STYLE_1            = i++, //T
    BEFORE_STYLE_2            = i++, //Y
    BEFORE_STYLE_3            = i++, //L
    BEFORE_STYLE_4            = i++, //E
    AFTER_STYLE_1             = i++, //T
    AFTER_STYLE_2             = i++, //Y
    AFTER_STYLE_3             = i++, //L
    AFTER_STYLE_4             = i++, //E

    BEFORE_ENTITY             = i++, //&
    BEFORE_NUMERIC_ENTITY     = i++, //#
    IN_NAMED_ENTITY           = i++,
    IN_NUMERIC_ENTITY         = i++,
    IN_HEX_ENTITY             = i++, //X

    j = 0,

    SPECIAL_NONE              = j++,
    SPECIAL_SCRIPT            = j++,
    SPECIAL_STYLE             = j++;

function whitespace(c){
	return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
}

function characterState(char, SUCCESS){
	return function(c){
		if(c === char) this._state = SUCCESS;
	};
}

function ifElseState(upper, SUCCESS, FAILURE){
	var lower = upper.toLowerCase();

	if(upper === lower){
		return function(c){
			if(c === lower){
				this._state = SUCCESS;
			} else {
				this._state = FAILURE;
				this._index--;
			}
		};
	} else {
		return function(c){
			if(c === lower || c === upper){
				this._state = SUCCESS;
			} else {
				this._state = FAILURE;
				this._index--;
			}
		};
	}
}

function consumeSpecialNameChar(upper, NEXT_STATE){
	var lower = upper.toLowerCase();

	return function(c){
		if(c === lower || c === upper){
			this._state = NEXT_STATE;
		} else {
			this._state = IN_TAG_NAME;
			this._index--; //consume the token again
		}
	};
}

function Tokenizer(options, cbs){
	this._state = TEXT;
	this._buffer = "";
	this._sectionStart = 0;
	this._index = 0;
	this._bufferOffset = 0; //chars removed from _buffer
	this._baseState = TEXT;
	this._special = SPECIAL_NONE;
	this._cbs = cbs;
	this._running = true;
	this._ended = false;
	this._xmlMode = !!(options && options.xmlMode);
	this._decodeEntities = !!(options && options.decodeEntities);
}

Tokenizer.prototype._stateText = function(c){
	if(c === "<"){
		if(this._index > this._sectionStart){
			this._cbs.ontext(this._getSection());
		}
		this._state = BEFORE_TAG_NAME;
		this._sectionStart = this._index;
	} else if(this._decodeEntities && this._special === SPECIAL_NONE && c === "&"){
		if(this._index > this._sectionStart){
			this._cbs.ontext(this._getSection());
		}
		this._baseState = TEXT;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateBeforeTagName = function(c){
	if(c === "/"){
		this._state = BEFORE_CLOSING_TAG_NAME;
	} else if(c === "<"){
		this._cbs.ontext(this._getSection());
		this._sectionStart = this._index;
	} else if(c === ">" || this._special !== SPECIAL_NONE || whitespace(c)) {
		this._state = TEXT;
	} else if(c === "!"){
		this._state = BEFORE_DECLARATION;
		this._sectionStart = this._index + 1;
	} else if(c === "?"){
		this._state = IN_PROCESSING_INSTRUCTION;
		this._sectionStart = this._index + 1;
	} else {
		this._state = (!this._xmlMode && (c === "s" || c === "S")) ?
						BEFORE_SPECIAL : IN_TAG_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInTagName = function(c){
	if(c === "/" || c === ">" || whitespace(c)){
		this._emitToken("onopentagname");
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateBeforeCloseingTagName = function(c){
	if(whitespace(c));
	else if(c === ">"){
		this._state = TEXT;
	} else if(this._special !== SPECIAL_NONE){
		if(c === "s" || c === "S"){
			this._state = BEFORE_SPECIAL_END;
		} else {
			this._state = TEXT;
			this._index--;
		}
	} else {
		this._state = IN_CLOSING_TAG_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInCloseingTagName = function(c){
	if(c === ">" || whitespace(c)){
		this._emitToken("onclosetag");
		this._state = AFTER_CLOSING_TAG_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateAfterCloseingTagName = function(c){
	//skip everything until ">"
	if(c === ">"){
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	}
};

Tokenizer.prototype._stateBeforeAttributeName = function(c){
	if(c === ">"){
		this._cbs.onopentagend();
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(c === "/"){
		this._state = IN_SELF_CLOSING_TAG;
	} else if(!whitespace(c)){
		this._state = IN_ATTRIBUTE_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInSelfClosingTag = function(c){
	if(c === ">"){
		this._cbs.onselfclosingtag();
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(!whitespace(c)){
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateInAttributeName = function(c){
	if(c === "=" || c === "/" || c === ">" || whitespace(c)){
		this._cbs.onattribname(this._getSection());
		this._sectionStart = -1;
		this._state = AFTER_ATTRIBUTE_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateAfterAttributeName = function(c){
	if(c === "="){
		this._state = BEFORE_ATTRIBUTE_VALUE;
	} else if(c === "/" || c === ">"){
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	} else if(!whitespace(c)){
		this._cbs.onattribend();
		this._state = IN_ATTRIBUTE_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateBeforeAttributeValue = function(c){
	if(c === "\""){
		this._state = IN_ATTRIBUTE_VALUE_DQ;
		this._sectionStart = this._index + 1;
	} else if(c === "'"){
		this._state = IN_ATTRIBUTE_VALUE_SQ;
		this._sectionStart = this._index + 1;
	} else if(!whitespace(c)){
		this._state = IN_ATTRIBUTE_VALUE_NQ;
		this._sectionStart = this._index;
		this._index--; //reconsume token
	}
};

Tokenizer.prototype._stateInAttributeValueDoubleQuotes = function(c){
	if(c === "\""){
		this._emitToken("onattribdata");
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
	} else if(this._decodeEntities && c === "&"){
		this._emitToken("onattribdata");
		this._baseState = this._state;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInAttributeValueSingleQuotes = function(c){
	if(c === "'"){
		this._emitToken("onattribdata");
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
	} else if(this._decodeEntities && c === "&"){
		this._emitToken("onattribdata");
		this._baseState = this._state;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInAttributeValueNoQuotes = function(c){
	if(whitespace(c) || c === ">"){
		this._emitToken("onattribdata");
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	} else if(this._decodeEntities && c === "&"){
		this._emitToken("onattribdata");
		this._baseState = this._state;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateBeforeDeclaration = function(c){
	this._state = c === "[" ? BEFORE_CDATA_1 :
					c === "-" ? BEFORE_COMMENT :
						IN_DECLARATION;
};

Tokenizer.prototype._stateInDeclaration = function(c){
	if(c === ">"){
		this._cbs.ondeclaration(this._getSection());
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	}
};

Tokenizer.prototype._stateInProcessingInstruction = function(c){
	if(c === ">"){
		this._cbs.onprocessinginstruction(this._getSection());
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	}
};

Tokenizer.prototype._stateBeforeComment = function(c){
	if(c === "-"){
		this._state = IN_COMMENT;
		this._sectionStart = this._index + 1;
	} else {
		this._state = IN_DECLARATION;
	}
};

Tokenizer.prototype._stateInComment = function(c){
	if(c === "-") this._state = AFTER_COMMENT_1;
};

Tokenizer.prototype._stateAfterComment1 = function(c){
	if(c === "-"){
		this._state = AFTER_COMMENT_2;
	} else {
		this._state = IN_COMMENT;
	}
};

Tokenizer.prototype._stateAfterComment2 = function(c){
	if(c === ">"){
		//remove 2 trailing chars
		this._cbs.oncomment(this._buffer.substring(this._sectionStart, this._index - 2));
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(c !== "-"){
		this._state = IN_COMMENT;
	}
	// else: stay in AFTER_COMMENT_2 (`--->`)
};

Tokenizer.prototype._stateBeforeCdata1 = ifElseState("C", BEFORE_CDATA_2, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata2 = ifElseState("D", BEFORE_CDATA_3, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata3 = ifElseState("A", BEFORE_CDATA_4, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata4 = ifElseState("T", BEFORE_CDATA_5, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata5 = ifElseState("A", BEFORE_CDATA_6, IN_DECLARATION);

Tokenizer.prototype._stateBeforeCdata6 = function(c){
	if(c === "["){
		this._state = IN_CDATA;
		this._sectionStart = this._index + 1;
	} else {
		this._state = IN_DECLARATION;
		this._index--;
	}
};

Tokenizer.prototype._stateInCdata = function(c){
	if(c === "]") this._state = AFTER_CDATA_1;
};

Tokenizer.prototype._stateAfterCdata1 = characterState("]", AFTER_CDATA_2);

Tokenizer.prototype._stateAfterCdata2 = function(c){
	if(c === ">"){
		//remove 2 trailing chars
		this._cbs.oncdata(this._buffer.substring(this._sectionStart, this._index - 2));
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(c !== "]") {
		this._state = IN_CDATA;
	}
	//else: stay in AFTER_CDATA_2 (`]]]>`)
};

Tokenizer.prototype._stateBeforeSpecial = function(c){
	if(c === "c" || c === "C"){
		this._state = BEFORE_SCRIPT_1;
	} else if(c === "t" || c === "T"){
		this._state = BEFORE_STYLE_1;
	} else {
		this._state = IN_TAG_NAME;
		this._index--; //consume the token again
	}
};

Tokenizer.prototype._stateBeforeSpecialEnd = function(c){
	if(this._special === SPECIAL_SCRIPT && (c === "c" || c === "C")){
		this._state = AFTER_SCRIPT_1;
	} else if(this._special === SPECIAL_STYLE && (c === "t" || c === "T")){
		this._state = AFTER_STYLE_1;
	}
	else this._state = TEXT;
};

Tokenizer.prototype._stateBeforeScript1 = consumeSpecialNameChar("R", BEFORE_SCRIPT_2);
Tokenizer.prototype._stateBeforeScript2 = consumeSpecialNameChar("I", BEFORE_SCRIPT_3);
Tokenizer.prototype._stateBeforeScript3 = consumeSpecialNameChar("P", BEFORE_SCRIPT_4);
Tokenizer.prototype._stateBeforeScript4 = consumeSpecialNameChar("T", BEFORE_SCRIPT_5);

Tokenizer.prototype._stateBeforeScript5 = function(c){
	if(c === "/" || c === ">" || whitespace(c)){
		this._special = SPECIAL_SCRIPT;
	}
	this._state = IN_TAG_NAME;
	this._index--; //consume the token again
};

Tokenizer.prototype._stateAfterScript1 = ifElseState("R", AFTER_SCRIPT_2, TEXT);
Tokenizer.prototype._stateAfterScript2 = ifElseState("I", AFTER_SCRIPT_3, TEXT);
Tokenizer.prototype._stateAfterScript3 = ifElseState("P", AFTER_SCRIPT_4, TEXT);
Tokenizer.prototype._stateAfterScript4 = ifElseState("T", AFTER_SCRIPT_5, TEXT);

Tokenizer.prototype._stateAfterScript5 = function(c){
	if(c === ">" || whitespace(c)){
		this._special = SPECIAL_NONE;
		this._state = IN_CLOSING_TAG_NAME;
		this._sectionStart = this._index - 6;
		this._index--; //reconsume the token
	}
	else this._state = TEXT;
};

Tokenizer.prototype._stateBeforeStyle1 = consumeSpecialNameChar("Y", BEFORE_STYLE_2);
Tokenizer.prototype._stateBeforeStyle2 = consumeSpecialNameChar("L", BEFORE_STYLE_3);
Tokenizer.prototype._stateBeforeStyle3 = consumeSpecialNameChar("E", BEFORE_STYLE_4);

Tokenizer.prototype._stateBeforeStyle4 = function(c){
	if(c === "/" || c === ">" || whitespace(c)){
		this._special = SPECIAL_STYLE;
	}
	this._state = IN_TAG_NAME;
	this._index--; //consume the token again
};

Tokenizer.prototype._stateAfterStyle1 = ifElseState("Y", AFTER_STYLE_2, TEXT);
Tokenizer.prototype._stateAfterStyle2 = ifElseState("L", AFTER_STYLE_3, TEXT);
Tokenizer.prototype._stateAfterStyle3 = ifElseState("E", AFTER_STYLE_4, TEXT);

Tokenizer.prototype._stateAfterStyle4 = function(c){
	if(c === ">" || whitespace(c)){
		this._special = SPECIAL_NONE;
		this._state = IN_CLOSING_TAG_NAME;
		this._sectionStart = this._index - 5;
		this._index--; //reconsume the token
	}
	else this._state = TEXT;
};

Tokenizer.prototype._stateBeforeEntity = ifElseState("#", BEFORE_NUMERIC_ENTITY, IN_NAMED_ENTITY);
Tokenizer.prototype._stateBeforeNumericEntity = ifElseState("X", IN_HEX_ENTITY, IN_NUMERIC_ENTITY);

//for entities terminated with a semicolon
Tokenizer.prototype._parseNamedEntityStrict = function(){
	//offset = 1
	if(this._sectionStart + 1 < this._index){
		var entity = this._buffer.substring(this._sectionStart + 1, this._index),
		    map = this._xmlMode ? xmlMap : entityMap;

		if(map.hasOwnProperty(entity)){
			this._emitPartial(map[entity]);
			this._sectionStart = this._index + 1;
		}
	}
};


//parses legacy entities (without trailing semicolon)
Tokenizer.prototype._parseLegacyEntity = function(){
	var start = this._sectionStart + 1,
	    limit = this._index - start;

	if(limit > 6) limit = 6; //the max length of legacy entities is 6

	while(limit >= 2){ //the min length of legacy entities is 2
		var entity = this._buffer.substr(start, limit);

		if(legacyMap.hasOwnProperty(entity)){
			this._emitPartial(legacyMap[entity]);
			this._sectionStart += limit + 1;
			return;
		} else {
			limit--;
		}
	}
};

Tokenizer.prototype._stateInNamedEntity = function(c){
	if(c === ";"){
		this._parseNamedEntityStrict();
		if(this._sectionStart + 1 < this._index && !this._xmlMode){
			this._parseLegacyEntity();
		}
		this._state = this._baseState;
	} else if((c < "a" || c > "z") && (c < "A" || c > "Z") && (c < "0" || c > "9")){
		if(this._xmlMode);
		else if(this._sectionStart + 1 === this._index);
		else if(this._baseState !== TEXT){
			if(c !== "="){
				this._parseNamedEntityStrict();
			}
		} else {
			this._parseLegacyEntity();
		}

		this._state = this._baseState;
		this._index--;
	}
};

Tokenizer.prototype._decodeNumericEntity = function(offset, base){
	var sectionStart = this._sectionStart + offset;

	if(sectionStart !== this._index){
		//parse entity
		var entity = this._buffer.substring(sectionStart, this._index);
		var parsed = parseInt(entity, base);

		this._emitPartial(decodeCodePoint(parsed));
		this._sectionStart = this._index;
	} else {
		this._sectionStart--;
	}

	this._state = this._baseState;
};

Tokenizer.prototype._stateInNumericEntity = function(c){
	if(c === ";"){
		this._decodeNumericEntity(2, 10);
		this._sectionStart++;
	} else if(c < "0" || c > "9"){
		if(!this._xmlMode){
			this._decodeNumericEntity(2, 10);
		} else {
			this._state = this._baseState;
		}
		this._index--;
	}
};

Tokenizer.prototype._stateInHexEntity = function(c){
	if(c === ";"){
		this._decodeNumericEntity(3, 16);
		this._sectionStart++;
	} else if((c < "a" || c > "f") && (c < "A" || c > "F") && (c < "0" || c > "9")){
		if(!this._xmlMode){
			this._decodeNumericEntity(3, 16);
		} else {
			this._state = this._baseState;
		}
		this._index--;
	}
};

Tokenizer.prototype._cleanup = function (){
	if(this._sectionStart < 0){
		this._buffer = "";
		this._bufferOffset += this._index;
		this._index = 0;
	} else if(this._running){
		if(this._state === TEXT){
			if(this._sectionStart !== this._index){
				this._cbs.ontext(this._buffer.substr(this._sectionStart));
			}
			this._buffer = "";
			this._bufferOffset += this._index;
			this._index = 0;
		} else if(this._sectionStart === this._index){
			//the section just started
			this._buffer = "";
			this._bufferOffset += this._index;
			this._index = 0;
		} else {
			//remove everything unnecessary
			this._buffer = this._buffer.substr(this._sectionStart);
			this._index -= this._sectionStart;
			this._bufferOffset += this._sectionStart;
		}

		this._sectionStart = 0;
	}
};

//TODO make events conditional
Tokenizer.prototype.write = function(chunk){
	if(this._ended) this._cbs.onerror(Error(".write() after done!"));

	this._buffer += chunk;
	this._parse();
};

Tokenizer.prototype._parse = function(){
	while(this._index < this._buffer.length && this._running){
		var c = this._buffer.charAt(this._index);
		if(this._state === TEXT) {
			this._stateText(c);
		} else if(this._state === BEFORE_TAG_NAME){
			this._stateBeforeTagName(c);
		} else if(this._state === IN_TAG_NAME) {
			this._stateInTagName(c);
		} else if(this._state === BEFORE_CLOSING_TAG_NAME){
			this._stateBeforeCloseingTagName(c);
		} else if(this._state === IN_CLOSING_TAG_NAME){
			this._stateInCloseingTagName(c);
		} else if(this._state === AFTER_CLOSING_TAG_NAME){
			this._stateAfterCloseingTagName(c);
		} else if(this._state === IN_SELF_CLOSING_TAG){
			this._stateInSelfClosingTag(c);
		}

		/*
		*	attributes
		*/
		else if(this._state === BEFORE_ATTRIBUTE_NAME){
			this._stateBeforeAttributeName(c);
		} else if(this._state === IN_ATTRIBUTE_NAME){
			this._stateInAttributeName(c);
		} else if(this._state === AFTER_ATTRIBUTE_NAME){
			this._stateAfterAttributeName(c);
		} else if(this._state === BEFORE_ATTRIBUTE_VALUE){
			this._stateBeforeAttributeValue(c);
		} else if(this._state === IN_ATTRIBUTE_VALUE_DQ){
			this._stateInAttributeValueDoubleQuotes(c);
		} else if(this._state === IN_ATTRIBUTE_VALUE_SQ){
			this._stateInAttributeValueSingleQuotes(c);
		} else if(this._state === IN_ATTRIBUTE_VALUE_NQ){
			this._stateInAttributeValueNoQuotes(c);
		}

		/*
		*	declarations
		*/
		else if(this._state === BEFORE_DECLARATION){
			this._stateBeforeDeclaration(c);
		} else if(this._state === IN_DECLARATION){
			this._stateInDeclaration(c);
		}

		/*
		*	processing instructions
		*/
		else if(this._state === IN_PROCESSING_INSTRUCTION){
			this._stateInProcessingInstruction(c);
		}

		/*
		*	comments
		*/
		else if(this._state === BEFORE_COMMENT){
			this._stateBeforeComment(c);
		} else if(this._state === IN_COMMENT){
			this._stateInComment(c);
		} else if(this._state === AFTER_COMMENT_1){
			this._stateAfterComment1(c);
		} else if(this._state === AFTER_COMMENT_2){
			this._stateAfterComment2(c);
		}

		/*
		*	cdata
		*/
		else if(this._state === BEFORE_CDATA_1){
			this._stateBeforeCdata1(c);
		} else if(this._state === BEFORE_CDATA_2){
			this._stateBeforeCdata2(c);
		} else if(this._state === BEFORE_CDATA_3){
			this._stateBeforeCdata3(c);
		} else if(this._state === BEFORE_CDATA_4){
			this._stateBeforeCdata4(c);
		} else if(this._state === BEFORE_CDATA_5){
			this._stateBeforeCdata5(c);
		} else if(this._state === BEFORE_CDATA_6){
			this._stateBeforeCdata6(c);
		} else if(this._state === IN_CDATA){
			this._stateInCdata(c);
		} else if(this._state === AFTER_CDATA_1){
			this._stateAfterCdata1(c);
		} else if(this._state === AFTER_CDATA_2){
			this._stateAfterCdata2(c);
		}

		/*
		* special tags
		*/
		else if(this._state === BEFORE_SPECIAL){
			this._stateBeforeSpecial(c);
		} else if(this._state === BEFORE_SPECIAL_END){
			this._stateBeforeSpecialEnd(c);
		}

		/*
		* script
		*/
		else if(this._state === BEFORE_SCRIPT_1){
			this._stateBeforeScript1(c);
		} else if(this._state === BEFORE_SCRIPT_2){
			this._stateBeforeScript2(c);
		} else if(this._state === BEFORE_SCRIPT_3){
			this._stateBeforeScript3(c);
		} else if(this._state === BEFORE_SCRIPT_4){
			this._stateBeforeScript4(c);
		} else if(this._state === BEFORE_SCRIPT_5){
			this._stateBeforeScript5(c);
		}

		else if(this._state === AFTER_SCRIPT_1){
			this._stateAfterScript1(c);
		} else if(this._state === AFTER_SCRIPT_2){
			this._stateAfterScript2(c);
		} else if(this._state === AFTER_SCRIPT_3){
			this._stateAfterScript3(c);
		} else if(this._state === AFTER_SCRIPT_4){
			this._stateAfterScript4(c);
		} else if(this._state === AFTER_SCRIPT_5){
			this._stateAfterScript5(c);
		}

		/*
		* style
		*/
		else if(this._state === BEFORE_STYLE_1){
			this._stateBeforeStyle1(c);
		} else if(this._state === BEFORE_STYLE_2){
			this._stateBeforeStyle2(c);
		} else if(this._state === BEFORE_STYLE_3){
			this._stateBeforeStyle3(c);
		} else if(this._state === BEFORE_STYLE_4){
			this._stateBeforeStyle4(c);
		}

		else if(this._state === AFTER_STYLE_1){
			this._stateAfterStyle1(c);
		} else if(this._state === AFTER_STYLE_2){
			this._stateAfterStyle2(c);
		} else if(this._state === AFTER_STYLE_3){
			this._stateAfterStyle3(c);
		} else if(this._state === AFTER_STYLE_4){
			this._stateAfterStyle4(c);
		}

		/*
		* entities
		*/
		else if(this._state === BEFORE_ENTITY){
			this._stateBeforeEntity(c);
		} else if(this._state === BEFORE_NUMERIC_ENTITY){
			this._stateBeforeNumericEntity(c);
		} else if(this._state === IN_NAMED_ENTITY){
			this._stateInNamedEntity(c);
		} else if(this._state === IN_NUMERIC_ENTITY){
			this._stateInNumericEntity(c);
		} else if(this._state === IN_HEX_ENTITY){
			this._stateInHexEntity(c);
		}

		else {
			this._cbs.onerror(Error("unknown _state"), this._state);
		}

		this._index++;
	}

	this._cleanup();
};

Tokenizer.prototype.pause = function(){
	this._running = false;
};
Tokenizer.prototype.resume = function(){
	this._running = true;

	if(this._index < this._buffer.length){
		this._parse();
	}
	if(this._ended){
		this._finish();
	}
};

Tokenizer.prototype.end = function(chunk){
	if(this._ended) this._cbs.onerror(Error(".end() after done!"));
	if(chunk) this.write(chunk);

	this._ended = true;

	if(this._running) this._finish();
};

Tokenizer.prototype._finish = function(){
	//if there is remaining data, emit it in a reasonable way
	if(this._sectionStart < this._index){
		this._handleTrailingData();
	}

	this._cbs.onend();
};

Tokenizer.prototype._handleTrailingData = function(){
	var data = this._buffer.substr(this._sectionStart);

	if(this._state === IN_CDATA || this._state === AFTER_CDATA_1 || this._state === AFTER_CDATA_2){
		this._cbs.oncdata(data);
	} else if(this._state === IN_COMMENT || this._state === AFTER_COMMENT_1 || this._state === AFTER_COMMENT_2){
		this._cbs.oncomment(data);
	} else if(this._state === IN_NAMED_ENTITY && !this._xmlMode){
		this._parseLegacyEntity();
		if(this._sectionStart < this._index){
			this._state = this._baseState;
			this._handleTrailingData();
		}
	} else if(this._state === IN_NUMERIC_ENTITY && !this._xmlMode){
		this._decodeNumericEntity(2, 10);
		if(this._sectionStart < this._index){
			this._state = this._baseState;
			this._handleTrailingData();
		}
	} else if(this._state === IN_HEX_ENTITY && !this._xmlMode){
		this._decodeNumericEntity(3, 16);
		if(this._sectionStart < this._index){
			this._state = this._baseState;
			this._handleTrailingData();
		}
	} else if(
		this._state !== IN_TAG_NAME &&
		this._state !== BEFORE_ATTRIBUTE_NAME &&
		this._state !== BEFORE_ATTRIBUTE_VALUE &&
		this._state !== AFTER_ATTRIBUTE_NAME &&
		this._state !== IN_ATTRIBUTE_NAME &&
		this._state !== IN_ATTRIBUTE_VALUE_SQ &&
		this._state !== IN_ATTRIBUTE_VALUE_DQ &&
		this._state !== IN_ATTRIBUTE_VALUE_NQ &&
		this._state !== IN_CLOSING_TAG_NAME
	){
		this._cbs.ontext(data);
	}
	//else, ignore remaining data
	//TODO add a way to remove current tag
};

Tokenizer.prototype.reset = function(){
	Tokenizer.call(this, {xmlMode: this._xmlMode, decodeEntities: this._decodeEntities}, this._cbs);
};

Tokenizer.prototype.getAbsoluteIndex = function(){
	return this._bufferOffset + this._index;
};

Tokenizer.prototype._getSection = function(){
	return this._buffer.substring(this._sectionStart, this._index);
};

Tokenizer.prototype._emitToken = function(name){
	this._cbs[name](this._getSection());
	this._sectionStart = -1;
};

Tokenizer.prototype._emitPartial = function(value){
	if(this._baseState !== TEXT){
		this._cbs.onattribdata(value); //TODO implement the new event
	} else {
		this._cbs.ontext(value);
	}
};


/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = Stream;

var Parser = __webpack_require__(30),
    WritableStream = __webpack_require__(15).Writable || __webpack_require__(146).Writable,
    StringDecoder = __webpack_require__(23).StringDecoder,
    Buffer = __webpack_require__(2).Buffer;

function Stream(cbs, options){
	var parser = this._parser = new Parser(cbs, options);
	var decoder = this._decoder = new StringDecoder();

	WritableStream.call(this, {decodeStrings: false});

	this.once("finish", function(){
		parser.end(decoder.end());
	});
}

__webpack_require__(1)(Stream, WritableStream);

WritableStream.prototype._write = function(chunk, encoding, cb){
	if(chunk instanceof Buffer) chunk = this._decoder.write(chunk);
	this._parser.write(chunk);
	cb();
};

/***/ }),
/* 33 */
/***/ (function(module, exports) {

var toString = {}.toString;

module.exports = Array.isArray || function (arr) {
  return toString.call(arr) == '[object Array]';
};


/***/ }),
/* 34 */
/***/ (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__(21);

/*<replacement>*/
var util = __webpack_require__(7);
util.inherits = __webpack_require__(1);
/*</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);
};

/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(process) {

module.exports = Readable;

/*<replacement>*/
var processNextTick = __webpack_require__(20);
/*</replacement>*/

/*<replacement>*/
var isArray = __webpack_require__(33);
/*</replacement>*/

/*<replacement>*/
var Duplex;
/*</replacement>*/

Readable.ReadableState = ReadableState;

/*<replacement>*/
var EE = __webpack_require__(9).EventEmitter;

var EElistenerCount = function (emitter, type) {
  return emitter.listeners(type).length;
};
/*</replacement>*/

/*<replacement>*/
var Stream;
(function () {
  try {
    Stream = __webpack_require__(15);
  } catch (_) {} finally {
    if (!Stream) Stream = __webpack_require__(9).EventEmitter;
  }
})();
/*</replacement>*/

var Buffer = __webpack_require__(2).Buffer;
/*<replacement>*/
var bufferShim = __webpack_require__(17);
/*</replacement>*/

/*<replacement>*/
var util = __webpack_require__(7);
util.inherits = __webpack_require__(1);
/*</replacement>*/

/*<replacement>*/
var debugUtil = __webpack_require__(147);
var debug = void 0;
if (debugUtil && debugUtil.debuglog) {
  debug = debugUtil.debuglog('stream');
} else {
  debug = function () {};
}
/*</replacement>*/

var BufferList = __webpack_require__(94);
var StringDecoder;

util.inherits(Readable, Stream);

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__(3);

  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__(23).StringDecoder;
    this.decoder = new StringDecoder(options.encoding);
    this.encoding = options.encoding;
  }
}

function Readable(options) {
  Duplex = Duplex || __webpack_require__(3);

  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__(23).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.
  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
  forEach(events, function (ev) {
    stream.on(ev, self.emit.bind(self, ev));
  });

  // 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__(6)))

/***/ }),
/* 36 */
/***/ (function(module, exports) {

module.exports = {
	SHIFT: 0xFFE1,
	CTRL: 0xFFE3,
	ALT: 0xFFE9,
	DELETE: 0xFFFF,
	ENTER: 0xFF0D,
	WIN: 0xFFEB
};

/***/ }),
/* 37 */
/***/ (function(module, exports) {

module.exports = {
	IDLE: 			0,
	CONNECTING: 	1,
	WAITING: 		2,
	CONNECTED:    	3,
	DISCONNECTING: 	4,
	DISCONNECTED: 	5
};

/***/ }),
/* 38 */
/***/ (function(module, exports) {

module.exports = angular;

/***/ }),
/* 39 */
/***/ (function(module, exports) {

module.exports =
/******/ (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;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// 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 = "/resources/js/csClient/min/";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./src/app/Common/Libraries/common.libraries.browserSessionProvider.ts");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./src/app/Common/Libraries/common.libraries.browserSessionProvider.ts":
/*!*****************************************************************************!*\
  !*** ./src/app/Common/Libraries/common.libraries.browserSessionProvider.ts ***!
  \*****************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var common_libraries_uuidService_1 = __webpack_require__(/*! ./common.libraries.uuidService */ "./src/app/Common/Libraries/common.libraries.uuidService.ts");
var sessionStorageKey = "csStgrBrowserSession";
var browserSession = getSessionStorage();
var BrowserSessionProvider = /** @class */ (function () {
    function BrowserSessionProvider() {
    }
    BrowserSessionProvider.prototype.get = function () {
        return browserSession;
    };
    return BrowserSessionProvider;
}());
exports.BrowserSessionProvider = BrowserSessionProvider;
function getSessionStorage() {
    var parentWindow = window.parent;
    if (parentWindow.cs && parentWindow.cs.browserSession) {
        return parentWindow.cs.browserSession;
    }
    var browserSession = JSON.parse(window.sessionStorage.getItem(sessionStorageKey));
    if (browserSession == null) {
        browserSession = {
            id: new common_libraries_uuidService_1.UuidService().generate(),
            sequence: 0
        };
        window.sessionStorage.setItem(sessionStorageKey, JSON.stringify(browserSession));
    }
    else {
        browserSession.sequence += 1;
        window.sessionStorage.setItem(sessionStorageKey, JSON.stringify(browserSession));
    }
    publishSessionIdOnGlobalScope(browserSession);
    return browserSession;
}
function publishSessionIdOnGlobalScope(browserSession) {
    var customWindow = window;
    customWindow.cs = customWindow.cs || {};
    customWindow.cs.browserSession = browserSession;
}


/***/ }),

/***/ "./src/app/Common/Libraries/common.libraries.uuidService.ts":
/*!******************************************************************!*\
  !*** ./src/app/Common/Libraries/common.libraries.uuidService.ts ***!
  \******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var BASE64URICHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split("");
var UuidService = /** @class */ (function () {
    function UuidService() {
    }
    UuidService.prototype.generate = function (len, radix) {
        if (len === void 0) { len = 22; }
        if (radix === void 0) { radix = BASE64URICHARS.length; }
        var newId = [];
        for (var i = 0; i < len; i++) {
            newId[i] = BASE64URICHARS[0 | Math.random() * radix];
        }
        return newId.join("");
    };
    return UuidService;
}());
exports.UuidService = UuidService;


/***/ })

/******/ });
//# sourceMappingURL=browserSessionProvider.js.map

/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {

(function() {
	if (!isAngularDefined())
		return;

	__webpack_require__(102);

	__webpack_require__(112);
	__webpack_require__(113);
	__webpack_require__(117);
	__webpack_require__(116);
	__webpack_require__(115);
	__webpack_require__(119);
	__webpack_require__(120);
	__webpack_require__(118);
	__webpack_require__(114);
	__webpack_require__(111);

	module.exports = __webpack_require__(0);
})();

function isAngularDefined() {
	try {
		__webpack_require__(38);//in new modules instead next 2 lines, should be: "return !!require('angular').module;"
		return true;
	} catch (ex) {
		return false;
	}
}

/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {

try {
    var $ = __webpack_require__(11);

    module.exports = __webpack_require__(124);    
} catch (_) {
    console.log("cloudshare-tour package is not available because of missing externals");
    module.exports = null;
}


/***/ }),
/* 42 */
/***/ (function(module, exports) {

module.exports =
/******/ (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;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// 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 = "/resources/js/csClient/min/";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./src/SelfService/ConnectivityTest/FailureInformation/index.deploy.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./src/SelfService/ConnectivityTest/FailureInformation/connectivityTest.failureInformation.directive.js":
/*!**************************************************************************************************************!*\
  !*** ./src/SelfService/ConnectivityTest/FailureInformation/connectivityTest.failureInformation.directive.js ***!
  \**************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* harmony default export */ __webpack_exports__["default"] = (function (ngModule) {
  ngModule.directive("csConnectivityTestFailureInformation", function () {
    return {
      restrict: "E",
      scope: {
        failedTests: "=",
        regionName: "=",
        gatewayHost: "="
      },
      template: __webpack_require__(/*! ./connectivityTest.failureInformation.template.html */ "./src/SelfService/ConnectivityTest/FailureInformation/connectivityTest.failureInformation.template.html"),
      bindToController: true,
      controllerAs: "ctrl",
      controller: ConnectivityTestFailureInformation
    };
  });

  var ConnectivityTestFailureInformation = function ConnectivityTestFailureInformation($scope) {
    var _this = this;

    _classCallCheck(this, ConnectivityTestFailureInformation);

    this.$scope = $scope;
    this.$scope.$watch(function () {
      return _this.failedTests;
    }, function () {
      var failedTests = _this.failedTests || [];
      _this.processedFailedTests = "";

      if (failedTests.indexOf("ws-browser-support") >= 0) {
        _this.processedFailedTests = "ws-browser-support";
        return;
      }

      var result = [];
      ["ws-echo-server", "certificate-authority", "ws-gateway-server"].forEach(function (testId) {
        if (failedTests.indexOf(testId) >= 0) {
          result.push(testId);
        }
      });
      _this.processedFailedTests = result.join(",");
    }, true);
  };

  ConnectivityTestFailureInformation.$inject = ["$scope"];
});

/***/ }),

/***/ "./src/SelfService/ConnectivityTest/FailureInformation/connectivityTest.failureInformation.template.html":
/*!***************************************************************************************************************!*\
  !*** ./src/SelfService/ConnectivityTest/FailureInformation/connectivityTest.failureInformation.template.html ***!
  \***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = "<div class=cs-connectivity-tests-failure-information ng-show=ctrl.processedFailedTests><div ng-switch=ctrl.processedFailedTests><div ng-switch-when=ws-browser-support><p translate>Your browser does not support WebSockets. WebSockets support is required for access to VMs on CloudShare.</p><p translate>To fix this problem, you can either switch to a different browser, such as Chrome or Firefox, or try upgrading to the latest version of your browser.</p></div><div ng-switch-when=ws-echo-server><p translate>Our test could not establish a secure WebSocket connection to <code>echo.websocket.org</code>. However, you are able to connect successfully to CloudShare's remote access gateway.</p><p translate>Either there is a problem with <code>echo.websocket.org</code> server, or the WebSockets echo server test was blocked by a firewall rule.</p><p translate>There is no need to fix this problem in order to connect to VMs on CloudShare.</p></div><div ng-switch-when=certificate-authority><p translate>You are able to connect successfully to CloudShare's remote access gateway via WebSockets. However, your computer or browser is missing required certificate authority trusts. You are likely to experience intermittent disconnections when you connect to CloudShare VMs.</p><p translate>To fix this problem, please contact your administrator and make sure GoDaddy certificates are trusted by your computer and browser.</p></div><div ng-switch-when=ws-gateway-server><p translate-params-region-name=ctrl.regionName translate-params-gateway-host=ctrl.gatewayHost translate>Our test could not establish a secure WebSocket connection to CloudShare's remote access gateway in '{{regionName}}' region (<code>{{gatewayHost}}</code>).</p><p translate>You cannot connect to CloudShare VMs.</p><p translate-params-gateway-host=ctrl.gatewayHost translate>To fix this problem, please contact your administrator and make sure secure HTTP and WebSocket connections to <code>{{gatewayHost}}</code> on port 443 are not blocked by any firewall or other security measure.</p></div><div ng-switch-when=ws-echo-server,certificate-authority><p translate>You are able to connect successfully to CloudShare's remote access gateway. However, our test could not establish a secure WebSocket connection to <code>echo.websocket.org</code>. In addition, your computer or browser is missing required certificate authority trusts.</p><p translate>You might experience intermitted disconnections, due to the missing certificate authority trusts. To fix this problem, please contact your administrator and make sure GoDaddy's certificates are trusted on your computer.</p><p translate>Either there is a problem with the <code>echo.websockets.org</code> server or the WebSockets echo server test was blocked by a firewall rule. There is no need to fix this problem in order to connect to VMs on CloudShare.</p></div><div ng-switch-when=ws-echo-server,ws-gateway-server><p translate-params-region-name=ctrl.regionName translate-params-gateway-host=ctrl.gatewayHost translate>Our test could not establish a secure WebSocket connection to '{{regionName}}' (<code>{{gatewayHost}}</code>) or to <code>echo.websockets.org</code>.</p><p translate>You cannot connect to VMs on CloudShare.</p><p translate-params-gateway-host=ctrl.gatewayHost translate>To fix this problem, please contact your administrator and make sure secure HTTP and WebSocket connections to <code>{{gatewayHost}}</code> on port 443 are not blocked by any firewall or other security measure.</p></div><div ng-switch-when=certificate-authority,ws-gateway-server><p translate-params-region-name=ctrl.regionName translate-params-gateway-host=ctrl.gatewayHost translate>Our test could not establish a secure WebSocket connection to CloudShare's remote access gateway in '{{regionName}}' (<code>{{gatewayHost}}</code>). In addition, your computer or browser is missing required certificate authority trusts.</p><p translate>You cannot connect to VMs on CloudShare.</p><p><span translate>To fix these problems, please contact your administrator and make sure:</span><ul><li translate-params-gateway-host=ctrl.gatewayHost translate>Secure HTTP and WebSocket connections to <code>{{gatewayHost}}</code> on port 443 are not blocked by any firewall or other security measure.</li><li translate>GoDaddy's certificates are trusted on your computer and browser.</li></ul></p></div><div ng-switch-when=ws-echo-server,certificate-authority,ws-gateway-server><p translate-params-region-name=ctrl.regionName translate-params-gateway-host=ctrl.gatewayHost translate>Our test could not establish a secure WebSocket connection to '{{regionName}}' region (<code>{{gatewayHost}}</code>) or to <code>echo.websocket.org</code>. In addition, your computer or browser is missing required certificate authority trusts.</p><p translate>You cannot connect to VMs on CloudShare.</p><p><span translate>To fix these problems, please contact your administrator and make sure:</span><ul><li translate-params-gateway-host=ctrl.gatewayHost translate>Secure HTTP and WebSocket connections to <code>{{gatewayHost}}</code> on port 443 are not blocked by any firewall or other security measure.</li><li translate>GoDaddy's certificates are trusted on your computer and browser.</li></ul></p></div></div></div>"

/***/ }),

/***/ "./src/SelfService/ConnectivityTest/FailureInformation/index.deploy.js":
/*!*****************************************************************************!*\
  !*** ./src/SelfService/ConnectivityTest/FailureInformation/index.deploy.js ***!
  \*****************************************************************************/
/*! exports provided: directiveFunction */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _connectivityTest_failureInformation_directive__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./connectivityTest.failureInformation.directive */ "./src/SelfService/ConnectivityTest/FailureInformation/connectivityTest.failureInformation.directive.js");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "directiveFunction", function() { return _connectivityTest_failureInformation_directive__WEBPACK_IMPORTED_MODULE_0__["default"]; });




/***/ })

/******/ });
//# sourceMappingURL=connectivity-test-failure-information.js.map

/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {

var bottle = __webpack_require__(130);

window.cs = window.cs || {};
window.cs.guacclient = bottle.container.CloudShareGuacamole;
module.exports = bottle.container.CloudShareGuacamole;


/***/ }),
/* 44 */
/***/ (function(module, exports, __webpack_require__) {

try {
    var _ = __webpack_require__(24);
    var $ = __webpack_require__(11);
    var csws = __webpack_require__(25).csws;
    var HeartBeatsDispatcher_ = __webpack_require__(138);
    var WebsocketsConnector = __webpack_require__(139);

    module.exports = function HeartBeatsDispatcher() {
        var websocketsConnector = new WebsocketsConnector(csws, '/api/v3/WebSockets', 'heartbeat');
        return new HeartBeatsDispatcher_(websocketsConnector);
    };    
} catch (_) {
    console.log("heartbeat-over-ws package is not available because of missing externals");
    module.exports = null;
}


/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {

var sanitizeHtmlModule = __webpack_require__(100);

var Configurations = {
    envViewer: {
        allowedTags: ["span", "img", "h1", "h2", "h3", "h4", "cs-viewer-start-button", "countdown-clock", "alteryx-start-button"],
        allowedAttributes: {
            "*": ["style",
                "class",
                "cs-viewer-modal-video",
                "cs-viewer-video-url",
                "cs-viewer-video-autoplay",
                "cs-viewer-video-width",
                "cs-viewer-video-height",
                "cs-viewer-video-title",
                "cs-viewer-link",
                "time-minutes"
            ]
        }
    },
    topMostTooltip: {
        allowedTags: ["span", "img", "h1", "h2" ],
        allowedAttributes: {
            "*": ["style", "class"]
        }
    },
    viewerResources: {
        allowedTags: ["span", "img", "h1", "h2" ],
        allowedAttributes: {
            "*": ["style"]
        }
    },
    permissive: {
        allowedTags: ["img", "h1", "h2", "span", "u", "font"],
        allowedAttributes: {
            "*": ["alt", "dir", "src", "style", "href", "target", "cellpadding", "cellspacing", "id", "colspan",
                "class", "face", "color", "ref", "align", "lang", "border", "scope", "height", "title", "width"]
        }
    }
};

function HtmlSanitizer() {
    var that = this;

    that._configurations = {};
    Object.keys(Configurations).forEach(function(configurationName) {
        that._configurations[configurationName] = that._createConfig(Configurations[configurationName]);
    });
}

HtmlSanitizer.prototype.sanitize = function(html, configName) {
    var that = this;

    var config = that._configurations[configName];
    if (!that._configurations[configName])
        throw new Error("HtmlSanitizer: No such configuration '" + configName + "'");
    return sanitizeHtmlModule(html, config);
};

HtmlSanitizer.prototype._createConfig = function(config) {
    var that = this;

    var defaultConfig = that._getDefaultConfigurationCopy();

    if (!config)
        return defaultConfig;

    if (config.allowedTags)
        defaultConfig.allowedTags = defaultConfig.allowedTags.concat(config.allowedTags);

    if (config.allowedAttributes) {
        Object.keys(config.allowedAttributes).forEach(function(tag) {
            if (!defaultConfig.allowedAttributes[tag])
                defaultConfig.allowedAttributes[tag] = config.allowedAttributes[tag];
            else
                defaultConfig.allowedAttributes[tag] = defaultConfig.allowedAttributes[tag].concat(config.allowedAttributes[tag]);
        });
    }

    return defaultConfig;
};

HtmlSanitizer.prototype._getDefaultConfigurationCopy = function() {
    return JSON.parse(JSON.stringify(sanitizeHtmlModule.defaults));
};

module.exports = HtmlSanitizer;

/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {

var bottle = __webpack_require__(141);

window.cs = window.cs || {};
window.cs.guacclient = bottle.container.CloudShareSpark;
module.exports = bottle.container.CloudShareSpark;


/***/ }),
/* 47 */
/***/ (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('')
}


/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(14)();
exports.push([module.i, ".chocolatey-client  {\r\n\tfont-family: 'open-sans', sans-serif;\r\n\ttext-align: center;\r\n}\r\n\r\n.chocolatey-client > .spacer {\r\n\tdisplay: inline-block;\r\n\twidth: 20px;\r\n}\r\n\r\n.chocolatey-client  a {\r\n\tcolor: rgb(0, 160, 198);\r\n\ttext-decoration: none;\r\n}\r\n\r\n.chocolatey-client .package-list {\r\n\tmargin-right: 15px;\r\n}\t\r\n\r\n.chocolatey-client .package-list .empty-notice {\r\n\tposition: relative;\r\n\theight: 100%;\r\n}\r\n\r\n.chocolatey-client .package-list .empty-notice span {\r\n\tdisplay: inline-block;\r\n\tposition: absolute;\r\n\ttop: 30%;\r\n\tleft: 50%;\r\n\t-ms-transform: translateX(-50%);\r\n\t-moz-transform: translateX(-50%);\r\n\t-webkit-transform: translateX(-50%);\r\n\ttransform: translateX(-50%);\r\n}\r\n\r\n\r\n.chocolatey-client .packages-pane {\r\n\tvertical-align: top;\r\n\twidth: 45%;\r\n\tdisplay: inline-block;\r\n\ttext-align: left;\r\n}\r\n\r\n.chocolatey-client .packages-pane > .title {\r\n\theight: 80px;\r\n\ttext-align: center;\r\n}\r\n\r\n.chocolatey-client .packages-pane .title .title-text {\r\n\tdisplay: inline-block;\r\n\tfont-size: 23px;\r\n\tmargin: 26.5px 0;\r\n}\r\n\r\n.chocolatey-client .details-pane {\r\n\tvertical-align: top;\r\n\twidth: 100%;\r\n\tdisplay: inline-block;\r\n}\r\n\r\n\r\n\r\n.chocolatey-client .package-item {\r\n\tposition: relative;\r\n\tborder-bottom: 1px solid rgb(208, 208, 208);\r\n}\r\n\r\n.chocolatey-client .package-item table {\r\n\twidth: 100%;\r\n}\r\n\r\n.chocolatey-client .package-item .icon {\r\n\tvertical-align: top;\r\n\twidth: 44px;\r\n}\r\n\r\n.chocolatey-client .package-item .info {\r\n\tvertical-align: top;\r\n}\r\n\r\n.chocolatey-client .package-item .info .title {\r\n\theight: auto;\r\n\tmargin-top: 7px;\r\n\tfont-size: 22px;\r\n}\r\n\r\n.chocolatey-client .package-item .info .authors {\r\n\tmargin: 7px 0;\r\n\tfont-size: 14px;\r\n}\r\n\r\n.chocolatey-client .package-item .info .description {\r\n\tfont-size: 13px;\r\n\tmargin: 10px 0;\r\n}\r\n\r\n.chocolatey-client .package-item .actions {\r\n\tvertical-align: middle;\r\n\ttext-align: right;\r\n}\r\n\r\n.chocolatey-client button {\r\n\tbackground-color: rgb(122, 122, 122);\r\n\tborder: 1px solid rgb(122, 122, 122);\r\n\tborder-radius: 2px;\r\n\tcolor: white;\r\n\twhite-space: nowrap;\r\n\tpadding: 3px 5px;\r\n\toutline: none;\r\n\tcursor: pointer;\r\n\tfont-size: 12px;\r\n}\r\n.chocolatey-client button:hover {\r\n\tbackground-color: rgb(25, 166, 206);\r\n\tborder: 1px solid rgb(25, 166, 206);\r\n}\r\n\r\n.chocolatey-client button[disabled] {\r\n\tbackground-color: rgb(122, 122, 122);\r\n\tborder: 1px solid rgb(122, 122, 122);\r\n\tcursor: default;\r\n\topacity: 0.5;\r\n}\r\n\r\n.chocolatey-client .package-item .icon img {\r\n\twidth: 30px;\r\n\tmargin: 6px 7px;\r\n}\r\n\r\n.chocolatey-client .search-input {\r\n\tposition: relative;\r\n\twidth: 100%;\r\n\ttext-align: center;\r\n\theight: 80px;\r\n}\r\n\r\n.chocolatey-client .search-input input[type=text] {\r\n\twidth: 90%;\r\n\tborder: 1px solid rgb(161, 161, 161);\r\n\tborder-radius: 2px;\r\n\tpadding-left: 16px;\r\n\tpadding-top: 8px;\r\n\tpadding-bottom: 8px;\r\n\tfont-size: 17px;\r\n\tmargin: 21px 0;\r\n}\r\n\r\n.chocolatey-client .package-detailed-item {\r\n\ttext-align: center;\r\n}\r\n\r\n.chocolatey-client .scrolled {\r\n\t-moz-box-shadow: inset 0 13px 15px -13px rgba(18, 146, 192, 0.21);\r\n\t-webkit-box-shadow: inset 0 13px 15px -13px rgba(18, 146, 192, 0.21);\r\n\tbox-shadow: inset 0 13px 15px -13px rgba(18, 146, 192, 0.21);\r\n}\r\n\r\n\r\n.chocolatey-client .package-detailed-item .content {\r\n\tdisplay: inline-block;\r\n\twidth: 90%;\r\n\ttext-align: left;\r\n}\r\n\r\n.chocolatey-client .details-pane .header {\r\n\tposition: relative;\r\n\tmargin: 15px 0;\r\n}\r\n\r\n.chocolatey-client .details-pane .header .back {\r\n\tmargin: 6px 0;\r\n\tposition: absolute; \r\n\ttop: 0; \r\n\tleft: 0;\r\n}\r\n\r\n\r\n.chocolatey-client .details-pane .header .header-content {\r\n\ttext-align: center; \r\n\ttext-align: center; \r\n\tmax-width: 85%; \r\n\tmargin: auto;\r\n}\r\n\r\n.chocolatey-client .details-pane .header .header-content .title {\r\n\tdisplay: inline-block;\r\n\tfont-size: 20px;\r\n\tvertical-align: middle;\r\n}\r\n\r\n.chocolatey-client .details-pane .header .header-content .icon {\r\n\tdisplay: inline-block;\r\n\theight: 100%;\r\n\tvertical-align: middle;\r\n}\r\n\r\n.chocolatey-client .details-pane .header .header-content .icon img {\r\n\twidth: 30px;\r\n}\r\n\r\n.chocolatey-client .details-pane .header .header-content .action {\r\n\tdisplay: inline-block;\r\n\tmargin-left: 10px;\r\n\tvertical-align: middle;\r\n}\r\n\r\n.chocolatey-client .package-detailed-item .section {\r\n\tborder-bottom: 1px solid #ccc;\r\n\tfont-weight: bold;\r\n\tcolor: #555;\r\n\tmargin-top: 10px;\r\n}\r\n\r\n.chocolatey-client .package-detailed-item .label {\r\n\tvertical-align: top;\r\n}\r\n\r\n.chocolatey-client .package-detailed-item .version {\r\n\tfont-family: monospace;\r\n}\r\n\r\n.chocolatey-client .spinner {\r\n\ttext-align: center;\r\n}\r\n\r\n.chocolatey-button {\r\n\tposition: relative;\r\n\tdisplay: inline-block;\r\n\twidth: 16px;\r\n\theight: 16px;\r\n}\r\n\r\n.chocolatey-button > button {\r\n\tposition: absolute;\r\n\ttop: 0;\r\n\tleft: 0;\r\n\twidth: 16px;\r\n\theight: 16px;\r\n    border: 1px solid transparent;\r\n    border-radius: 3px;\r\n    background-size: 13px 13px;\r\n    background-repeat: no-repeat;\r\n    background-color: #7a7a7a;\r\n    outline: none;\r\n    padding: 0;\r\n    cursor: pointer;\r\n}\r\n\r\n.chocolatey-button > button:hover {\r\n\tbackground-color: #009ace;\r\n}\r\n\r\n.chocolatey-button > .chocolatey-button-overlay {\r\n\tdisplay: none;\r\n\tposition: absolute;\r\n\ttop: 0;\r\n\tleft: 0;\r\n\twidth: 16px;\r\n\theight: 16px;\r\n\tbackground-color: #009ace;\r\n\topacity: 0.5;\r\n\tcursor: pointer;\r\n\tborder-radius: 3px;\r\n}", ""]);

/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(14)();
exports.push([module.i, "/* ========================================================================\r\n * bootstrap-tour - v0.10.2\r\n * http://bootstraptour.com\r\n * ========================================================================\r\n * Copyright 2012-2015 Ulrich Sossou\r\n *\r\n * ========================================================================\r\n * Licensed under the MIT License (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *     https://opensource.org/licenses/MIT\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n * ========================================================================\r\n */\r\n\r\n.tour-backdrop {\r\n  position: fixed;\r\n  top: 0;\r\n  right: 0;\r\n  bottom: 0;\r\n  left: 0;\r\n  z-index: 1;\r\n  background-color: #000;\r\n  opacity: 0.8;\r\n  filter: alpha(opacity=80);\r\n}\r\n.tour-step-backdrop {\r\n  position: relative;\r\n  z-index: 2;\r\n}\r\n.tour-step-backdrop > td {\r\n  position: relative;\r\n  z-index: 2;\r\n}\r\n.tour-step-backdrop-disable-click{\r\n  pointer-events: none;\r\n}\r\n.tour-step-background {\r\n  position: absolute !important;\r\n  z-index: 1;\r\n  background: inherit;\r\n  border-radius: 3px;\r\n}\r\n.popover[class*=\"tour-\"] {\r\n  z-index: 100;\r\n}\r\n.popover[class*=\"tour-\"] .popover-navigation {\r\n  padding: 9px 14px;\r\n}\r\n.popover[class*=\"tour-\"] .popover-navigation *[data-role=\"end\"] {\r\n  float: right;\r\n}\r\n.popover[class*=\"tour-\"] .popover-navigation *[data-role=\"prev\"],\r\n.popover[class*=\"tour-\"] .popover-navigation *[data-role=\"next\"],\r\n.popover[class*=\"tour-\"] .popover-navigation *[data-role=\"end\"] {\r\n  cursor: pointer;\r\n}\r\n.popover[class*=\"tour-\"] .popover-navigation *[data-role=\"prev\"].disabled,\r\n.popover[class*=\"tour-\"] .popover-navigation *[data-role=\"next\"].disabled,\r\n.popover[class*=\"tour-\"] .popover-navigation *[data-role=\"end\"].disabled {\r\n  cursor: default;\r\n}\r\n.popover[class*=\"tour-\"].orphan {\r\n  position: fixed;\r\n  margin-top: 0;\r\n}\r\n.popover[class*=\"tour-\"].orphan .arrow {\r\n  display: none;\r\n}\r\n.popover a {\r\n  cursor: pointer;\r\n}", ""]);

/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(14)();
exports.push([module.i, ".popover.tour .close-button {\r\n    position: absolute;\r\n    top: 7px;\r\n    right: 8px;\r\n    font-size: 16px;\r\n    color: #666;\r\n    cursor: pointer;\r\n}\r\n\r\n.popover.tour .close-button:hover {\r\n    text-decoration: none;\r\n}\r\n\r\n.popover.tour .popover-title {\r\n    padding-right: 25px;\r\n}", ""]);

/***/ }),
/* 51 */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(14)();
exports.push([module.i, ".cs-image-flow-modal {\r\n    position: fixed;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    z-index: 2;\r\n    text-align: center;\r\n}\r\n\r\n.cs-image-flow-modal .vertical-aligner {\r\n    display: inline-block;\r\n    height: 100%;\r\n    vertical-align: middle;\r\n}\r\n\r\n.cs-image-flow-modal .modal-backdrop {\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    background-color: black;\r\n    opacity: 0.5;\r\n    z-index: 0;\r\n}\r\n\r\n.cs-image-flow-modal .modal-container {\r\n    position: relative;\r\n    display: inline-block;\r\n    background-color: white;\r\n    border-radius: 4px;\r\n    overflow: hidden;\r\n    box-shadow: 0 0 30px -6px black;\r\n    max-width: 100%;\r\n    vertical-align: middle;\r\n    -webkit-transform: translateY(-50%);\r\n    -moz-transform: translateY(-50%);\r\n    transform: translateY(-50%);\r\n    top: 40%;\r\n}\r\n\r\n.cs-image-flow-modal .flow-modal-header {\r\n    background-color: #f7f7f7;\r\n    border-bottom: 1px solid #ebebeb;\r\n    font-family: \"open sans\", sans-serif;\r\n    font-size: 17px;\r\n    color: #676767;\r\n    padding: 5px 0;\r\n}\r\n\r\n.cs-image-flow-modal .flow-modal-image-container {\r\n    position: relative;\r\n    width: 100%;\r\n    height: 100%;\r\n}\r\n\r\n.cs-image-flow-modal .flow-modal-image-container img {\r\n    max-width: 100%;\r\n}\r\n\r\n.cs-image-flow-modal .flow-modal-image-container [image-flow-spot] {\r\n    position: absolute;\r\n    display: inline-block;\r\n    width: 10px;\r\n    height: 10px;\r\n}", ""]);

/***/ }),
/* 52 */
/***/ (function(module, exports, __webpack_require__) {

/*
  Module dependencies
*/
var ElementType = __webpack_require__(53);
var entities = __webpack_require__(63);

/*
  Boolean Attributes
*/
var booleanAttributes = {
  __proto__: null,
  allowfullscreen: true,
  async: true,
  autofocus: true,
  autoplay: true,
  checked: true,
  controls: true,
  default: true,
  defer: true,
  disabled: true,
  hidden: true,
  ismap: true,
  loop: true,
  multiple: true,
  muted: true,
  open: true,
  readonly: true,
  required: true,
  reversed: true,
  scoped: true,
  seamless: true,
  selected: true,
  typemustmatch: true
};

var unencodedElements = {
  __proto__: null,
  style: true,
  script: true,
  xmp: true,
  iframe: true,
  noembed: true,
  noframes: true,
  plaintext: true,
  noscript: true
};

/*
  Format attributes
*/
function formatAttrs(attributes, opts) {
  if (!attributes) return;

  var output = '',
      value;

  // Loop through the attributes
  for (var key in attributes) {
    value = attributes[key];
    if (output) {
      output += ' ';
    }

    if (!value && booleanAttributes[key]) {
      output += key;
    } else {
      output += key + '="' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '"';
    }
  }

  return output;
}

/*
  Self-enclosing tags (stolen from node-htmlparser)
*/
var singleTag = {
  __proto__: null,
  area: true,
  base: true,
  basefont: true,
  br: true,
  col: true,
  command: true,
  embed: true,
  frame: true,
  hr: true,
  img: true,
  input: true,
  isindex: true,
  keygen: true,
  link: true,
  meta: true,
  param: true,
  source: true,
  track: true,
  wbr: true,
};


var render = module.exports = function(dom, opts) {
  if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];
  opts = opts || {};

  var output = '';

  for(var i = 0; i < dom.length; i++){
    var elem = dom[i];

    if (elem.type === 'root')
      output += render(elem.children, opts);
    else if (ElementType.isTag(elem))
      output += renderTag(elem, opts);
    else if (elem.type === ElementType.Directive)
      output += renderDirective(elem);
    else if (elem.type === ElementType.Comment)
      output += renderComment(elem);
    else if (elem.type === ElementType.CDATA)
      output += renderCdata(elem);
    else
      output += renderText(elem, opts);
  }

  return output;
};

function renderTag(elem, opts) {
  // Handle SVG
  if (elem.name === "svg") opts = {decodeEntities: opts.decodeEntities, xmlMode: true};

  var tag = '<' + elem.name,
      attribs = formatAttrs(elem.attribs, opts);

  if (attribs) {
    tag += ' ' + attribs;
  }

  if (
    opts.xmlMode
    && (!elem.children || elem.children.length === 0)
  ) {
    tag += '/>';
  } else {
    tag += '>';
    if (elem.children) {
      tag += render(elem.children, opts);
    }

    if (!singleTag[elem.name] || opts.xmlMode) {
      tag += '</' + elem.name + '>';
    }
  }

  return tag;
}

function renderDirective(elem) {
  return '<' + elem.data + '>';
}

function renderText(elem, opts) {
  var data = elem.data || '';

  // if entities weren't decoded, no need to encode them back
  if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) {
    data = entities.encodeXML(data);
  }

  return data;
}

function renderCdata(elem) {
  return '<![CDATA[' + elem.children[0].data + ']]>';
}

function renderComment(elem) {
  return '<!--' + elem.data + '-->';
}


/***/ }),
/* 53 */
/***/ (function(module, exports) {

//Types of elements found in the DOM
module.exports = {
	Text: "text", //Text
	Directive: "directive", //<? ... ?>
	Comment: "comment", //<!-- ... -->
	Script: "script", //<script> tags
	Style: "style", //<style> tags
	Tag: "tag", //Any tag
	CDATA: "cdata", //<![CDATA[ ... ]]>

	isTag: function(elem){
		return elem.type === "tag" || elem.type === "script" || elem.type === "style";
	}
};

/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {

var ElementType = __webpack_require__(8);

var re_whitespace = /\s+/g;
var NodePrototype = __webpack_require__(26);
var ElementPrototype = __webpack_require__(55);

function DomHandler(callback, options, elementCB){
	if(typeof callback === "object"){
		elementCB = options;
		options = callback;
		callback = null;
	} else if(typeof options === "function"){
		elementCB = options;
		options = defaultOpts;
	}
	this._callback = callback;
	this._options = options || defaultOpts;
	this._elementCB = elementCB;
	this.dom = [];
	this._done = false;
	this._tagStack = [];
	this._parser = this._parser || null;
}

//default options
var defaultOpts = {
	normalizeWhitespace: false, //Replace all whitespace with single spaces
	withStartIndices: false, //Add startIndex properties to nodes
};

DomHandler.prototype.onparserinit = function(parser){
	this._parser = parser;
};

//Resets the handler back to starting state
DomHandler.prototype.onreset = function(){
	DomHandler.call(this, this._callback, this._options, this._elementCB);
};

//Signals the handler that parsing is done
DomHandler.prototype.onend = function(){
	if(this._done) return;
	this._done = true;
	this._parser = null;
	this._handleCallback(null);
};

DomHandler.prototype._handleCallback =
DomHandler.prototype.onerror = function(error){
	if(typeof this._callback === "function"){
		this._callback(error, this.dom);
	} else {
		if(error) throw error;
	}
};

DomHandler.prototype.onclosetag = function(){
	//if(this._tagStack.pop().name !== name) this._handleCallback(Error("Tagname didn't match!"));
	var elem = this._tagStack.pop();
	if(this._elementCB) this._elementCB(elem);
};

DomHandler.prototype._addDomElement = function(element){
	var parent = this._tagStack[this._tagStack.length - 1];
	var siblings = parent ? parent.children : this.dom;
	var previousSibling = siblings[siblings.length - 1];

	element.next = null;

	if(this._options.withStartIndices){
		element.startIndex = this._parser.startIndex;
	}

	if (this._options.withDomLvl1) {
		element.__proto__ = element.type === "tag" ? ElementPrototype : NodePrototype;
	}

	if(previousSibling){
		element.prev = previousSibling;
		previousSibling.next = element;
	} else {
		element.prev = null;
	}

	siblings.push(element);
	element.parent = parent || null;
};

DomHandler.prototype.onopentag = function(name, attribs){
	var element = {
		type: name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag,
		name: name,
		attribs: attribs,
		children: []
	};

	this._addDomElement(element);

	this._tagStack.push(element);
};

DomHandler.prototype.ontext = function(data){
	//the ignoreWhitespace is officially dropped, but for now,
	//it's an alias for normalizeWhitespace
	var normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace;

	var lastTag;

	if(!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length-1]).type === ElementType.Text){
		if(normalize){
			lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
		} else {
			lastTag.data += data;
		}
	} else {
		if(
			this._tagStack.length &&
			(lastTag = this._tagStack[this._tagStack.length - 1]) &&
			(lastTag = lastTag.children[lastTag.children.length - 1]) &&
			lastTag.type === ElementType.Text
		){
			if(normalize){
				lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
			} else {
				lastTag.data += data;
			}
		} else {
			if(normalize){
				data = data.replace(re_whitespace, " ");
			}

			this._addDomElement({
				data: data,
				type: ElementType.Text
			});
		}
	}
};

DomHandler.prototype.oncomment = function(data){
	var lastTag = this._tagStack[this._tagStack.length - 1];

	if(lastTag && lastTag.type === ElementType.Comment){
		lastTag.data += data;
		return;
	}

	var element = {
		data: data,
		type: ElementType.Comment
	};

	this._addDomElement(element);
	this._tagStack.push(element);
};

DomHandler.prototype.oncdatastart = function(){
	var element = {
		children: [{
			data: "",
			type: ElementType.Text
		}],
		type: ElementType.CDATA
	};

	this._addDomElement(element);
	this._tagStack.push(element);
};

DomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function(){
	this._tagStack.pop();
};

DomHandler.prototype.onprocessinginstruction = function(name, data){
	this._addDomElement({
		name: name,
		data: data,
		type: ElementType.Directive
	});
};

module.exports = DomHandler;


/***/ }),
/* 55 */
/***/ (function(module, exports, __webpack_require__) {

// DOM-Level-1-compliant structure
var NodePrototype = __webpack_require__(26);
var ElementPrototype = module.exports = Object.create(NodePrototype);

var domLvl1 = {
	tagName: "name"
};

Object.keys(domLvl1).forEach(function(key) {
	var shorthand = domLvl1[key];
	Object.defineProperty(ElementPrototype, key, {
		get: function() {
			return this[shorthand] || null;
		},
		set: function(val) {
			this[shorthand] = val;
			return val;
		}
	});
});


/***/ }),
/* 56 */
/***/ (function(module, exports, __webpack_require__) {

var DomUtils = module.exports;

[
	__webpack_require__(61),
	__webpack_require__(62),
	__webpack_require__(59),
	__webpack_require__(60),
	__webpack_require__(58),
	__webpack_require__(57)
].forEach(function(ext){
	Object.keys(ext).forEach(function(key){
		DomUtils[key] = ext[key].bind(DomUtils);
	});
});


/***/ }),
/* 57 */
/***/ (function(module, exports) {

// removeSubsets
// Given an array of nodes, remove any member that is contained by another.
exports.removeSubsets = function(nodes) {
	var idx = nodes.length, node, ancestor, replace;

	// Check if each node (or one of its ancestors) is already contained in the
	// array.
	while (--idx > -1) {
		node = ancestor = nodes[idx];

		// Temporarily remove the node under consideration
		nodes[idx] = null;
		replace = true;

		while (ancestor) {
			if (nodes.indexOf(ancestor) > -1) {
				replace = false;
				nodes.splice(idx, 1);
				break;
			}
			ancestor = ancestor.parent;
		}

		// If the node has been found to be unique, re-insert it.
		if (replace) {
			nodes[idx] = node;
		}
	}

	return nodes;
};

// Source: http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
var POSITION = {
	DISCONNECTED: 1,
	PRECEDING: 2,
	FOLLOWING: 4,
	CONTAINS: 8,
	CONTAINED_BY: 16
};

// Compare the position of one node against another node in any other document.
// The return value is a bitmask with the following values:
//
// document order:
// > There is an ordering, document order, defined on all the nodes in the
// > document corresponding to the order in which the first character of the
// > XML representation of each node occurs in the XML representation of the
// > document after expansion of general entities. Thus, the document element
// > node will be the first node. Element nodes occur before their children.
// > Thus, document order orders element nodes in order of the occurrence of
// > their start-tag in the XML (after expansion of entities). The attribute
// > nodes of an element occur after the element and before its children. The
// > relative order of attribute nodes is implementation-dependent./
// Source:
// http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
//
// @argument {Node} nodaA The first node to use in the comparison
// @argument {Node} nodeB The second node to use in the comparison
//
// @return {Number} A bitmask describing the input nodes' relative position.
//         See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
//         a description of these values.
var comparePos = exports.compareDocumentPosition = function(nodeA, nodeB) {
	var aParents = [];
	var bParents = [];
	var current, sharedParent, siblings, aSibling, bSibling, idx;

	if (nodeA === nodeB) {
		return 0;
	}

	current = nodeA;
	while (current) {
		aParents.unshift(current);
		current = current.parent;
	}
	current = nodeB;
	while (current) {
		bParents.unshift(current);
		current = current.parent;
	}

	idx = 0;
	while (aParents[idx] === bParents[idx]) {
		idx++;
	}

	if (idx === 0) {
		return POSITION.DISCONNECTED;
	}

	sharedParent = aParents[idx - 1];
	siblings = sharedParent.children;
	aSibling = aParents[idx];
	bSibling = bParents[idx];

	if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {
		if (sharedParent === nodeB) {
			return POSITION.FOLLOWING | POSITION.CONTAINED_BY;
		}
		return POSITION.FOLLOWING;
	} else {
		if (sharedParent === nodeA) {
			return POSITION.PRECEDING | POSITION.CONTAINS;
		}
		return POSITION.PRECEDING;
	}
};

// Sort an array of nodes based on their relative position in the document and
// remove any duplicate nodes. If the array contains nodes that do not belong
// to the same document, sort order is unspecified.
//
// @argument {Array} nodes Array of DOM nodes
//
// @returns {Array} collection of unique nodes, sorted in document order
exports.uniqueSort = function(nodes) {
	var idx = nodes.length, node, position;

	nodes = nodes.slice();

	while (--idx > -1) {
		node = nodes[idx];
		position = nodes.indexOf(node);
		if (position > -1 && position < idx) {
			nodes.splice(idx, 1);
		}
	}
	nodes.sort(function(a, b) {
		var relative = comparePos(a, b);
		if (relative & POSITION.PRECEDING) {
			return -1;
		} else if (relative & POSITION.FOLLOWING) {
			return 1;
		}
		return 0;
	});

	return nodes;
};


/***/ }),
/* 58 */
/***/ (function(module, exports, __webpack_require__) {

var ElementType = __webpack_require__(8);
var isTag = exports.isTag = ElementType.isTag;

exports.testElement = function(options, element){
	for(var key in options){
		if(!options.hasOwnProperty(key));
		else if(key === "tag_name"){
			if(!isTag(element) || !options.tag_name(element.name)){
				return false;
			}
		} else if(key === "tag_type"){
			if(!options.tag_type(element.type)) return false;
		} else if(key === "tag_contains"){
			if(isTag(element) || !options.tag_contains(element.data)){
				return false;
			}
		} else if(!element.attribs || !options[key](element.attribs[key])){
			return false;
		}
	}
	return true;
};

var Checks = {
	tag_name: function(name){
		if(typeof name === "function"){
			return function(elem){ return isTag(elem) && name(elem.name); };
		} else if(name === "*"){
			return isTag;
		} else {
			return function(elem){ return isTag(elem) && elem.name === name; };
		}
	},
	tag_type: function(type){
		if(typeof type === "function"){
			return function(elem){ return type(elem.type); };
		} else {
			return function(elem){ return elem.type === type; };
		}
	},
	tag_contains: function(data){
		if(typeof data === "function"){
			return function(elem){ return !isTag(elem) && data(elem.data); };
		} else {
			return function(elem){ return !isTag(elem) && elem.data === data; };
		}
	}
};

function getAttribCheck(attrib, value){
	if(typeof value === "function"){
		return function(elem){ return elem.attribs && value(elem.attribs[attrib]); };
	} else {
		return function(elem){ return elem.attribs && elem.attribs[attrib] === value; };
	}
}

function combineFuncs(a, b){
	return function(elem){
		return a(elem) || b(elem);
	};
}

exports.getElements = function(options, element, recurse, limit){
	var funcs = Object.keys(options).map(function(key){
		var value = options[key];
		return key in Checks ? Checks[key](value) : getAttribCheck(key, value);
	});

	return funcs.length === 0 ? [] : this.filter(
		funcs.reduce(combineFuncs),
		element, recurse, limit
	);
};

exports.getElementById = function(id, element, recurse){
	if(!Array.isArray(element)) element = [element];
	return this.findOne(getAttribCheck("id", id), element, recurse !== false);
};

exports.getElementsByTagName = function(name, element, recurse, limit){
	return this.filter(Checks.tag_name(name), element, recurse, limit);
};

exports.getElementsByTagType = function(type, element, recurse, limit){
	return this.filter(Checks.tag_type(type), element, recurse, limit);
};


/***/ }),
/* 59 */
/***/ (function(module, exports) {

exports.removeElement = function(elem){
	if(elem.prev) elem.prev.next = elem.next;
	if(elem.next) elem.next.prev = elem.prev;

	if(elem.parent){
		var childs = elem.parent.children;
		childs.splice(childs.lastIndexOf(elem), 1);
	}
};

exports.replaceElement = function(elem, replacement){
	var prev = replacement.prev = elem.prev;
	if(prev){
		prev.next = replacement;
	}

	var next = replacement.next = elem.next;
	if(next){
		next.prev = replacement;
	}

	var parent = replacement.parent = elem.parent;
	if(parent){
		var childs = parent.children;
		childs[childs.lastIndexOf(elem)] = replacement;
	}
};

exports.appendChild = function(elem, child){
	child.parent = elem;

	if(elem.children.push(child) !== 1){
		var sibling = elem.children[elem.children.length - 2];
		sibling.next = child;
		child.prev = sibling;
		child.next = null;
	}
};

exports.append = function(elem, next){
	var parent = elem.parent,
		currNext = elem.next;

	next.next = currNext;
	next.prev = elem;
	elem.next = next;
	next.parent = parent;

	if(currNext){
		currNext.prev = next;
		if(parent){
			var childs = parent.children;
			childs.splice(childs.lastIndexOf(currNext), 0, next);
		}
	} else if(parent){
		parent.children.push(next);
	}
};

exports.prepend = function(elem, prev){
	var parent = elem.parent;
	if(parent){
		var childs = parent.children;
		childs.splice(childs.lastIndexOf(elem), 0, prev);
	}

	if(elem.prev){
		elem.prev.next = prev;
	}
	
	prev.parent = parent;
	prev.prev = elem.prev;
	prev.next = elem;
	elem.prev = prev;
};




/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {

var isTag = __webpack_require__(8).isTag;

module.exports = {
	filter: filter,
	find: find,
	findOneChild: findOneChild,
	findOne: findOne,
	existsOne: existsOne,
	findAll: findAll
};

function filter(test, element, recurse, limit){
	if(!Array.isArray(element)) element = [element];

	if(typeof limit !== "number" || !isFinite(limit)){
		limit = Infinity;
	}
	return find(test, element, recurse !== false, limit);
}

function find(test, elems, recurse, limit){
	var result = [], childs;

	for(var i = 0, j = elems.length; i < j; i++){
		if(test(elems[i])){
			result.push(elems[i]);
			if(--limit <= 0) break;
		}

		childs = elems[i].children;
		if(recurse && childs && childs.length > 0){
			childs = find(test, childs, recurse, limit);
			result = result.concat(childs);
			limit -= childs.length;
			if(limit <= 0) break;
		}
	}

	return result;
}

function findOneChild(test, elems){
	for(var i = 0, l = elems.length; i < l; i++){
		if(test(elems[i])) return elems[i];
	}

	return null;
}

function findOne(test, elems){
	var elem = null;

	for(var i = 0, l = elems.length; i < l && !elem; i++){
		if(!isTag(elems[i])){
			continue;
		} else if(test(elems[i])){
			elem = elems[i];
		} else if(elems[i].children.length > 0){
			elem = findOne(test, elems[i].children);
		}
	}

	return elem;
}

function existsOne(test, elems){
	for(var i = 0, l = elems.length; i < l; i++){
		if(
			isTag(elems[i]) && (
				test(elems[i]) || (
					elems[i].children.length > 0 &&
					existsOne(test, elems[i].children)
				)
			)
		){
			return true;
		}
	}

	return false;
}

function findAll(test, elems){
	var result = [];
	for(var i = 0, j = elems.length; i < j; i++){
		if(!isTag(elems[i])) continue;
		if(test(elems[i])) result.push(elems[i]);

		if(elems[i].children.length > 0){
			result = result.concat(findAll(test, elems[i].children));
		}
	}
	return result;
}


/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {

var ElementType = __webpack_require__(8),
    getOuterHTML = __webpack_require__(52),
    isTag = ElementType.isTag;

module.exports = {
	getInnerHTML: getInnerHTML,
	getOuterHTML: getOuterHTML,
	getText: getText
};

function getInnerHTML(elem, opts){
	return elem.children ? elem.children.map(function(elem){
		return getOuterHTML(elem, opts);
	}).join("") : "";
}

function getText(elem){
	if(Array.isArray(elem)) return elem.map(getText).join("");
	if(isTag(elem) || elem.type === ElementType.CDATA) return getText(elem.children);
	if(elem.type === ElementType.Text) return elem.data;
	return "";
}


/***/ }),
/* 62 */
/***/ (function(module, exports) {

var getChildren = exports.getChildren = function(elem){
	return elem.children;
};

var getParent = exports.getParent = function(elem){
	return elem.parent;
};

exports.getSiblings = function(elem){
	var parent = getParent(elem);
	return parent ? getChildren(parent) : [elem];
};

exports.getAttributeValue = function(elem, name){
	return elem.attribs && elem.attribs[name];
};

exports.hasAttrib = function(elem, name){
	return !!elem.attribs && hasOwnProperty.call(elem.attribs, name);
};

exports.getName = function(elem){
	return elem.name;
};


/***/ }),
/* 63 */
/***/ (function(module, exports, __webpack_require__) {

var encode = __webpack_require__(65),
    decode = __webpack_require__(64);

exports.decode = function(data, level){
	return (!level || level <= 0 ? decode.XML : decode.HTML)(data);
};

exports.decodeStrict = function(data, level){
	return (!level || level <= 0 ? decode.XML : decode.HTMLStrict)(data);
};

exports.encode = function(data, level){
	return (!level || level <= 0 ? encode.XML : encode.HTML)(data);
};

exports.encodeXML = encode.XML;

exports.encodeHTML4 =
exports.encodeHTML5 =
exports.encodeHTML  = encode.HTML;

exports.decodeXML =
exports.decodeXMLStrict = decode.XML;

exports.decodeHTML4 =
exports.decodeHTML5 =
exports.decodeHTML = decode.HTML;

exports.decodeHTML4Strict =
exports.decodeHTML5Strict =
exports.decodeHTMLStrict = decode.HTMLStrict;

exports.escape = encode.escape;


/***/ }),
/* 64 */
/***/ (function(module, exports, __webpack_require__) {

var entityMap = __webpack_require__(18),
    legacyMap = __webpack_require__(28),
    xmlMap    = __webpack_require__(19),
    decodeCodePoint = __webpack_require__(27);

var decodeXMLStrict  = getStrictDecoder(xmlMap),
    decodeHTMLStrict = getStrictDecoder(entityMap);

function getStrictDecoder(map){
	var keys = Object.keys(map).join("|"),
	    replace = getReplacer(map);

	keys += "|#[xX][\\da-fA-F]+|#\\d+";

	var re = new RegExp("&(?:" + keys + ");", "g");

	return function(str){
		return String(str).replace(re, replace);
	};
}

var decodeHTML = (function(){
	var legacy = Object.keys(legacyMap)
		.sort(sorter);

	var keys = Object.keys(entityMap)
		.sort(sorter);

	for(var i = 0, j = 0; i < keys.length; i++){
		if(legacy[j] === keys[i]){
			keys[i] += ";?";
			j++;
		} else {
			keys[i] += ";";
		}
	}

	var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"),
	    replace = getReplacer(entityMap);

	function replacer(str){
		if(str.substr(-1) !== ";") str += ";";
		return replace(str);
	}

	//TODO consider creating a merged map
	return function(str){
		return String(str).replace(re, replacer);
	};
}());

function sorter(a, b){
	return a < b ? 1 : -1;
}

function getReplacer(map){
	return function replace(str){
		if(str.charAt(1) === "#"){
			if(str.charAt(2) === "X" || str.charAt(2) === "x"){
				return decodeCodePoint(parseInt(str.substr(3), 16));
			}
			return decodeCodePoint(parseInt(str.substr(2), 10));
		}
		return map[str.slice(1, -1)];
	};
}

module.exports = {
	XML: decodeXMLStrict,
	HTML: decodeHTML,
	HTMLStrict: decodeHTMLStrict
};

/***/ }),
/* 65 */
/***/ (function(module, exports, __webpack_require__) {

var inverseXML = getInverseObj(__webpack_require__(19)),
    xmlReplacer = getInverseReplacer(inverseXML);

exports.XML = getInverse(inverseXML, xmlReplacer);

var inverseHTML = getInverseObj(__webpack_require__(18)),
    htmlReplacer = getInverseReplacer(inverseHTML);

exports.HTML = getInverse(inverseHTML, htmlReplacer);

function getInverseObj(obj){
	return Object.keys(obj).sort().reduce(function(inverse, name){
		inverse[obj[name]] = "&" + name + ";";
		return inverse;
	}, {});
}

function getInverseReplacer(inverse){
	var single = [],
	    multiple = [];

	Object.keys(inverse).forEach(function(k){
		if(k.length === 1){
			single.push("\\" + k);
		} else {
			multiple.push(k);
		}
	});

	//TODO add ranges
	multiple.unshift("[" + single.join("") + "]");

	return new RegExp(multiple.join("|"), "g");
}

var re_nonASCII = /[^\0-\x7F]/g,
    re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;

function singleCharReplacer(c){
	return "&#x" + c.charCodeAt(0).toString(16).toUpperCase() + ";";
}

function astralReplacer(c){
	// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
	var high = c.charCodeAt(0);
	var low  = c.charCodeAt(1);
	var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
	return "&#x" + codePoint.toString(16).toUpperCase() + ";";
}

function getInverse(inverse, re){
	function func(name){
		return inverse[name];
	}

	return function(data){
		return data
				.replace(re, func)
				.replace(re_astralSymbols, astralReplacer)
				.replace(re_nonASCII, singleCharReplacer);
	};
}

var re_xmlChars = getInverseReplacer(inverseXML);

function escapeXML(data){
	return data
			.replace(re_xmlChars, singleCharReplacer)
			.replace(re_astralSymbols, astralReplacer)
			.replace(re_nonASCII, singleCharReplacer);
}

exports.escape = escapeXML;


/***/ }),
/* 66 */
/***/ (function(module, exports) {

module.exports = {
	"0": 65533,
	"128": 8364,
	"130": 8218,
	"131": 402,
	"132": 8222,
	"133": 8230,
	"134": 8224,
	"135": 8225,
	"136": 710,
	"137": 8240,
	"138": 352,
	"139": 8249,
	"140": 338,
	"142": 381,
	"145": 8216,
	"146": 8217,
	"147": 8220,
	"148": 8221,
	"149": 8226,
	"150": 8211,
	"151": 8212,
	"152": 732,
	"153": 8482,
	"154": 353,
	"155": 8250,
	"156": 339,
	"158": 382,
	"159": 376
};

/***/ }),
/* 67 */
/***/ (function(module, exports) {

/* ========================================================================
 * bootstrap-tour - v0.10.2
 * http://bootstraptour.com
 * ========================================================================
 * Copyright 2012-2015 Ulrich Sossou
 *
 * ========================================================================
 * Licensed under the MIT License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/MIT
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================================
 */

/* ========================================================================
 * This is a modified version for CloudShare
 * ========================================================================
 */

(function($, window) {
    var Tour, document;
    document = window.document;
    Tour = (function() {
        function Tour(options) {
            var storage;
            try {
                storage = window.localStorage;
            } catch (_error) {
                storage = false;
            }
            this._options = $.extend({
                name: 'tour',
                steps: [],
                container: 'body',
                autoscroll: true,
                autoscrollElement: 'body',
                keyboard: true,
                storage: storage,
                debug: false,
                backdrop: false,
                backdropContainer: 'body',
                backdropPadding: 0,
                redirect: true,
                orphan: false,
                duration: false,
                delay: false,
                basePath: '',
                template: '<div class="popover" role="tooltip"> <div class="arrow"></div> <h3 class="popover-title"></h3> <div class="popover-content"></div> <div class="popover-navigation"> <div class="btn-group"> <button class="btn btn-sm btn-default" data-role="prev">&laquo; Prev</button> <button class="btn btn-sm btn-default" data-role="next">Next &raquo;</button> <button class="btn btn-sm btn-default" data-role="pause-resume" data-pause-text="Pause" data-resume-text="Resume">Pause</button> </div> <button class="btn btn-sm btn-default" data-role="end">End tour</button> </div> </div>',
                afterSetState: function(key, value) {},
                afterGetState: function(key, value) {},
                afterRemoveState: function(key) {},
                onStart: function(tour) {},
                onEnd: function(tour) {},
                onShow: function(tour) {},
                onShown: function(tour) {},
                onHide: function(tour) {},
                onHidden: function(tour) {},
                onNext: function(tour) {},
                onPrev: function(tour) {},
                onPause: function(tour, duration) {},
                onResume: function(tour, duration) {},
                onRedirectError: function(tour) {}
            }, options);
            this._force = false;
            this._inited = false;
            this._current = null;
            this.backdrop = {
                overlay: null,
                $element: null,
                $background: null,
                backgroundShown: false,
                overlayElementShown: false
            };
            this._scrollCallback = null;
            this;
        }

        Tour.prototype.addSteps = function(steps) {
            var step, _i, _len;
            for (_i = 0, _len = steps.length; _i < _len; _i++) {
                step = steps[_i];
                this.addStep(step);
            }
            return this;
        };

        Tour.prototype.addStep = function(step) {
            this._options.steps.push(step);
            return this;
        };

        Tour.prototype.getStep = function(i) {
            if (this._options.steps[i] != null) {
                return $.extend({
                    id: "step-" + i,
                    path: '',
                    host: '',
                    placement: 'right',
                    title: '',
                    content: '<p></p>',
                    next: i === this._options.steps.length - 1 ? -1 : i + 1,
                    prev: i - 1,
                    animation: true,
                    container: this._options.container,
                    autoscroll: this._options.autoscroll,
                    autoscrollElement: this._options.autoscrollElement,
                    backdrop: this._options.backdrop,
                    backdropContainer: this._options.backdropContainer,
                    backdropPadding: this._options.backdropPadding,
                    redirect: this._options.redirect,
                    reflexElement: this._options.steps[i].element,
                    orphan: this._options.orphan,
                    duration: this._options.duration,
                    delay: this._options.delay,
                    template: this._options.template,
                    onShow: this._options.onShow,
                    onShown: this._options.onShown,
                    onHide: this._options.onHide,
                    onHidden: this._options.onHidden,
                    onNext: this._options.onNext,
                    onPrev: this._options.onPrev,
                    onPause: this._options.onPause,
                    onResume: this._options.onResume,
                    onRedirectError: this._options.onRedirectError
                }, this._options.steps[i]);
            }
        };

        Tour.prototype.init = function(force) {
            this._force = force;
            if (this.ended()) {
                this._debug('Tour ended, init prevented.');
                return this;
            }
            this.setCurrentStep();
            this.setNextStep();
            this._initMouseNavigation();
            this._initKeyboardNavigation();
            this._onResize((function(_this) {
                return function() {
                    return _this.showStep(_this._current);
                };
            })(this));
            if (this._current !== null) {
                this.showStep(this._current);
            }
            this._inited = true;
            return this;
        };

        Tour.prototype.isInitialized = function() {
            return this._inited;
        };

        Tour.prototype.start = function(force) {
            var promise;
            if (force == null) {
                force = false;
            }
            if (!this._inited) {
                this.init(force);
            }
            if (this._current === null) {
                promise = this._makePromise(this._options.onStart != null ? this._options.onStart(this) : void 0);
                this._callOnPromiseDone(promise, this.showStep, 0);
            }
            return this;
        };

        Tour.prototype.next = function() {
            var promise;
            promise = this.hideStep(this._current);
            return this._callOnPromiseDone(promise, this._showNextStep);
        };

        Tour.prototype.prev = function() {
            var promise;
            promise = this.hideStep(this._current);
            return this._callOnPromiseDone(promise, this._showPrevStep);
        };

        Tour.prototype.goTo = function(i) {
            var promise;
            promise = this.hideStep(this._current);
            return this._callOnPromiseDone(promise, this.showStep, i);
        };

        Tour.prototype.end = function() {
            var endHelper, promise;
            endHelper = (function(_this) {
                return function(e) {
                    $(document).off("click.tour-" + _this._options.name);
                    $(document).off("keyup.tour-" + _this._options.name);
                    $(window).off("resize.tour-" + _this._options.name);

                    _this._setState('end', 'yes');
                    _this._inited = false;
                    _this._force = false;
                    _this._clearTimer();
                    if (_this._options.onEnd != null) {
                        return _this._options.onEnd(_this);
                    }
                };
            })(this);
            promise = this.hideStep(this._current);
            return this._callOnPromiseDone(promise, endHelper);
        };

        Tour.prototype.ended = function() {
            return !this._force && !!this._getState('end');
        };

        Tour.prototype.restart = function() {
            this._removeState('current_step');
            this._removeState('end');
            this._removeState('redirect_to');
            this._current = null;
            return this.start();
        };

        Tour.prototype.pause = function() {
            var step;
            step = this.getStep(this._current);
            if (!(step && step.duration)) {
                return this;
            }
            this._paused = true;
            this._duration -= new Date().getTime() - this._start;
            window.clearTimeout(this._timer);
            this._debug("Paused/Stopped step " + (this._current + 1) + " timer (" + this._duration + " remaining).");
            if (step.onPause != null) {
                return step.onPause(this, this._duration);
            }
        };

        Tour.prototype.resume = function() {
            var step;
            step = this.getStep(this._current);
            if (!(step && step.duration)) {
                return this;
            }
            this._paused = false;
            this._start = new Date().getTime();
            this._duration = this._duration || step.duration;
            this._timer = window.setTimeout((function(_this) {
                return function() {
                    if (_this._isLast()) {
                        return _this.next();
                    } else {
                        return _this.end();
                    }
                };
            })(this), this._duration);
            this._debug("Started step " + (this._current + 1) + " timer with duration " + this._duration);
            if ((step.onResume != null) && this._duration !== step.duration) {
                return step.onResume(this, this._duration);
            }
        };

        Tour.prototype.hideStep = function(i) {
            var hideStepHelper, promise, step;
            step = this.getStep(i);
            if (!step) {
                return;
            }
            this._removeOnScroll();
            this._clearTimer();
            promise = this._makePromise(step.onHide != null ? step.onHide(this, i) : void 0);
            hideStepHelper = (function(_this) {
                return function(e) {
                    var $element;
                    $element = step.orphan ? $("body") : $(step.element);
                    if (!($element.data('bs.popover') || $element.data('popover'))) {
                        $element = $(".tour-" + _this._options.name + ".tour-" + _this._options.name + "-" + i);
                        $element.remove();
                    }
                    $element.popover('destroy').removeClass("tour-" + _this._options.name + "-element tour-" + _this._options.name + "-" + i + "-element");
                    $element.removeData('bs.popover');
                    if (step.reflex) {
                        $(step.reflexElement).removeClass('tour-step-element-reflex').off("" + (_this._reflexEvent(step.reflex)) + ".tour-" + _this._options.name);
                    }
                    if (step.backdrop) {
                        _this._hideBackdrop();
                    }
                    if (step.onHidden != null) {
                        return step.onHidden(_this);
                    }
                };
            })(this);
            this._callOnPromiseDone(promise, hideStepHelper);
            return promise;
        };

        Tour.prototype.showStep = function(i, disableAutoScroll) {
            var promise, showStepHelper, skipToPrevious, step;
            if (this.ended()) {
                this._debug('Tour ended, showStep prevented.');
                return this;
            }
            step = this.getStep(i);
            if (!step) {
                return;
            }
            if (this._isOrphan(step) && step.optional && !step.orphan) {
                return this.showStep(i + 1);
            }
            skipToPrevious = i < this._current;
            this.setNextStep(i);
            promise = this._makePromise(step.onShow != null ? step.onShow(this, i) : void 0);
            showStepHelper = (function(_this) {
                return function(e) {
                    var path, showPopoverAndOverlay;
                    _this.setCurrentStep(i);
                    path = (function() {
                        switch ({}.toString.call(step.path)) {
                            case '[object Function]':
                                return step.path();
                            case '[object String]':
                                return this._options.basePath + step.path;
                            default:
                                return step.path;
                        }
                    }).call(_this);

                    if (_this._isRedirect(step.host, path, document.location)) {
                        _this._redirect(step, i, path);
                        if (!_this._isJustPathHashDifferent(step.host, path, document.location)) {
                            return;
                        }
                    }
                    if (_this._isOrphan(step)) {
                        if (step.orphan === false) {
                            _this._debug("Stop at orphan step " + (_this._current + 1) + ".\nOrphan option is false and the element does not exist or is hidden.");
                            return;
                        }
                        _this._debug("Show the orphan step " + (_this._current + 1) + ". Orphan option is true.");
                    }
                    if (step.backdrop) {
                        _this._showBackdrop(step);
                    }
                    showPopoverAndOverlay = function() {
                        if (_this.getCurrentStep() !== i || _this.ended()) {
                            return;
                        }
                        if ((step.element != null) && step.backdrop) {
                            _this._showOverlayElement(step);
                        }
                        _this._showPopover(step, i);
                        _this._setShowStepOnScroll();
                        if (step.onShown != null) {
                            step.onShown(_this);
                        }
                        return _this._debug("Step " + (_this._current + 1) + " of " + _this._options.steps.length);
                    };
                    if (!disableAutoScroll && step.autoscroll) {
                        _this._scrollIntoView(step.element, showPopoverAndOverlay, step.autoscrollElement);
                    } else {
                        showPopoverAndOverlay();
                    }
                    if (step.duration) {
                        return _this.resume();
                    }
                };
            })(this);
            if (step.delay) {
                this._debug("Wait " + step.delay + " milliseconds to show the step " + (this._current + 1));
                window.setTimeout((function(_this) {
                    return function() {
                        return _this._callOnPromiseDone(promise, showStepHelper);
                    };
                })(this), step.delay);
            } else {
                this._callOnPromiseDone(promise, showStepHelper);
            }
            return promise;
        };

        Tour.prototype.getCurrentStep = function() {
            if (this._current == null)
                this.setCurrentStep();
            return this._current;
        };

        Tour.prototype.setCurrentStep = function(value) {
            if (value != null) {
                this._current = value;
                this._setState('current_step', value);
            } else {
                this._current = this._getState('current_step');
                this._current = this._current === null ? null : parseInt(this._current, 10);
            }
            return this;
        };

        Tour.prototype.getNextStep = function() {
            if (this._next == null)
                this.setNextStep();
            return this._next;
        };

        Tour.prototype.setNextStep = function(value) {
            if (value != null) {
                this._next = value;
                this._setState('next_step', value);
            } else {
                this._next = this._getState('next_step');
                this._next = this._next === null ? null : parseInt(this._next, 10);
            }
            return this;
        };

        Tour.prototype.redraw = function() {
            return this._showOverlayElement(this.getStep(this.getCurrentStep()).element, true);
        };

        Tour.prototype._setState = function(key, value) {
            var e, keyName;
            if (this._options.storage) {
                keyName = "" + this._options.name + "_" + key;
                try {
                    this._options.storage.setItem(keyName, value);
                } catch (_error) {
                    e = _error;
                    if (e.code === DOMException.QUOTA_EXCEEDED_ERR) {
                        this._debug('LocalStorage quota exceeded. State storage failed.');
                    }
                }
                return this._options.afterSetState(keyName, value);
            } else {
                if (this._state == null) {
                    this._state = {};
                }
                return this._state[key] = value;
            }
        };

        Tour.prototype._removeState = function(key) {
            var keyName;
            if (this._options.storage) {
                keyName = "" + this._options.name + "_" + key;
                this._options.storage.removeItem(keyName);
                return this._options.afterRemoveState(keyName);
            } else {
                if (this._state != null) {
                    return delete this._state[key];
                }
            }
        };

        Tour.prototype._getState = function(key) {
            var keyName, value;
            if (this._options.storage) {
                keyName = "" + this._options.name + "_" + key;
                value = this._options.storage.getItem(keyName);
            } else {
                if (this._state != null) {
                    value = this._state[key];
                }
            }
            if (value === void 0 || value === 'null') {
                value = null;
            }
            this._options.afterGetState(key, value);
            return value;
        };

        Tour.prototype._showNextStep = function() {
            var promise, showNextStepHelper, step;
            step = this.getStep(this._current);
            showNextStepHelper = (function(_this) {
                return function(e) {
                    return _this.showStep(step.next);
                };
            })(this);
            promise = this._makePromise(step.onNext != null ? step.onNext(this) : void 0);
            return this._callOnPromiseDone(promise, showNextStepHelper);
        };

        Tour.prototype._showPrevStep = function() {
            var promise, showPrevStepHelper, step;
            step = this.getStep(this._current);
            showPrevStepHelper = (function(_this) {
                return function(e) {
                    return _this.showStep(step.prev);
                };
            })(this);
            promise = this._makePromise(step.onPrev != null ? step.onPrev(this) : void 0);
            return this._callOnPromiseDone(promise, showPrevStepHelper);
        };

        Tour.prototype._debug = function(text) {
            if (this._options.debug) {
                return window.console.log("Bootstrap Tour '" + this._options.name + "' | " + text);
            }
        };

        Tour.prototype._isRedirect = function(host, path, location) {
            var currentPath;
            if (host !== '') {
                if (this._isHostDifferent(host, location.href)) {
                    return true;
                }
            }
            currentPath = [location.pathname, location.search, location.hash].join('');
            return (path != null) && path !== '' && (({}.toString.call(path) === '[object RegExp]' && !path.test(currentPath)) || ({}.toString.call(path) === '[object String]' && this._isPathDifferent(path, currentPath)));
        };

        Tour.prototype._isHostDifferent = function(host, currentURL) {
            return this._getProtocol(host) !== this._getProtocol(currentURL) || this._getHost(host) !== this._getHost(currentURL);
        };

        Tour.prototype._isPathDifferent = function(path, currentPath) {
            return this._getPath(path) !== this._getPath(currentPath) || !this._equal(this._getQuery(path), this._getQuery(currentPath)) || !this._equal(this._getHash(path), this._getHash(currentPath));
        };

        Tour.prototype._isJustPathHashDifferent = function(host, path, location) {
            var currentPath;
            if (host !== '') {
                if (this._isHostDifferent(host, location.href)) {
                    return false;
                }
            }
            currentPath = [location.pathname, location.search, location.hash].join('');
            if ({}.toString.call(path) === '[object String]') {
                return this._getPath(path) === this._getPath(currentPath) && this._equal(this._getQuery(path), this._getQuery(currentPath)) && !this._equal(this._getHash(path), this._getHash(currentPath));
            }
            return false;
        };

        Tour.prototype._redirect = function(step, i, path) {
            if ($.isFunction(step.redirect)) {
                return step.redirect.call(this, path);
            } else if (step.redirect === true) {
                this._debug("Redirect to " + step.host + path);
                if (this._getState('redirect_to') === ("" + i)) {
                    this._debug("Error redirection loop to " + path);
                    this._removeState('redirect_to');
                    if (step.onRedirectError != null) {
                        return step.onRedirectError(this);
                    }
                } else {
                    this._setState('redirect_to', "" + i);
                    return document.location.href = "" + step.host + path;
                }
            }
        };

        Tour.prototype._isOrphan = function(step) {
            return (step.element == null) || !$(step.element).length || $(step.element).is(':hidden') && ($(step.element)[0].namespaceURI !== 'http://www.w3.org/2000/svg');
        };

        Tour.prototype._isLast = function() {
            return this._current < this._options.steps.length - 1;
        };

        Tour.prototype._showPopover = function(step, i) {
            var $element, $tip, isOrphan, options, shouldAddSmart;
            $(".tour-" + this._options.name).remove();
            options = $.extend({}, this._options);
            if (step.orphan && step.element) {
                if ($(step.element).length === 0) {
                    return;
                }
            }
            isOrphan = step.orphan || this._isOrphan(step);
            step.template = this._template(step, i);
            if (isOrphan) {
                step.element = 'body';
                step.placement = 'top';
            }
            $element = $(step.element);
            $element.addClass("tour-" + this._options.name + "-element tour-" + this._options.name + "-" + i + "-element");
            if (step.options) {
                $.extend(options, step.options);
            }
            if (step.reflex && !isOrphan) {
                $(step.reflexElement).addClass('tour-step-element-reflex').off("" + (this._reflexEvent(step.reflex)) + ".tour-" + this._options.name).on("" + (this._reflexEvent(step.reflex)) + ".tour-" + this._options.name, (function(_this) {
                    return function() {
                        if (_this._isLast()) {
                            return _this.next();
                        } else {
                            return _this.end();
                        }
                    };
                })(this));
            }
            shouldAddSmart = step.smartPlacement === true && step.placement.search(/auto/i) === -1;
            $element.popover({
                placement: shouldAddSmart ? "auto " + step.placement : step.placement,
                trigger: 'manual',
                title: step.title,
                content: step.content,
                html: true,
                animation: step.animation,
                container: step.container,
                template: step.template,
                selector: step.element
            }).popover('show');
            $tip = $element.data('bs.popover') ? $element.data('bs.popover').tip() : $element.data('popover').tip();
            $tip.attr('id', step.id);
            if (step.width)
                $tip.css("max-width", step.width);
            this._reposition($tip, step);
            if (isOrphan) {
                return this._center($tip);
            }
        };

        Tour.prototype._template = function(step, i) {
            var $navigation, $next, $prev, $resume, $template, template, isOrphan;
            isOrphan = step.orphan || this._isOrphan(step);
            template = step.template;
            if (isOrphan && {}.toString.call(step.orphan) !== '[object Boolean]') {
                template = step.orphan;
            }
            $template = $.isFunction(template) ? $(template(i, step)) : $(template);
            $navigation = $template.find('.popover-navigation');
            $prev = $navigation.find('[data-role="prev"]');
            $next = $navigation.find('[data-role="next"]');
            $resume = $navigation.find('[data-role="pause-resume"]');
            if (isOrphan) {
                $template.addClass('orphan');
            }
            $template.addClass("tour-" + this._options.name + " tour-" + this._options.name + "-" + i);
            if (step.reflex) {
                $template.addClass("tour-" + this._options.name + "-reflex");
            }
            if (step.prev < 0) {
                $prev.addClass('disabled');
                $prev.prop('disabled', true);
            }
            if (step.next < 0) {
                $next.addClass('disabled');
                $next.prop('disabled', true);
            }
            if (!step.duration) {
                $resume.remove();
            }
            return $template.clone().wrap('<div>').parent().html();
        };

        Tour.prototype._reflexEvent = function(reflex) {
            if ({}.toString.call(reflex) === '[object Boolean]') {
                return 'click';
            } else {
                return reflex;
            }
        };

        Tour.prototype._reposition = function($tip, step) {
            var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset, stepOffset;
            stepOffset = {
                left: parseInt(step.offsetX) || 0,
                top: parseInt(step.offsetY) || 0
            };
            offsetWidth = $tip[0].offsetWidth;
            offsetHeight = $tip[0].offsetHeight;
            tipOffset = $tip.offset();
            tipOffset.left += stepOffset.left;
            tipOffset.top += stepOffset.top;
            originalLeft = tipOffset.left;
            originalTop = tipOffset.top;
            offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight();
            if (offsetBottom < 0) {
                tipOffset.top = tipOffset.top + offsetBottom;
            }
            offsetRight = $('html').outerWidth() - tipOffset.left - $tip.outerWidth();
            if (offsetRight < 0) {
                tipOffset.left = tipOffset.left + offsetRight;
            }
            if (tipOffset.top < 0) {
                tipOffset.top = 0;
            }
            if (tipOffset.left < 0) {
                tipOffset.left = 0;
            }
            $tip.offset(tipOffset);
            if (step.placement === 'bottom' || step.placement === 'top') {
                if (originalLeft !== tipOffset.left) {
                    return this._replaceArrow($tip, (tipOffset.left - originalLeft) * 2, offsetWidth, 'left');
                }
            } else {
                if (originalTop !== tipOffset.top) {
                    return this._replaceArrow($tip, (tipOffset.top - originalTop) * 2, offsetHeight, 'top');
                }
            }
        };

        Tour.prototype._center = function($tip) {
            return $tip.css('top', $(window).outerHeight() / 2 - $tip.outerHeight() / 2);
        };

        Tour.prototype._replaceArrow = function($tip, delta, dimension, position) {
            return $tip.find('.arrow').css(position, delta ? 50 * (1 - delta / dimension) + '%' : '');
        };

        Tour.prototype._scrollIntoView = function(element, callback, autoscrollElement) {
            var $element, $window, counter, offsetTop, scrollTop, windowHeight, $autoscrollElement;
            $element = $(element);

            if (!$element.length) {
                return callback();
            }
            $autoscrollElement = $(autoscrollElement || "body, html");
            $window = $(window);
            offsetTop = this._calculateOffsetTop($element[0]);
            windowHeight = $window.height();
            scrollTop = Math.max(0, offsetTop - (windowHeight / 2));
            this._debug("Scroll into view. ScrollTop: " + scrollTop + ". Element offset: " + offsetTop + ". Window height: " + windowHeight + ".");
            counter = 0;
            return $autoscrollElement.stop(true, true).animate({
                scrollTop: Math.ceil(scrollTop)
            }, (function(_this) {
                return function() {
                    counter += 1;
                    if (counter >= $autoscrollElement.length) {
                        callback();
                        return _this._debug("Scroll into view.\nAnimation end element offset: " + ($element.offset().top) + ".\nWindow height: " + ($window.height()) + ".");
                    }
                };
            })(this));
        };

        Tour.prototype._calculateOffsetTop = function(element) {
            var top = 0;
            while (element) {
                top += element.offsetTop;
                element = element.offsetParent;
            }
            return top;
        };

        Tour.prototype._onResize = function(callback, timeout) {
            $(window).on("resize.tour-" + this._options.name, resizeCallback);

            function resizeCallback() {
                clearTimeout(timeout);
                return timeout = setTimeout(callback, 100);
            }
        };

        Tour.prototype._setShowStepOnScroll = function() {
            var _this = this;
            this._setOnScroll(function() {
                _this.showStep(_this.getCurrentStep(), true);
            });
        };

        Tour.prototype._setOnScroll = function(callback) {
            var timeout;
            this._removeOnScroll();
            this._scrollCallback = function() {
                clearTimeout(timeout);
                timeout = setTimeout(callback, 100);
            };
            window.addEventListener("scroll", this._scrollCallback, true);
        };

        Tour.prototype._removeOnScroll = function() {
            if (this._scrollCallback) {
                window.removeEventListener("scroll", this._scrollCallback, true);
                this._scrollCallback = null;
            }
        };

        Tour.prototype._initMouseNavigation = function() {
            var _this;
            _this = this;
            return $(document).off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='prev']").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='next']").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='end']").off("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='pause-resume']").on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='next']", (function(_this) {
                return function(e) {
                    e.preventDefault();
                    return _this.next();
                };
            })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='prev']", (function(_this) {
                return function(e) {
                    e.preventDefault();
                    return _this.prev();
                };
            })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='end']", (function(_this) {
                return function(e) {
                    e.preventDefault();
                    return _this.end();
                };
            })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='hide']", (function(_this) {
                return function(e) {
                    e.preventDefault();
                    return _this.hideStep(_this.getCurrentStep());
                };
            })(this)).on("click.tour-" + this._options.name, ".popover.tour-" + this._options.name + " *[data-role='pause-resume']", function(e) {
                var $this;
                e.preventDefault();
                $this = $(this);
                $this.text(_this._paused ? $this.data('pause-text') : $this.data('resume-text'));
                if (_this._paused) {
                    return _this.resume();
                } else {
                    return _this.pause();
                }
            });
        };

        Tour.prototype._initKeyboardNavigation = function() {
            if (!this._options.keyboard) {
                return;
            }
            return $(document).on("keyup.tour-" + this._options.name, (function(_this) {
                return function(e) {
                    if (!e.which) {
                        return;
                    }
                    switch (e.which) {
                        case 39:
                            e.preventDefault();
                            if (_this._isLast()) {
                                return _this.next();
                            } else {
                                return _this.end();
                            }
                        case 37:
                            e.preventDefault();
                            if (_this._current > 0) {
                                return _this.prev();
                            }
                            break;
                        case 27:
                            e.preventDefault();
                            return _this.end();
                    }
                };
            })(this));
        };

        Tour.prototype._makePromise = function(result) {
            if (result && $.isFunction(result.then)) {
                return result;
            } else {
                return null;
            }
        };

        Tour.prototype._callOnPromiseDone = function(promise, cb, arg) {
            if (promise) {
                return promise.then((function(_this) {
                    return function(e) {
                        return cb.call(_this, arg);
                    };
                })(this));
            } else {
                return cb.call(this, arg);
            }
        };

        Tour.prototype._showBackdrop = function(step) {
            if (this.backdrop.backgroundShown) {
                return;
            }
            this.backdrop = $('<div>', {
                "class": 'tour-backdrop'
            });
            this.backdrop.backgroundShown = true;
            return $(step.backdropContainer).append(this.backdrop);
        };

        Tour.prototype._hideBackdrop = function() {
            this._hideOverlayElement();
            return this._hideBackground();
        };

        Tour.prototype._hideBackground = function() {
            if (this.backdrop) {
                if (this.backdrop.remove)
                    this.backdrop.remove();
                this.backdrop.overlay = null;
                return this.backdrop.backgroundShown = false;
            }
        };

        Tour.prototype._showOverlayElement = function(step, force) {
            var $element, elementData;
            $element = $(step.element);
            if (!$element || $element.length === 0 || this.backdrop.overlayElementShown && !force) {
                return;
            }
            if (!this.backdrop.overlayElementShown) {
                this.backdrop.$element = $element.addClass('tour-step-backdrop');
                if (step.disableClick)
                    this.backdrop.$element = $element.addClass('tour-step-backdrop-disable-click');
                this.backdrop.$background = $('<div>', {
                    "class": 'tour-step-background'
                });
                if (step.backdropBackgroundCssClass)
                    this.backdrop.$background.addClass(step.backdropBackgroundCssClass);
                if (step.backdropElementCssClass)
                    this.backdrop.$element.addClass(step.backdropElementCssClass);
                this.backdrop.$background.appendTo(step.backdropContainer);
                this.backdrop.overlayElementShown = true;
            }
            elementData = {
                width: $element.innerWidth(),
                height: $element.innerHeight(),
                offset: $element.offset()
            };
            if (step.backdropPadding) {
                elementData = this._applyBackdropPadding(step.backdropPadding, elementData);
            }
            return this.backdrop.$background.width(elementData.width).height(elementData.height).offset(elementData.offset);
        };

        Tour.prototype._hideOverlayElement = function() {
            if (!this.backdrop.overlayElementShown) {
                return;
            }
            this.backdrop.$element.removeClass('tour-step-backdrop');
            this.backdrop.$element.removeClass('tour-step-backdrop-disable-click');
            this.backdrop.$background.remove();
            this.backdrop.$element = null;
            this.backdrop.$background = null;
            return this.backdrop.overlayElementShown = false;
        };

        Tour.prototype._applyBackdropPadding = function(padding, data) {
            if (typeof padding === 'object') {
                if (padding.top == null) {
                    padding.top = 0;
                }
                if (padding.right == null) {
                    padding.right = 0;
                }
                if (padding.bottom == null) {
                    padding.bottom = 0;
                }
                if (padding.left == null) {
                    padding.left = 0;
                }
                data.offset.top = data.offset.top - padding.top;
                data.offset.left = data.offset.left - padding.left;
                data.width = data.width + padding.left + padding.right;
                data.height = data.height + padding.top + padding.bottom;
            } else {
                data.offset.top = data.offset.top - padding;
                data.offset.left = data.offset.left - padding;
                data.width = data.width + (padding * 2);
                data.height = data.height + (padding * 2);
            }
            return data;
        };

        Tour.prototype._clearTimer = function() {
            window.clearTimeout(this._timer);
            this._timer = null;
            return this._duration = null;
        };

        Tour.prototype._getProtocol = function(url) {
            url = url.split('://');
            if (url.length > 1) {
                return url[0];
            } else {
                return 'http';
            }
        };

        Tour.prototype._getHost = function(url) {
            url = url.split('//');
            url = url.length > 1 ? url[1] : url[0];
            return url.split('/')[0];
        };

        Tour.prototype._getPath = function(path) {
            return path.replace(/\/?$/, '').split('?')[0].split('#')[0];
        };

        Tour.prototype._getQuery = function(path) {
            return this._getParams(path, '?');
        };

        Tour.prototype._getHash = function(path) {
            return this._getParams(path, '#');
        };

        Tour.prototype._getParams = function(path, start) {
            var param, params, paramsObject, _i, _len;
            params = path.split(start);
            if (params.length === 1) {
                return {};
            }
            params = params[1].split('&');
            paramsObject = {};
            for (_i = 0, _len = params.length; _i < _len; _i++) {
                param = params[_i];
                param = param.split('=');
                paramsObject[param[0]] = param[1] || '';
            }
            return paramsObject;
        };

        Tour.prototype._equal = function(obj1, obj2) {
            var k, v;
            if ({}.toString.call(obj1) === '[object Object]' && {}.toString.call(obj2) === '[object Object]') {
                for (k in obj1) {
                    v = obj1[k];
                    if (obj2[k] !== v) {
                        return false;
                    }
                }
                for (k in obj2) {
                    v = obj2[k];
                    if (obj1[k] !== v) {
                        return false;
                    }
                }
                return true;
            }
            return obj1 === obj2;
        };

        return Tour;

    })();
    return window.Tour = Tour;
})(jQuery, window);

/*** EXPORTS FROM exports-loader ***/
module.exports = window.Tour;

/***/ }),
/* 68 */
/***/ (function(module, exports) {

module.exports = "<div class=\"chocolatey-button\" tour-tag-name=\"chocolatey-button\">\r\n\t<button type=\"button\" ng-click=\"ngClick\"></button>\r\n</div>";

/***/ }),
/* 69 */
/***/ (function(module, exports) {

module.exports = "<div class=\"chocolatey-client\">\r\n\t<packages-pane show-search=\"true\" \r\n\t\t\t\t   first-view=\"popular\"\r\n\t\t\t\t   selected-packages=\"selectedPackages\" \r\n\t\t\t\t   on-select-package=\"selectPackage\"></packages-pane>\r\n\t\t\t\t   \r\n\t<packages-pane show-search=\"false\"\r\n\t\t\t\t   title=\"Selected Packages\" \r\n\t\t\t\t   first-view=\"selected-packages\" \r\n\t\t\t\t   selected-packages=\"selectedPackages\" \r\n\t\t\t\t   on-unselect-package=\"unselectPackage\"></packages-pane>\r\n</div>";

/***/ }),
/* 70 */
/***/ (function(module, exports) {

module.exports = "<div class=\"details-pane\">\r\n\t<div class=\"header\">\r\n\t\t<div class=\"back\">\r\n\t\t\t<a href=\"javascript:;\" ng-click=\"back()\">&lt; back</a>\r\n\t\t</div>\r\n\t\t<div class=\"header-content\" style=\"\">\r\n\t\t\t<div class=\"icon\">\r\n\t\t\t\t<img ng-src=\"{{package.iconUrl}}\" />\r\n\t\t\t</div>\r\n\t\t\t<div class=\"title\">\r\n\t\t\t\t<span ng-bind=\"package.title || package.idName\"></span> \r\n\t\t\t\t<span ng-bind=\"package.version\"></span>\r\n\t\t\t</div>\r\n\t\t\t<div class=\"action\">\r\n\t\t\t\t<button type=\"button\" ng-show=\"onSelectPackage\" ng-click=\"onSelectPackage(package)\" ng-disabled=\"isSelected()\">Add &gt;</button>\r\n\t\t\t\t<button type=\"button\" ng-show=\"onUnselectPackage\" ng-click=\"unselectAndGoBack()\">&lt; Remove</button>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n\t<package-detailed-item package=\"package\" \r\n\t\t\t\t\t\t   on-select-package=\"onSelectPackage\" \r\n\t\t\t\t\t\t   on-unselect-package=\"unselectAndGoBack\"\r\n\t\t\t\t\t\t   selected-packages=\"selectedPackages\"></package-details-item>\r\n</div>";

/***/ }),
/* 71 */
/***/ (function(module, exports) {

module.exports = "<div class=\"markdown\" ng-bind-html=\"parsedContent\">\r\n</div>";

/***/ }),
/* 72 */
/***/ (function(module, exports) {

module.exports = "<div class=\"package-detailed-item\" ng-class=\"{'scrolled': scrolled}\">\r\n\t<div class=\"content\">\r\n\t\t<div class=\"section\">Description</div>\r\n\t\t<div class=\"description\">\r\n\t\t\t<markdown content=\"package.description\"></markdown>\r\n\t\t</div>\r\n\t\t\r\n\t\t<div class=\"section\">Extra details:</div>\r\n\t\t<table>\r\n\t\t\t<tr>\r\n\t\t\t\t<td class=\"label\">Authors:</td>\r\n\t\t\t\t<td><span ng-bind=\"package.authors\"></span></td>\r\n\t\t\t</tr>\r\n\t\t\t<tr>\r\n\t\t\t\t<td class=\"label\">Downloads:</td>\r\n\t\t\t\t<td><span ng-bind=\"package.downloadCount\"></span></td>\r\n\t\t\t</tr>\r\n\t\t\t<tr>\r\n\t\t\t\t<td class=\"label\">Chocolatey link:</td>\r\n\t\t\t\t<td>\r\n\t\t\t\t\t<div class=\"link\">\r\n\t\t\t\t\t\t<a ng-href=\"{{package.galleryDetailsUrl}}\" ng-bind=\"package.galleryDetailsUrl\" target=\"_blank\"></a>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</td>\r\n\t\t\t</tr>\r\n\t\t\t<tr>\r\n\t\t\t\t<td class=\"label\">Project site:</td>\r\n\t\t\t\t<td>\r\n\t\t\t\t\t<div class=\"link\">\r\n\t\t\t\t\t\t<a ng-href=\"{{package.projectUrl}}\" ng-bind=\"package.projectUrl\" target=\"_blank\"></a>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</td>\r\n\t\t\t</tr>\r\n\t\t\t<tr>\r\n\t\t\t\t<td class=\"label\">Tags:</td>\r\n\t\t\t\t<td><span ng-bind=\"package.tags\"></span></td>\r\n\t\t\t</tr>\r\n\t\t</table>\r\n\t\t<div ng-show=\"onSelectPackage\" class=\"section\">Choose another version</div>\r\n\t\t<table ng-show=\"onSelectPackage\">\r\n\t\t\t<tr ng-repeat=\"version in versions\">\r\n\t\t\t\t<td class=\"version\">\r\n\t\t\t\t\t<span ng-bind=\"version\"></span>\r\n\t\t\t\t</td>\r\n\t\t\t\t<td>\r\n\t\t\t\t\t<button type=\"button\" ng-click=\"selectVersion(version)\" ng-disabled=\"isSelected(version)\">Add &gt;</button>\r\n\t\t\t\t</td>\r\n\t\t\t</tr>\r\n\t\t</table>\r\n\t\t<spinner ng-show=\"onSelectPackage && showVersionSpinner\"></spinner>\r\n\t\t<div ng-show=\"onSelectPackage && noMore && versions.length == 0\">\r\n\t\t\tNo other versions found.\r\n\t\t</div>\r\n\t</div>\r\n</div>";

/***/ }),
/* 73 */
/***/ (function(module, exports) {

module.exports = "<div class=\"package-item\">\r\n\t<table>\r\n\t\t<tr>\r\n\t\t\t<td class=\"icon\">\r\n\t\t\t\t<img ng-src=\"{{package.iconUrl}}\" />\r\n\t\t\t</td>\r\n\t\t\t<td class=\"info\">\r\n\t\t\t\t<div class=\"title\"><span ng-bind=\"package.title || package.idName\"></span> <span ng-bind=\"package.version\"></span></div>\r\n\t\t\t\t<div class=\"authors\">By: <span ng-bind=\"package.authors\"></span></div>\r\n\t\t\t\t<div class=\"description\">\r\n\t\t\t\t\t<span ng-bind=\"shortDescription\"></span>\r\n\t\t\t\t\t<a href=\"javascript:;\" ng-click=\"onViewDetails(package)\">more information</a>\r\n\t\t\t\t</div>\r\n\t\t\t</td>\r\n\t\t\t<td class=\"actions\">\r\n\t\t\t\t<div ng-show=\"onSelectPackage\">\r\n\t\t\t\t\t<button type=\"button\" ng-click=\"onSelectPackage(package)\" ng-disabled=\"isSelected()\">Add &gt;</button>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div ng-show=\"onUnselectPackage\">\r\n\t\t\t\t\t<button type=\"button\" ng-click=\"onUnselectPackage(package)\">&lt; Remove</button>\r\n\t\t\t\t</div>\r\n\t\t\t</td>\r\n\t\t</tr>\r\n\t</table>\r\n</div>";

/***/ }),
/* 74 */
/***/ (function(module, exports) {

module.exports = "<div class=\"package-list\" ng-class=\"{'scrolled': scrolled}\">\r\n\t<package-item ng-repeat=\"p in packages\" \r\n\t\t\t\t  package=\"p\" \r\n\t\t\t\t  on-view-details=\"onViewDetails\" \r\n\t\t\t\t  on-view-versions=\"onViewVersions\"\r\n\t\t\t\t  on-select-package=\"onSelectPackage\"\r\n\t\t\t\t  on-unselect-package=\"onUnselectPackage\",\r\n\t\t\t\t  selected-packages=\"selectedPackages\"></package-item>\r\n\t<div class=\"empty-notice\" ng-show=\"!showSpinner && packages.length == 0\">\r\n\t\t<span ng-bind=\"emptyPhrase\"></span>\r\n\t</div>\r\n\t<spinner ng-show=\"showSpinner\"></spinner>\r\n</div>";

/***/ }),
/* 75 */
/***/ (function(module, exports) {

module.exports = "<div class=\"packages-pane\">\r\n\t<search-input ng-show=\"showSearch\" on-search=\"searchPackages\"></search-input>\r\n\t<div class=\"title\" ng-show=\"title\">\r\n\t\t<div class=\"title-text\">\r\n\t\t\t<span ng-bind=\"title\"></span>\r\n\t\t</div>\r\n\t</div>\r\n\t\r\n\t<package-list ng-show=\"selectedView=='search'\" \r\n\t\t\t\t packages=\"packages\"\r\n\t\t\t\t empty-phrase=\"No Packages Found\"\r\n\t\t\t\t on-view-details=\"viewDetails\" \r\n\t\t\t\t selected-packages=\"selectedPackages\" \r\n\t\t\t\t on-select-package=\"onSelectPackage\"\r\n\t\t\t\t on-need-more=\"fetchMoreSearch\"\r\n\t\t\t\t show-spinner=\"showSpinner\"\r\n\t\t\t\t selected-packages=\"selectedPackages\"></package-list>\r\n\r\n\t<package-list ng-show=\"selectedView=='popular'\" \r\n\t\t\t\t  packages=\"packages\"\r\n\t\t\t\t  empty-phrase=\"No Packages Found\"\r\n\t\t\t\t  on-view-details=\"viewDetails\" \r\n\t\t\t\t  selected-packages=\"selectedPackages\" \r\n\t\t\t\t  on-select-package=\"onSelectPackage\"\r\n\t\t\t\t  on-need-more=\"fetchMorePopular\"\r\n\t\t\t\t  show-spinner=\"showSpinner\"\r\n\t\t\t\t  selected-packages=\"selectedPackages\"></package-list>\r\n\r\n\t<package-list ng-show=\"selectedView=='selected-packages'\"\r\n\t\t\t\t  packages=\"selectedPackages\"\r\n\t\t\t\t  empty-phrase=\"No Packages Selected\" \r\n\t\t\t\t  show-spinner=\"showSpinner\" \r\n\t\t\t\t  on-view-details=\"viewDetails\" \r\n\t\t\t\t  on-unselect-package=\"onUnselectPackage\"\r\n\t\t\t\t  selected-packages=\"selectedPackages\"></package-list>\r\n\r\n\t<details-pane ng-show=\"selectedView=='details'\" \r\n\t\t\t\t  back=\"back\" \r\n\t\t\t\t  package=\"viewPackage\"\r\n\t\t\t\t  on-select-package=\"onSelectPackage\"\r\n\t\t\t\t  on-unselect-package=\"onUnselectPackage\"\r\n\t\t\t\t  selected-packages=\"selectedPackages\"></details-pane>\r\n</div>";

/***/ }),
/* 76 */
/***/ (function(module, exports) {

module.exports = "<div class=\"search-input\">\r\n\t<input type=\"text\" placeholder=\"Search for packages, try 'git' or '.net'\" />\r\n</div>";

/***/ }),
/* 77 */
/***/ (function(module, exports) {

module.exports = "<div class=\"spinner\">\r\n\t<img />\r\n</div>";

/***/ }),
/* 78 */
/***/ (function(module, exports) {

module.exports = "<div class=\"popover tour\" style=\"padding-bottom: 15px;\">\r\n    <div class=\"arrow\"></div>\r\n    <h3 class=\"popover-title\"></h3>\r\n    <a data-role='hide' class=\"close-button\">&times;</a>\r\n    <div class=\"popover-content\"></div>\r\n</div>";

/***/ }),
/* 79 */
/***/ (function(module, exports) {

module.exports = "<div class=\"popover tour\" style=\"padding-bottom: 15px;\">\r\n    <div class=\"arrow\"></div>\r\n    <h3 class=\"popover-title\"></h3>\r\n    <div class=\"popover-content\"></div>\r\n    <span class='popover-navigation' style=\"padding: 10px\">\r\n        <button class='btn btn-default' data-role='end' style=\"margin-right: 15px;\">End tour</button>\r\n    </span>\r\n</div>";

/***/ }),
/* 80 */
/***/ (function(module, exports) {

module.exports = "<div class=\"popover tour\" style=\"padding-bottom: 15px;\">\r\n    <div class=\"arrow\"></div>\r\n    <h3 class=\"popover-title\"></h3>\r\n    <a data-role='hide' class=\"close-button\">&times;</a>\r\n    <div class=\"popover-content\"></div>\r\n    <span class='popover-navigation' style=\"padding: 10px\">\r\n        <button class='btn btn-default' data-role='next'>Next</button>\r\n    </span>\r\n</div>";

/***/ }),
/* 81 */
/***/ (function(module, exports) {

module.exports = "<div class=\"popover tour\" style=\"padding-bottom: 15px;\">\r\n    <div class=\"arrow\"></div>\r\n    <h3 class=\"popover-title\"></h3>\r\n    <div class=\"popover-content\"></div>\r\n    <span class='popover-navigation' style=\"padding: 10px\">\r\n        <button class='btn btn-default' data-role='next'>Next</button>\r\n        <button class='btn btn-link' data-role='end' style=\"margin-right: 15px;\">End tour</button>\r\n    </span>\r\n</div>";

/***/ }),
/* 82 */
/***/ (function(module, exports) {

module.exports = "<div class=\"popover tour\" style=\"padding-bottom: 15px;\">\r\n    <div class=\"arrow\"></div>\r\n    <h3 class=\"popover-title\"></h3>\r\n    <div class=\"popover-content\"></div>\r\n</div>";

/***/ }),
/* 83 */
/***/ (function(module, exports) {

module.exports = "<div class=\"cs-image-flow-modal\">\r\n    <div class=\"modal-backdrop\"></div>\r\n    <div class=\"modal-container\">\r\n        <div class=\"flow-modal-header\">\r\n        </div>\r\n        <div class=\"flow-modal-image-container\">\r\n        </div>\r\n    </div>\r\n</div>";

/***/ }),
/* 84 */
/***/ (function(module, exports) {

module.exports = "<div class=\"popover tour\" style=\"padding-bottom: 15px;\">\r\n    <div class=\"arrow\"></div>\r\n    <h3 class=\"popover-title\"></h3>\r\n    <div class=\"popover-content\"></div>\r\n    <span class='popover-navigation' style=\"padding: 10px\">\r\n        <button class='btn btn-default' data-role='end' style=\"margin-right: 15px;\">Got It!</button>\r\n    </span>\r\n</div>";

/***/ }),
/* 85 */
/***/ (function(module, exports) {

module.exports = "<div class=\"popover tour\" style=\"padding-bottom: 15px;\">\r\n    <div class=\"arrow\"></div>\r\n    <h3 class=\"popover-title\"></h3>\r\n    <div class=\"popover-content\"></div>\r\n    <span class='popover-navigation' style=\"padding: 10px\">\r\n        <button class='btn btn-default' data-role='end' style=\"float: none;\">Got It!</button>\r\n        <button class='btn btn-default' data-role='next' style=\"float: right; margin-right: 15px;\">Next</button>\r\n    </span>\r\n</div>";

/***/ }),
/* 86 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = CollectingHandler;

function CollectingHandler(cbs){
	this._cbs = cbs || {};
	this.events = [];
}

var EVENTS = __webpack_require__(10).EVENTS;
Object.keys(EVENTS).forEach(function(name){
	if(EVENTS[name] === 0){
		name = "on" + name;
		CollectingHandler.prototype[name] = function(){
			this.events.push([name]);
			if(this._cbs[name]) this._cbs[name]();
		};
	} else if(EVENTS[name] === 1){
		name = "on" + name;
		CollectingHandler.prototype[name] = function(a){
			this.events.push([name, a]);
			if(this._cbs[name]) this._cbs[name](a);
		};
	} else if(EVENTS[name] === 2){
		name = "on" + name;
		CollectingHandler.prototype[name] = function(a, b){
			this.events.push([name, a, b]);
			if(this._cbs[name]) this._cbs[name](a, b);
		};
	} else {
		throw Error("wrong number of arguments");
	}
});

CollectingHandler.prototype.onreset = function(){
	this.events = [];
	if(this._cbs.onreset) this._cbs.onreset();
};

CollectingHandler.prototype.restart = function(){
	if(this._cbs.onreset) this._cbs.onreset();

	for(var i = 0, len = this.events.length; i < len; i++){
		if(this._cbs[this.events[i][0]]){

			var num = this.events[i].length;

			if(num === 1){
				this._cbs[this.events[i][0]]();
			} else if(num === 2){
				this._cbs[this.events[i][0]](this.events[i][1]);
			} else {
				this._cbs[this.events[i][0]](this.events[i][1], this.events[i][2]);
			}
		}
	}
};


/***/ }),
/* 87 */
/***/ (function(module, exports, __webpack_require__) {

var index = __webpack_require__(10),
    DomHandler = index.DomHandler,
    DomUtils = index.DomUtils;

//TODO: make this a streamable handler
function FeedHandler(callback, options){
	this.init(callback, options);
}

__webpack_require__(1)(FeedHandler, DomHandler);

FeedHandler.prototype.init = DomHandler;

function getElements(what, where){
	return DomUtils.getElementsByTagName(what, where, true);
}
function getOneElement(what, where){
	return DomUtils.getElementsByTagName(what, where, true, 1)[0];
}
function fetch(what, where, recurse){
	return DomUtils.getText(
		DomUtils.getElementsByTagName(what, where, recurse, 1)
	).trim();
}

function addConditionally(obj, prop, what, where, recurse){
	var tmp = fetch(what, where, recurse);
	if(tmp) obj[prop] = tmp;
}

var isValidFeed = function(value){
	return value === "rss" || value === "feed" || value === "rdf:RDF";
};

FeedHandler.prototype.onend = function(){
	var feed = {},
	    feedRoot = getOneElement(isValidFeed, this.dom),
	    tmp, childs;

	if(feedRoot){
		if(feedRoot.name === "feed"){
			childs = feedRoot.children;

			feed.type = "atom";
			addConditionally(feed, "id", "id", childs);
			addConditionally(feed, "title", "title", childs);
			if((tmp = getOneElement("link", childs)) && (tmp = tmp.attribs) && (tmp = tmp.href)) feed.link = tmp;
			addConditionally(feed, "description", "subtitle", childs);
			if((tmp = fetch("updated", childs))) feed.updated = new Date(tmp);
			addConditionally(feed, "author", "email", childs, true);

			feed.items = getElements("entry", childs).map(function(item){
				var entry = {}, tmp;

				item = item.children;

				addConditionally(entry, "id", "id", item);
				addConditionally(entry, "title", "title", item);
				if((tmp = getOneElement("link", item)) && (tmp = tmp.attribs) && (tmp = tmp.href)) entry.link = tmp;
				if((tmp = fetch("summary", item) || fetch("content", item))) entry.description = tmp;
				if((tmp = fetch("updated", item))) entry.pubDate = new Date(tmp);
				return entry;
			});
		} else {
			childs = getOneElement("channel", feedRoot.children).children;

			feed.type = feedRoot.name.substr(0, 3);
			feed.id = "";
			addConditionally(feed, "title", "title", childs);
			addConditionally(feed, "link", "link", childs);
			addConditionally(feed, "description", "description", childs);
			if((tmp = fetch("lastBuildDate", childs))) feed.updated = new Date(tmp);
			addConditionally(feed, "author", "managingEditor", childs, true);

			feed.items = getElements("item", feedRoot.children).map(function(item){
				var entry = {}, tmp;

				item = item.children;

				addConditionally(entry, "id", "guid", item);
				addConditionally(entry, "title", "title", item);
				addConditionally(entry, "link", "link", item);
				addConditionally(entry, "description", "description", item);
				if((tmp = fetch("pubDate", item))) entry.pubDate = new Date(tmp);
				return entry;
			});
		}
	}
	this.dom = feed;
	DomHandler.prototype._handleCallback.call(
		this, feedRoot ? null : Error("couldn't find root of feed")
	);
};

module.exports = FeedHandler;


/***/ }),
/* 88 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = ProxyHandler;

function ProxyHandler(cbs){
	this._cbs = cbs || {};
}

var EVENTS = __webpack_require__(10).EVENTS;
Object.keys(EVENTS).forEach(function(name){
	if(EVENTS[name] === 0){
		name = "on" + name;
		ProxyHandler.prototype[name] = function(){
			if(this._cbs[name]) this._cbs[name]();
		};
	} else if(EVENTS[name] === 1){
		name = "on" + name;
		ProxyHandler.prototype[name] = function(a){
			if(this._cbs[name]) this._cbs[name](a);
		};
	} else if(EVENTS[name] === 2){
		name = "on" + name;
		ProxyHandler.prototype[name] = function(a, b){
			if(this._cbs[name]) this._cbs[name](a, b);
		};
	} else {
		throw Error("wrong number of arguments");
	}
});

/***/ }),
/* 89 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = Stream;

var Parser = __webpack_require__(32);

function Stream(options){
	Parser.call(this, new Cbs(this), options);
}

__webpack_require__(1)(Stream, Parser);

Stream.prototype.readable = true;

function Cbs(scope){
	this.scope = scope;
}

var EVENTS = __webpack_require__(10).EVENTS;

Object.keys(EVENTS).forEach(function(name){
	if(EVENTS[name] === 0){
		Cbs.prototype["on" + name] = function(){
			this.scope.emit(name);
		};
	} else if(EVENTS[name] === 1){
		Cbs.prototype["on" + name] = function(a){
			this.scope.emit(name, a);
		};
	} else if(EVENTS[name] === 2){
		Cbs.prototype["on" + name] = function(a, b){
			this.scope.emit(name, a, b);
		};
	} else {
		throw Error("wrong number of arguments!");
	}
});

/***/ }),
/* 90 */
/***/ (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
}


/***/ }),
/* 91 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
var __WEBPACK_AMD_DEFINE_RESULT__;/*
 A JavaScript implementation of the SHA family of hashes, as
 defined in FIPS PUB 180-2 as well as the corresponding HMAC implementation
 as defined in FIPS PUB 198a

 Copyright Brian Turek 2008-2016
 Distributed under the BSD License
 See http://caligatio.github.com/jsSHA/ for more information

 Several functions taken from Paul Johnston
*/
(function(V){function A(a,b,c){var e=0,f=[0],k="",h=null,k=c||"UTF8";if("UTF8"!==k&&"UTF16BE"!==k&&"UTF16LE"!==k)throw"encoding must be UTF8, UTF16BE, or UTF16LE";if("HEX"===b){if(0!==a.length%2)throw"srcString of HEX type must be in byte increments";h=E(a);e=h.binLen;f=h.value}else if("TEXT"===b||"ASCII"===b)h=M(a,k),e=h.binLen,f=h.value;else if("B64"===b)h=N(a),e=h.binLen,f=h.value;else if("BYTES"===b)h=O(a),e=h.binLen,f=h.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES";
this.getHash=function(a,b,c,k){var h=null,d=f.slice(),n=e,m;3===arguments.length?"number"!==typeof c&&(k=c,c=1):2===arguments.length&&(c=1);if(c!==parseInt(c,10)||1>c)throw"numRounds must a integer >= 1";switch(b){case "HEX":h=P;break;case "B64":h=Q;break;case "BYTES":h=R;break;default:throw"format must be HEX, B64, or BYTES";}if("SHA-1"===a)for(m=0;m<c;m+=1)d=B(d,n),n=160;else if("SHA-224"===a)for(m=0;m<c;m+=1)d=x(d,n,a),n=224;else if("SHA-256"===a)for(m=0;m<c;m+=1)d=x(d,n,a),n=256;else if("SHA-384"===
a)for(m=0;m<c;m+=1)d=x(d,n,a),n=384;else if("SHA-512"===a)for(m=0;m<c;m+=1)d=x(d,n,a),n=512;else throw"Chosen SHA variant is not supported";return h(d,S(k))};this.getHMAC=function(a,b,c,h,q){var d,n,m,u,r=[],v=[];d=null;switch(h){case "HEX":h=P;break;case "B64":h=Q;break;case "BYTES":h=R;break;default:throw"outputFormat must be HEX, B64, or BYTES";}if("SHA-1"===c)n=64,u=160;else if("SHA-224"===c)n=64,u=224;else if("SHA-256"===c)n=64,u=256;else if("SHA-384"===c)n=128,u=384;else if("SHA-512"===c)n=
128,u=512;else throw"Chosen SHA variant is not supported";if("HEX"===b)d=E(a),m=d.binLen,d=d.value;else if("TEXT"===b||"ASCII"===b)d=M(a,k),m=d.binLen,d=d.value;else if("B64"===b)d=N(a),m=d.binLen,d=d.value;else if("BYTES"===b)d=O(a),m=d.binLen,d=d.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES";a=8*n;b=n/4-1;if(n<m/8){for(d="SHA-1"===c?B(d,m):x(d,m,c);d.length<=b;)d.push(0);d[b]&=4294967040}else if(n>m/8){for(;d.length<=b;)d.push(0);d[b]&=4294967040}for(n=0;n<=b;n+=1)r[n]=d[n]^
909522486,v[n]=d[n]^1549556828;c="SHA-1"===c?B(v.concat(B(r.concat(f),a+e)),a+u):x(v.concat(x(r.concat(f),a+e,c)),a+u,c);return h(c,S(q))}}function q(a,b){this.a=a;this.b=b}function M(a,b){var c=[],e,f=[],k=0,h,p,q;if("UTF8"===b)for(h=0;h<a.length;h+=1)for(e=a.charCodeAt(h),f=[],128>e?f.push(e):2048>e?(f.push(192|e>>>6),f.push(128|e&63)):55296>e||57344<=e?f.push(224|e>>>12,128|e>>>6&63,128|e&63):(h+=1,e=65536+((e&1023)<<10|a.charCodeAt(h)&1023),f.push(240|e>>>18,128|e>>>12&63,128|e>>>6&63,128|e&63)),
p=0;p<f.length;p+=1){for(q=k>>>2;c.length<=q;)c.push(0);c[q]|=f[p]<<24-k%4*8;k+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(h=0;h<a.length;h+=1){e=a.charCodeAt(h);"UTF16LE"===b&&(p=e&255,e=p<<8|e>>8);for(q=k>>>2;c.length<=q;)c.push(0);c[q]|=e<<16-k%4*8;k+=2}return{value:c,binLen:8*k}}function E(a){var b=[],c=a.length,e,f,k;if(0!==c%2)throw"String of HEX type must be in byte increments";for(e=0;e<c;e+=2){f=parseInt(a.substr(e,2),16);if(isNaN(f))throw"String of HEX type contains invalid characters";
for(k=e>>>3;b.length<=k;)b.push(0);b[e>>>3]|=f<<24-e%8*4}return{value:b,binLen:4*c}}function O(a){var b=[],c,e,f;for(e=0;e<a.length;e+=1)c=a.charCodeAt(e),f=e>>>2,b.length<=f&&b.push(0),b[f]|=c<<24-e%4*8;return{value:b,binLen:8*a.length}}function N(a){var b=[],c=0,e,f,k,h,p;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw"Invalid character in base-64 string";f=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==f&&f<a.length)throw"Invalid '=' found in base-64 string";for(f=0;f<a.length;f+=4){p=a.substr(f,4);
for(k=h=0;k<p.length;k+=1)e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(p[k]),h|=e<<18-6*k;for(k=0;k<p.length-1;k+=1){for(e=c>>>2;b.length<=e;)b.push(0);b[e]|=(h>>>16-8*k&255)<<24-c%4*8;c+=1}}return{value:b,binLen:8*c}}function P(a,b){var c="",e=4*a.length,f,k;for(f=0;f<e;f+=1)k=a[f>>>2]>>>8*(3-f%4),c+="0123456789abcdef".charAt(k>>>4&15)+"0123456789abcdef".charAt(k&15);return b.outputUpper?c.toUpperCase():c}function Q(a,b){var c="",e=4*a.length,f,k,h;for(f=0;f<e;f+=
3)for(h=f+1>>>2,k=a.length<=h?0:a[h],h=f+2>>>2,h=a.length<=h?0:a[h],h=(a[f>>>2]>>>8*(3-f%4)&255)<<16|(k>>>8*(3-(f+1)%4)&255)<<8|h>>>8*(3-(f+2)%4)&255,k=0;4>k;k+=1)8*f+6*k<=32*a.length?c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(h>>>6*(3-k)&63):c+=b.b64Pad;return c}function R(a){var b="",c=4*a.length,e,f;for(e=0;e<c;e+=1)f=a[e>>>2]>>>8*(3-e%4)&255,b+=String.fromCharCode(f);return b}function S(a){var b={outputUpper:!1,b64Pad:"="};try{a.hasOwnProperty("outputUpper")&&
(b.outputUpper=a.outputUpper),a.hasOwnProperty("b64Pad")&&(b.b64Pad=a.b64Pad)}catch(c){}if("boolean"!==typeof b.outputUpper)throw"Invalid outputUpper formatting option";if("string"!==typeof b.b64Pad)throw"Invalid b64Pad formatting option";return b}function y(a,b){return a<<b|a>>>32-b}function r(a,b){return a>>>b|a<<32-b}function v(a,b){var c=null,c=new q(a.a,a.b);return c=32>=b?new q(c.a>>>b|c.b<<32-b&4294967295,c.b>>>b|c.a<<32-b&4294967295):new q(c.b>>>b-32|c.a<<64-b&4294967295,c.a>>>b-32|c.b<<64-
b&4294967295)}function T(a,b){var c=null;return c=32>=b?new q(a.a>>>b,a.b>>>b|a.a<<32-b&4294967295):new q(0,a.a>>>b-32)}function W(a,b,c){return a&b^~a&c}function X(a,b,c){return new q(a.a&b.a^~a.a&c.a,a.b&b.b^~a.b&c.b)}function U(a,b,c){return a&b^a&c^b&c}function Y(a,b,c){return new q(a.a&b.a^a.a&c.a^b.a&c.a,a.b&b.b^a.b&c.b^b.b&c.b)}function Z(a){return r(a,2)^r(a,13)^r(a,22)}function aa(a){var b=v(a,28),c=v(a,34);a=v(a,39);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function ba(a){return r(a,6)^r(a,
11)^r(a,25)}function ca(a){var b=v(a,14),c=v(a,18);a=v(a,41);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function da(a){return r(a,7)^r(a,18)^a>>>3}function ea(a){var b=v(a,1),c=v(a,8);a=T(a,7);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function fa(a){return r(a,17)^r(a,19)^a>>>10}function ga(a){var b=v(a,19),c=v(a,61);a=T(a,6);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function D(a,b){var c=(a&65535)+(b&65535);return((a>>>16)+(b>>>16)+(c>>>16)&65535)<<16|c&65535}function ha(a,b,c,e){var f=(a&65535)+(b&65535)+(c&
65535)+(e&65535);return((a>>>16)+(b>>>16)+(c>>>16)+(e>>>16)+(f>>>16)&65535)<<16|f&65535}function F(a,b,c,e,f){var k=(a&65535)+(b&65535)+(c&65535)+(e&65535)+(f&65535);return((a>>>16)+(b>>>16)+(c>>>16)+(e>>>16)+(f>>>16)+(k>>>16)&65535)<<16|k&65535}function ia(a,b){var c,e,f;c=(a.b&65535)+(b.b&65535);e=(a.b>>>16)+(b.b>>>16)+(c>>>16);f=(e&65535)<<16|c&65535;c=(a.a&65535)+(b.a&65535)+(e>>>16);e=(a.a>>>16)+(b.a>>>16)+(c>>>16);return new q((e&65535)<<16|c&65535,f)}function ja(a,b,c,e){var f,k,h;f=(a.b&65535)+
(b.b&65535)+(c.b&65535)+(e.b&65535);k=(a.b>>>16)+(b.b>>>16)+(c.b>>>16)+(e.b>>>16)+(f>>>16);h=(k&65535)<<16|f&65535;f=(a.a&65535)+(b.a&65535)+(c.a&65535)+(e.a&65535)+(k>>>16);k=(a.a>>>16)+(b.a>>>16)+(c.a>>>16)+(e.a>>>16)+(f>>>16);return new q((k&65535)<<16|f&65535,h)}function ka(a,b,c,e,f){var k,h,p;k=(a.b&65535)+(b.b&65535)+(c.b&65535)+(e.b&65535)+(f.b&65535);h=(a.b>>>16)+(b.b>>>16)+(c.b>>>16)+(e.b>>>16)+(f.b>>>16)+(k>>>16);p=(h&65535)<<16|k&65535;k=(a.a&65535)+(b.a&65535)+(c.a&65535)+(e.a&65535)+
(f.a&65535)+(h>>>16);h=(a.a>>>16)+(b.a>>>16)+(c.a>>>16)+(e.a>>>16)+(f.a>>>16)+(k>>>16);return new q((h&65535)<<16|k&65535,p)}function B(a,b){var c=[],e,f,k,h,p,q,r,t,v,d=[1732584193,4023233417,2562383102,271733878,3285377520];for(e=(b+65>>>9<<4)+15;a.length<=e;)a.push(0);a[b>>>5]|=128<<24-b%32;a[e]=b&4294967295;a[e-1]=b/4294967296|0;v=a.length;for(r=0;r<v;r+=16){e=d[0];f=d[1];k=d[2];h=d[3];p=d[4];for(t=0;80>t;t+=1)c[t]=16>t?a[t+r]:y(c[t-3]^c[t-8]^c[t-14]^c[t-16],1),q=20>t?F(y(e,5),f&k^~f&h,p,1518500249,
c[t]):40>t?F(y(e,5),f^k^h,p,1859775393,c[t]):60>t?F(y(e,5),U(f,k,h),p,2400959708,c[t]):F(y(e,5),f^k^h,p,3395469782,c[t]),p=h,h=k,k=y(f,30),f=e,e=q;d[0]=D(e,d[0]);d[1]=D(f,d[1]);d[2]=D(k,d[2]);d[3]=D(h,d[3]);d[4]=D(p,d[4])}return d}function x(a,b,c){var e,f,k,h,p,r,v,t,z,d,n,m,u,x,y,w,A,B,G,H,I,J,K,L,g,C=[],E,l=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,
264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];d=[3238371032,
914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428];f=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];if("SHA-224"===c||"SHA-256"===c)n=64,e=(b+65>>>9<<4)+15,x=16,y=1,g=Number,w=D,A=ha,B=F,G=da,H=fa,I=Z,J=ba,L=U,K=W,d="SHA-224"===c?d:f;else if("SHA-384"===c||"SHA-512"===c)n=80,e=(b+129>>>10<<5)+31,x=32,y=2,g=q,w=ia,A=ja,B=ka,G=ea,H=ga,I=aa,J=ca,L=Y,K=X,l=[new g(l[0],3609767458),new g(l[1],602891725),new g(l[2],3964484399),new g(l[3],
2173295548),new g(l[4],4081628472),new g(l[5],3053834265),new g(l[6],2937671579),new g(l[7],3664609560),new g(l[8],2734883394),new g(l[9],1164996542),new g(l[10],1323610764),new g(l[11],3590304994),new g(l[12],4068182383),new g(l[13],991336113),new g(l[14],633803317),new g(l[15],3479774868),new g(l[16],2666613458),new g(l[17],944711139),new g(l[18],2341262773),new g(l[19],2007800933),new g(l[20],1495990901),new g(l[21],1856431235),new g(l[22],3175218132),new g(l[23],2198950837),new g(l[24],3999719339),
new g(l[25],766784016),new g(l[26],2566594879),new g(l[27],3203337956),new g(l[28],1034457026),new g(l[29],2466948901),new g(l[30],3758326383),new g(l[31],168717936),new g(l[32],1188179964),new g(l[33],1546045734),new g(l[34],1522805485),new g(l[35],2643833823),new g(l[36],2343527390),new g(l[37],1014477480),new g(l[38],1206759142),new g(l[39],344077627),new g(l[40],1290863460),new g(l[41],3158454273),new g(l[42],3505952657),new g(l[43],106217008),new g(l[44],3606008344),new g(l[45],1432725776),new g(l[46],
1467031594),new g(l[47],851169720),new g(l[48],3100823752),new g(l[49],1363258195),new g(l[50],3750685593),new g(l[51],3785050280),new g(l[52],3318307427),new g(l[53],3812723403),new g(l[54],2003034995),new g(l[55],3602036899),new g(l[56],1575990012),new g(l[57],1125592928),new g(l[58],2716904306),new g(l[59],442776044),new g(l[60],593698344),new g(l[61],3733110249),new g(l[62],2999351573),new g(l[63],3815920427),new g(3391569614,3928383900),new g(3515267271,566280711),new g(3940187606,3454069534),
new g(4118630271,4000239992),new g(116418474,1914138554),new g(174292421,2731055270),new g(289380356,3203993006),new g(460393269,320620315),new g(685471733,587496836),new g(852142971,1086792851),new g(1017036298,365543100),new g(1126000580,2618297676),new g(1288033470,3409855158),new g(1501505948,4234509866),new g(1607167915,987167468),new g(1816402316,1246189591)],d="SHA-384"===c?[new g(3418070365,d[0]),new g(1654270250,d[1]),new g(2438529370,d[2]),new g(355462360,d[3]),new g(1731405415,d[4]),new g(41048885895,
d[5]),new g(3675008525,d[6]),new g(1203062813,d[7])]:[new g(f[0],4089235720),new g(f[1],2227873595),new g(f[2],4271175723),new g(f[3],1595750129),new g(f[4],2917565137),new g(f[5],725511199),new g(f[6],4215389547),new g(f[7],327033209)];else throw"Unexpected error in SHA-2 implementation";for(;a.length<=e;)a.push(0);a[b>>>5]|=128<<24-b%32;a[e]=b&4294967295;a[e-1]=b/4294967296|0;E=a.length;for(m=0;m<E;m+=x){b=d[0];e=d[1];f=d[2];k=d[3];h=d[4];p=d[5];r=d[6];v=d[7];for(u=0;u<n;u+=1)16>u?(z=u*y+m,t=a.length<=
z?0:a[z],z=a.length<=z+1?0:a[z+1],C[u]=new g(t,z)):C[u]=A(H(C[u-2]),C[u-7],G(C[u-15]),C[u-16]),t=B(v,J(h),K(h,p,r),l[u],C[u]),z=w(I(b),L(b,e,f)),v=r,r=p,p=h,h=w(k,t),k=f,f=e,e=b,b=w(t,z);d[0]=w(b,d[0]);d[1]=w(e,d[1]);d[2]=w(f,d[2]);d[3]=w(k,d[3]);d[4]=w(h,d[4]);d[5]=w(p,d[5]);d[6]=w(r,d[6]);d[7]=w(v,d[7])}if("SHA-224"===c)a=[d[0],d[1],d[2],d[3],d[4],d[5],d[6]];else if("SHA-256"===c)a=d;else if("SHA-384"===c)a=[d[0].a,d[0].b,d[1].a,d[1].b,d[2].a,d[2].b,d[3].a,d[3].b,d[4].a,d[4].b,d[5].a,d[5].b];else if("SHA-512"===
c)a=[d[0].a,d[0].b,d[1].a,d[1].b,d[2].a,d[2].b,d[3].a,d[3].b,d[4].a,d[4].b,d[5].a,d[5].b,d[6].a,d[6].b,d[7].a,d[7].b];else throw"Unexpected error in SHA-2 implementation";return a} true?!(__WEBPACK_AMD_DEFINE_RESULT__ = function(){return A}.call(exports, __webpack_require__, exports, module),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=A:exports=A:V.jsSHA=A})(this);


/***/ }),
/* 92 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {/**
 * marked - a markdown parser
 * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
 * https://github.com/chjj/marked
 */

;(function() {

/**
 * Block-Level Grammar
 */

var block = {
  newline: /^\n+/,
  code: /^( {4}[^\n]+\n*)+/,
  fences: noop,
  hr: /^( *[-*_]){3,} *(?:\n+|$)/,
  heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
  nptable: noop,
  lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
  blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
  list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
  html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
  def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
  table: noop,
  paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
  text: /^[^\n]+/
};

block.bullet = /(?:[*+-]|\d+\.)/;
block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
block.item = replace(block.item, 'gm')
  (/bull/g, block.bullet)
  ();

block.list = replace(block.list)
  (/bull/g, block.bullet)
  ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
  ('def', '\\n+(?=' + block.def.source + ')')
  ();

block.blockquote = replace(block.blockquote)
  ('def', block.def)
  ();

block._tag = '(?!(?:'
  + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
  + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
  + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';

block.html = replace(block.html)
  ('comment', /<!--[\s\S]*?-->/)
  ('closed', /<(tag)[\s\S]+?<\/\1>/)
  ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
  (/tag/g, block._tag)
  ();

block.paragraph = replace(block.paragraph)
  ('hr', block.hr)
  ('heading', block.heading)
  ('lheading', block.lheading)
  ('blockquote', block.blockquote)
  ('tag', '<' + block._tag)
  ('def', block.def)
  ();

/**
 * Normal Block Grammar
 */

block.normal = merge({}, block);

/**
 * GFM Block Grammar
 */

block.gfm = merge({}, block.normal, {
  fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
  paragraph: /^/,
  heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
});

block.gfm.paragraph = replace(block.paragraph)
  ('(?!', '(?!'
    + block.gfm.fences.source.replace('\\1', '\\2') + '|'
    + block.list.source.replace('\\1', '\\3') + '|')
  ();

/**
 * GFM + Tables Block Grammar
 */

block.tables = merge({}, block.gfm, {
  nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
  table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
});

/**
 * Block Lexer
 */

function Lexer(options) {
  this.tokens = [];
  this.tokens.links = {};
  this.options = options || marked.defaults;
  this.rules = block.normal;

  if (this.options.gfm) {
    if (this.options.tables) {
      this.rules = block.tables;
    } else {
      this.rules = block.gfm;
    }
  }
}

/**
 * Expose Block Rules
 */

Lexer.rules = block;

/**
 * Static Lex Method
 */

Lexer.lex = function(src, options) {
  var lexer = new Lexer(options);
  return lexer.lex(src);
};

/**
 * Preprocessing
 */

Lexer.prototype.lex = function(src) {
  src = src
    .replace(/\r\n|\r/g, '\n')
    .replace(/\t/g, '    ')
    .replace(/\u00a0/g, ' ')
    .replace(/\u2424/g, '\n');

  return this.token(src, true);
};

/**
 * Lexing
 */

Lexer.prototype.token = function(src, top, bq) {
  var src = src.replace(/^ +$/gm, '')
    , next
    , loose
    , cap
    , bull
    , b
    , item
    , space
    , i
    , l;

  while (src) {
    // newline
    if (cap = this.rules.newline.exec(src)) {
      src = src.substring(cap[0].length);
      if (cap[0].length > 1) {
        this.tokens.push({
          type: 'space'
        });
      }
    }

    // code
    if (cap = this.rules.code.exec(src)) {
      src = src.substring(cap[0].length);
      cap = cap[0].replace(/^ {4}/gm, '');
      this.tokens.push({
        type: 'code',
        text: !this.options.pedantic
          ? cap.replace(/\n+$/, '')
          : cap
      });
      continue;
    }

    // fences (gfm)
    if (cap = this.rules.fences.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'code',
        lang: cap[2],
        text: cap[3] || ''
      });
      continue;
    }

    // heading
    if (cap = this.rules.heading.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'heading',
        depth: cap[1].length,
        text: cap[2]
      });
      continue;
    }

    // table no leading pipe (gfm)
    if (top && (cap = this.rules.nptable.exec(src))) {
      src = src.substring(cap[0].length);

      item = {
        type: 'table',
        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
        cells: cap[3].replace(/\n$/, '').split('\n')
      };

      for (i = 0; i < item.align.length; i++) {
        if (/^ *-+: *$/.test(item.align[i])) {
          item.align[i] = 'right';
        } else if (/^ *:-+: *$/.test(item.align[i])) {
          item.align[i] = 'center';
        } else if (/^ *:-+ *$/.test(item.align[i])) {
          item.align[i] = 'left';
        } else {
          item.align[i] = null;
        }
      }

      for (i = 0; i < item.cells.length; i++) {
        item.cells[i] = item.cells[i].split(/ *\| */);
      }

      this.tokens.push(item);

      continue;
    }

    // lheading
    if (cap = this.rules.lheading.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'heading',
        depth: cap[2] === '=' ? 1 : 2,
        text: cap[1]
      });
      continue;
    }

    // hr
    if (cap = this.rules.hr.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'hr'
      });
      continue;
    }

    // blockquote
    if (cap = this.rules.blockquote.exec(src)) {
      src = src.substring(cap[0].length);

      this.tokens.push({
        type: 'blockquote_start'
      });

      cap = cap[0].replace(/^ *> ?/gm, '');

      // Pass `top` to keep the current
      // "toplevel" state. This is exactly
      // how markdown.pl works.
      this.token(cap, top, true);

      this.tokens.push({
        type: 'blockquote_end'
      });

      continue;
    }

    // list
    if (cap = this.rules.list.exec(src)) {
      src = src.substring(cap[0].length);
      bull = cap[2];

      this.tokens.push({
        type: 'list_start',
        ordered: bull.length > 1
      });

      // Get each top-level item.
      cap = cap[0].match(this.rules.item);

      next = false;
      l = cap.length;
      i = 0;

      for (; i < l; i++) {
        item = cap[i];

        // Remove the list item's bullet
        // so it is seen as the next token.
        space = item.length;
        item = item.replace(/^ *([*+-]|\d+\.) +/, '');

        // Outdent whatever the
        // list item contains. Hacky.
        if (~item.indexOf('\n ')) {
          space -= item.length;
          item = !this.options.pedantic
            ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
            : item.replace(/^ {1,4}/gm, '');
        }

        // Determine whether the next list item belongs here.
        // Backpedal if it does not belong in this list.
        if (this.options.smartLists && i !== l - 1) {
          b = block.bullet.exec(cap[i + 1])[0];
          if (bull !== b && !(bull.length > 1 && b.length > 1)) {
            src = cap.slice(i + 1).join('\n') + src;
            i = l - 1;
          }
        }

        // Determine whether item is loose or not.
        // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
        // for discount behavior.
        loose = next || /\n\n(?!\s*$)/.test(item);
        if (i !== l - 1) {
          next = item.charAt(item.length - 1) === '\n';
          if (!loose) loose = next;
        }

        this.tokens.push({
          type: loose
            ? 'loose_item_start'
            : 'list_item_start'
        });

        // Recurse.
        this.token(item, false, bq);

        this.tokens.push({
          type: 'list_item_end'
        });
      }

      this.tokens.push({
        type: 'list_end'
      });

      continue;
    }

    // html
    if (cap = this.rules.html.exec(src)) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: this.options.sanitize
          ? 'paragraph'
          : 'html',
        pre: !this.options.sanitizer
          && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
        text: cap[0]
      });
      continue;
    }

    // def
    if ((!bq && top) && (cap = this.rules.def.exec(src))) {
      src = src.substring(cap[0].length);
      this.tokens.links[cap[1].toLowerCase()] = {
        href: cap[2],
        title: cap[3]
      };
      continue;
    }

    // table (gfm)
    if (top && (cap = this.rules.table.exec(src))) {
      src = src.substring(cap[0].length);

      item = {
        type: 'table',
        header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
        align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
        cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
      };

      for (i = 0; i < item.align.length; i++) {
        if (/^ *-+: *$/.test(item.align[i])) {
          item.align[i] = 'right';
        } else if (/^ *:-+: *$/.test(item.align[i])) {
          item.align[i] = 'center';
        } else if (/^ *:-+ *$/.test(item.align[i])) {
          item.align[i] = 'left';
        } else {
          item.align[i] = null;
        }
      }

      for (i = 0; i < item.cells.length; i++) {
        item.cells[i] = item.cells[i]
          .replace(/^ *\| *| *\| *$/g, '')
          .split(/ *\| */);
      }

      this.tokens.push(item);

      continue;
    }

    // top-level paragraph
    if (top && (cap = this.rules.paragraph.exec(src))) {
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'paragraph',
        text: cap[1].charAt(cap[1].length - 1) === '\n'
          ? cap[1].slice(0, -1)
          : cap[1]
      });
      continue;
    }

    // text
    if (cap = this.rules.text.exec(src)) {
      // Top-level should never reach here.
      src = src.substring(cap[0].length);
      this.tokens.push({
        type: 'text',
        text: cap[0]
      });
      continue;
    }

    if (src) {
      throw new
        Error('Infinite loop on byte: ' + src.charCodeAt(0));
    }
  }

  return this.tokens;
};

/**
 * Inline-Level Grammar
 */

var inline = {
  escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
  autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
  url: noop,
  tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
  link: /^!?\[(inside)\]\(href\)/,
  reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
  nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
  strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
  em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
  code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
  br: /^ {2,}\n(?!\s*$)/,
  del: noop,
  text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
};

inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;

inline.link = replace(inline.link)
  ('inside', inline._inside)
  ('href', inline._href)
  ();

inline.reflink = replace(inline.reflink)
  ('inside', inline._inside)
  ();

/**
 * Normal Inline Grammar
 */

inline.normal = merge({}, inline);

/**
 * Pedantic Inline Grammar
 */

inline.pedantic = merge({}, inline.normal, {
  strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
  em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
});

/**
 * GFM Inline Grammar
 */

inline.gfm = merge({}, inline.normal, {
  escape: replace(inline.escape)('])', '~|])')(),
  url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
  del: /^~~(?=\S)([\s\S]*?\S)~~/,
  text: replace(inline.text)
    (']|', '~]|')
    ('|', '|https?://|')
    ()
});

/**
 * GFM + Line Breaks Inline Grammar
 */

inline.breaks = merge({}, inline.gfm, {
  br: replace(inline.br)('{2,}', '*')(),
  text: replace(inline.gfm.text)('{2,}', '*')()
});

/**
 * Inline Lexer & Compiler
 */

function InlineLexer(links, options) {
  this.options = options || marked.defaults;
  this.links = links;
  this.rules = inline.normal;
  this.renderer = this.options.renderer || new Renderer;
  this.renderer.options = this.options;

  if (!this.links) {
    throw new
      Error('Tokens array requires a `links` property.');
  }

  if (this.options.gfm) {
    if (this.options.breaks) {
      this.rules = inline.breaks;
    } else {
      this.rules = inline.gfm;
    }
  } else if (this.options.pedantic) {
    this.rules = inline.pedantic;
  }
}

/**
 * Expose Inline Rules
 */

InlineLexer.rules = inline;

/**
 * Static Lexing/Compiling Method
 */

InlineLexer.output = function(src, links, options) {
  var inline = new InlineLexer(links, options);
  return inline.output(src);
};

/**
 * Lexing/Compiling
 */

InlineLexer.prototype.output = function(src) {
  var out = ''
    , link
    , text
    , href
    , cap;

  while (src) {
    // escape
    if (cap = this.rules.escape.exec(src)) {
      src = src.substring(cap[0].length);
      out += cap[1];
      continue;
    }

    // autolink
    if (cap = this.rules.autolink.exec(src)) {
      src = src.substring(cap[0].length);
      if (cap[2] === '@') {
        text = cap[1].charAt(6) === ':'
          ? this.mangle(cap[1].substring(7))
          : this.mangle(cap[1]);
        href = this.mangle('mailto:') + text;
      } else {
        text = escape(cap[1]);
        href = text;
      }
      out += this.renderer.link(href, null, text);
      continue;
    }

    // url (gfm)
    if (!this.inLink && (cap = this.rules.url.exec(src))) {
      src = src.substring(cap[0].length);
      text = escape(cap[1]);
      href = text;
      out += this.renderer.link(href, null, text);
      continue;
    }

    // tag
    if (cap = this.rules.tag.exec(src)) {
      if (!this.inLink && /^<a /i.test(cap[0])) {
        this.inLink = true;
      } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
        this.inLink = false;
      }
      src = src.substring(cap[0].length);
      out += this.options.sanitize
        ? this.options.sanitizer
          ? this.options.sanitizer(cap[0])
          : escape(cap[0])
        : cap[0]
      continue;
    }

    // link
    if (cap = this.rules.link.exec(src)) {
      src = src.substring(cap[0].length);
      this.inLink = true;
      out += this.outputLink(cap, {
        href: cap[2],
        title: cap[3]
      });
      this.inLink = false;
      continue;
    }

    // reflink, nolink
    if ((cap = this.rules.reflink.exec(src))
        || (cap = this.rules.nolink.exec(src))) {
      src = src.substring(cap[0].length);
      link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
      link = this.links[link.toLowerCase()];
      if (!link || !link.href) {
        out += cap[0].charAt(0);
        src = cap[0].substring(1) + src;
        continue;
      }
      this.inLink = true;
      out += this.outputLink(cap, link);
      this.inLink = false;
      continue;
    }

    // strong
    if (cap = this.rules.strong.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.strong(this.output(cap[2] || cap[1]));
      continue;
    }

    // em
    if (cap = this.rules.em.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.em(this.output(cap[2] || cap[1]));
      continue;
    }

    // code
    if (cap = this.rules.code.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.codespan(escape(cap[2], true));
      continue;
    }

    // br
    if (cap = this.rules.br.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.br();
      continue;
    }

    // del (gfm)
    if (cap = this.rules.del.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.del(this.output(cap[1]));
      continue;
    }

    // text
    if (cap = this.rules.text.exec(src)) {
      src = src.substring(cap[0].length);
      out += this.renderer.text(escape(this.smartypants(cap[0])));
      continue;
    }

    if (src) {
      throw new
        Error('Infinite loop on byte: ' + src.charCodeAt(0));
    }
  }

  return out;
};

/**
 * Compile Link
 */

InlineLexer.prototype.outputLink = function(cap, link) {
  var href = escape(link.href)
    , title = link.title ? escape(link.title) : null;

  return cap[0].charAt(0) !== '!'
    ? this.renderer.link(href, title, this.output(cap[1]))
    : this.renderer.image(href, title, escape(cap[1]));
};

/**
 * Smartypants Transformations
 */

InlineLexer.prototype.smartypants = function(text) {
  if (!this.options.smartypants) return text;
  return text
    // em-dashes
    .replace(/---/g, '\u2014')
    // en-dashes
    .replace(/--/g, '\u2013')
    // opening singles
    .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
    // closing singles & apostrophes
    .replace(/'/g, '\u2019')
    // opening doubles
    .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
    // closing doubles
    .replace(/"/g, '\u201d')
    // ellipses
    .replace(/\.{3}/g, '\u2026');
};

/**
 * Mangle Links
 */

InlineLexer.prototype.mangle = function(text) {
  if (!this.options.mangle) return text;
  var out = ''
    , l = text.length
    , i = 0
    , ch;

  for (; i < l; i++) {
    ch = text.charCodeAt(i);
    if (Math.random() > 0.5) {
      ch = 'x' + ch.toString(16);
    }
    out += '&#' + ch + ';';
  }

  return out;
};

/**
 * Renderer
 */

function Renderer(options) {
  this.options = options || {};
}

Renderer.prototype.code = function(code, lang, escaped) {
  if (this.options.highlight) {
    var out = this.options.highlight(code, lang);
    if (out != null && out !== code) {
      escaped = true;
      code = out;
    }
  }

  if (!lang) {
    return '<pre><code>'
      + (escaped ? code : escape(code, true))
      + '\n</code></pre>';
  }

  return '<pre><code class="'
    + this.options.langPrefix
    + escape(lang, true)
    + '">'
    + (escaped ? code : escape(code, true))
    + '\n</code></pre>\n';
};

Renderer.prototype.blockquote = function(quote) {
  return '<blockquote>\n' + quote + '</blockquote>\n';
};

Renderer.prototype.html = function(html) {
  return html;
};

Renderer.prototype.heading = function(text, level, raw) {
  return '<h'
    + level
    + ' id="'
    + this.options.headerPrefix
    + raw.toLowerCase().replace(/[^\w]+/g, '-')
    + '">'
    + text
    + '</h'
    + level
    + '>\n';
};

Renderer.prototype.hr = function() {
  return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
};

Renderer.prototype.list = function(body, ordered) {
  var type = ordered ? 'ol' : 'ul';
  return '<' + type + '>\n' + body + '</' + type + '>\n';
};

Renderer.prototype.listitem = function(text) {
  return '<li>' + text + '</li>\n';
};

Renderer.prototype.paragraph = function(text) {
  return '<p>' + text + '</p>\n';
};

Renderer.prototype.table = function(header, body) {
  return '<table>\n'
    + '<thead>\n'
    + header
    + '</thead>\n'
    + '<tbody>\n'
    + body
    + '</tbody>\n'
    + '</table>\n';
};

Renderer.prototype.tablerow = function(content) {
  return '<tr>\n' + content + '</tr>\n';
};

Renderer.prototype.tablecell = function(content, flags) {
  var type = flags.header ? 'th' : 'td';
  var tag = flags.align
    ? '<' + type + ' style="text-align:' + flags.align + '">'
    : '<' + type + '>';
  return tag + content + '</' + type + '>\n';
};

// span level renderer
Renderer.prototype.strong = function(text) {
  return '<strong>' + text + '</strong>';
};

Renderer.prototype.em = function(text) {
  return '<em>' + text + '</em>';
};

Renderer.prototype.codespan = function(text) {
  return '<code>' + text + '</code>';
};

Renderer.prototype.br = function() {
  return this.options.xhtml ? '<br/>' : '<br>';
};

Renderer.prototype.del = function(text) {
  return '<del>' + text + '</del>';
};

Renderer.prototype.link = function(href, title, text) {
  if (this.options.sanitize) {
    try {
      var prot = decodeURIComponent(unescape(href))
        .replace(/[^\w:]/g, '')
        .toLowerCase();
    } catch (e) {
      return '';
    }
    if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
      return '';
    }
  }
  var out = '<a href="' + href + '"';
  if (title) {
    out += ' title="' + title + '"';
  }
  out += '>' + text + '</a>';
  return out;
};

Renderer.prototype.image = function(href, title, text) {
  var out = '<img src="' + href + '" alt="' + text + '"';
  if (title) {
    out += ' title="' + title + '"';
  }
  out += this.options.xhtml ? '/>' : '>';
  return out;
};

Renderer.prototype.text = function(text) {
  return text;
};

/**
 * Parsing & Compiling
 */

function Parser(options) {
  this.tokens = [];
  this.token = null;
  this.options = options || marked.defaults;
  this.options.renderer = this.options.renderer || new Renderer;
  this.renderer = this.options.renderer;
  this.renderer.options = this.options;
}

/**
 * Static Parse Method
 */

Parser.parse = function(src, options, renderer) {
  var parser = new Parser(options, renderer);
  return parser.parse(src);
};

/**
 * Parse Loop
 */

Parser.prototype.parse = function(src) {
  this.inline = new InlineLexer(src.links, this.options, this.renderer);
  this.tokens = src.reverse();

  var out = '';
  while (this.next()) {
    out += this.tok();
  }

  return out;
};

/**
 * Next Token
 */

Parser.prototype.next = function() {
  return this.token = this.tokens.pop();
};

/**
 * Preview Next Token
 */

Parser.prototype.peek = function() {
  return this.tokens[this.tokens.length - 1] || 0;
};

/**
 * Parse Text Tokens
 */

Parser.prototype.parseText = function() {
  var body = this.token.text;

  while (this.peek().type === 'text') {
    body += '\n' + this.next().text;
  }

  return this.inline.output(body);
};

/**
 * Parse Current Token
 */

Parser.prototype.tok = function() {
  switch (this.token.type) {
    case 'space': {
      return '';
    }
    case 'hr': {
      return this.renderer.hr();
    }
    case 'heading': {
      return this.renderer.heading(
        this.inline.output(this.token.text),
        this.token.depth,
        this.token.text);
    }
    case 'code': {
      return this.renderer.code(this.token.text,
        this.token.lang,
        this.token.escaped);
    }
    case 'table': {
      var header = ''
        , body = ''
        , i
        , row
        , cell
        , flags
        , j;

      // header
      cell = '';
      for (i = 0; i < this.token.header.length; i++) {
        flags = { header: true, align: this.token.align[i] };
        cell += this.renderer.tablecell(
          this.inline.output(this.token.header[i]),
          { header: true, align: this.token.align[i] }
        );
      }
      header += this.renderer.tablerow(cell);

      for (i = 0; i < this.token.cells.length; i++) {
        row = this.token.cells[i];

        cell = '';
        for (j = 0; j < row.length; j++) {
          cell += this.renderer.tablecell(
            this.inline.output(row[j]),
            { header: false, align: this.token.align[j] }
          );
        }

        body += this.renderer.tablerow(cell);
      }
      return this.renderer.table(header, body);
    }
    case 'blockquote_start': {
      var body = '';

      while (this.next().type !== 'blockquote_end') {
        body += this.tok();
      }

      return this.renderer.blockquote(body);
    }
    case 'list_start': {
      var body = ''
        , ordered = this.token.ordered;

      while (this.next().type !== 'list_end') {
        body += this.tok();
      }

      return this.renderer.list(body, ordered);
    }
    case 'list_item_start': {
      var body = '';

      while (this.next().type !== 'list_item_end') {
        body += this.token.type === 'text'
          ? this.parseText()
          : this.tok();
      }

      return this.renderer.listitem(body);
    }
    case 'loose_item_start': {
      var body = '';

      while (this.next().type !== 'list_item_end') {
        body += this.tok();
      }

      return this.renderer.listitem(body);
    }
    case 'html': {
      var html = !this.token.pre && !this.options.pedantic
        ? this.inline.output(this.token.text)
        : this.token.text;
      return this.renderer.html(html);
    }
    case 'paragraph': {
      return this.renderer.paragraph(this.inline.output(this.token.text));
    }
    case 'text': {
      return this.renderer.paragraph(this.parseText());
    }
  }
};

/**
 * Helpers
 */

function escape(html, encode) {
  return html
    .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

function unescape(html) {
	// explicitly match decimal, hex, and named HTML entities 
  return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
    n = n.toLowerCase();
    if (n === 'colon') return ':';
    if (n.charAt(0) === '#') {
      return n.charAt(1) === 'x'
        ? String.fromCharCode(parseInt(n.substring(2), 16))
        : String.fromCharCode(+n.substring(1));
    }
    return '';
  });
}

function replace(regex, opt) {
  regex = regex.source;
  opt = opt || '';
  return function self(name, val) {
    if (!name) return new RegExp(regex, opt);
    val = val.source || val;
    val = val.replace(/(^|[^\[])\^/g, '$1');
    regex = regex.replace(name, val);
    return self;
  };
}

function noop() {}
noop.exec = noop;

function merge(obj) {
  var i = 1
    , target
    , key;

  for (; i < arguments.length; i++) {
    target = arguments[i];
    for (key in target) {
      if (Object.prototype.hasOwnProperty.call(target, key)) {
        obj[key] = target[key];
      }
    }
  }

  return obj;
}


/**
 * Marked
 */

function marked(src, opt, callback) {
  if (callback || typeof opt === 'function') {
    if (!callback) {
      callback = opt;
      opt = null;
    }

    opt = merge({}, marked.defaults, opt || {});

    var highlight = opt.highlight
      , tokens
      , pending
      , i = 0;

    try {
      tokens = Lexer.lex(src, opt)
    } catch (e) {
      return callback(e);
    }

    pending = tokens.length;

    var done = function(err) {
      if (err) {
        opt.highlight = highlight;
        return callback(err);
      }

      var out;

      try {
        out = Parser.parse(tokens, opt);
      } catch (e) {
        err = e;
      }

      opt.highlight = highlight;

      return err
        ? callback(err)
        : callback(null, out);
    };

    if (!highlight || highlight.length < 3) {
      return done();
    }

    delete opt.highlight;

    if (!pending) return done();

    for (; i < tokens.length; i++) {
      (function(token) {
        if (token.type !== 'code') {
          return --pending || done();
        }
        return highlight(token.text, token.lang, function(err, code) {
          if (err) return done(err);
          if (code == null || code === token.text) {
            return --pending || done();
          }
          token.text = code;
          token.escaped = true;
          --pending || done();
        });
      })(tokens[i]);
    }

    return;
  }
  try {
    if (opt) opt = merge({}, marked.defaults, opt);
    return Parser.parse(Lexer.lex(src, opt), opt);
  } catch (e) {
    e.message += '\nPlease report this to https://github.com/chjj/marked.';
    if ((opt || marked.defaults).silent) {
      return '<p>An error occured:</p><pre>'
        + escape(e.message + '', true)
        + '</pre>';
    }
    throw e;
  }
}

/**
 * Options
 */

marked.options =
marked.setOptions = function(opt) {
  merge(marked.defaults, opt);
  return marked;
};

marked.defaults = {
  gfm: true,
  tables: true,
  breaks: false,
  pedantic: false,
  sanitize: false,
  sanitizer: null,
  mangle: true,
  smartLists: false,
  silent: false,
  highlight: null,
  langPrefix: 'lang-',
  smartypants: false,
  headerPrefix: '',
  renderer: new Renderer,
  xhtml: false
};

/**
 * Expose
 */

marked.Parser = Parser;
marked.parser = Parser.parse;

marked.Renderer = Renderer;

marked.Lexer = Lexer;
marked.lexer = Lexer.lex;

marked.InlineLexer = InlineLexer;
marked.inlineLexer = InlineLexer.output;

marked.parse = marked;

if (true) {
  module.exports = marked;
} else if (typeof define === 'function' && define.amd) {
  define(function() { return marked; });
} else {
  this.marked = marked;
}

}).call(function() {
  return this || (typeof window !== 'undefined' ? window : global);
}());

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4)))

/***/ }),
/* 93 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(3)


/***/ }),
/* 94 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var Buffer = __webpack_require__(2).Buffer;
/*<replacement>*/
var bufferShim = __webpack_require__(17);
/*</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;
};

/***/ }),
/* 95 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(34)


/***/ }),
/* 96 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(process) {var Stream = (function (){
  try {
    return __webpack_require__(15); // hack to fix a circular dependency issue when used with browserify
  } catch(_){}
}());
exports = module.exports = __webpack_require__(35);
exports.Stream = Stream || exports;
exports.Readable = exports;
exports.Writable = __webpack_require__(22);
exports.Duplex = __webpack_require__(3);
exports.Transform = __webpack_require__(21);
exports.PassThrough = __webpack_require__(34);

if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {
  module.exports = Stream;
}

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))

/***/ }),
/* 97 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(21)


/***/ }),
/* 98 */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(22)


/***/ }),
/* 99 */
/***/ (function(module, exports) {

module.exports = function (string) {
  return string.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&")
}


/***/ }),
/* 100 */
/***/ (function(module, exports, __webpack_require__) {

var htmlparser = __webpack_require__(10);
var extend = __webpack_require__(109);
var quoteRegexp = __webpack_require__(99);

function each(obj, cb) {
  if (obj) Object.keys(obj).forEach(function (key) {
    cb(obj[key], key);
  });
}

// Avoid false positives with .__proto__, .hasOwnProperty, etc.
function has(obj, key) {
  return ({}).hasOwnProperty.call(obj, key);
}

module.exports = sanitizeHtml;

// Ignore the _recursing flag; it's there for recursive
// invocation as a guard against this exploit:
// https://github.com/fb55/htmlparser2/issues/105

function sanitizeHtml(html, options, _recursing) {
  var result = '';

  function Frame(tag, attribs) {
    var that = this;
    this.tag = tag;
    this.attribs = attribs || {};
    this.tagPosition = result.length;
    this.text = ''; // Node inner text

    this.updateParentNodeText = function() {
      if (stack.length) {
          var parentFrame = stack[stack.length - 1];
          parentFrame.text += that.text;
      }
    };
  }

  if (!options) {
    options = sanitizeHtml.defaults;
    options.parser = htmlParserDefaults;
  } else {
    options = extend(sanitizeHtml.defaults, options);
    if (options.parser) {
      options.parser = extend(htmlParserDefaults, options.parser);
    } else {
      options.parser = htmlParserDefaults;
    }
  }

  // Tags that contain something other than HTML, or where discarding
  // the text when the tag is disallowed makes sense for other reasons.
  // If we are not allowing these tags, we should drop their content too.
  // For other tags you would drop the tag but keep its content.
  var nonTextTagsArray = options.nonTextTags || [ 'script', 'style', 'textarea' ];
  var allowedAttributesMap;
  var allowedAttributesGlobMap;
  if(options.allowedAttributes) {
    allowedAttributesMap = {};
    allowedAttributesGlobMap = {};
    each(options.allowedAttributes, function(attributes, tag) {
      allowedAttributesMap[tag] = [];
      var globRegex = [];
      attributes.forEach(function(name) {
        if(name.indexOf('*') >= 0) {
          globRegex.push(quoteRegexp(name).replace(/\\\*/g, '.*'));
        } else {
          allowedAttributesMap[tag].push(name);
        }
      });
      allowedAttributesGlobMap[tag] = new RegExp('^(' + globRegex.join('|') + ')$');
    });
  }
  var allowedClassesMap = {};
  each(options.allowedClasses, function(classes, tag) {
    // Implicitly allows the class attribute
    if(allowedAttributesMap) {
      if (!has(allowedAttributesMap, tag)) {
        allowedAttributesMap[tag] = [];
      }
      allowedAttributesMap[tag].push('class');
    }

    allowedClassesMap[tag] = classes;
  });

  var transformTagsMap = {};
  var transformTagsAll;
  each(options.transformTags, function(transform, tag) {
    var transFun;
    if (typeof transform === 'function') {
      transFun = transform;
    } else if (typeof transform === "string") {
      transFun = sanitizeHtml.simpleTransform(transform);
    }
    if (tag === '*') {
      transformTagsAll = transFun;
    } else {
      transformTagsMap[tag] = transFun;
    }
  });

  var depth = 0;
  var stack = [];
  var skipMap = {};
  var transformMap = {};
  var skipText = false;
  var skipTextDepth = 0;

  var parser = new htmlparser.Parser({
    onopentag: function(name, attribs) {
      if (skipText) {
        skipTextDepth++;
        return;
      }
      var frame = new Frame(name, attribs);
      stack.push(frame);

      var skip = false;
      var hasText = frame.text ? true : false;
      var transformedTag;
      if (has(transformTagsMap, name)) {
        transformedTag = transformTagsMap[name](name, attribs);

        frame.attribs = attribs = transformedTag.attribs;

        if (transformedTag.text !== undefined) {
          frame.innerText = transformedTag.text;
        }

        if (name !== transformedTag.tagName) {
          frame.name = name = transformedTag.tagName;
          transformMap[depth] = transformedTag.tagName;
        }
      }
      if (transformTagsAll) {
        transformedTag = transformTagsAll(name, attribs);

        frame.attribs = attribs = transformedTag.attribs;
        if (name !== transformedTag.tagName) {
          frame.name = name = transformedTag.tagName;
          transformMap[depth] = transformedTag.tagName;
        }
      }

      if (options.allowedTags && options.allowedTags.indexOf(name) === -1) {
        skip = true;
        if (nonTextTagsArray.indexOf(name) !== -1) {
          skipText = true;
          skipTextDepth = 1;
        }
        skipMap[depth] = true;
      }
      depth++;
      if (skip) {
        // We want the contents but not this tag
        return;
      }
      result += '<' + name;
      if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
        each(attribs, function(value, a) {
          if (!allowedAttributesMap ||
              (has(allowedAttributesMap, name) && allowedAttributesMap[name].indexOf(a) !== -1 ) ||
              (allowedAttributesMap['*'] && allowedAttributesMap['*'].indexOf(a) !== -1 ) ||
              (has(allowedAttributesGlobMap, name) && allowedAttributesGlobMap[name].test(a)) ||
              (allowedAttributesGlobMap['*'] && allowedAttributesGlobMap['*'].test(a))) {
            if ((a === 'href') || (a === 'src')) {
              if (naughtyHref(name, value)) {
                delete frame.attribs[a];
                return;
              }
            }
            if (a === 'class') {
              value = filterClasses(value, allowedClassesMap[name]);
              if (!value.length) {
                delete frame.attribs[a];
                return;
              }
            }
            result += ' ' + a;
            if (value.length) {
              result += '="' + escapeHtml(value) + '"';
            }
          } else {
            delete frame.attribs[a];
          }
        });
      }
      if (options.selfClosing.indexOf(name) !== -1) {
        result += " />";
      } else {
        result += ">";
        if (frame.innerText && !hasText && !options.textFilter) {
          result += frame.innerText;
        }
      }
    },
    ontext: function(text) {
      if (skipText) {
        return;
      }
      var lastFrame = stack[stack.length-1];
      var tag;

      if (lastFrame) {
        tag = lastFrame.tag;
        // If inner text was set by transform function then let's use it
        text = lastFrame.innerText !== undefined ? lastFrame.innerText : text;
      }

      if ((tag === 'script') || (tag === 'style')) {
        // htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing
        // script tags is, by definition, game over for XSS protection, so if that's
        // your concern, don't allow them. The same is essentially true for style tags
        // which have their own collection of XSS vectors.
        result += text;
      } else {
        var escaped = escapeHtml(text);
        if (options.textFilter) {
          result += options.textFilter(escaped);
        } else {
          result += escaped;
        }
      }
      if (stack.length) {
           var frame = stack[stack.length - 1];
           frame.text += text;
      }
    },
    onclosetag: function(name) {

      if (skipText) {
        skipTextDepth--;
        if (!skipTextDepth) {
          skipText = false;
        } else {
          return;
        }
      }

      var frame = stack.pop();
      if (!frame) {
        // Do not crash on bad markup
        return;
      }
      skipText = false;
      depth--;
      if (skipMap[depth]) {
        delete skipMap[depth];
        frame.updateParentNodeText();
        return;
      }

      if (transformMap[depth]) {
        name = transformMap[depth];
        delete transformMap[depth];
      }

      if (options.exclusiveFilter && options.exclusiveFilter(frame)) {
         result = result.substr(0, frame.tagPosition);
         return;
      }

      frame.updateParentNodeText();

      if (options.selfClosing.indexOf(name) !== -1) {
         // Already output />
         return;
      }

      result += "</" + name + ">";
    }
  }, options.parser);
  parser.write(html);
  parser.end();

  return result;

  function escapeHtml(s) {
    if (typeof(s) !== 'string') {
      s = s + '';
    }
    return s.replace(/\&/g, '&amp;').replace(/</g, '&lt;').replace(/\>/g, '&gt;').replace(/\"/g, '&quot;');
  }

  function naughtyHref(name, href) {
    // Browsers ignore character codes of 32 (space) and below in a surprising
    // number of situations. Start reading here:
    // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_tab
    href = href.replace(/[\x00-\x20]+/g, '');
    // Clobber any comments in URLs, which the browser might
    // interpret inside an XML data island, allowing
    // a javascript: URL to be snuck through
    href = href.replace(/<\!\-\-.*?\-\-\>/g, '');
    // Case insensitive so we don't get faked out by JAVASCRIPT #1
    var matches = href.match(/^([a-zA-Z]+)\:/);
    if (!matches) {
      // Protocol-relative URL: "//some.evil.com/nasty"
      if (href.match(/^\/\//)) {
        return !options.allowProtocolRelative;
      }

      // No scheme
      return false;
    }
    var scheme = matches[1].toLowerCase();

    if (has(options.allowedSchemesByTag, name)) {
      return options.allowedSchemesByTag[name].indexOf(scheme) === -1;
    }

    return !options.allowedSchemes || options.allowedSchemes.indexOf(scheme) === -1;
  }

  function filterClasses(classes, allowed) {
    if (!allowed) {
      // The class attribute is allowed without filtering on this tag
      return classes;
    }
    classes = classes.split(/\s+/);
    return classes.filter(function(clss) {
      return allowed.indexOf(clss) !== -1;
    }).join(' ');
  }
}

// Defaults are accessible to you so that you can use them as a starting point
// programmatically if you wish

var htmlParserDefaults = {
  decodeEntities: true
};
sanitizeHtml.defaults = {
  allowedTags: [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
    'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
    'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre' ],
  allowedAttributes: {
    a: [ 'href', 'name', 'target' ],
    // We don't currently allow img itself by default, but this
    // would make sense if we did
    img: [ 'src' ]
  },
  // Lots of these won't come up by default because we don't allow them
  selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],
  // URL schemes we permit
  allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
  allowedSchemesByTag: {},
  allowProtocolRelative: true
};

sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) {
  merge = (merge === undefined) ? true : merge;
  newAttribs = newAttribs || {};

  return function(tagName, attribs) {
    var attrib;
    if (merge) {
      for (attrib in newAttribs) {
        attribs[attrib] = newAttribs[attrib];
      }
    } else {
      attribs = newAttribs;
    }

    return {
      tagName: newTagName,
      attribs: attribs
    };
  };
};


/***/ }),
/* 101 */
/***/ (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__(4), __webpack_require__(6)))

/***/ }),
/* 102 */
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(48);
if(typeof content === 'string') content = [[module.i, content, '']];
// add the styles to the DOM
var update = __webpack_require__(16)(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../../node_modules/css-loader/index.js!./style.css", function() {
			var newContent = require("!!../../../node_modules/css-loader/index.js!./style.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 103 */
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(49);
if(typeof content === 'string') content = [[module.i, content, '']];
// add the styles to the DOM
var update = __webpack_require__(16)(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../../node_modules/css-loader/index.js!./bootstrap-tour.css", function() {
			var newContent = require("!!../../../node_modules/css-loader/index.js!./bootstrap-tour.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 104 */
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(50);
if(typeof content === 'string') content = [[module.i, content, '']];
// add the styles to the DOM
var update = __webpack_require__(16)(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../../node_modules/css-loader/index.js!./FlowTemplate.css", function() {
			var newContent = require("!!../../../node_modules/css-loader/index.js!./FlowTemplate.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 105 */
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(51);
if(typeof content === 'string') content = [[module.i, content, '']];
// add the styles to the DOM
var update = __webpack_require__(16)(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../../node_modules/css-loader/index.js!./ImageFlowModal.css", function() {
			var newContent = require("!!../../../node_modules/css-loader/index.js!./ImageFlowModal.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),
/* 106 */
/***/ (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__(101);
exports.setImmediate = setImmediate;
exports.clearImmediate = clearImmediate;


/***/ }),
/* 107 */
/***/ (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__(4)))

/***/ }),
/* 108 */
/***/ (function(module, exports) {

module.exports = function(module) {
	if(!module.webpackPolyfill) {
		module.deprecate = function() {};
		module.paths = [];
		// module.parent = undefined by default
		if(!module.children) module.children = [];
		Object.defineProperty(module, "loaded", {
			enumerable: true,
			get: function() {
				return module.l;
			}
		});
		Object.defineProperty(module, "id", {
			enumerable: true,
			get: function() {
				return module.i;
			}
		});
		module.webpackPolyfill = 1;
	}
	return module;
};


/***/ }),
/* 109 */
/***/ (function(module, exports) {

module.exports = extend

var hasOwnProperty = Object.prototype.hasOwnProperty;

function extend() {
    var target = {}

    for (var i = 0; i < arguments.length; i++) {
        var source = arguments[i]

        for (var key in source) {
            if (hasOwnProperty.call(source, key)) {
                target[key] = source[key]
            }
        }
    }

    return target
}


/***/ }),
/* 110 */
/***/ (function(module, exports) {

function ChocolateyPackages(cssdk, config) {
	this.cssdk = cssdk;
	this.config = config;
}

ChocolateyPackages.prototype.search = function(query, skip, take) {
	return post(this, "chocolateySearch", {
		query: query,
		orderBy: "relevance",
		skip: skip,
		take: take
	});
}

ChocolateyPackages.prototype.getMostPopular = function(skip, take) {
	return get(this, "chocolateySearch/actions/getMostPopular", {
		skip: skip,
		take: take
	});
}

ChocolateyPackages.prototype.getAllVersions = function(idName, skip, take) {
	return get(this, "chocolateySearch/actions/getAllVersions", {
		idName: idName,
		skip: skip,
		take: take
	});
}

function get(self, path, queryParams) {
	return req(self, 'GET', path, queryParams);
}

function post(self, path, content) {
	return req(self, 'POST', path, null, content);
}

function req(self, method, path, queryParams, content) {
	return self.cssdk.req({
		hostname: self.config.cloudShareHostname,
		method: method,
		apiId: self.config.apiId,
		apiKey: self.config.apiKey,
		path: path,
		queryParams: queryParams,
		content: content
	});
}

module.exports = ChocolateyPackages;

/***/ }),
/* 111 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("chocolateyButton", ["chocolateyClientConfig", function(chocolateyClientConfig) {
	return {
		scope: {
			ngClick: "&"
		},
		restrict: 'E',
		template: __webpack_require__(68),
		link: function(scope, element) {
			element.find('button')
			.css('background-image', 'url(' + chocolateyClientConfig.chocolateyIconSmallImagePath + ')');
		}
	};
}]);

/***/ }),
/* 112 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("chocolateyClient", function() {
	return {
		scope: {
			selectedPackages: "=ngModel"
		},
		restrict: 'E',
		template: __webpack_require__(69),
		controller: 'chocolateyClientController'
	};
})
.controller('chocolateyClientController', ['$scope', function($scope) {
	$scope.selectPackage = function(package) {
		if (!tryToReplaceExistingPackage(package)) 
			$scope.selectedPackages.push(package);
	};

	$scope.unselectPackage = function(package) {
		$scope.selectedPackages = $scope.selectedPackages.filter(function(pkg) {
			return pkg.idName !== package.idName ||
				   pkg.version !== package.version;
		});
	};

	function tryToReplaceExistingPackage(package) {
		var replaced = false;
		for (var i = 0; i < $scope.selectedPackages.length; ++i) {
			var p = $scope.selectedPackages[i];
			if (p.idName == package.idName) {
				$scope.selectedPackages[i] = package;
				replaced = true;
			}
		}
		return replaced;
	}
}]);

/***/ }),
/* 113 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("detailsPane", function() {
	return {
		scope: {
			back: "=",
			package: "=",
			onSelectPackage: "=",
			onUnselectPackage: "=",
			selectedPackages: "="
		},
		restrict: 'E',
		template: __webpack_require__(70),
		controller: 'detailsPaneController'
	};
})
.controller('detailsPaneController', ['$scope', function($scope) {
	
	$scope.unselectAndGoBack = function() {
		$scope.onUnselectPackage($scope.package);
		$scope.back();
	};

	$scope.isSelected = function(version) {
		if (!$scope.selectedPackages || !$scope.package)
			return false;
		if (!version)
			version = $scope.package.version;
		return !$scope.selectedPackages.every(function(p) {
			return p.idName !== $scope.package.idName ||
				   p.version !== version;
		});
	};
}]);

/***/ }),
/* 114 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);
var marked = __webpack_require__(92);

ngModule
.directive('markdown', function() {
	return {
		scope: {
			content: "="
		},
		restrict: 'E',
		link: function(scope, element) {
			scope.$watch('content', function(newValue) {
				if (newValue)
					scope.parsedContent = marked(newValue);
			});
		},
		template: __webpack_require__(71)
	};
});

/***/ }),
/* 115 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("packageDetailedItem", ["$timeout", function($timeout) {
	return {
		scope: {
			package: "=",
			onSelectPackage: "=",
			onUnselectPackage: "=",
			selectedPackages: "="
		},
		restrict: 'E',
		link: function(scope, element) {
			var el = $(element.find('.package-detailed-item'));
			el.slimScroll({
				height: '470px',
				railDraggable : true
			});

			el.scroll(function() {
				if (this.scrollTop + this.offsetHeight == this.scrollHeight)
					$timeout(scope.fetchVersions, 0, true);
				var scrollTop = this.scrollTop;
				$timeout(function() {
					scope.scrolled = scrollTop > 0;
				}, 0, true);
			});

			scope.$watch('versions', function() {
				if (el[0].scrollTop == 0 && el[0].offsetHeight === el[0].scrollHeight)
					$timeout(scope.fetchVersions, 0, true);
			});
		},
		template: __webpack_require__(72),
		controller: "packageDetailedItemController"
	};	
}])
.controller("packageDetailedItemController", ["$scope", "$timeout", "chocolateyPackages", function($scope, $timeout, chocolateyPackages) {
	$scope.fetchVersions = function() {
		if (!$scope.package || $scope.noMore || $scope.tid)
			return;
		$scope.showVersionSpinner = true;
		$scope.tid = $timeout(function() {
			chocolateyPackages.getAllVersions($scope.package.idName, $scope.skip, $scope.take)
			.then(function(response) {
				if (response.content.length === 0 || response.content.length < $scope.take)
					$scope.noMore = true;
				$scope.versions = $scope.versions.concat(response.content.map(function(p) {
					return p.version;
				}));
				$scope.showVersionSpinner = false;
				$scope.tid = null;
				$scope.skip += $scope.take;
				$scope.$apply();
			});
		}, 1000);
	};

	$scope.selectVersion = function(version) {
		if (!$scope.onSelectPackage || !$scope.package)
			return;
		var newPackage = copyObject($scope.package);
		newPackage.version = version;
		$scope.onSelectPackage(newPackage);
	};

	$scope.isSelected = function(version) {
		if (!$scope.selectedPackages || !$scope.package)
			return false;
		if (!version)
			version = $scope.package.version;
		return !$scope.selectedPackages.every(function(p) {
			return p.idName !== $scope.package.idName ||
				   p.version !== version;
		});
	};

	$scope.$watch('package', reset);
	reset();

	function reset() {
		$scope.take = 5;
		$scope.skip = 0;
		$scope.versions = [];
		$scope.noMore = false;
		$scope.showVersionSpinner = false;
		$scope.tid = null;
		$scope.fetchVersions();
	}

	function copyObject(object) {
		var result = {};
		for (var k in object) {
			if (object.hasOwnProperty(k))
				result[k] = object[k];
		}
		return result;
	}
}]);

/***/ }),
/* 116 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("packageItem", function() {
	return {
		scope: {
			package: "=",
			onViewDetails: "=",
			onViewVersions: "=",
			onSelectPackage: "=",
			onUnselectPackage: "=",
			selectedPackages: "="
		},
		restrict: 'E',
		link: function(scope) {
			var description = scope.package.description;
			if (description && description.length > 250) {
				scope.shortDescription = description.substr(0, 250) + "...";
			} else {
				scope.shortDescription = description;
			}
		},
		template: __webpack_require__(73),
		controller: "packageItemController"
	};	
})
.controller("packageItemController", ["$scope", function($scope) {
	$scope.isSelected = function() {
		if (!$scope.selectedPackages)
			return false;
		return !$scope.selectedPackages.every(function(p) {
			return p.idName !== $scope.package.idName ||
				   p.version !== $scope.package.version;
		});
	};
}]);

/***/ }),
/* 117 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("packageList", ['$timeout', function($timeout) {
	return {
		scope: {
			packages: "=",
			showSpinner: "=",
			emptyPhrase: "@",
			onViewDetails: "=",
			onViewVersions: "=",
			onSelectPackage: "=",
			onUnselectPackage: "=",
			onNeedMore: "=",
			selectedPackages: "="
		},
		restrict: 'E',
		link: function(scope, element) {
			var listElement = $(element).find('.package-list');
			listElement.first().slimScroll({
				height: '500px',
				railDraggable : true,
				alwaysVisible: true
			});

			listElement.scroll(function() {
				if (this.scrollTop + this.offsetHeight == this.scrollHeight && scope.onNeedMore)
					$timeout(scope.onNeedMore, 0, true);
				var scrollTop = this.scrollTop;
				$timeout(function() {
					scope.scrolled = scrollTop > 0;
				}, 0, true);
			});
		},
		template: __webpack_require__(74)
	};	
}])

/***/ }),
/* 118 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("packagesPane", function() {
	return {
		scope: {
			showSearch: "=",
			firstView: "@",
			title: "@",
			selectedPackages: "=",
			onSelectPackage: "=",
			onUnselectPackage: "="
		},
		restrict: 'E',
		template: __webpack_require__(75),
		controller: 'packagesPaneController'
	};
})
.controller("packagesPaneController", ["$scope", "$timeout", "chocolateyPackages", function($scope, $timeout, chocolateyPackages) {
	$scope.back = function() {
		if ($scope.viewBreadcrumbs.length > 1)
			$scope.viewBreadcrumbs.pop();
		$scope.selectedView = $scope.viewBreadcrumbs[$scope.viewBreadcrumbs.length - 1];
	};

	$scope.viewDetails = function(package) {
		$scope.viewPackage = package;
		$scope.viewBreadcrumbs.push('details');
		$scope.selectedView = 'details';
	};

	$scope.searchPackages = function(query) {
		if (query) {
			$scope.selectedView = 'search';
			$scope.viewBreadcrumbs = ['search'];
		} else {
			$scope.selectedView = 'popular';
			$scope.viewBreadcrumbs = ['popular'];
			$scope.getMostPopular();
			return;
		}
		$scope.skip = 0;
		$scope.take = 5;
		$scope.query = query;
		$scope.showSpinner = true;
		chocolateyPackages.search(query, $scope.skip, $scope.take)
		.then(function(response) {
			$scope.showSpinner = false;
			$scope.packages = response.content;
			$scope.$apply();
		});
	};

	$scope.getMostPopular = function() {
		$scope.skip = 0;
		$scope.take = 5;
		$scope.packages = null;
		$scope.noMore = false;
		$scope.showSpinner = true;
		chocolateyPackages.getMostPopular($scope.skip, $scope.take)
		.then(function(response) {
			$scope.showSpinner = false;
			$scope.packages = response.content;
			$scope.$apply();
		});
	};

	$scope.fetchMoreSearch = function() {
		if ($scope.query == null || $scope.noMore || $scope.tid)
			return;
		$scope.skip += $scope.take;
		$scope.showSpinner = true;
		$scope.tid = $timeout(function() {
			chocolateyPackages.search($scope.query, $scope.skip, $scope.take)
			.then(function(response) {
				if (response.content.length == 0)
					$scope.noMore = true;
				$scope.showSpinner = false;
				$scope.packages = $scope.packages.concat(response.content);
				$scope.tid = null;
				$scope.$apply();
			});
		}, 1000);
	};

	$scope.fetchMorePopular = function() {
		if ($scope.noMore || $scope.tid)
			return;
		$scope.skip += $scope.take;
		$scope.showSpinner = true;
		$scope.tid = $timeout(function() {
			chocolateyPackages.getMostPopular($scope.skip, $scope.take)
			.then(function(response) {
				$scope.showSpinner = false;
				$scope.packages = $scope.packages.concat(response.content);
				$scope.tid = null;
				$scope.$apply();
			});
		}, 1000);
	};
	
	$scope.skip = 0;
	$scope.take = 5;
	$scope.packages = null;
	$scope.query = null;
	$scope.showSpinner = false;
	$scope.noMore = false;
	$scope.tid = null;
	if (!$scope.selectedPackages)
		$scope.selectedPackages = [];
	$scope.selectedView = $scope.firstView || 'popular';
	$scope.viewBreadcrumbs = [$scope.selectedView];
	$scope.viewPackage = null;
	$scope.getMostPopular();
}]);

/***/ }),
/* 119 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);

ngModule
.directive("searchInput", ['$timeout', function($timeout) {
	return {
		scope: {
			onSearch: '='
		},
		restrict: 'E',
		link: function(scope, element) {
			var tid = null;
			element.find("input[type=text]").on('keyup', function() {
				var inputElement = this;
				if (tid != null) {
					$timeout.cancel(tid);
					tid = null;
				}
				tid = $timeout(function() {
					scope.onSearch(inputElement.value);
				}, 500);
			});
		},
		template: __webpack_require__(76)
	};	
}]);

/***/ }),
/* 120 */
/***/ (function(module, exports, __webpack_require__) {

var ngModule = __webpack_require__(0);
var $ = __webpack_require__(11);

ngModule
.directive("spinner", ['chocolateyClientConfig', function(chocolateyClientConfig) {
	return {
		scope: {},
		restrict: 'E',
		link: function(scope, element) {
			element.find('img').attr('src', chocolateyClientConfig.preloaderImagePath);
		},
		template: __webpack_require__(77)
	};	
}]);

/***/ }),
/* 121 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(103);
module.exports = __webpack_require__(67);

/***/ }),
/* 122 */
/***/ (function(module, exports, __webpack_require__) {

var Bottle = __webpack_require__(13);
var bottle = new Bottle();

bottle.value("XMLHttpRequest", XMLHttpRequest);
bottle.value("Tour", __webpack_require__(121));
bottle.service("TourService", __webpack_require__(123), "XMLHttpRequest", "Tour");

module.exports = bottle;


/***/ }),
/* 123 */
/***/ (function(module, exports, __webpack_require__) {

var $ = __webpack_require__(11);
var Promise = __webpack_require__(5).Promise;
var TOUR_DEBUG = false;
__webpack_require__(105);
__webpack_require__(104);

function TourService(XMLHttpRequest, Tour) {
    this._XMLHttpRequest = XMLHttpRequest;
    this._Tour = Tour;

    this._initialized = false;
    this._initPromise = null;
    this._onces = {};
    this._flows = {};
    this._imageFlows = {};

    this._flowTours = {};
    this._imageFlowTours = {};
    this._onceTours = {};

    this._imageFlowModalElements = {};

    this._eventListeners = {
        show: {},
        hide: {},
        next: {},
        end: []
    };

    this._currentlyStartedFlowNames = {};
    this._currentlyStartedOnceNames = {};
    this._dictionary = {};

    this._hideAllFlowsOnHashChange();
    this._openImageFlowAnchorClicks();
}

TourService.prototype.init = function() {
    if (this._initialized) {
        return new Promise(function(resolve) {
            resolve();
        });
    }

    if (this._initPromise)
        return this._initPromise;

    this._initPromise = this._getTourDb()
        .then((function(tourDb) {
            this._onces = this._getOncesFromTourDb(tourDb);
            this._flows = this._getFlowsFromTourDb(tourDb);
            this._imageFlows = tourDb.imageFlows;
            this._flowTours = this._createFlowTours(this._flows);
            this._imageFlowTours = this._createImageFlowTours(this._imageFlows);
            this._onceTours = this._createOnceTours(this._onces);
            this._initialized = true;
            this._initPromise = null;
        }).bind(this))
        ["catch"](function(error) {
        console.error(error);
    });

    return this._initPromise;
};

TourService.prototype.reportProceedEvent = function(name) {
    var _this = this;
    this.init()
        .then(function() {
            Object.keys(_this._flows).forEach(function(flowName) {
                var flow = _this._flows[flowName];
                flow.forEach(function(flowStep, stepIndex) {
                    if (flowStep.proceedOn === name) {
                        var flowTour = _this._flowTours[flowName];
                        if (!flowTour.isInitialized())
                            flowTour.init();
                        if (flowTour.getCurrentStep() === stepIndex)
                            flowTour.next();
                    }
                });
            });
        });
};

TourService.prototype.startFlow = function(flowName) {
    return this._getTourFlow(flowName)
        .then((function(tour) {
            if (!tour || this._hasStartedFlows(flowName))
                return false;

            tour.init();

            if (tour.ended())
                tour.restart();

            this._currentlyStartedFlowNames[flowName] = true;
            return true;
        }).bind(this));
};

TourService.prototype.restartFlow = function(flowName) {
    return this._getTourFlow(flowName)
        .then((function(tour) {
            if (!tour || this._hasStartedFlows(flowName))
                return false;

            tour.restart();

            this._currentlyStartedFlowNames[flowName] = true;
            return true;
        }).bind(this));
};

TourService.prototype.getCurrentStep = function(flowName) {
    var tour = this._flowTours[flowName];
    if (!tour) {
        console.error("Couldn't find flow " + flowName);
        return -1;
    }
    return tour.getCurrentStep() || 0;
};

TourService.prototype.showOnce = function(tagName) {
    var _this = this;

    return this.init()
        .then(function() {
            if (_this._hasStartedFlows())
                return false;

            var once = _this._onceTours[tagName];
            if (!once) {
                console.error("Couldn't find once for tag name " + tagName);
                return false;
            }
            if (!once.isInitialized())
                once.init();
            once.start();

            return true;
        });
};

/**
 * Starts all flows that are triggered with tagName.
 *
 * This allows to 'wake' the tour up upon refresh when the tag's
 * element is ready.
 *
 * If the flow is stopped on another tag and step the tour isn't started
 *
 * @param tagName
 */
TourService.prototype.startFlowsOnTagName = function(tagName) {
    var _this = this;

    return this.init()
        .then(function() {
            if (_this._hasStartedFlows())
                return false;
            Object.keys(_this._flows).forEach(function(flowName) {
                var flow = _this._flows[flowName];
                flow.forEach(function(flowStep, stepIndex) {
                    if (flowStep.tagName === tagName) {
                        var flowTour = _this._flowTours[flowName];
                        if ((!flowStep.disableAutoContinue && !flowTour.ended() && stepIndex === flowTour.getCurrentStep()) ||
                            (flowStep.autoStart && flowTour.getCurrentStep() === null)) {
                            if (!flowTour.isInitialized()) {
                                flowTour.init();
                            } else if (flowTour.getCurrentStep() === null) {
                                flowTour.start();
                            } else {

                                flowTour.showStep(flowTour.getCurrentStep());
                            }
                            _this._currentlyStartedFlowNames[flowName] = true;
                        }
                    }
                });
            });
            return true;
        });
};

/**
 * Shows all onces that are triggered with tagName.
 *
 * This allows to 'wake' the tour up upon refresh when the tag's
 * element is ready.
 *
 * @param tagName
 */
TourService.prototype.showOncesOnTagName = function(tagName) {
    var _this = this;

    return this.init()
        .then(function() {
            if (_this._hasStartedFlows())
                return false;

            Object.keys(_this._onces).forEach(function(onceTagName) {
                if (tagName === onceTagName) {
                    var onceTour = _this._onceTours[onceTagName];
                    if (!onceTour.isInitialized())
                        onceTour.init();
                    onceTour.showStep(0);
                }
            });

            return true;
        });
};

TourService.prototype.addEventListener = function(eventName, flowName, stepIndex, callback) {
    if (eventName === "end") {
        this._eventListeners.end.push(arguments[1] || function(){});
    } else {
        var flowListeners = this._eventListeners[eventName] = this._eventListeners[eventName] || {};
        var stepListeners = flowListeners[flowName] = flowListeners[flowName] || {};
        stepListeners[stepIndex] = callback;
    }

};

TourService.prototype.addToDictionary = function(key, value) {
    var _this = this;
    if (typeof key === "string") {
        this._dictionary[key] = value;
    } else if (typeof key === "object") {
        var dictionary = key;
        Object.keys(dictionary).forEach(function(key) {
            _this._dictionary[key] = dictionary[key];
        });
    }
};

TourService.prototype.endFlow = function(flowName) {
    var tour = this._flowTours[flowName];
    if (tour)
        tour.end();
    this._currentlyStartedFlowNames[flowName] = false;
};

TourService.prototype.hideAllFlows = function() {
    var this_ = this;

    Object.keys(this_._currentlyStartedFlowNames).forEach(function(flowName) {
        var tour = this_._flowTours[flowName];
        tour.hideStep(tour.getCurrentStep());
        this_._currentlyStartedFlowNames[flowName] = false;
    });

    Object.keys(this_._onceTours).forEach(function(onceName) {
        var tour = this_._onceTours[onceName];
        tour.hideStep(tour.getCurrentStep());
    });
};

TourService.prototype._hideAllOnces = function() {
    var _this = this;
    Object.keys(this._currentlyStartedOnceNames).forEach(function(onceTagName) {
        if (!_this._currentlyStartedOnceNames[onceTagName])
            return;
        var tour = _this._onceTours[onceTagName];
        if (!tour)
            return;
        tour.hideStep(0);
    });
};

TourService.prototype.startImageFlow = function(flowName) {
    var _this = this;

    return this.init()
        .then(function() {
            _this._addImageFlowModal(flowName);
        })
        .then(function() {
            var tour = _this._imageFlowTours[flowName];
            if (!tour)
                return false;

            if (!tour.isInitialized())
                tour.init();
            if (tour.getCurrentStep() === null)
                tour.start();
            if (tour.ended())
                tour.restart();

            _this._currentlyStartedFlowNames[flowName] = true;
            return true;
        });
};

TourService.prototype._createImageFlowModalElement = function(flowName) {
    var imageFlow = this._imageFlows[flowName];
    var modal = $(__webpack_require__(83));

    modal.find(".flow-modal-header").text(imageFlow.title);
    var image = new Image();
    image.src = imageFlow.imageUrl;
    var imageContainerElement = modal.find(".flow-modal-image-container");
    imageContainerElement.append(image);

    imageFlow.steps.forEach(function(step) {
        if (!step.position)
            return;
        var spotElement = $('<div image-flow-spot="'+step.position[0]+'-'+step.position[1]+'"/>');
        spotElement.css("left", (step.position[0] * 100) + "%");
        spotElement.css("top", (step.position[1] * 100) + "%");
        imageContainerElement.append(spotElement);
    });
    return modal;
};


TourService.prototype._callEventListener = function(eventName, flowName, stepIndex) {
    if (eventName === "end") {
        var lastStep = this._flows[flowName].length - 1 === stepIndex;
        this._eventListeners.end.forEach(function(f){f(flowName, lastStep);});
    } else {
        if (!this._eventListeners[eventName] ||
            !this._eventListeners[eventName][flowName] ||
            !this._eventListeners[eventName][flowName][stepIndex]) {
            return;
        }
        this._eventListeners[eventName][flowName][stepIndex]();
    }
};

TourService.prototype._hasStartedFlows = function(exceptFlowName) {
    var _this = this;
    return Object.keys(this._currentlyStartedFlowNames).filter(function(flowName) {
            return flowName !== exceptFlowName && _this._currentlyStartedFlowNames[flowName];
        }).length > 0;
};

TourService.prototype._hideAllFlowsOnHashChange = function() {
    var this_ = this;
    window.addEventListener("hashchange", function() {
        this_.hideAllFlows();
    });
};


TourService.prototype._getTourFlow = function(flowName) {
    return this.init()
        .then((function() {
            var tour = this._flowTours[flowName];
            if (!tour) {
                console.error("Couldn't find flow " + flowName);
                return null;
            }
            return tour;
        }).bind(this));
};

TourService.prototype._getFlowsFromTourDb = function(tourDb) {
    var result = {};

    Object.keys(tourDb.flows).forEach(function(flowName) {
        var flow = tourDb.flows[flowName];
        if (!flow.enabled)
            return;
        flow.steps.forEach(function(flowStep) {
            if (!result[flowName])
                result[flowName] = [];
            flowStep.disableAutoContinue = flow.disableAutoContinue;
            result[flowName].push(flowStep);
        });
    });

    return result;
};

TourService.prototype._getOncesFromTourDb = function(tourDb) {
    var result = {};

    Object.keys(tourDb.onces).forEach(function(onceTag) {
        var once = tourDb.onces[onceTag];
        if (!once.enabled)
            return;
        once.tagName = onceTag;
        result[onceTag] = once;
    });

    return result;
};

TourService.prototype._replaceDictionaryKeysInStep = function(flowName, stepIndex) {
    var _this = this;
    var tourElement = $(".tour-cs-tour-flow-" + flowName + "-" + stepIndex);
    var tourTitleElement = tourElement.find(".popover-title");
    var tourContentElement = tourElement.find(".popover-content");

    replaceTokens(tourTitleElement);
    replaceTokens(tourContentElement);

    function replaceTokens(element) {
        var html = element.html() || "";
        element.html(_this._replaceDictionaryKeys(html));
    }
};

TourService.prototype._replaceDictionaryKeys = function(text, escape) {
    var _this = this;

    return text.replace(/\$\{((\s|.)+)}/gi, function(match, key) {
        var value = _this._dictionary[key];
        if (typeof value === "string")
            return escape === false ? value : escapeHTML(value);
        return match;
    });

    function escapeHTML(html) {
        return $("<div>").text(html).html();
    }
};

TourService.prototype._createFlowTours = function(flows) {
    var _this = this;
    var result = {};

    Object.keys(flows).forEach(function(flowName) {
        var flow = flows[flowName];

        result[flowName] = new _this._Tour({
            name: _this._getFlowStorageKey(flowName),
            debug: TOUR_DEBUG,
            keyboard: false,
            steps: _this._flowStepsToTourSteps(flow),
            onShow: function(tour) {
                _this._callEventListener("show", flowName, tour.getCurrentStep());

                _this._openStepSideBarMenu(flow, tour.getCurrentStep());
                _this._hideAllOnces();
            },
            onShown: function(tour) {
                var flowStep = flow[tour.getCurrentStep()];
                if (flowStep.proceedOnTextInput) {
                    var element = $(_this._getTourTagNameSelector(flowStep.tagName));
                    element.on("input.tourDebounce", createDebounce(tour));
                }
                _this._replaceDictionaryKeysInStep(flowName, tour.getCurrentStep());
                _this._callEventListener("shown", flowName, tour.getCurrentStep());
            },
            onHide: function(tour) {
                _this._callEventListener("hide", flowName, tour.getCurrentStep());
            },
            onEnd: function (tour) {
                _this._callEventListener("end", flowName, tour.getCurrentStep());
                _this._postEndTourEvent(flowName, tour.getCurrentStep());
                _this._currentlyStartedFlowNames[flowName] = false;
            },
            onNext: function (tour) {
                var flowStep = flow[tour.getCurrentStep()];
                var element = $(_this._getTourTagNameSelector(flowStep.tagName));
                element.off("input.tourDebounce");

                if (tour.getCurrentStep() === flow.length - 1) {
                    tour.end();
                    _this._currentlyStartedFlowNames[flowName] = false;
                    return;
                }

                var redirectValue = flowStep.redirect ? _this._replaceDictionaryKeys("" + flowStep.redirect, false) : "";
                if (redirectValue) {
                    tour.setCurrentStep(tour.getCurrentStep() + 1);
                    if (flowStep.nextRedirect)
                        window.location = _this._escapeURL(_this._replaceDictionaryKeys(flowStep.nextRedirect, false));
                    return new Promise(function(resolve, reject) {
                        if (redirectValue === "hash") {
                            window.addEventListener("hashchange", function() {
                                resolve();
                            });
                        }
                    });
                }

                _this._callEventListener("next", flowName, tour.getCurrentStep());
            }
        });

        function createDebounce(tour) {
            var x = null;
            return debounce;

            function debounce(e) {
                clearTimeout(x);
                x = setTimeout(function() {
                    tour.next();
                }, 350);
            }
        }


    });
    return result;
};

TourService.prototype._createImageFlowTours = function(imageFlows) {
    var _this = this;
    var result = {};

    Object.keys(imageFlows).forEach(function(flowName) {
        var imageFlow = imageFlows[flowName];

        result[flowName] = new _this._Tour({
            name: _this._getImageFlowStorageKey(flowName),
            debug: TOUR_DEBUG,
            steps: _this._imageFlowStepsToTourSteps(imageFlow.steps),
            onEnd: function (tour) {
                _this._removeImageFlowModal(flowName);
            }
        });
    });

    return result;
};


TourService.prototype._escapeURL = function(url) {
    if (url)
        return url.replace(/^javascript:/, "");
    return url;
};

TourService.prototype._openStepSideBarMenu = function(flowSteps, currentStepIndex) {
    var currentStep;
    var nextStep;
    var delay;

    if (currentStepIndex !== null) {
        currentStep = flowSteps[currentStepIndex];
        nextStep = flowSteps[currentStepIndex + 1];
        delay = currentStep.delay;
    } else {
        currentStep = null;
        nextStep = flowSteps[0];
        delay = nextStep.delay;
    }

    if (nextStep && nextStep.openSideBarMenu && window.cs && window.cs.sideBarService) {
        setTimeout(function() {
            window.cs.sideBarService.openSubMenu(nextStep.openSideBarMenu);
        }, delay);
    }
};

TourService.prototype._createOnceTours = function(onces) {
    var _this = this;
    var result = {};

    Object.keys(onces).forEach((function(onceTagName) {
        var once = onces[onceTagName];

        result[onceTagName] = new Tour({
            name: this._getOnceStorageKey(onceTagName),
            debug: TOUR_DEBUG,
            steps: [this._onceOrFlowStepToTourStep(once, onceTagName)],
            onShow: function (tour) {
                _this._currentlyStartedOnceNames[onceTagName] = true;
            },
            onHide: function(tour) {
                _this._currentlyStartedOnceNames[onceTagName] = false;
            }
        });
    }).bind(this));

    return result;
};

TourService.prototype._flowStepsToTourSteps = function(flowSteps) {
    var _this = this;
    return flowSteps.map(function(step) {
        return _this._onceOrFlowStepToTourStep(step);
    });
};

TourService.prototype._onceOrFlowStepToTourStep = function(step, tagName) {
    var _this = this;
    tagName = tagName || step.tagName;
    return  {
        element: this._getTourTagNameSelector(tagName),
        container: step.container || "body",
        autoscrollElement: step.autoscrollElement,
        orphan: step.orphan,
        animation: false,
        optional: step.optional,
        title: step.title,
        content: step.description,
        backdrop: step.darkBackground,
        backdropBackgroundCssClass: step.backdropBackgroundCssClass,
        backdropElementCssClass: step.backdropElementCssClass,
        placement: step.placement,
        offsetX: step.offsetX,
        offsetY: step.offsetY,
        width: step.width,
        delay: step.delay,
        template: this._getTemplate(step),
        disableClick: step.disableClick
    };
};

TourService.prototype._getTourTagNameSelector = function(tagName) {
    return  tagName ? "[tour-tag-name='" + tagName + "']:first" : null;
};

TourService.prototype._imageFlowStepsToTourSteps = function(flowSteps) {
    var _this = this;
    return flowSteps.map(function(step) {
        var selector = ".flow-modal-image-container";
        if (step.position)
            selector = "[image-flow-spot=\"" + step.position[0] + "-" + step.position[1] + "\"]";

        return {
            element: selector,
            container: "body",
            orphan: !step.position || step.orphan,
            title: step.title,
            content: step.description,
            placement: step.placement,
            delay: step.delay,
            template: _this._getTemplate(step)
        };
    });
};

TourService.prototype._getTourDb = function() {
    return this._xhrGet("/api/v3/unauthenticated/tourdb")
        .then((function(response) {
            return JSON.parse(response.content);
        }).bind(this), function(response) {
            console.error("Failed to get tourDb json", response);
        })
        ["catch"](function(error) {
        console.error("Failed to parse tourDb json", error);
    });
};

TourService.prototype._postEndTourEvent = function(flowName, stepIndex) {
    this._xhrPost("/api/v3/ui/adduievent", {
        eventName: "EndTour",
        parameters: [
            "flowName", flowName,
            "stepIndex", stepIndex
        ]
    });
};

TourService.prototype._xhrGet = function(path) {
    return this._doXhr("GET", path);
};

TourService.prototype._xhrPost = function(path, payload) {
    return this._doXhr("POST", path, payload);
};

TourService.prototype._doXhr = function(method, path, payload) {
    return new Promise((function(resolve, reject) {
        var xhr = new this._XMLHttpRequest();
        xhr.open(method, path);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (parseInt(xhr.status / 100) === 2)
                    resolve({status: xhr.status, content: xhr.responseText});
                else
                    reject({status: xhr.status, content: xhr.responseText});
            }
        };
        if (payload) {
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.setRequestHeader("Accept", "application/json");
            xhr.send(JSON.stringify(payload));
        } else {
            xhr.send();
        }
    }).bind(this));
};

TourService.prototype._getImageFlowStorageKey = function(name) {
    return "cs-image-tour-flow-" + name;
};

TourService.prototype._getFlowStorageKey = function(name) {
    return "cs-tour-flow-" + name;
};

TourService.prototype._getOnceStorageKey = function(name) {
    return "cs-tour-" + name;
};

TourService.prototype._getTemplate = function(step) {
    switch (step.template) {
        case "flow":
            return this._customizeTemplate(step, __webpack_require__(78));
        case "flow-without-exit":
            return this._customizeTemplate(step, __webpack_require__(82));
        case "flow-with-next":
            return this._customizeTemplate(step, __webpack_require__(80));
        case "flow-with-end":
            return this._customizeTemplate(step, __webpack_require__(79));
        case "flow-with-next-and-end":
            return this._customizeTemplate(step, __webpack_require__(81));
        case "show-once-flow":
            return this._customizeTemplate(step, __webpack_require__(84));
        case "show-once-flow-with-next":
            return this._customizeTemplate(step, __webpack_require__(85));
    }
};

TourService.prototype._customizeTemplate = function(step, template) {
    if (!step.nextLabel)
        return template;
    var dom = $(template);
    dom.find("[data-role=next]:nth-child(1)").text(step.nextLabel);
    return dom[0].outerHTML;
};

TourService.prototype._addImageFlowModal = function(flowName) {
    if (!this._imageFlowModalElements[flowName])
        this._imageFlowModalElements[flowName] = this._createImageFlowModalElement(flowName);
    var modal = this._imageFlowModalElements[flowName];
    if (modal.parent().length === 0) {
        $(document.body).append(modal);
        modal.fadeOut(0);
        modal.fadeIn(200);
    }
};

TourService.prototype._removeImageFlowModal = function(flowName) {
    var modalElement = this._imageFlowModalElements[flowName];
    if (modalElement) {
        modalElement.fadeOut(200, function() {
            modalElement.remove();
        });
    }
};

TourService.prototype._openImageFlowAnchorClicks = function() {
    var _this = this;
    window.addEventListener("click", function(e) {
        if (e.target && e.target.nodeName === "A" && e.target.attributes["image-flow"]) {
            var imageFlowName = e.target.attributes["image-flow"].value;
            _this.startImageFlow(imageFlowName);
        }
    }, true);
};

module.exports = TourService;

/***/ }),
/* 124 */
/***/ (function(module, exports, __webpack_require__) {

var bottle = __webpack_require__(122);

window.addEventListener("load", function() {
	bottle.container.TourService.init();
}, true);

module.exports = bottle.container.TourService;

/***/ }),
/* 125 */
/***/ (function(module, exports) {


function AuthenticationParameterProvider(hmacService) {
	this.hmacService = hmacService;
}

/*
	options = {
		url: entire request url (https://...),
		apiId
		apiKey
	}
*/
AuthenticationParameterProvider.prototype.get = function(options) {
	var params = getParameters(options);
	var hmac = getHmac(this, params);
	return getAuthString(params, hmac);
};

function getAuthString(params, hmac) {
	return "userapiid:" + params.apiId + ";timestamp:" + params.timestamp + ";token:" + params.token + ";hmac:" + hmac;
}

function getParameters(options) {
	return {
		apiId: options.apiId,
		apiKey: options.apiKey,
		timestamp: getTimestamp(),
		token: getReenterancyToken(),
		url: options.url
	};
}

function getReenterancyToken() {
	return Math.random().toString().substring(2, 12);
}

function getTimestamp() {
	return Math.floor(Date.now() / 1000);
}

function getHmac(self, params) {
	return self.hmacService.hash({
		apiKey: params.apiKey,
		url: params.url,
		timestamp: params.timestamp,
		token: params.token
	});
}

module.exports = AuthenticationParameterProvider;


/***/ }),
/* 126 */
/***/ (function(module, exports, __webpack_require__) {

var Bottle = __webpack_require__(13);
var bottle = new Bottle();

bottle.service('HMACService', __webpack_require__(128));
bottle.service('Http', __webpack_require__(129));
bottle.service('AuthenticationParameterProvider', __webpack_require__(125), 'HMACService');
bottle.service('CloudShareClient', __webpack_require__(127), 'Http', 'AuthenticationParameterProvider');

module.exports = bottle;

/***/ }),
/* 127 */
/***/ (function(module, exports, __webpack_require__) {

var Promise = __webpack_require__(5).Promise;

function CloudShareClient(http, authenticationParameterProvider) {
	this.http = http;
	this.authParamProvider = authenticationParameterProvider;
}

/*
	options = {
		[hostname],
		method,
		path,
		[queryParams],
		[content],
		[apiId],
		[apiKey]
	}
*/
CloudShareClient.prototype.req = function(options) {
	var self = this;
	return new Promise(function(resolve, reject) {
		options = validateAndMassageOptions(options, reject);
		resolve(request(self, options));
	});
};

function request(self, options) {
	return self.http.req({
		method: options.method,
		url: generateUrlWithoutQueryString(options),
		headers: getHeaders(self, options),
		queryParams: options.queryParams,
		content: options.content
	});
}

function getHeaders(self, options) {
	var headers = {
		'Content-Type': 'application/json',
		'Accept': 'application/json'
	};
	if (options.apiId && options.apiKey)
		headers['Authorization'] = 'cs_sha1 ' + getAuthParam(self, options);
	return headers;
}

function getAuthParam(self, options) {
	return self.authParamProvider.get({
		url: generateUrlWithQueryString(options),
		apiId: options.apiId,
		apiKey: options.apiKey
	});	
}

function validateAndMassageOptions(options, reject) {
	options = options || {};
	validateOptions(options, reject);
	prefixPathWithSlash(options);
	return options;
}

function prefixPathWithSlash(options) {
	if (options.path.indexOf('/') !== 0)
		options.path = '/' + options.path;
}

function validateOptions(options, reject) {
	if (!options.hostname)
		throw new Error("Missing hostname");
	else if (!options.method)
		throw new Error("Missing HTTP method");
	else if (!options.path)
		throw new Error("Missing path");
}

function generateUrlWithQueryString(options) {
	return generateUrlWithoutQueryString(options) + createQueryParams(options.queryParams);
}

function generateUrlWithoutQueryString(options) {
	return 'https://' + options.hostname + '/api/v3' + options.path;
}

function createQueryParams(obj) {
	if (!obj)
		return "";
	var str = [];
	for (var p in obj) {
	   if (obj.hasOwnProperty(p))
	       str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
	}
	return str.length > 0 ? "?" + str.join("&") : "";
}

function tryJSONParse(text) {
	try {
		return JSON.parse(text);
	} catch (e) {
		return text;
	}
}

module.exports = CloudShareClient;



/***/ }),
/* 128 */
/***/ (function(module, exports, __webpack_require__) {

var jssha = __webpack_require__(91);

function HMACService() {
	this.jssha = jssha;
}

HMACService.prototype.hash = function(params) {
	var text = params.apiKey + params.url + params.timestamp + params.token;
	return new this.jssha(text, 'TEXT').getHash('SHA-1', 'HEX');
}

module.exports = HMACService;

/***/ }),
/* 129 */
/***/ (function(module, exports, __webpack_require__) {

var Promise = __webpack_require__(5).Promise;

function Http() {

}

/*
	options = {
		method
		url
		headers [object]
		queryParams [object]
		content [object|string]
	}
*/
Http.prototype.req = function(options) {
	return new Promise(function(resolve, reject) {
		if (!options.method)
			throw new Error('HTTP method missing');
		else if (!options.url)
			throw new Error('URL is missing');		
		var xhr = new XMLHttpRequest();
		xhr.open(options.method, createUrl(options.url, options.queryParams));
		setHeaders(xhr, options.headers);
		xhr.onreadystatechange = function() {
			onReadyStateChange(xhr, resolve, reject);
		};
		send(xhr, options.content);
	});
}

function createUrl(url, queryParams) {
	if (typeof queryParams === 'object')
		return url + '?' + createQueryParams(queryParams);
	else
		return url;
}

function send(xhr, content) {
	if (typeof content === 'object')
		xhr.send(JSON.stringify(content));
	else if (typeof content === 'string')
		xhr.send(content);
	else
		xhr.send();
}

function onReadyStateChange(xhr, resolve, reject) {
	if (xhr.readyState !== 4)
		return;
	var content = parseResponseText(xhr);
	if (xhr.status >= 200 && xhr.status < 300) 
		resolve({content: content, status: xhr.status});
	else
		reject({content: content, status: xhr.status});
}

function parseResponseText(xhr) {
	if (isResponseJson(xhr))
		return JSON.parse(xhr.responseText);
	else
		return xhr.responseText;
}

function isResponseJson(xhr) {
	var contentType = xhr.getResponseHeader('Content-Type');
	return contentType && 
		   (contentType.indexOf('application/json') === 0 || contentType.indexOf('text/json') === 0);
}

function setHeaders(xhr, headers) {
	if (!headers)
		return;
	var headerNames = Object.keys(headers);
	for (var i = 0; i < headerNames.length; ++i) {
		var headerName = headerNames[i];
		xhr.setRequestHeader(headerName, headers[headerName]);
	}
}

function createQueryParams(obj) {
	var str = [];
	for(var p in obj){
	   if (obj.hasOwnProperty(p)) {
	       str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
	   }
	}
	return str.join("&");
}

function createDeferred() {
	var resolve, reject;
	var promise = new Promise(function(_resolve, _reject) {
		resolve = _resolve;
		reject = _reject;
	});
	return {
		promise: promise,
		reject: reject,
		resolve: resolve
	};
}

module.exports = Http;

/***/ }),
/* 130 */
/***/ (function(module, exports, __webpack_require__) {

var Bottle = __webpack_require__(13);
var bottle = new Bottle();

bottle.factory('CloudShareClient', function() { return __webpack_require__(12); });
bottle.service('SymkeyService', __webpack_require__(136));
bottle.service('KeyStrokesService', __webpack_require__(135), 'SymkeyService');
bottle.service('GuacamoleClientFactory', __webpack_require__(132));
bottle.service('CloudShareGuacamole', __webpack_require__(131), 'GuacamoleClientFactory', 'CloudShareClient', 'KeyStrokesService');

module.exports = bottle;

/***/ }),
/* 131 */
/***/ (function(module, exports, __webpack_require__) {

var Promise = __webpack_require__(5).Promise;
var GuacamoleStates = __webpack_require__(37);
var ControlSymkeys = __webpack_require__(36);

function CloudShareGuacamole(guacamoleClientFactory, csclient, keyStrokesService) {
	this.guacamoleClientFactory = guacamoleClientFactory;
	this.csclient = csclient;
	this.keyStrokesService = keyStrokesService;
	this.guacamoleClients = {};
	this.STATES = GuacamoleStates;
}

/*
	options = {
		id,
		url,
		containerElement,
		connectionConfiguration,
		cloudShareHostname,
		[apiId],
		[apiKey],
		[onstatechange],
		[onerror],
		[onclipboard],
		[onresize],
		[onsync]
	}
*/
CloudShareGuacamole.prototype.connect = function(options) {
	var self = this;
	return new Promise(function(resolve) {
		checkOptions(options);
		if (!isClientConnected(self, options.id))
			resolve(requestPasswordAndConnect(self, options));
		else
			resolve();
	});
};

CloudShareGuacamole.prototype.disconnect = function(id) {
	var self = this;
	return new Promise(function(resolve) {
		var client = self.guacamoleClients[id];
		if (client)
			resolve(client.disconnect());
		else
			resolve();
	});
};

CloudShareGuacamole.prototype.setClipboard = function(id, text) {
	var client = this.guacamoleClients[id];
	if (client)
		client.setClipboard(text);
};

CloudShareGuacamole.prototype.sendText = function(id, text) {
	var client = this.guacamoleClients[id];
	if (!client)
		return;
	var ks = this.keyStrokesService.toKeyStrokes(text);
	sendKeyStrokes(client, ks);
};

CloudShareGuacamole.prototype.sendCtrlAltDelete = function(id) {
	var client = this.guacamoleClients[id];
	if (!client)
		return;
	sendKeyStrokes(client, [
		{isDown: true, symkey: ControlSymkeys.CTRL },
		{isDown: true, symkey: ControlSymkeys.ALT },
		{isDown: true, symkey: ControlSymkeys.DELETE },
		{isDown: false, symkey: ControlSymkeys.CTRL },
		{isDown: false, symkey: ControlSymkeys.ALT },
		{isDown: false, symkey: ControlSymkeys.DELETE }
	]);
}

CloudShareGuacamole.prototype.sendWindowsKey = function(id) {
	var client = this.guacamoleClients[id];
	if (!client)
		return;
	sendKeyStrokes(client, [
		{isDown: true, symkey: ControlSymkeys.WIN },
		{isDown: false, symkey: ControlSymkeys.WIN }
	]);
}

CloudShareGuacamole.prototype.resize = function(id, width, height) {
	var client = this.guacamoleClients[id];
	if (client)
		client.resize(width, height);
};

CloudShareGuacamole.prototype.scale = function(id, scale) {
	var client = this.guacamoleClients[id];
	if (client)
		client.scale(scale);
};

CloudShareGuacamole.prototype.getScale = function(id) {
	var client = this.guacamoleClients[id];
	if (client)
		return client.getScale();
	else
		return 1;
};

CloudShareGuacamole.prototype.getShareProtocol = function(id) {
    var client = this.guacamoleClients[id];
    if (client)
        return client.getShareProtocol();
    else
        return null;
};

CloudShareGuacamole.prototype.getFlattenedCanvas = function(id) {
	var client = this.guacamoleClients[id];
	if (client)
		return client.getFlattenedCanvas();
};

CloudShareGuacamole.prototype.disableInputs = function(id) {
	var client = this.guacamoleClients[id];
	if (client)
		return client.disableInputs();	
};

CloudShareGuacamole.prototype.enableInputs = function(id) {
	var client = this.guacamoleClients[id];
	if (client)
		return client.enableInputs();	
};

CloudShareGuacamole.prototype.getConnectionType = function(id) {

    if (id === null || id === undefined || !(this.guacamoleClients[id]))
        return null;

    return this.guacamoleClients[id].getConnectionType();
};

function requestPasswordAndConnect(self, options) {
	return requestPassword(self, options)
	.then(function(response) {
		var client = getOrCreateGuacamoleClient(self,
                                                options,
                                                response.content.host,
                                                response.content.httpFallBackHost,
                                                response.content.protocol);
		return client.connect(response.content.key, response.content.node);
	})['catch'](function(response) {
		if (options.onerror)
			options.onerror(new Error("Failed to authenticate"));
	});
}

function isClientConnected(self, id) {
	var client = self.guacamoleClients[id];
	if (!client)
		return false;
	return client.currentState === GuacamoleStates.CONNECTING ||
			client.currentState === GuacamoleStates.WAITING ||
			client.currentState === GuacamoleStates.CONNECTED;
}

function getOrCreateGuacamoleClient(self, options, overrideHostname, overrideHttpHostname, shareProtocol) {
	if (!self.guacamoleClients[options.id]) {
		var client = self.guacamoleClients[options.id] = createGuacamoleClient(self, options, overrideHostname, overrideHttpHostname, shareProtocol);
		self.lastUsedHostName  = client.hostname;
		options.containerElement.appendChild(client.getElement());
	}
	return self.guacamoleClients[options.id];
}

function createGuacamoleClient(self, options, overrideHostname, overrideHttpHostname, shareProtocol) {
	return self.guacamoleClientFactory.getClient({
		hostname: overrideHostname || options.hostname,
		hostnameForHttpfailover: overrideHttpHostname || options.hostnameForHttpfailover,
        shareProtocol: shareProtocol,
		notSecure: !!options.notSecure,
		onstatechange: options.onstatechange || function() {},
		onerror: options.onerror || function() {},
		onclipboard: options.onclipboard || function() {},
		onresize: options.onresize || function() {},
        enablehttpfailover: options.enablehttpfailover !== undefined ? options.enablehttpfailover : false,
		onsync: options.onsync || function() {},
		onlogsync: options.onlogsync || function() {},
		onhttpfallback: options.onhttpfallback || function() {},
	});
}

function requestPassword(self, options) {
	return self.csclient.req({
		hostname: options.cloudShareHostname,
		method: 'POST',
		path: 'GuacamoleConnection',
		apiId: options.apiId,
		apiKey: options.apiKey,
		content: options.connectionConfiguration
	});
}

function checkOptions(options) {
	if (!options)
		throw new Error('Missing options');
	else if (options.id !== 0 && !options.id)
		throw new Error('Missing ID parameter');
	else if (!options.hostname)
		throw new Error('Missing hostname parameter');
	else if (!options.containerElement)
		throw new Error('Missing containerElement parameter');
	else if (!options.connectionConfiguration)
		throw new Error('Missing connectionConfiguration parameter');
	else if (!options.cloudShareHostname)
		throw new Error('Missing cloudShareHostname parameter');
}

function sendKeyStrokes(client, keyStrokes) {
	for (var i = 0; i < keyStrokes.length; ++i) {
		var k = keyStrokes[i];
		if (k.isDown)
			client.sendSymkeyDown(k.symkey);
		else
			client.sendSymkeyUp(k.symkey);
	}
}

module.exports = CloudShareGuacamole;

/***/ }),
/* 132 */
/***/ (function(module, exports, __webpack_require__) {

var GuacamoleClient = __webpack_require__(133);

function GuacamoleClientFactory() {

}

/*
	options = {
		url,
		[onstatechange,]
		[onclipboard,]
		[onerror]
	}
*/
GuacamoleClientFactory.prototype.getClient = function(options) {
	var client = new GuacamoleClient(options);
	client.setup();
	return client;
};

module.exports = GuacamoleClientFactory;

/***/ }),
/* 133 */
/***/ (function(module, exports, __webpack_require__) {

var Guacamole = __webpack_require__(29);
var GuacamoleStates = __webpack_require__(37);
var GuacamoleError = __webpack_require__(134);
var Promise = __webpack_require__(5).Promise;
var webpDetect = __webpack_require__(137);

var Guacamole_Disconnected_Event_Id = 5;

/*
	options = {
		hostname,
		[notSecure],
		[onstatechange,]
		[onclipboard,]
		[onerror]
	}
*/
function GuacamoleClient(options) {
	checkOptions(options);
	this.tunnel = null;
	this.client = null;
	this.element = null;
	this.keyboard = null;
	this.mouse = null;
	this.hostname = options.hostname;
	this.notSecure = options.notSecure;
	this.onstatechange = options.onstatechange || function() {};
	this.onclipboard = options.onclipboard || function() {};
	this.onerror = options.onerror || function() {};
	this.onresize = options.onresize || function() {};
	this.onsync = options.onsync || function() {};
	this.onlogsync = options.onlogsync || function() {};
	this.onhttpfallback = options.onhttpfallback || function() {};
	this.connectedOnHttp = false;
	this.currentState = GuacamoleStates.IDLE;
	this.resolveDisconnect = null;
	this.resolveConnect = null;
	this.rejectConnect = null;
	this.inputsDisabled = false;
	this.connected = false;
	this.lastError = null;
	this.hostnameForHttpfailover = options.hostnameForHttpfailover || options.hostname;
	this.shareProtocol = options.shareProtocol;
    this.isWebpSupported = webpDetect.isWebpSupported;
	this.syncTimings = createSyncTimingsObject();
	this.beforeUnloadHandler = null;
}

GuacamoleClient.prototype.setup = function() {
    this.wsTunnel1 = new Guacamole.WebSocketTunnel(createUrl(this.notSecure, this.hostname));
    this.wsTunnel2 = new Guacamole.WebSocketTunnel(createUrl(this.notSecure, this.hostname));
    this.httpTunnel = new Guacamole.HTTPTunnel(createHttpsUrl(this.notSecure, this.hostnameForHttpfailover), true);
	

	var onStateChangeHandler = this.onstatechange;

	this.tunnel = new Guacamole.ChainedTunnel(this.wsTunnel1, this.wsTunnel2, this.httpTunnel);

	this.client = new Guacamole.Client(this.tunnel);

    setClientHandlers(this);
	this.element = createElement(this.client);
    this.keyboard = createGuacamoleKeyboard(this, this.element, this.client);
    this.mouse = createGuacamoleMouse(this, this.client);
    this.client.getDisplay().onresize = this.onresize;
    tryEnablingHardwareMouseCursor(this);
    setDisconnectOnBeforeUnload(this);
};

function tryEnablingHardwareMouseCursor(self) {
	self.client.getDisplay().oncursor = function(canvas, x, y) {
		self.client.getDisplay().showCursor(!self.mouse.setCursor(canvas, x, y));
	};
}

function createUrl(notSecure, hostname) {
	return (notSecure ? "ws://" : "wss://") + hostname + "/cloudshare-guacamole/websocket-tunnel";
}

function createHttpsUrl(notSecure, hostname) {
    return (notSecure ? "http://" : "https://") + hostname + "/cloudshare-guacamole/tunnel";
}

GuacamoleClient.prototype.getConnectionType = function(){

    if ( (this.wsTunnel1.state && this.wsTunnel1.state == 1) || (this.wsTunnel2.state && this.wsTunnel2.state == 1))
        return 'WebSocket';

    if (this.httpTunnel.state && this.httpTunnel.state == 1)
        return 'HTTP';

    return null;
}

GuacamoleClient.prototype.getTunnelsData = function() {
	return {
		wsTunnel1: this.wsTunnel1.state,
		wsTunnel2: this.wsTunnel2.state,
		httpTunnel: this.httpTunnel.state
	};
};

GuacamoleClient.prototype.connect = function(password, node) {
	var self = this;
	return new Promise(function(resolve, reject) {
		self.resolveConnect = resolve;
		self.rejectConnect = reject;
        if (node)
            self.client.connect("token=" + password + "&node=" + encodeURIComponent(node) + "&webp=" + self.isWebpSupported);
        else
		    self.client.connect("token=" + password + "&webp=" + self.isWebpSupported);
	});
};

GuacamoleClient.prototype.disconnect = function() {
	var self = this;
	return new Promise(function(resolve) {
		if (self.currentState === GuacamoleStates.DISCONNECTED || self.currentState === GuacamoleStates.DISCONNECTING){
			resolve();
		} else {
			self.resolveDisconnect = resolve;
			self.client.disconnect();
		}
	});
};

GuacamoleClient.prototype.resize = function(width, height) {
	this.client.sendSize(width, height);
};

GuacamoleClient.prototype.scale = function(scale) {
	this.client.getDisplay().scale(scale);
};

GuacamoleClient.prototype.setClipboard = function(text) {
	this.client.setClipboard(text);
};

GuacamoleClient.prototype.sendSymkeyUp = function(symkey) {
	this.client.sendKeyEvent(0, symkey);
};

GuacamoleClient.prototype.sendSymkeyDown = function(symkey) {
	this.client.sendKeyEvent(1, symkey);
};

GuacamoleClient.prototype.getElement = function() {
	return this.element;
};

GuacamoleClient.prototype.getFlattenedCanvas = function() {
	return this.client.getDisplay().flatten();
};

GuacamoleClient.prototype.getScale = function() {
	return this.client.getDisplay().getScale();
};

GuacamoleClient.prototype.getShareProtocol = function() {
	return this.shareProtocol || null;
};

GuacamoleClient.prototype.disableInputs = function() {
	this.inputsDisabled = true;
};

GuacamoleClient.prototype.enableInputs = function() {
	this.inputsDisabled = false;
};

function checkOptions(options) {
	if (!options)
		throw new Error('Missing options object parameter');
	if (!options.hostname)
		throw new Error('Missing hostname parameter');
}

function createElement(client, options) {
	var element = document.createElement('div');
	element.appendChild(client.getDisplay().getElement());
	element.appendChild(createTextArea());	
	
	return element;
}

function createTextArea() {
	var textarea = document.createElement('textarea');
	textarea.style.position = "absolute";
	textarea.style.top = '0px';
	textarea.style.left = '-999999px';
	return textarea;
}

function updateSyncTimings(self) {
	var t = +new Date();
	var c = self.syncTimings.count;
	var a = self.syncTimings.intervalAverage;
	var a2 = self.syncTimings.intervalAverage2;
	var dt = t - self.syncTimings.lastTime;
	var dt2 = dt * dt;
	a = (dt + c * a) / (c + 1);
	a2 = (dt2 + c * a2) / (c + 1);

	self.syncTimings.lastTime = t;
	self.syncTimings.lastDeltaTime = dt;
	self.syncTimings.count += 1;
	self.syncTimings.intervalAverage = a;
	self.syncTimings.intervalAverage2 = a2;
	self.syncTimings.intervalStandardDeviation = Math.sqrt(a2 - a*a);

	var is = Object.keys(self.syncTimings.maxIntervals);
	is.forEach(function(i) {
		var mi = self.syncTimings.maxIntervals[i];
		if (dt > mi.value)
			mi.value = dt;
	});
}

function startSyncTimingsLog(self) {
	self.syncTimings = createSyncTimingsObject();
	self.logsyncTimeoutId = runInterval();

	function runInterval() {
		if (self.currentState !== GuacamoleStates.CONNECTED)
			return;

		var now = +new Date();
		var logParameters = {
			intervalAverage: self.syncTimings.intervalAverage,
			intervalStandardDeviation: self.syncTimings.intervalStandardDeviation,
			maxIntervals: {}
		};
		var is = Object.keys(self.syncTimings.maxIntervals);
		is.forEach(function(i) {
			var mi = self.syncTimings.maxIntervals[i];
			var intervalMs = i[i.length - 1] == "m" ? parseInt(i) * 60 * 1000 : parseInt(i) * 1000;
			if (now - mi.timestamp >= intervalMs) {
				logParameters.maxIntervals[i] = mi.value;
				mi.value = 0;
				mi.timestamp = now;
			}
		});
		self.onlogsync(logParameters);
		return setTimeout(runInterval, self.syncTimings.gcdIntervalMs);
	}
}

function stopSyncTimingsLog(self) {
	clearTimeout(self.logsyncTimeoutId);
	self.logsyncTimeoutId = 0;
}

function createSyncTimingsObject() {
	var now = +new Date();
	return {
		lastTime: now,
		count: 0,
		intervalAverage: 0,
		intervalAverage2: 0,
		intervalStandardDeviation: 0,
		gcdIntervalMs: 60000,
		maxIntervals: {
			"1m": { value: 0, timestamp: now },
			"2m": { value: 0, timestamp: now },
			"5m": { value: 0, timestamp: now },
			"30m": { value: 0, timestamp: now }
		}
	};
}

function setClientHandlers(self) {
	setOnClipboard(self.client, self.onclipboard);
	self.client.onstatechange = function(state) {
		handleClientStateChange(self, state);
	};
	self.client.onerror = errorHandler;
	self.tunnel.onerror = errorHandler;
	self.client.onsync = function(arg) {
		if (self.currentState !== GuacamoleStates.CONNECTED)
			return;
		updateSyncTimings(self);
		if (window.printSync)
			console.info("dt:%d\tavg:%d", self.syncTimings.lastDeltaTime, self.syncTimings.intervalAverage);
		self.onsync(arg, self.syncTimings);
	};

	function errorHandler(err) {
		self.lastError = err;
		self.onerror(new GuacamoleError(err, self.getTunnelsData()));
		self.client.disconnect();
	}
}

function handleClientStateChange(self, state) {
	if (self.currentState === state)
		return;
	self.currentState = state;
	resolveDisconnectPromiseIfDisconnectedAndRejectConnectIfNotConnected(self, state);
	resolveConnectPromiseIfConnected(self, state);
	if (self.currentState === GuacamoleStates.CONNECTED)
		startSyncTimingsLog(self);
	else
		stopSyncTimingsLog(self);

	emitHttpFallbackEvent(self);

	self.onstatechange(state);
}

function emitHttpFallbackEvent(self) {
	if (!self.connectedOnHttp &&
		self.httpTunnel.state !== Guacamole.Tunnel.State.CONNECTING &&
		(self.currentState === GuacamoleStates.CONNECTED ||
		 self.currentState === GuacamoleStates.DISCONNECTED)) {
		
		self.connectedOnHttp = true;
		self.onhttpfallback();
	}

	if (self.currentState === GuacamoleStates.DISCONNECTED) {
		 self.connectedOnHttp = false;
	}
}

function resolveDisconnectPromiseIfDisconnectedAndRejectConnectIfNotConnected(self, state) {
	if (state === GuacamoleStates.DISCONNECTED && self.resolveDisconnect) {
		if (!self.connected && self.rejectConnect)
			self.rejectConnect(self.lastError);
		self.connected = false;
		self.previousElementDisplayStyle = self.element.style.display;
		self.element.style.display = "none";
		self.resolveDisconnect();
	}
}

function resolveConnectPromiseIfConnected(self, state) {
	if (state === GuacamoleStates.CONNECTED && self.resolveConnect) {
		self.connected = true;
		self.lastError = null;
		if (self.element.style.display === "none")
			self.element.style.display = self.previousElementDisplayStyle || "";
		self.resolveConnect();
	}
}

function setOnClipboard(client, onclipboard) {
	client.onclipboard = function(inputStream) {
		var sr = new Guacamole.StringReader(inputStream);
        sr.ontext = function(text) {
			onclipboard(text);
        };
	};
}

function createGuacamoleKeyboard(self, element, client) {
	var textarea = element.querySelector('textarea');
	var keyboard = new Guacamole.Keyboard(textarea);
	keyboard.onkeydown = function(keySym) {
		if (!self.inputsDisabled)
			client.sendKeyEvent(1, keySym);
	};
	keyboard.onkeyup = function(keySym) {
		if (!self.inputsDisabled)
			client.sendKeyEvent(0, keySym);
	};
	element.addEventListener('click', function() {
		textarea.focus();
	});
	return keyboard;
}

function createGuacamoleMouse(self, client) {
	var mouse = new Guacamole.Mouse(client.getDisplay().getElement());
	mouse.onmousemove = mouseEventHandler;
	mouse.onmouseup = mouseEventHandler;
	mouse.onmousedown = mouseEventHandler;
	return mouse;

	function mouseEventHandler(mouseState) {
		if (self.inputsDisabled)
			return;
		var element = client.getDisplay().getElement();
		if (mouseState.x < 0 || mouseState.x >= element.offsetWidth ||
				mouseState.y < 0 || mouseState.y >= element.offsetHeight)
            return;
		var scale = client.getDisplay().getScale();
		client.sendMouseState(new Guacamole.Mouse.State(
							mouseState.x / scale,
                            mouseState.y / scale,
                            mouseState.left,
                            mouseState.middle,
                            mouseState.right,
                            mouseState.up,
                            mouseState.down))
	};
}

function setDisconnectOnBeforeUnload(self) {
	if (self.beforeUnloadHandler) {
		document.removeEventListener('beforeunload', self.beforeUnloadHandler);
	}
	self.beforeUnloadHandler = function() {
		self.client.disconnect();
	};
	document.addEventListener('beforeunload', self.beforeUnloadHandler);
}

module.exports = GuacamoleClient;

/***/ }),
/* 134 */
/***/ (function(module, exports, __webpack_require__) {

var Guacamole = __webpack_require__(29);

function GuacamoleError(errorArg, tunnelsData) {
	this._errorArg = errorArg;
	this._tunnelsData = tunnelsData;
}

GuacamoleError.prototype.toLogString = function() {
	return this._errorArgToString() + " : " + this._tunnelsDataToString();
};

GuacamoleError.prototype.toClientString = function() {
    var result = "";
	if (this._errorArg instanceof Guacamole.Status &&
        this._errorTable[this._errorArg.code] &&
        this._errorTable[this._errorArg.code].clientDescription) {
        result = this._errorTable[this._errorArg.code].clientDescription;
    }
    return result;
};

GuacamoleError.prototype.shouldReconnect = function() {
    if (this._errorArg instanceof Guacamole.Status)
        return !!(this._errorTable[this._errorArg.code] && this._errorTable[this._errorArg.code].shouldReconnect);
	return false;
};

GuacamoleError.prototype._errorArgToString = function() {
    var errorTableEntry = this._errorTable[this._errorArg.code];
	if (errorTableEntry)
		return 'Status(' + this._errorArg.code + ', ' + errorTableEntry.name + ", " + errorTableEntry.logDescription + ", " + this._errorArg.message + ')';
	else
		return 'Status(' + this._errorArg.code + ', ' + this._errorArg.message + ')';
};

GuacamoleError.prototype._tunnelsDataToString = function() {
    return "TunnelsData(" + 
            "wsTunnel1=" + this._tunnelsData.wsTunnel1 + ", " +
            "wsTunnel2=" + this._tunnelsData.wsTunnel2 + ", " +
            "httpTunnel=" + this._tunnelsData.httpTunnel + ")";
};

GuacamoleError.prototype._errorTable = {
    0x0000: {
        name: "SUCCESS",
        logDescription: "The operation succeeded",
        shouldReconnect: false
    },

    0x0100: {
        name: "UNSUPPORTED",
        logDescription: "The requested operation is unsupported.",
        shouldReconnect: true
    },

    0x0200: {
        name: "SERVER_ERROR",
        logDescription: "The operation could not be performed due to an internal failure.",
        shouldReconnect: true
    },

    0x0201: {
        name: "SERVER_BUSY",
        logDescription: "The operation could not be performed as the server is busy.",
        shouldReconnect: true
    },

    0x0202: {
        name: "UPSTREAM_TIMEOUT",
        logDescription: "The operation could not be performed because the upstream server is not responding.",
        clientDescription: "The remote machine stopped responding",
        shouldReconnect: true
    },

    0x0203: {
        name: "UPSTREAM_ERROR",
        logDescription: "The operation was unsuccessful due to an error or otherwise unexpected condition of the upstream server.",
        clientDescription: "An error occurred on the remote machine",
        shouldReconnect: true
    },

    0x0204: {
        name: "RESOURCE_NOT_FOUND",
        logDescription: "The operation could not be performed as the requested resource does not exist.",
        shouldReconnect: true
    },

    0x0205: {
        name: "RESOURCE_CONFLICT",
        logDescription: "The operation could not be performed as the requested resource is already in use.",
        shouldReconnect: true
    },

    0x0206: {
        name: "RESOURCE_CLOSED",
        logDescription: "The operation could not be performed as the requested resource is now closed.",
        shouldReconnect: true
    },

    0x0207: {
        name: "UPSTREAM_NOT_FOUND",
        logDescription: "The operation could not be performed because the upstream server does not appear to exist.",
        clientDescription: "The remote machine was not found",
        shouldReconnect: true
    },

    0x0208:  {
        name: "UPSTREAM_UNAVAILABLE",
        logDescription: "The operation could not be performed because the upstream server is not available to service the request.",
        clientDescription: "The remote machine stopped responding",
        shouldReconnect: true
    },

    0x0209: {
        name: "SESSION_CONFLICT",
        logDescription: "The session within the upstream server has ended because it conflicted with another session.",
        clientDescription: "You have been logged out because another user connected to the remote machine",
        shouldReconnect: false
    },

    0x020A: {
        name: "SESSION_TIMEOUT",
        logDescription: "The session within the upstream server has ended because it appeared to be inactive.",
        clientDescription: "You have been logged out by the remote machine due to inactivity",
        shouldReconnect: true
    },

    0x020B: {
        name: "SESSION_CLOSED",
        logDescription: "The session within the upstream server has been forcibly terminated.",
        clientDescription: "You have been logged out by the remote machine",
        shouldReconnect: false
    },

    0x0300: {
        name: "CLIENT_BAD_REQUEST",
        logDescription: "The operation could not be performed because bad parameters were given.",
        shouldReconnect: true
    },

    0x0301: {
        name: "CLIENT_UNAUTHORIZED",
        logDescription: "Permission was denied to perform the operation, as the user is not yet authorized (not yet logged in, for example.",
        shouldReconnect: false
    },

    0x0303: {
        name: "CLIENT_FORBIDDEN",
        logDescription: "Permission was denied to perform the operation, and this permission will not be granted even if the user is authorized.",
        shouldReconnect: false
    },

    0x0308: {
        name: "CLIENT_TIMEOUT",
        logDescription: "client took too long to respond",
        shouldReconnect: true
    },

    0x030D: {
        name: "CLIENT_OVERRUN",
        logDescription: "The client sent too much data.",
        shouldReconnect: true
    },

    0x030F: {
        name: "CLIENT_BAD_TYPE",
        logDescription: "The client sent data of an unsupported or unexpected type.",
        shouldReconnect: true
    },

    0x031D: {
        name: "CLIENT_TOO_MANY",
        logDescription: "The operation failed because the current client is already using too many resources.",
        shouldReconnect: true
    }
};

module.exports = GuacamoleError;

/***/ }),
/* 135 */
/***/ (function(module, exports, __webpack_require__) {

var ControlSymkeys = __webpack_require__(36);

function KeyStrokesService(symkeyService) {
	this.symkeyService = symkeyService;
}

KeyStrokesService.prototype.toKeyStrokes = function(text) {
	var result = [];
	for (var i = 0; i < text.length; ++i) {
		var c = text[i];
		if (isLineBreak(c))
			pushKeyStrokeSymkey(result, ControlSymkeys.ENTER);
		else if (isShifted(c)) 
			pushShiftedKeyStrokeChar(this, result, c);
		else
			pushKeyStrokeChar(this, result, c);
	}
	return result;
};

function pushShiftedKeyStrokeChar(self, result, c) {
	result.push(downKeyStroke(ControlSymkeys.SHIFT));
	pushKeyStrokeChar(self, result, c);
	result.push(upKeyStroke(ControlSymkeys.SHIFT));
}

function pushKeyStrokeChar(self, result, c) {
	result.push(toDownKeyStroke(self, c));
	result.push(toUpKeyStroke(self, c));
}

function pushKeyStrokeSymkey(result, symkey) {
	result.push(downKeyStroke(symkey));
	result.push(upKeyStroke(symkey));
}

function isLineBreak(c) {
	return c === "\n";
}

function isShifted(c) {
	return isUpperCase(c) || isSpecial(c);	
}

function isSpecial(c) {
	return '!@#$%^&*()_?|:+{}<>~"'.indexOf(c) !== -1;
}

function isUpperCase(c) {
	return c >= 'A' && c <= 'Z';
}

function downKeyStroke(symkey) {
	return {
		isDown: true,
		symkey: symkey
	};
}

function upKeyStroke(symkey) {
	return {
		isDown: false,
		symkey: symkey
	};
}

function toDownKeyStroke(self, c) {
	return {
		isDown: true,
		symkey: self.symkeyService.toSymKey(c)
	};
}

function toUpKeyStroke(self, c) {
	return {
		isDown: false,
		symkey: self.symkeyService.toSymKey(c)
	};
}

module.exports = KeyStrokesService;

/***/ }),
/* 136 */
/***/ (function(module, exports) {

function SymkeyService() {
	
}

SymkeyService.prototype.toSymKey = function(text) {
	var charcode = text.charCodeAt(0);
	if (isControlCharacter(charcode))
		return 0xFF00 | charcode;
	if (isASCII(charcode))
		return charcode;
	if (isUnicodeCharacter(charcode))
		return 0x01000000 | charcode;
	return null;
};

function isASCII(charcode) {
	return charcode >= 0x00 && charcode <= 0xFF;
}

function isControlCharacter(charcode) {
    return charcode <= 0x1F || (charcode >= 0x7F && charcode <= 0x9F);
}

function isUnicodeCharacter(charcode) {
	return charcode > 0xFF && charcode < 0x110000;
}

module.exports = SymkeyService;

/***/ }),
/* 137 */
/***/ (function(module, exports) {

var webpDetect = {
    isWebpSupported: false
};

function hasWebP() {
    var img = new Image();
    img.onload = function() {
        webpDetect.isWebpSupported = true;
    };
    img.onerror = function() {
        webpDetect.isWebpSupported = false;
    };
    img.src = "data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==";
}

hasWebP();

module.exports = webpDetect;


/***/ }),
/* 138 */
/***/ (function(module, exports, __webpack_require__) {

var _ = __webpack_require__(24);

function HeartbeatDispatcher(websocketsConnector) {
    this.websocketsConnector = websocketsConnector;
    this.registeredCallbacks = {};
    this.pendingActions = {};
    this.noWebSocket = false;
    this.inited = false;
}

HeartbeatDispatcher.prototype.register = function(action, callback) {

    if (!this.registeredCallbacks[action]) {
        this.registeredCallbacks[action] = [];
    }
    this.registeredCallbacks[action].push(callback);

    // Push to pending actions - for invalidating
    this.pendingActions[action] = action;
};

HeartbeatDispatcher.prototype.clearRegistration = function() {
    this.registeredCallbacks = {};
};

HeartbeatDispatcher.prototype.notifyRegisters = function(action) {
    var callbacks = this.registeredCallbacks[action];
    if (callbacks) {
        _.each(callbacks, function(callback) {
            callback();
        });
    }
};

HeartbeatDispatcher.prototype.init = function(data, bufferTime, fallback) {
    var that = this;

    if (that.inited)
        return;

    that.inited = true;

    if (this.noWebSocket) {
        if (fallback) fallback();
        return;
    }

    if (!bufferTime) {
        throw new Error("'bufferTime' must be provided!");
    }

    var doFallback = function () {
        if (fallback) {
            that.noWebSocket = true;
            fallback();
        }
    };

    console.info("ws-heartbeats: connecting with " + bufferTime + " seconds buffer time");

    return this.websocketsConnector.connect(data, doFallback).done(function () {
        if (that.noWebSocket) return;
        that.bufferTime = that.bufferTime || 1000000;

        that.websocketsConnector.notify = function (action) {
            that.pendingActions[action] = action;
        };

        if (that.bufferTime > bufferTime) {
            that.bufferTime = bufferTime;

            if (that.refreshIntervalId) {
                clearInterval(that.refreshIntervalId);
            }

            that.refreshIntervalId = setInterval(function () {
                _.each(that.pendingActions, function (action) {
                    that.notifyRegisters(action);
                });
                that.pendingActions = {};
            }, that.bufferTime * 1000);
        }
    });
};

HeartbeatDispatcher.prototype.stop = function() {
    this.websocketsConnector.notify = null;
    clearInterval(this.refreshIntervalId);
};

module.exports = HeartbeatDispatcher;


/***/ }),
/* 139 */
/***/ (function(module, exports, __webpack_require__) {

var _ = __webpack_require__(24);

var $ = __webpack_require__(11);

function WebSocketsConnector(csws, url, controller) {
    this.csws = csws;
    this.url = url;
    this.controller = controller;
    this.webSocketsClient = null;
    this.notify = null;

    this.RETRY_DELAY = 5000;
}

WebSocketsConnector.prototype.connect = function (data, fallback) {
    var that = this;
    return $.ajax({
        url: that.url,
        data: data
    }).done(function (webSocketData) {
        that._connectToWebsockets(webSocketData, data, fallback);
    });
};

WebSocketsConnector.prototype._connectToWebsockets = function (webSocketData, connectionData, fallback) {
    var that = this;

    var fallbackCalled = false;

    this.csws.listen({
        protocolAndHost: webSocketData.url,
        dispatcherName: this.controller,
        token: webSocketData.token,
        tokenRefresher: this._createTokenRefresher(connectionData),
        onopen: function(e) {
            console.info("ws-heartbeats: connected");
        },  
        ontopicListeners: {
            message: function(message) {
                if (that.notify)
                    that.notify(message.action);
            }
        },
        onerror: callFallbackOnceIfDefined,
        onclose: callFallbackOnceIfDefined,
        noRetry: !!fallback
    });

    function callFallbackOnceIfDefined() {
        if (fallback && !fallbackCalled) {
            console.error("ws-heartbeats: disconnected, using fallback");
            fallbackCalled = true;
            fallback();
        }
    }

};

WebSocketsConnector.prototype._createTokenRefresher = function(data) {
    return function() {
        return $.ajax({
            url: this.url,
            data: data
        })
        .then(function (webSocketData) {
            return webSocketData.token;
        });
    };
}

module.exports = WebSocketsConnector;

/***/ }),
/* 140 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(Buffer) {module.exports =
/******/ (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;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// 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 = "/resources/js/csClient/min/";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./src/Controls/SparkClient/index.deploy.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./node_modules/base64-js/index.js":
/*!*****************************************!*\
  !*** ./node_modules/base64-js/index.js ***!
  \*****************************************/
/*! no static exports found */
/***/ (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
}

// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63

function getLens (b64) {
  var len = b64.length

  if (len % 4 > 0) {
    throw new Error('Invalid string. Length must be a multiple of 4')
  }

  // Trim off extra bytes after placeholder bytes are found
  // See: https://github.com/beatgammit/base64-js/issues/42
  var validLen = b64.indexOf('=')
  if (validLen === -1) validLen = len

  var placeHoldersLen = validLen === len
    ? 0
    : 4 - (validLen % 4)

  return [validLen, placeHoldersLen]
}

// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function _byteLength (b64, validLen, placeHoldersLen) {
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function toByteArray (b64) {
  var tmp
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]

  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))

  var curByte = 0

  // if there are placeholders, only get up to the last complete 4 chars
  var len = placeHoldersLen > 0
    ? validLen - 4
    : validLen

  var i
  for (i = 0; i < len; i += 4) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 18) |
      (revLookup[b64.charCodeAt(i + 1)] << 12) |
      (revLookup[b64.charCodeAt(i + 2)] << 6) |
      revLookup[b64.charCodeAt(i + 3)]
    arr[curByte++] = (tmp >> 16) & 0xFF
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 2) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 2) |
      (revLookup[b64.charCodeAt(i + 1)] >> 4)
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 1) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 10) |
      (revLookup[b64.charCodeAt(i + 1)] << 4) |
      (revLookup[b64.charCodeAt(i + 2)] >> 2)
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = 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) & 0xFF0000) +
      ((uint8[i + 1] << 8) & 0xFF00) +
      (uint8[i + 2] & 0xFF)
    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 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]
    parts.push(
      lookup[tmp >> 2] +
      lookup[(tmp << 4) & 0x3F] +
      '=='
    )
  } else if (extraBytes === 2) {
    tmp = (uint8[len - 2] << 8) + uint8[len - 1]
    parts.push(
      lookup[tmp >> 10] +
      lookup[(tmp >> 4) & 0x3F] +
      lookup[(tmp << 2) & 0x3F] +
      '='
    )
  }

  return parts.join('')
}


/***/ }),

/***/ "./node_modules/buffer-shims/index.js":
/*!********************************************!*\
  !*** ./node_modules/buffer-shims/index.js ***!
  \********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(global) {

var buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js");
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(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/buffer/index.js":
/*!**************************************!*\
  !*** ./node_modules/buffer/index.js ***!
  \**************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(global) {/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <http://feross.org>
 * @license  MIT
 */
/* eslint-disable no-proto */



var base64 = __webpack_require__(/*! base64-js */ "./node_modules/base64-js/index.js")
var ieee754 = __webpack_require__(/*! ieee754 */ "./node_modules/ieee754/index.js")
var isArray = __webpack_require__(/*! isarray */ "./node_modules/isarray/index.js")

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(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/core-util-is/lib/util.js":
/*!***********************************************!*\
  !*** ./node_modules/core-util-is/lib/util.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (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(this, __webpack_require__(/*! ./../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer))

/***/ }),

/***/ "./node_modules/events/events.js":
/*!***************************************!*\
  !*** ./node_modules/events/events.js ***!
  \***************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// 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 R = typeof Reflect === 'object' ? Reflect : null
var ReflectApply = R && typeof R.apply === 'function'
  ? R.apply
  : function ReflectApply(target, receiver, args) {
    return Function.prototype.apply.call(target, receiver, args);
  }

var ReflectOwnKeys
if (R && typeof R.ownKeys === 'function') {
  ReflectOwnKeys = R.ownKeys
} else if (Object.getOwnPropertySymbols) {
  ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target)
      .concat(Object.getOwnPropertySymbols(target));
  };
} else {
  ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target);
  };
}

function ProcessEmitWarning(warning) {
  if (console && console.warn) console.warn(warning);
}

var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
  return value !== value;
}

function EventEmitter() {
  EventEmitter.init.call(this);
}
module.exports = EventEmitter;
module.exports.once = once;

// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;

EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
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.
var defaultMaxListeners = 10;

function checkListener(listener) {
  if (typeof listener !== 'function') {
    throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
  }
}

Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
  enumerable: true,
  get: function() {
    return defaultMaxListeners;
  },
  set: function(arg) {
    if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
      throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
    }
    defaultMaxListeners = arg;
  }
});

EventEmitter.init = function() {

  if (this._events === undefined ||
      this._events === Object.getPrototypeOf(this)._events) {
    this._events = Object.create(null);
    this._eventsCount = 0;
  }

  this._maxListeners = this._maxListeners || undefined;
};

// 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 setMaxListeners(n) {
  if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
    throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
  }
  this._maxListeners = n;
  return this;
};

function _getMaxListeners(that) {
  if (that._maxListeners === undefined)
    return EventEmitter.defaultMaxListeners;
  return that._maxListeners;
}

EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
  return _getMaxListeners(this);
};

EventEmitter.prototype.emit = function emit(type) {
  var args = [];
  for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
  var doError = (type === 'error');

  var events = this._events;
  if (events !== undefined)
    doError = (doError && events.error === undefined);
  else if (!doError)
    return false;

  // If there is no 'error' event listener then throw.
  if (doError) {
    var er;
    if (args.length > 0)
      er = args[0];
    if (er instanceof Error) {
      // Note: The comments on the `throw` lines are intentional, they show
      // up in Node's output if this results in an unhandled exception.
      throw er; // Unhandled 'error' event
    }
    // At least give some kind of context to the user
    var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
    err.context = er;
    throw err; // Unhandled 'error' event
  }

  var handler = events[type];

  if (handler === undefined)
    return false;

  if (typeof handler === 'function') {
    ReflectApply(handler, this, args);
  } else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      ReflectApply(listeners[i], this, args);
  }

  return true;
};

function _addListener(target, type, listener, prepend) {
  var m;
  var events;
  var existing;

  checkListener(listener);

  events = target._events;
  if (events === undefined) {
    events = target._events = Object.create(null);
    target._eventsCount = 0;
  } else {
    // To avoid recursion in the case that type === "newListener"! Before
    // adding it to the listeners, first emit "newListener".
    if (events.newListener !== undefined) {
      target.emit('newListener', type,
                  listener.listener ? listener.listener : listener);

      // Re-assign `events` because a newListener handler could have caused the
      // this._events to be assigned to a new object
      events = target._events;
    }
    existing = events[type];
  }

  if (existing === undefined) {
    // Optimize the case of one listener. Don't need the extra array object.
    existing = events[type] = listener;
    ++target._eventsCount;
  } else {
    if (typeof existing === 'function') {
      // Adding the second element, need to change to array.
      existing = events[type] =
        prepend ? [listener, existing] : [existing, listener];
      // If we've already got an array, just append.
    } else if (prepend) {
      existing.unshift(listener);
    } else {
      existing.push(listener);
    }

    // Check for listener leak
    m = _getMaxListeners(target);
    if (m > 0 && existing.length > m && !existing.warned) {
      existing.warned = true;
      // No error code for this since it is a Warning
      // eslint-disable-next-line no-restricted-syntax
      var w = new Error('Possible EventEmitter memory leak detected. ' +
                          existing.length + ' ' + String(type) + ' listeners ' +
                          'added. Use emitter.setMaxListeners() to ' +
                          'increase limit');
      w.name = 'MaxListenersExceededWarning';
      w.emitter = target;
      w.type = type;
      w.count = existing.length;
      ProcessEmitWarning(w);
    }
  }

  return target;
}

EventEmitter.prototype.addListener = function addListener(type, listener) {
  return _addListener(this, type, listener, false);
};

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.prependListener =
    function prependListener(type, listener) {
      return _addListener(this, type, listener, true);
    };

function onceWrapper() {
  if (!this.fired) {
    this.target.removeListener(this.type, this.wrapFn);
    this.fired = true;
    if (arguments.length === 0)
      return this.listener.call(this.target);
    return this.listener.apply(this.target, arguments);
  }
}

function _onceWrap(target, type, listener) {
  var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
  var wrapped = onceWrapper.bind(state);
  wrapped.listener = listener;
  state.wrapFn = wrapped;
  return wrapped;
}

EventEmitter.prototype.once = function once(type, listener) {
  checkListener(listener);
  this.on(type, _onceWrap(this, type, listener));
  return this;
};

EventEmitter.prototype.prependOnceListener =
    function prependOnceListener(type, listener) {
      checkListener(listener);
      this.prependListener(type, _onceWrap(this, type, listener));
      return this;
    };

// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
    function removeListener(type, listener) {
      var list, events, position, i, originalListener;

      checkListener(listener);

      events = this._events;
      if (events === undefined)
        return this;

      list = events[type];
      if (list === undefined)
        return this;

      if (list === listener || list.listener === listener) {
        if (--this._eventsCount === 0)
          this._events = Object.create(null);
        else {
          delete events[type];
          if (events.removeListener)
            this.emit('removeListener', type, list.listener || listener);
        }
      } else if (typeof list !== 'function') {
        position = -1;

        for (i = list.length - 1; i >= 0; i--) {
          if (list[i] === listener || list[i].listener === listener) {
            originalListener = list[i].listener;
            position = i;
            break;
          }
        }

        if (position < 0)
          return this;

        if (position === 0)
          list.shift();
        else {
          spliceOne(list, position);
        }

        if (list.length === 1)
          events[type] = list[0];

        if (events.removeListener !== undefined)
          this.emit('removeListener', type, originalListener || listener);
      }

      return this;
    };

EventEmitter.prototype.off = EventEmitter.prototype.removeListener;

EventEmitter.prototype.removeAllListeners =
    function removeAllListeners(type) {
      var listeners, events, i;

      events = this._events;
      if (events === undefined)
        return this;

      // not listening for removeListener, no need to emit
      if (events.removeListener === undefined) {
        if (arguments.length === 0) {
          this._events = Object.create(null);
          this._eventsCount = 0;
        } else if (events[type] !== undefined) {
          if (--this._eventsCount === 0)
            this._events = Object.create(null);
          else
            delete events[type];
        }
        return this;
      }

      // emit removeListener for all listeners on all events
      if (arguments.length === 0) {
        var keys = Object.keys(events);
        var key;
        for (i = 0; i < keys.length; ++i) {
          key = keys[i];
          if (key === 'removeListener') continue;
          this.removeAllListeners(key);
        }
        this.removeAllListeners('removeListener');
        this._events = Object.create(null);
        this._eventsCount = 0;
        return this;
      }

      listeners = events[type];

      if (typeof listeners === 'function') {
        this.removeListener(type, listeners);
      } else if (listeners !== undefined) {
        // LIFO order
        for (i = listeners.length - 1; i >= 0; i--) {
          this.removeListener(type, listeners[i]);
        }
      }

      return this;
    };

function _listeners(target, type, unwrap) {
  var events = target._events;

  if (events === undefined)
    return [];

  var evlistener = events[type];
  if (evlistener === undefined)
    return [];

  if (typeof evlistener === 'function')
    return unwrap ? [evlistener.listener || evlistener] : [evlistener];

  return unwrap ?
    unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}

EventEmitter.prototype.listeners = function listeners(type) {
  return _listeners(this, type, true);
};

EventEmitter.prototype.rawListeners = function rawListeners(type) {
  return _listeners(this, type, false);
};

EventEmitter.listenerCount = function(emitter, type) {
  if (typeof emitter.listenerCount === 'function') {
    return emitter.listenerCount(type);
  } else {
    return listenerCount.call(emitter, type);
  }
};

EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
  var events = this._events;

  if (events !== undefined) {
    var evlistener = events[type];

    if (typeof evlistener === 'function') {
      return 1;
    } else if (evlistener !== undefined) {
      return evlistener.length;
    }
  }

  return 0;
}

EventEmitter.prototype.eventNames = function eventNames() {
  return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};

function arrayClone(arr, n) {
  var copy = new Array(n);
  for (var i = 0; i < n; ++i)
    copy[i] = arr[i];
  return copy;
}

function spliceOne(list, index) {
  for (; index + 1 < list.length; index++)
    list[index] = list[index + 1];
  list.pop();
}

function unwrapListeners(arr) {
  var ret = new Array(arr.length);
  for (var i = 0; i < ret.length; ++i) {
    ret[i] = arr[i].listener || arr[i];
  }
  return ret;
}

function once(emitter, name) {
  return new Promise(function (resolve, reject) {
    function eventListener() {
      if (errorListener !== undefined) {
        emitter.removeListener('error', errorListener);
      }
      resolve([].slice.call(arguments));
    };
    var errorListener;

    // Adding an error listener is not optional because
    // if an error is thrown on an event emitter we cannot
    // guarantee that the actual event we are waiting will
    // be fired. The result could be a silent way to create
    // memory or file descriptor leaks, which is something
    // we should avoid.
    if (name !== 'error') {
      errorListener = function errorListener(err) {
        emitter.removeListener(name, eventListener);
        reject(err);
      };

      emitter.once('error', errorListener);
    }

    emitter.once(name, eventListener);
  });
}


/***/ }),

/***/ "./node_modules/exports-loader/index.js?window.getSparkI18n!./node_modules/imports-loader/index.js?windows=>this!./externals/SparkModule/strings-en.js":
/*!*******************************************************************************************************************************************!*\
  !*** ./node_modules/exports-loader?window.getSparkI18n!./node_modules/imports-loader?windows=>this!./externals/SparkModule/strings-en.js ***!
  \*******************************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/*** IMPORTS FROM imports-loader ***/
var windows = this;

(function () {
    var i18n = window.csl10n || {
        translate: function (x) {
            return x;
        },
        notifyReady: function () { },
        init: function(callback) { callback(); }
    };
    var _ = i18n.translate;

    i18n.init(function () {
        window.__svi18n = {
            noauth: _('Sorry, you are not authorized'),
            wait: _('Please wait while connecting...'),
            errorDecompress: _('Error on decompressing data.'),
            logError: _('The logon process failed.'),
            remoteApp: {
                warn: _('Warning: This is the parent window of following RemoteApps:'),
                close: _("Please quit the application from application's File menu.")
            },
            info: {
                'closed': _('Connection was closed!'),
                'recording': _('You session is recorded and monitored.'),
                'menucopy': _("Pasting is unavailable via remote computer's Edit menu, but you can use Ctrl+V or browser's Edit menu"),
                'restart': _('Please restart gateway.'),
                'files': _('My Files'),
                'info': _('Information'),
                'joinsession': _('Session %1 joined, from %2 %3'), //%1 sessionId, %2 hostname, %3 user name
                'exitsession': _('Session %1 exited, from %2 %3'),
                'givecontrol': _('You have the control.'),
                'nocontrol': _("You don't have control any more."),
                'title': _('%1 %2 @ %3'), //title of request contrl, %1 user name, %2 number ID, %2 host name
                'recontrol': _('Requesting control'),
                'touchremoting': _('Touch remoting is enabled'),
                'printready': _('Click here to print document to local devices'),
                'reconnecting': _('Reconnecting...'),
                'copy': _('Use Ctrl+C or browser\'s Edit menu to copy content.<br>For image, use "Copy image" menu or select the image and copy.<br>Use "paste special - Device Independent Bitmap" in Office if you copy image from IE.'),
                'copyWarning': _('Please use copy dialog to copy image/content.'),
                'reqjoin': _('Requesting joining'),
                'recready': _('Recorded file is ready. Please right click and save the link.'),
                'sessionPaused': _('You session has been paused by administrator'),
                'sessionResumed': _('You session has been resumed'),
                'autoresume': _('Be aware that your session is paused. If you click Yes your session will be resumed.'),
                'user': _('login as: '),
                'password': _('password: '),
                'copylable': _('Copy'),
                'download': _('Download files'),
                'fileReady': _('Downloading is ready'),
                'imgCopyDownload': _('Please copy image (via context menu) or save it if your application doesn\'t support HTML format'),
                'userCopy': _('Failed to copy the followings to local clipboard. Please copy it again via context menu'),
                'succeeded': _('Operation succeeded.'),
                'digit6': _('It must be a 6 digit number'),
                'TwainNotSupported': _('The selected scanner does not supoort TWAIN protocol. Could not use Twain-based DataSource')
            },
            errorCode: {
                '1': _('The disconnection was initiated by an administrative tool on the server in another session.'),
                '2': _('The disconnection was due to a forced logoff initiated by an administrative tool on the server in another session.'),
                '3': _('The idle session limit timer on the server has elapsed.'),
                '4': _('The active session limit timer on the server has elapsed.'),
                '5': _('Another user connected to the server, forcing the disconnection of the current connection.'),
                '6': _('The server ran out of available memory resources.'),
                '7': _('The server denied the connection.'),
                '9': _('The user cannot connect to the server due to insufficient access privileges.'),
                'A': _('The server does not accept saved user credentials and requires that the user enter their credentials for each connection.'),
                'B': _("The disconnection was initiated by an administrative tool on the server running in the user's session."),
                'C': _('The disconnection was initiated by the user logging off his or her session on the server.'),
                //Protocol-independent licensing codes:
                '100': _('An internal error has occurred in the Terminal Services licensing component.'),
                '101': _('A Terminal Server License Server could not be found to provide a license.'),
                '102': _('There are no Client Access Licenses  available for the target remote computer.'),
                '103': _('The remote computer received an invalid licensing message from the client.'),
                '104': _('The Client Access License stored by the client has been modified.'),
                '105': _('The Client Access License stored by the client is in an invalid format'),
                '106': _('Network problems have caused the licensing protocol to be terminated.'),
                '107': _('The client prematurely ended the licensing protocol.'),
                '108': _('A licensing message was incorrectly encrypted.'),
                '109': _('The Client Access License stored by the client could not be upgraded or renewed.'),
                '10A': _('The remote computer is not licensed to accept remote connections'),
                'connection': _('Failed to connect to Gateway!'),
                'pwdmatch': _('Passwords don\'t match'),
                //error code from server
                'S0': _('New RemoteApp or desktop found. Please refresh your list.'),
                'S1': _('License expired.'),
                'S2': _('You must log in first.'),
                'S3': _('Disconnected by server.'),
                'S4': _('Control request was refused'),
                'S6': _('Joining request was refused'),
                'S7': _('The password is not correct'),
                'S8': _('Remote control was denied due to group policy settings'),
                'S9': _('The user is already under remote control'), //37
                'S10': _('Remote control of the user session has ended.'), //302
                'S11': _('Status update of printing: '),
                'S100': _('You password is about to expire. Days left: '),
                'S3000': _('Invalid user.'),
                'S3001': _('No access right.'),
                'S3002': _('Failed to generate PDF file.'),
                'S3003': _('PDF Converter not found.'),
                'S3004': _('Unknown host name: '),
                'S3005': _('Error:'),
                'S3006': _('Wrong user name or password!'),
                'S3007': _('File not found'),
                'S3008': _('Failed to play file'),
                'S3009': _('Only accept connections from localhost. You can try localhost, 127.0.0.1, host name, or local IP'),
                'S3010': _('Session not found or cannot be joined'),
                'S3011': _('Maximum number of concurrent users is reached.'),
                'S3012': _('User session timeout'),
                'S3014': _('Invalid symlink'),
                'S3015': _('Wrong symlink password'),
                'S3016': _('There is not enough free disk space.'),
                'S3017': _('Can not connect to the remote computer: computer is not available or Remote Desktop is not enabled.'),
                'S3018': _('File is blocked.'),
                'S3019': _('Maximum number of emergency concurrent users is reached.'),
                'S3020': _('Maximum number of emergency license days is reached.'),
                'S3021': _('Wrong authentication code')
            },
            serverStatus: {
                '401': _('The destination computer is being located.'),
                '402': _('The destination computer is being prepared for use.'),
                '403': _('The destination computer is being prepared to accept a remote connection.'),
                '404': _('The client is being redirected to the destination computer.'),
                '501': _('The destination virtual machine image is being loaded.'),
                '502': _('The destination virtual machine is being resumed from sleep or hibernation.'),
                '503': _('The destination virtual machine is being booted')
            },
            file: {
                'zero': _('File size is 0, ignored '),
                'slice': _("FileReader doesn't support slice"),
                'uploadDone': _('File uploading finished. Please refresh the shared disk in My Computer.'),
                'folder': _('folder'),
                '1': _('Invalid directory.'),
                '2': _('Not a directory')
            },
            player: {
                'noinput': _('No input found.'),
                'fmterror': _('Invalid file format.')
            },
            template: {
                'filecontainer': _('<div id="total" class="progressback" style="display: none">\
                                Uploading...<div class="progressfront"></div>\
                            </div>\
                            <div class="th"><button id="__sv_position__">Your Position:</button> <span id="parentPath"></span><input type="file" id="uploadfile" name="upload" multiple /> \
                                <input type="button" id="__cancelUpload" style="visibility:hidden" value="Cancel uploading"><span id="__diskSpace"></span><input id="__sv_folder_name_" placeholder="folder name" ><img id="__sv_folder__" src="%1/folder.png" align="center" name="folder" title="New folder" ></div>\
                            <table id="filelist" summary="File List">\
                            <thead>\
                                <tr>\
                                <th scope="col">Name</th>\
                                <th scope="col">Type</th>\
                                <th scope="col">Size</th>\
                                <th scope="col">Date modified</th>\
                                <th scope="col">Action</th>\
                                </tr>\
                            </thead>\
                            <tbody>\
                                <tr style="cursor: pointer">\
                                    <td></td>\
                                    <td></td>\
                                    <td align="right"></td>\
                                    <td></td>\
                                    <td><img id="__sv_download__" src="%1/download.png" title="Download" name="download"><img id="__sv_view__" src="%1/view.png" name="view" title="View"><img id="__sv_del__" src="%1/del.png" name="delete" title="Delete"></td>\
                                </tr>\
                            </tbody>\
                            </table>'),
                'login': _('Enter your credentials:<br>\
                    <form id= "frmLogin">\
                    <input type="text" placeholder="User name" id="loginUser"/><br>\
                    <input type="password" placeholder="Password" id="loginPassword" autocomplete="off"/><br>\
                    <input type="text" placeholder="Domain" id="loginDomain"/>\
                    <input type="submit" id="loginConnect"/>\
                    </form>'),
                'loaded': false,
                'init': function () {
                    var fc = document.getElementById('filecontainer');
                    var tp = window.__svi18n.template;
                    if (fc) {
                        fc.innerHTML = tp.filecontainer.replace("%1", getLibPath("resource.js"));
//                        console.log('file container template loaded.');
                    }else {
                        if (tp.loaded) return;
                        window.addEventListener('DOMContentLoaded', tp.init, false);
                    }
                    tp.loaded = true;
                }
            },
            vnc: {
                notvnc: _('Invalid RFB server'),
                securityError: _('Security type is not supported'),
                authError: _('Failed to authenticate')
            }
        };
        window.__svi18n.template.init();

        i18n.notifyReady();
    });

    window.getSparkI18n = function() {
        return window.__svi18n;
    };
})();


/*** EXPORTS FROM exports-loader ***/
module.exports = window.getSparkI18n;

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/appcfg.js":
/*!**************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/appcfg.js ***!
  \**************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/appcfg.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/audiorecorder_min.js":
/*!*************************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/audiorecorder_min.js ***!
  \*************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/audiorecorder_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/cloud.png":
/*!**************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/cloud.png ***!
  \**************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/cloud.png";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/del.png":
/*!************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/del.png ***!
  \************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/del.png";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/handle.png":
/*!***************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/handle.png ***!
  \***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/handle.png";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5.css":
/*!************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5.css ***!
  \************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/hi5.css";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5_min.js":
/*!***************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5_min.js ***!
  \***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/hi5_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5core_min.js":
/*!*******************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5core_min.js ***!
  \*******************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/hi5core_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/info.png":
/*!*************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/info.png ***!
  \*************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/info.png";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/kbd.png":
/*!************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/kbd.png ***!
  \************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/kbd.png";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/plugin.swf":
/*!***************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/plugin.swf ***!
  \***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/plugin.swf";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdp.css":
/*!************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdp.css ***!
  \************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/rdp.css";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdp_min.js":
/*!***************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdp_min.js ***!
  \***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/rdp_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdpcore_min.js":
/*!*******************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdpcore_min.js ***!
  \*******************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/rdpcore_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdpworker_min.js":
/*!*********************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdpworker_min.js ***!
  \*********************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/rdpworker_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/recording_min.js":
/*!*********************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/recording_min.js ***!
  \*********************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/recording_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/resource.js":
/*!****************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/resource.js ***!
  \****************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/resource.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/ssh_min.js":
/*!***************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/ssh_min.js ***!
  \***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/ssh_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/strings-en.js":
/*!******************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/strings-en.js ***!
  \******************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/strings-en.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/surface_min.js":
/*!*******************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/surface_min.js ***!
  \*******************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/surface_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/jquery-3.4.1.min.js":
/*!*******************************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/jquery-3.4.1.min.js ***!
  \*******************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/jquery-3.4.1.min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/jquery-ui-1.12.0.min.js":
/*!***********************************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/jquery-ui-1.12.0.min.js ***!
  \***********************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/jquery-ui-1.12.0.min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/wmks.min.js":
/*!***********************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/wmks.min.js ***!
  \***********************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/wmks.min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vnc_min.js":
/*!***************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vnc_min.js ***!
  \***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/vnc_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vncutil_min.js":
/*!*******************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vncutil_min.js ***!
  \*******************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/vncutil_min.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.adapter.js":
/*!********************************************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.adapter.js ***!
  \********************************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/sparkClient.iframe.adapter.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.html":
/*!**************************************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.html ***!
  \**************************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/sparkClient.iframe.html";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.wmksKeyCodeMap.js":
/*!***************************************************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.wmksKeyCodeMap.js ***!
  \***************************************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/sparkClient.iframe.wmksKeyCodeMap.js";

/***/ }),

/***/ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.wmksVscanCodeMap.js":
/*!*****************************************************************************************************************************************************!*\
  !*** ./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.wmksVscanCodeMap.js ***!
  \*****************************************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "sparkIframe/sparkClient.iframe.wmksVscanCodeMap.js";

/***/ }),

/***/ "./node_modules/ieee754/index.js":
/*!***************************************!*\
  !*** ./node_modules/ieee754/index.js ***!
  \***************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
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
}


/***/ }),

/***/ "./node_modules/inherits/inherits_browser.js":
/*!***************************************************!*\
  !*** ./node_modules/inherits/inherits_browser.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (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
  }
}


/***/ }),

/***/ "./node_modules/isarray/index.js":
/*!***************************************!*\
  !*** ./node_modules/isarray/index.js ***!
  \***************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var toString = {}.toString;

module.exports = Array.isArray || function (arr) {
  return toString.call(arr) == '[object Array]';
};


/***/ }),

/***/ "./node_modules/node-libs-browser/node_modules/string_decoder/lib/string_decoder.js":
/*!******************************************************************************************!*\
  !*** ./node_modules/node-libs-browser/node_modules/string_decoder/lib/string_decoder.js ***!
  \******************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
// 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.



/*<replacement>*/

var Buffer = __webpack_require__(/*! safe-buffer */ "./node_modules/node-libs-browser/node_modules/string_decoder/node_modules/safe-buffer/index.js").Buffer;
/*</replacement>*/

var isEncoding = Buffer.isEncoding || function (encoding) {
  encoding = '' + 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 _normalizeEncoding(enc) {
  if (!enc) return 'utf8';
  var retried;
  while (true) {
    switch (enc) {
      case 'utf8':
      case 'utf-8':
        return 'utf8';
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return 'utf16le';
      case 'latin1':
      case 'binary':
        return 'latin1';
      case 'base64':
      case 'ascii':
      case 'hex':
        return enc;
      default:
        if (retried) return; // undefined
        enc = ('' + enc).toLowerCase();
        retried = true;
    }
  }
};

// Do not cache `Buffer.isEncoding` when checking encoding names as some
// modules monkey-patch it to support additional encodings
function normalizeEncoding(enc) {
  var nenc = _normalizeEncoding(enc);
  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
  return nenc || enc;
}

// StringDecoder provides an interface for efficiently splitting a series of
// buffers into a series of JS strings without breaking apart multi-byte
// characters.
exports.StringDecoder = StringDecoder;
function StringDecoder(encoding) {
  this.encoding = normalizeEncoding(encoding);
  var nb;
  switch (this.encoding) {
    case 'utf16le':
      this.text = utf16Text;
      this.end = utf16End;
      nb = 4;
      break;
    case 'utf8':
      this.fillLast = utf8FillLast;
      nb = 4;
      break;
    case 'base64':
      this.text = base64Text;
      this.end = base64End;
      nb = 3;
      break;
    default:
      this.write = simpleWrite;
      this.end = simpleEnd;
      return;
  }
  this.lastNeed = 0;
  this.lastTotal = 0;
  this.lastChar = Buffer.allocUnsafe(nb);
}

StringDecoder.prototype.write = function (buf) {
  if (buf.length === 0) return '';
  var r;
  var i;
  if (this.lastNeed) {
    r = this.fillLast(buf);
    if (r === undefined) return '';
    i = this.lastNeed;
    this.lastNeed = 0;
  } else {
    i = 0;
  }
  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
  return r || '';
};

StringDecoder.prototype.end = utf8End;

// Returns only complete characters in a Buffer
StringDecoder.prototype.text = utf8Text;

// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
StringDecoder.prototype.fillLast = function (buf) {
  if (this.lastNeed <= buf.length) {
    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
  }
  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
  this.lastNeed -= buf.length;
};

// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
// continuation byte. If an invalid byte is detected, -2 is returned.
function utf8CheckByte(byte) {
  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
  return byte >> 6 === 0x02 ? -1 : -2;
}

// Checks at most 3 bytes at the end of a Buffer in order to detect an
// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
// needed to complete the UTF-8 character (if applicable) are returned.
function utf8CheckIncomplete(self, buf, i) {
  var j = buf.length - 1;
  if (j < i) return 0;
  var nb = utf8CheckByte(buf[j]);
  if (nb >= 0) {
    if (nb > 0) self.lastNeed = nb - 1;
    return nb;
  }
  if (--j < i || nb === -2) return 0;
  nb = utf8CheckByte(buf[j]);
  if (nb >= 0) {
    if (nb > 0) self.lastNeed = nb - 2;
    return nb;
  }
  if (--j < i || nb === -2) return 0;
  nb = utf8CheckByte(buf[j]);
  if (nb >= 0) {
    if (nb > 0) {
      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
    }
    return nb;
  }
  return 0;
}

// Validates as many continuation bytes for a multi-byte UTF-8 character as
// needed or are available. If we see a non-continuation byte where we expect
// one, we "replace" the validated continuation bytes we've seen so far with
// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
// behavior. The continuation byte check is included three times in the case
// where all of the continuation bytes for a character exist in the same buffer.
// It is also done this way as a slight performance increase instead of using a
// loop.
function utf8CheckExtraBytes(self, buf, p) {
  if ((buf[0] & 0xC0) !== 0x80) {
    self.lastNeed = 0;
    return '\ufffd';
  }
  if (self.lastNeed > 1 && buf.length > 1) {
    if ((buf[1] & 0xC0) !== 0x80) {
      self.lastNeed = 1;
      return '\ufffd';
    }
    if (self.lastNeed > 2 && buf.length > 2) {
      if ((buf[2] & 0xC0) !== 0x80) {
        self.lastNeed = 2;
        return '\ufffd';
      }
    }
  }
}

// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
function utf8FillLast(buf) {
  var p = this.lastTotal - this.lastNeed;
  var r = utf8CheckExtraBytes(this, buf, p);
  if (r !== undefined) return r;
  if (this.lastNeed <= buf.length) {
    buf.copy(this.lastChar, p, 0, this.lastNeed);
    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
  }
  buf.copy(this.lastChar, p, 0, buf.length);
  this.lastNeed -= buf.length;
}

// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
// partial character, the character's bytes are buffered until the required
// number of bytes are available.
function utf8Text(buf, i) {
  var total = utf8CheckIncomplete(this, buf, i);
  if (!this.lastNeed) return buf.toString('utf8', i);
  this.lastTotal = total;
  var end = buf.length - (total - this.lastNeed);
  buf.copy(this.lastChar, 0, end);
  return buf.toString('utf8', i, end);
}

// For UTF-8, a replacement character is added when ending on a partial
// character.
function utf8End(buf) {
  var r = buf && buf.length ? this.write(buf) : '';
  if (this.lastNeed) return r + '\ufffd';
  return r;
}

// UTF-16LE typically needs two bytes per character, but even if we have an even
// number of bytes available, we need to check if we end on a leading/high
// surrogate. In that case, we need to wait for the next two bytes in order to
// decode the last character properly.
function utf16Text(buf, i) {
  if ((buf.length - i) % 2 === 0) {
    var r = buf.toString('utf16le', i);
    if (r) {
      var c = r.charCodeAt(r.length - 1);
      if (c >= 0xD800 && c <= 0xDBFF) {
        this.lastNeed = 2;
        this.lastTotal = 4;
        this.lastChar[0] = buf[buf.length - 2];
        this.lastChar[1] = buf[buf.length - 1];
        return r.slice(0, -1);
      }
    }
    return r;
  }
  this.lastNeed = 1;
  this.lastTotal = 2;
  this.lastChar[0] = buf[buf.length - 1];
  return buf.toString('utf16le', i, buf.length - 1);
}

// For UTF-16LE we do not explicitly append special replacement characters if we
// end on a partial character, we simply let v8 handle that.
function utf16End(buf) {
  var r = buf && buf.length ? this.write(buf) : '';
  if (this.lastNeed) {
    var end = this.lastTotal - this.lastNeed;
    return r + this.lastChar.toString('utf16le', 0, end);
  }
  return r;
}

function base64Text(buf, i) {
  var n = (buf.length - i) % 3;
  if (n === 0) return buf.toString('base64', i);
  this.lastNeed = 3 - n;
  this.lastTotal = 3;
  if (n === 1) {
    this.lastChar[0] = buf[buf.length - 1];
  } else {
    this.lastChar[0] = buf[buf.length - 2];
    this.lastChar[1] = buf[buf.length - 1];
  }
  return buf.toString('base64', i, buf.length - n);
}

function base64End(buf) {
  var r = buf && buf.length ? this.write(buf) : '';
  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
  return r;
}

// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
function simpleWrite(buf) {
  return buf.toString(this.encoding);
}

function simpleEnd(buf) {
  return buf && buf.length ? this.write(buf) : '';
}

/***/ }),

/***/ "./node_modules/node-libs-browser/node_modules/string_decoder/node_modules/safe-buffer/index.js":
/*!******************************************************************************************************!*\
  !*** ./node_modules/node-libs-browser/node_modules/string_decoder/node_modules/safe-buffer/index.js ***!
  \******************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
/* eslint-disable node/no-deprecated-api */
var buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js")
var Buffer = buffer.Buffer

// alternative to using Object.keys for old browsers
function copyProps (src, dst) {
  for (var key in src) {
    dst[key] = src[key]
  }
}
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
  module.exports = buffer
} else {
  // Copy properties from require('buffer')
  copyProps(buffer, exports)
  exports.Buffer = SafeBuffer
}

function SafeBuffer (arg, encodingOrOffset, length) {
  return Buffer(arg, encodingOrOffset, length)
}

SafeBuffer.prototype = Object.create(Buffer.prototype)

// Copy static methods from Buffer
copyProps(Buffer, SafeBuffer)

SafeBuffer.from = function (arg, encodingOrOffset, length) {
  if (typeof arg === 'number') {
    throw new TypeError('Argument must not be a number')
  }
  return Buffer(arg, encodingOrOffset, length)
}

SafeBuffer.alloc = function (size, fill, encoding) {
  if (typeof size !== 'number') {
    throw new TypeError('Argument must be a number')
  }
  var buf = Buffer(size)
  if (fill !== undefined) {
    if (typeof encoding === 'string') {
      buf.fill(fill, encoding)
    } else {
      buf.fill(fill)
    }
  } else {
    buf.fill(0)
  }
  return buf
}

SafeBuffer.allocUnsafe = function (size) {
  if (typeof size !== 'number') {
    throw new TypeError('Argument must be a number')
  }
  return Buffer(size)
}

SafeBuffer.allocUnsafeSlow = function (size) {
  if (typeof size !== 'number') {
    throw new TypeError('Argument must be a number')
  }
  return buffer.SlowBuffer(size)
}


/***/ }),

/***/ "./node_modules/process-nextick-args/index.js":
/*!****************************************************!*\
  !*** ./node_modules/process-nextick-args/index.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (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(this, __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))

/***/ }),

/***/ "./node_modules/process/browser.js":
/*!*****************************************!*\
  !*** ./node_modules/process/browser.js ***!
  \*****************************************/
/*! no static exports found */
/***/ (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; };


/***/ }),

/***/ "./node_modules/readable-stream/duplex.js":
/*!************************************************!*\
  !*** ./node_modules/readable-stream/duplex.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! ./lib/_stream_duplex.js */ "./node_modules/readable-stream/lib/_stream_duplex.js")


/***/ }),

/***/ "./node_modules/readable-stream/lib/_stream_duplex.js":
/*!************************************************************!*\
  !*** ./node_modules/readable-stream/lib/_stream_duplex.js ***!
  \************************************************************/
/*! no static exports found */
/***/ (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__(/*! process-nextick-args */ "./node_modules/process-nextick-args/index.js");
/*</replacement>*/

/*<replacement>*/
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
/*</replacement>*/

var Readable = __webpack_require__(/*! ./_stream_readable */ "./node_modules/readable-stream/lib/_stream_readable.js");
var Writable = __webpack_require__(/*! ./_stream_writable */ "./node_modules/readable-stream/lib/_stream_writable.js");

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);
  }
}

/***/ }),

/***/ "./node_modules/readable-stream/lib/_stream_passthrough.js":
/*!*****************************************************************!*\
  !*** ./node_modules/readable-stream/lib/_stream_passthrough.js ***!
  \*****************************************************************/
/*! no static exports found */
/***/ (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__(/*! ./_stream_transform */ "./node_modules/readable-stream/lib/_stream_transform.js");

/*<replacement>*/
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
/*</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);
};

/***/ }),

/***/ "./node_modules/readable-stream/lib/_stream_readable.js":
/*!**************************************************************!*\
  !*** ./node_modules/readable-stream/lib/_stream_readable.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/* WEBPACK VAR INJECTION */(function(process) {

module.exports = Readable;

/*<replacement>*/
var processNextTick = __webpack_require__(/*! process-nextick-args */ "./node_modules/process-nextick-args/index.js");
/*</replacement>*/

/*<replacement>*/
var isArray = __webpack_require__(/*! isarray */ "./node_modules/isarray/index.js");
/*</replacement>*/

/*<replacement>*/
var Duplex;
/*</replacement>*/

Readable.ReadableState = ReadableState;

/*<replacement>*/
var EE = __webpack_require__(/*! events */ "./node_modules/events/events.js").EventEmitter;

var EElistenerCount = function (emitter, type) {
  return emitter.listeners(type).length;
};
/*</replacement>*/

/*<replacement>*/
var Stream;
(function () {
  try {
    Stream = __webpack_require__(/*! stream */ "./node_modules/stream-browserify/index.js");
  } catch (_) {} finally {
    if (!Stream) Stream = __webpack_require__(/*! events */ "./node_modules/events/events.js").EventEmitter;
  }
})();
/*</replacement>*/

var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer;
/*<replacement>*/
var bufferShim = __webpack_require__(/*! buffer-shims */ "./node_modules/buffer-shims/index.js");
/*</replacement>*/

/*<replacement>*/
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
/*</replacement>*/

/*<replacement>*/
var debugUtil = __webpack_require__(/*! util */ 0);
var debug = void 0;
if (debugUtil && debugUtil.debuglog) {
  debug = debugUtil.debuglog('stream');
} else {
  debug = function () {};
}
/*</replacement>*/

var BufferList = __webpack_require__(/*! ./internal/streams/BufferList */ "./node_modules/readable-stream/lib/internal/streams/BufferList.js");
var StringDecoder;

util.inherits(Readable, Stream);

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__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");

  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__(/*! string_decoder/ */ "./node_modules/node-libs-browser/node_modules/string_decoder/lib/string_decoder.js").StringDecoder;
    this.decoder = new StringDecoder(options.encoding);
    this.encoding = options.encoding;
  }
}

function Readable(options) {
  Duplex = Duplex || __webpack_require__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");

  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__(/*! string_decoder/ */ "./node_modules/node-libs-browser/node_modules/string_decoder/lib/string_decoder.js").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.
  var events = ['error', 'close', 'destroy', 'pause', 'resume'];
  forEach(events, function (ev) {
    stream.on(ev, self.emit.bind(self, ev));
  });

  // 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(this, __webpack_require__(/*! ./../../process/browser.js */ "./node_modules/process/browser.js")))

/***/ }),

/***/ "./node_modules/readable-stream/lib/_stream_transform.js":
/*!***************************************************************!*\
  !*** ./node_modules/readable-stream/lib/_stream_transform.js ***!
  \***************************************************************/
/*! no static exports found */
/***/ (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__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");

/*<replacement>*/
var util = __webpack_require__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
/*</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);
}

/***/ }),

/***/ "./node_modules/readable-stream/lib/_stream_writable.js":
/*!**************************************************************!*\
  !*** ./node_modules/readable-stream/lib/_stream_writable.js ***!
  \**************************************************************/
/*! no static exports found */
/***/ (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__(/*! process-nextick-args */ "./node_modules/process-nextick-args/index.js");
/*</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__(/*! core-util-is */ "./node_modules/core-util-is/lib/util.js");
util.inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");
/*</replacement>*/

/*<replacement>*/
var internalUtil = {
  deprecate: __webpack_require__(/*! util-deprecate */ "./node_modules/util-deprecate/browser.js")
};
/*</replacement>*/

/*<replacement>*/
var Stream;
(function () {
  try {
    Stream = __webpack_require__(/*! stream */ "./node_modules/stream-browserify/index.js");
  } catch (_) {} finally {
    if (!Stream) Stream = __webpack_require__(/*! events */ "./node_modules/events/events.js").EventEmitter;
  }
})();
/*</replacement>*/

var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer;
/*<replacement>*/
var bufferShim = __webpack_require__(/*! buffer-shims */ "./node_modules/buffer-shims/index.js");
/*</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__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");

  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__(/*! ./_stream_duplex */ "./node_modules/readable-stream/lib/_stream_duplex.js");

  // 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);
}

// If we get something that is not a buffer, string, null, or undefined,
// and we're not in objectMode, then that's an error.
// Otherwise stream chunks are all considered to be of length=1, and the
// watermarks determine how many objects to keep in the buffer, rather than
// how many bytes or characters.
function validChunk(stream, state, chunk, cb) {
  var valid = true;
  var er = false;
  // Always throw error if a null is written
  // if we are not in object mode then throw
  // if it is not a buffer, string, or undefined.
  if (chunk === null) {
    er = new TypeError('May not write null values to stream');
  } else if (!Buffer.isBuffer(chunk) && 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;

  if (typeof encoding === 'function') {
    cb = encoding;
    encoding = null;
  }

  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;

  if (typeof cb !== 'function') cb = nop;

  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
    state.pendingcb++;
    ret = writeOrBuffer(this, state, 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, chunk, encoding, cb) {
  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(this, __webpack_require__(/*! ./../../process/browser.js */ "./node_modules/process/browser.js"), __webpack_require__(/*! ./../../timers-browserify/main.js */ "./node_modules/timers-browserify/main.js").setImmediate))

/***/ }),

/***/ "./node_modules/readable-stream/lib/internal/streams/BufferList.js":
/*!*************************************************************************!*\
  !*** ./node_modules/readable-stream/lib/internal/streams/BufferList.js ***!
  \*************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer;
/*<replacement>*/
var bufferShim = __webpack_require__(/*! buffer-shims */ "./node_modules/buffer-shims/index.js");
/*</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;
};

/***/ }),

/***/ "./node_modules/readable-stream/passthrough.js":
/*!*****************************************************!*\
  !*** ./node_modules/readable-stream/passthrough.js ***!
  \*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! ./lib/_stream_passthrough.js */ "./node_modules/readable-stream/lib/_stream_passthrough.js")


/***/ }),

/***/ "./node_modules/readable-stream/readable.js":
/*!**************************************************!*\
  !*** ./node_modules/readable-stream/readable.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(process) {var Stream = (function (){
  try {
    return __webpack_require__(/*! stream */ "./node_modules/stream-browserify/index.js"); // hack to fix a circular dependency issue when used with browserify
  } catch(_){}
}());
exports = module.exports = __webpack_require__(/*! ./lib/_stream_readable.js */ "./node_modules/readable-stream/lib/_stream_readable.js");
exports.Stream = Stream || exports;
exports.Readable = exports;
exports.Writable = __webpack_require__(/*! ./lib/_stream_writable.js */ "./node_modules/readable-stream/lib/_stream_writable.js");
exports.Duplex = __webpack_require__(/*! ./lib/_stream_duplex.js */ "./node_modules/readable-stream/lib/_stream_duplex.js");
exports.Transform = __webpack_require__(/*! ./lib/_stream_transform.js */ "./node_modules/readable-stream/lib/_stream_transform.js");
exports.PassThrough = __webpack_require__(/*! ./lib/_stream_passthrough.js */ "./node_modules/readable-stream/lib/_stream_passthrough.js");

if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {
  module.exports = Stream;
}

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))

/***/ }),

/***/ "./node_modules/readable-stream/transform.js":
/*!***************************************************!*\
  !*** ./node_modules/readable-stream/transform.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! ./lib/_stream_transform.js */ "./node_modules/readable-stream/lib/_stream_transform.js")


/***/ }),

/***/ "./node_modules/readable-stream/writable.js":
/*!**************************************************!*\
  !*** ./node_modules/readable-stream/writable.js ***!
  \**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! ./lib/_stream_writable.js */ "./node_modules/readable-stream/lib/_stream_writable.js")


/***/ }),

/***/ "./node_modules/sanitize-html/index.js":
/*!*********************************************!*\
  !*** ./node_modules/sanitize-html/index.js ***!
  \*********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var htmlparser = __webpack_require__(/*! htmlparser2 */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js");
var extend = __webpack_require__(/*! xtend */ "./node_modules/xtend/immutable.js");
var quoteRegexp = __webpack_require__(/*! regexp-quote */ "./node_modules/sanitize-html/node_modules/regexp-quote/regexp-quote.js");

function each(obj, cb) {
  if (obj) Object.keys(obj).forEach(function (key) {
    cb(obj[key], key);
  });
}

// Avoid false positives with .__proto__, .hasOwnProperty, etc.
function has(obj, key) {
  return ({}).hasOwnProperty.call(obj, key);
}

module.exports = sanitizeHtml;

// Ignore the _recursing flag; it's there for recursive
// invocation as a guard against this exploit:
// https://github.com/fb55/htmlparser2/issues/105

function sanitizeHtml(html, options, _recursing) {
  var result = '';

  function Frame(tag, attribs) {
    var that = this;
    this.tag = tag;
    this.attribs = attribs || {};
    this.tagPosition = result.length;
    this.text = ''; // Node inner text

    this.updateParentNodeText = function() {
      if (stack.length) {
          var parentFrame = stack[stack.length - 1];
          parentFrame.text += that.text;
      }
    };
  }

  if (!options) {
    options = sanitizeHtml.defaults;
    options.parser = htmlParserDefaults;
  } else {
    options = extend(sanitizeHtml.defaults, options);
    if (options.parser) {
      options.parser = extend(htmlParserDefaults, options.parser);
    } else {
      options.parser = htmlParserDefaults;
    }
  }

  // Tags that contain something other than HTML, or where discarding
  // the text when the tag is disallowed makes sense for other reasons.
  // If we are not allowing these tags, we should drop their content too.
  // For other tags you would drop the tag but keep its content.
  var nonTextTagsArray = options.nonTextTags || [ 'script', 'style', 'textarea' ];
  var allowedAttributesMap;
  var allowedAttributesGlobMap;
  if(options.allowedAttributes) {
    allowedAttributesMap = {};
    allowedAttributesGlobMap = {};
    each(options.allowedAttributes, function(attributes, tag) {
      allowedAttributesMap[tag] = [];
      var globRegex = [];
      attributes.forEach(function(name) {
        if(name.indexOf('*') >= 0) {
          globRegex.push(quoteRegexp(name).replace(/\\\*/g, '.*'));
        } else {
          allowedAttributesMap[tag].push(name);
        }
      });
      allowedAttributesGlobMap[tag] = new RegExp('^(' + globRegex.join('|') + ')$');
    });
  }
  var allowedClassesMap = {};
  each(options.allowedClasses, function(classes, tag) {
    // Implicitly allows the class attribute
    if(allowedAttributesMap) {
      if (!has(allowedAttributesMap, tag)) {
        allowedAttributesMap[tag] = [];
      }
      allowedAttributesMap[tag].push('class');
    }

    allowedClassesMap[tag] = classes;
  });

  var transformTagsMap = {};
  var transformTagsAll;
  each(options.transformTags, function(transform, tag) {
    var transFun;
    if (typeof transform === 'function') {
      transFun = transform;
    } else if (typeof transform === "string") {
      transFun = sanitizeHtml.simpleTransform(transform);
    }
    if (tag === '*') {
      transformTagsAll = transFun;
    } else {
      transformTagsMap[tag] = transFun;
    }
  });

  var depth = 0;
  var stack = [];
  var skipMap = {};
  var transformMap = {};
  var skipText = false;
  var skipTextDepth = 0;

  var parser = new htmlparser.Parser({
    onopentag: function(name, attribs) {
      if (skipText) {
        skipTextDepth++;
        return;
      }
      var frame = new Frame(name, attribs);
      stack.push(frame);

      var skip = false;
      var hasText = frame.text ? true : false;
      var transformedTag;
      if (has(transformTagsMap, name)) {
        transformedTag = transformTagsMap[name](name, attribs);

        frame.attribs = attribs = transformedTag.attribs;

        if (transformedTag.text !== undefined) {
          frame.innerText = transformedTag.text;
        }

        if (name !== transformedTag.tagName) {
          frame.name = name = transformedTag.tagName;
          transformMap[depth] = transformedTag.tagName;
        }
      }
      if (transformTagsAll) {
        transformedTag = transformTagsAll(name, attribs);

        frame.attribs = attribs = transformedTag.attribs;
        if (name !== transformedTag.tagName) {
          frame.name = name = transformedTag.tagName;
          transformMap[depth] = transformedTag.tagName;
        }
      }

      if (options.allowedTags && options.allowedTags.indexOf(name) === -1) {
        skip = true;
        if (nonTextTagsArray.indexOf(name) !== -1) {
          skipText = true;
          skipTextDepth = 1;
        }
        skipMap[depth] = true;
      }
      depth++;
      if (skip) {
        // We want the contents but not this tag
        return;
      }
      result += '<' + name;
      if (!allowedAttributesMap || has(allowedAttributesMap, name) || allowedAttributesMap['*']) {
        each(attribs, function(value, a) {
          if (!allowedAttributesMap ||
              (has(allowedAttributesMap, name) && allowedAttributesMap[name].indexOf(a) !== -1 ) ||
              (allowedAttributesMap['*'] && allowedAttributesMap['*'].indexOf(a) !== -1 ) ||
              (has(allowedAttributesGlobMap, name) && allowedAttributesGlobMap[name].test(a)) ||
              (allowedAttributesGlobMap['*'] && allowedAttributesGlobMap['*'].test(a))) {
            if ((a === 'href') || (a === 'src')) {
              if (naughtyHref(name, value)) {
                delete frame.attribs[a];
                return;
              }
            }
            if (a === 'class') {
              value = filterClasses(value, allowedClassesMap[name]);
              if (!value.length) {
                delete frame.attribs[a];
                return;
              }
            }
            result += ' ' + a;
            if (value.length) {
              result += '="' + escapeHtml(value) + '"';
            }
          } else {
            delete frame.attribs[a];
          }
        });
      }
      if (options.selfClosing.indexOf(name) !== -1) {
        result += " />";
      } else {
        result += ">";
        if (frame.innerText && !hasText && !options.textFilter) {
          result += frame.innerText;
        }
      }
    },
    ontext: function(text) {
      if (skipText) {
        return;
      }
      var lastFrame = stack[stack.length-1];
      var tag;

      if (lastFrame) {
        tag = lastFrame.tag;
        // If inner text was set by transform function then let's use it
        text = lastFrame.innerText !== undefined ? lastFrame.innerText : text;
      }

      if ((tag === 'script') || (tag === 'style')) {
        // htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing
        // script tags is, by definition, game over for XSS protection, so if that's
        // your concern, don't allow them. The same is essentially true for style tags
        // which have their own collection of XSS vectors.
        result += text;
      } else {
        var escaped = escapeHtml(text);
        if (options.textFilter) {
          result += options.textFilter(escaped);
        } else {
          result += escaped;
        }
      }
      if (stack.length) {
           var frame = stack[stack.length - 1];
           frame.text += text;
      }
    },
    onclosetag: function(name) {

      if (skipText) {
        skipTextDepth--;
        if (!skipTextDepth) {
          skipText = false;
        } else {
          return;
        }
      }

      var frame = stack.pop();
      if (!frame) {
        // Do not crash on bad markup
        return;
      }
      skipText = false;
      depth--;
      if (skipMap[depth]) {
        delete skipMap[depth];
        frame.updateParentNodeText();
        return;
      }

      if (transformMap[depth]) {
        name = transformMap[depth];
        delete transformMap[depth];
      }

      if (options.exclusiveFilter && options.exclusiveFilter(frame)) {
         result = result.substr(0, frame.tagPosition);
         return;
      }

      frame.updateParentNodeText();

      if (options.selfClosing.indexOf(name) !== -1) {
         // Already output />
         return;
      }

      result += "</" + name + ">";
    }
  }, options.parser);
  parser.write(html);
  parser.end();

  return result;

  function escapeHtml(s) {
    if (typeof(s) !== 'string') {
      s = s + '';
    }
    return s.replace(/\&/g, '&amp;').replace(/</g, '&lt;').replace(/\>/g, '&gt;').replace(/\"/g, '&quot;');
  }

  function naughtyHref(name, href) {
    // Browsers ignore character codes of 32 (space) and below in a surprising
    // number of situations. Start reading here:
    // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Embedded_tab
    href = href.replace(/[\x00-\x20]+/g, '');
    // Clobber any comments in URLs, which the browser might
    // interpret inside an XML data island, allowing
    // a javascript: URL to be snuck through
    href = href.replace(/<\!\-\-.*?\-\-\>/g, '');
    // Case insensitive so we don't get faked out by JAVASCRIPT #1
    var matches = href.match(/^([a-zA-Z]+)\:/);
    if (!matches) {
      // No scheme = no way to inject js (right?)
      return false;
    }
    var scheme = matches[1].toLowerCase();

    if (has(options.allowedSchemesByTag, name)) {
      return options.allowedSchemesByTag[name].indexOf(scheme) === -1;
    }

    return !options.allowedSchemes || options.allowedSchemes.indexOf(scheme) === -1;
  }

  function filterClasses(classes, allowed) {
    if (!allowed) {
      // The class attribute is allowed without filtering on this tag
      return classes;
    }
    classes = classes.split(/\s+/);
    return classes.filter(function(clss) {
      return allowed.indexOf(clss) !== -1;
    }).join(' ');
  }
}

// Defaults are accessible to you so that you can use them as a starting point
// programmatically if you wish

var htmlParserDefaults = {
  decodeEntities: true
};
sanitizeHtml.defaults = {
  allowedTags: [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol',
    'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div',
    'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre' ],
  allowedAttributes: {
    a: [ 'href', 'name', 'target' ],
    // We don't currently allow img itself by default, but this
    // would make sense if we did
    img: [ 'src' ]
  },
  // Lots of these won't come up by default because we don't allow them
  selfClosing: [ 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta' ],
  // URL schemes we permit
  allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ],
  allowedSchemesByTag: {}
};

sanitizeHtml.simpleTransform = function(newTagName, newAttribs, merge) {
  merge = (merge === undefined) ? true : merge;
  newAttribs = newAttribs || {};

  return function(tagName, attribs) {
    var attrib;
    if (merge) {
      for (attrib in newAttribs) {
        attribs[attrib] = newAttribs[attrib];
      }
    } else {
      attribs = newAttribs;
    }

    return {
      tagName: newTagName,
      attribs: attribs
    };
  };
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/CollectingHandler.js":
/*!**************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/CollectingHandler.js ***!
  \**************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = CollectingHandler;

function CollectingHandler(cbs){
	this._cbs = cbs || {};
	this.events = [];
}

var EVENTS = __webpack_require__(/*! ./ */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js").EVENTS;
Object.keys(EVENTS).forEach(function(name){
	if(EVENTS[name] === 0){
		name = "on" + name;
		CollectingHandler.prototype[name] = function(){
			this.events.push([name]);
			if(this._cbs[name]) this._cbs[name]();
		};
	} else if(EVENTS[name] === 1){
		name = "on" + name;
		CollectingHandler.prototype[name] = function(a){
			this.events.push([name, a]);
			if(this._cbs[name]) this._cbs[name](a);
		};
	} else if(EVENTS[name] === 2){
		name = "on" + name;
		CollectingHandler.prototype[name] = function(a, b){
			this.events.push([name, a, b]);
			if(this._cbs[name]) this._cbs[name](a, b);
		};
	} else {
		throw Error("wrong number of arguments");
	}
});

CollectingHandler.prototype.onreset = function(){
	this.events = [];
	if(this._cbs.onreset) this._cbs.onreset();
};

CollectingHandler.prototype.restart = function(){
	if(this._cbs.onreset) this._cbs.onreset();

	for(var i = 0, len = this.events.length; i < len; i++){
		if(this._cbs[this.events[i][0]]){

			var num = this.events[i].length;

			if(num === 1){
				this._cbs[this.events[i][0]]();
			} else if(num === 2){
				this._cbs[this.events[i][0]](this.events[i][1]);
			} else {
				this._cbs[this.events[i][0]](this.events[i][1], this.events[i][2]);
			}
		}
	}
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/FeedHandler.js":
/*!********************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/FeedHandler.js ***!
  \********************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var index = __webpack_require__(/*! ./index.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js"),
    DomHandler = index.DomHandler,
    DomUtils = index.DomUtils;

//TODO: make this a streamable handler
function FeedHandler(callback, options){
	this.init(callback, options);
}

__webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")(FeedHandler, DomHandler);

FeedHandler.prototype.init = DomHandler;

function getElements(what, where){
	return DomUtils.getElementsByTagName(what, where, true);
}
function getOneElement(what, where){
	return DomUtils.getElementsByTagName(what, where, true, 1)[0];
}
function fetch(what, where, recurse){
	return DomUtils.getText(
		DomUtils.getElementsByTagName(what, where, recurse, 1)
	).trim();
}

function addConditionally(obj, prop, what, where, recurse){
	var tmp = fetch(what, where, recurse);
	if(tmp) obj[prop] = tmp;
}

var isValidFeed = function(value){
	return value === "rss" || value === "feed" || value === "rdf:RDF";
};

FeedHandler.prototype.onend = function(){
	var feed = {},
	    feedRoot = getOneElement(isValidFeed, this.dom),
	    tmp, childs;

	if(feedRoot){
		if(feedRoot.name === "feed"){
			childs = feedRoot.children;

			feed.type = "atom";
			addConditionally(feed, "id", "id", childs);
			addConditionally(feed, "title", "title", childs);
			if((tmp = getOneElement("link", childs)) && (tmp = tmp.attribs) && (tmp = tmp.href)) feed.link = tmp;
			addConditionally(feed, "description", "subtitle", childs);
			if((tmp = fetch("updated", childs))) feed.updated = new Date(tmp);
			addConditionally(feed, "author", "email", childs, true);

			feed.items = getElements("entry", childs).map(function(item){
				var entry = {}, tmp;

				item = item.children;

				addConditionally(entry, "id", "id", item);
				addConditionally(entry, "title", "title", item);
				if((tmp = getOneElement("link", item)) && (tmp = tmp.attribs) && (tmp = tmp.href)) entry.link = tmp;
				if((tmp = fetch("summary", item) || fetch("content", item))) entry.description = tmp;
				if((tmp = fetch("updated", item))) entry.pubDate = new Date(tmp);
				return entry;
			});
		} else {
			childs = getOneElement("channel", feedRoot.children).children;

			feed.type = feedRoot.name.substr(0, 3);
			feed.id = "";
			addConditionally(feed, "title", "title", childs);
			addConditionally(feed, "link", "link", childs);
			addConditionally(feed, "description", "description", childs);
			if((tmp = fetch("lastBuildDate", childs))) feed.updated = new Date(tmp);
			addConditionally(feed, "author", "managingEditor", childs, true);

			feed.items = getElements("item", feedRoot.children).map(function(item){
				var entry = {}, tmp;

				item = item.children;

				addConditionally(entry, "id", "guid", item);
				addConditionally(entry, "title", "title", item);
				addConditionally(entry, "link", "link", item);
				addConditionally(entry, "description", "description", item);
				if((tmp = fetch("pubDate", item))) entry.pubDate = new Date(tmp);
				return entry;
			});
		}
	}
	this.dom = feed;
	DomHandler.prototype._handleCallback.call(
		this, feedRoot ? null : Error("couldn't find root of feed")
	);
};

module.exports = FeedHandler;


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Parser.js":
/*!***************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/Parser.js ***!
  \***************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var Tokenizer = __webpack_require__(/*! ./Tokenizer.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Tokenizer.js");

/*
	Options:

	xmlMode: Disables the special behavior for script/style tags (false by default)
	lowerCaseAttributeNames: call .toLowerCase for each attribute name (true if xmlMode is `false`)
	lowerCaseTags: call .toLowerCase for each tag name (true if xmlMode is `false`)
*/

/*
	Callbacks:

	oncdataend,
	oncdatastart,
	onclosetag,
	oncomment,
	oncommentend,
	onerror,
	onopentag,
	onprocessinginstruction,
	onreset,
	ontext
*/

var formTags = {
	input: true,
	option: true,
	optgroup: true,
	select: true,
	button: true,
	datalist: true,
	textarea: true
};

var openImpliesClose = {
	tr      : { tr:true, th:true, td:true },
	th      : { th:true },
	td      : { thead:true, th:true, td:true },
	body    : { head:true, link:true, script:true },
	li      : { li:true },
	p       : { p:true },
	h1      : { p:true },
	h2      : { p:true },
	h3      : { p:true },
	h4      : { p:true },
	h5      : { p:true },
	h6      : { p:true },
	select  : formTags,
	input   : formTags,
	output  : formTags,
	button  : formTags,
	datalist: formTags,
	textarea: formTags,
	option  : { option:true },
	optgroup: { optgroup:true }
};

var voidElements = {
	__proto__: null,
	area: true,
	base: true,
	basefont: true,
	br: true,
	col: true,
	command: true,
	embed: true,
	frame: true,
	hr: true,
	img: true,
	input: true,
	isindex: true,
	keygen: true,
	link: true,
	meta: true,
	param: true,
	source: true,
	track: true,
	wbr: true,

	//common self closing svg elements
	path: true,
	circle: true,
	ellipse: true,
	line: true,
	rect: true,
	use: true,
	stop: true,
	polyline: true,
	polygon: true
};

var re_nameEnd = /\s|\//;

function Parser(cbs, options){
	this._options = options || {};
	this._cbs = cbs || {};

	this._tagname = "";
	this._attribname = "";
	this._attribvalue = "";
	this._attribs = null;
	this._stack = [];

	this.startIndex = 0;
	this.endIndex = null;

	this._lowerCaseTagNames = "lowerCaseTags" in this._options ?
									!!this._options.lowerCaseTags :
									!this._options.xmlMode;
	this._lowerCaseAttributeNames = "lowerCaseAttributeNames" in this._options ?
									!!this._options.lowerCaseAttributeNames :
									!this._options.xmlMode;

	if(this._options.Tokenizer) {
		Tokenizer = this._options.Tokenizer;
	}
	this._tokenizer = new Tokenizer(this._options, this);

	if(this._cbs.onparserinit) this._cbs.onparserinit(this);
}

__webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")(Parser, __webpack_require__(/*! events */ "./node_modules/events/events.js").EventEmitter);

Parser.prototype._updatePosition = function(initialOffset){
	if(this.endIndex === null){
		if(this._tokenizer._sectionStart <= initialOffset){
			this.startIndex = 0;
		} else {
			this.startIndex = this._tokenizer._sectionStart - initialOffset;
		}
	}
	else this.startIndex = this.endIndex + 1;
	this.endIndex = this._tokenizer.getAbsoluteIndex();
};

//Tokenizer event handlers
Parser.prototype.ontext = function(data){
	this._updatePosition(1);
	this.endIndex--;

	if(this._cbs.ontext) this._cbs.ontext(data);
};

Parser.prototype.onopentagname = function(name){
	if(this._lowerCaseTagNames){
		name = name.toLowerCase();
	}

	this._tagname = name;

	if(!this._options.xmlMode && name in openImpliesClose) {
		for(
			var el;
			(el = this._stack[this._stack.length - 1]) in openImpliesClose[name];
			this.onclosetag(el)
		);
	}

	if(this._options.xmlMode || !(name in voidElements)){
		this._stack.push(name);
	}

	if(this._cbs.onopentagname) this._cbs.onopentagname(name);
	if(this._cbs.onopentag) this._attribs = {};
};

Parser.prototype.onopentagend = function(){
	this._updatePosition(1);

	if(this._attribs){
		if(this._cbs.onopentag) this._cbs.onopentag(this._tagname, this._attribs);
		this._attribs = null;
	}

	if(!this._options.xmlMode && this._cbs.onclosetag && this._tagname in voidElements){
		this._cbs.onclosetag(this._tagname);
	}

	this._tagname = "";
};

Parser.prototype.onclosetag = function(name){
	this._updatePosition(1);

	if(this._lowerCaseTagNames){
		name = name.toLowerCase();
	}

	if(this._stack.length && (!(name in voidElements) || this._options.xmlMode)){
		var pos = this._stack.lastIndexOf(name);
		if(pos !== -1){
			if(this._cbs.onclosetag){
				pos = this._stack.length - pos;
				while(pos--) this._cbs.onclosetag(this._stack.pop());
			}
			else this._stack.length = pos;
		} else if(name === "p" && !this._options.xmlMode){
			this.onopentagname(name);
			this._closeCurrentTag();
		}
	} else if(!this._options.xmlMode && (name === "br" || name === "p")){
		this.onopentagname(name);
		this._closeCurrentTag();
	}
};

Parser.prototype.onselfclosingtag = function(){
	if(this._options.xmlMode || this._options.recognizeSelfClosing){
		this._closeCurrentTag();
	} else {
		this.onopentagend();
	}
};

Parser.prototype._closeCurrentTag = function(){
	var name = this._tagname;

	this.onopentagend();

	//self-closing tags will be on the top of the stack
	//(cheaper check than in onclosetag)
	if(this._stack[this._stack.length - 1] === name){
		if(this._cbs.onclosetag){
			this._cbs.onclosetag(name);
		}
		this._stack.pop();
	}
};

Parser.prototype.onattribname = function(name){
	if(this._lowerCaseAttributeNames){
		name = name.toLowerCase();
	}
	this._attribname = name;
};

Parser.prototype.onattribdata = function(value){
	this._attribvalue += value;
};

Parser.prototype.onattribend = function(){
	if(this._cbs.onattribute) this._cbs.onattribute(this._attribname, this._attribvalue);
	if(
		this._attribs &&
		!Object.prototype.hasOwnProperty.call(this._attribs, this._attribname)
	){
		this._attribs[this._attribname] = this._attribvalue;
	}
	this._attribname = "";
	this._attribvalue = "";
};

Parser.prototype._getInstructionName = function(value){
	var idx = value.search(re_nameEnd),
	    name = idx < 0 ? value : value.substr(0, idx);

	if(this._lowerCaseTagNames){
		name = name.toLowerCase();
	}

	return name;
};

Parser.prototype.ondeclaration = function(value){
	if(this._cbs.onprocessinginstruction){
		var name = this._getInstructionName(value);
		this._cbs.onprocessinginstruction("!" + name, "!" + value);
	}
};

Parser.prototype.onprocessinginstruction = function(value){
	if(this._cbs.onprocessinginstruction){
		var name = this._getInstructionName(value);
		this._cbs.onprocessinginstruction("?" + name, "?" + value);
	}
};

Parser.prototype.oncomment = function(value){
	this._updatePosition(4);

	if(this._cbs.oncomment) this._cbs.oncomment(value);
	if(this._cbs.oncommentend) this._cbs.oncommentend();
};

Parser.prototype.oncdata = function(value){
	this._updatePosition(1);

	if(this._options.xmlMode || this._options.recognizeCDATA){
		if(this._cbs.oncdatastart) this._cbs.oncdatastart();
		if(this._cbs.ontext) this._cbs.ontext(value);
		if(this._cbs.oncdataend) this._cbs.oncdataend();
	} else {
		this.oncomment("[CDATA[" + value + "]]");
	}
};

Parser.prototype.onerror = function(err){
	if(this._cbs.onerror) this._cbs.onerror(err);
};

Parser.prototype.onend = function(){
	if(this._cbs.onclosetag){
		for(
			var i = this._stack.length;
			i > 0;
			this._cbs.onclosetag(this._stack[--i])
		);
	}
	if(this._cbs.onend) this._cbs.onend();
};


//Resets the parser to a blank state, ready to parse a new HTML document
Parser.prototype.reset = function(){
	if(this._cbs.onreset) this._cbs.onreset();
	this._tokenizer.reset();

	this._tagname = "";
	this._attribname = "";
	this._attribs = null;
	this._stack = [];

	if(this._cbs.onparserinit) this._cbs.onparserinit(this);
};

//Parses a complete HTML document and pushes it to the handler
Parser.prototype.parseComplete = function(data){
	this.reset();
	this.end(data);
};

Parser.prototype.write = function(chunk){
	this._tokenizer.write(chunk);
};

Parser.prototype.end = function(chunk){
	this._tokenizer.end(chunk);
};

Parser.prototype.pause = function(){
	this._tokenizer.pause();
};

Parser.prototype.resume = function(){
	this._tokenizer.resume();
};

//alias for backwards compat
Parser.prototype.parseChunk = Parser.prototype.write;
Parser.prototype.done = Parser.prototype.end;

module.exports = Parser;


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/ProxyHandler.js":
/*!*********************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/ProxyHandler.js ***!
  \*********************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = ProxyHandler;

function ProxyHandler(cbs){
	this._cbs = cbs || {};
}

var EVENTS = __webpack_require__(/*! ./ */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js").EVENTS;
Object.keys(EVENTS).forEach(function(name){
	if(EVENTS[name] === 0){
		name = "on" + name;
		ProxyHandler.prototype[name] = function(){
			if(this._cbs[name]) this._cbs[name]();
		};
	} else if(EVENTS[name] === 1){
		name = "on" + name;
		ProxyHandler.prototype[name] = function(a){
			if(this._cbs[name]) this._cbs[name](a);
		};
	} else if(EVENTS[name] === 2){
		name = "on" + name;
		ProxyHandler.prototype[name] = function(a, b){
			if(this._cbs[name]) this._cbs[name](a, b);
		};
	} else {
		throw Error("wrong number of arguments");
	}
});

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Stream.js":
/*!***************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/Stream.js ***!
  \***************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = Stream;

var Parser = __webpack_require__(/*! ./WritableStream.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/WritableStream.js");

function Stream(options){
	Parser.call(this, new Cbs(this), options);
}

__webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")(Stream, Parser);

Stream.prototype.readable = true;

function Cbs(scope){
	this.scope = scope;
}

var EVENTS = __webpack_require__(/*! ../ */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js").EVENTS;

Object.keys(EVENTS).forEach(function(name){
	if(EVENTS[name] === 0){
		Cbs.prototype["on" + name] = function(){
			this.scope.emit(name);
		};
	} else if(EVENTS[name] === 1){
		Cbs.prototype["on" + name] = function(a){
			this.scope.emit(name, a);
		};
	} else if(EVENTS[name] === 2){
		Cbs.prototype["on" + name] = function(a, b){
			this.scope.emit(name, a, b);
		};
	} else {
		throw Error("wrong number of arguments!");
	}
});

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Tokenizer.js":
/*!******************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/Tokenizer.js ***!
  \******************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = Tokenizer;

var decodeCodePoint = __webpack_require__(/*! entities/lib/decode_codepoint.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/decode_codepoint.js"),
    entityMap = __webpack_require__(/*! entities/maps/entities.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/entities.json"),
    legacyMap = __webpack_require__(/*! entities/maps/legacy.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/legacy.json"),
    xmlMap    = __webpack_require__(/*! entities/maps/xml.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/xml.json"),

    i = 0,

    TEXT                      = i++,
    BEFORE_TAG_NAME           = i++, //after <
    IN_TAG_NAME               = i++,
    IN_SELF_CLOSING_TAG       = i++,
    BEFORE_CLOSING_TAG_NAME   = i++,
    IN_CLOSING_TAG_NAME       = i++,
    AFTER_CLOSING_TAG_NAME    = i++,

    //attributes
    BEFORE_ATTRIBUTE_NAME     = i++,
    IN_ATTRIBUTE_NAME         = i++,
    AFTER_ATTRIBUTE_NAME      = i++,
    BEFORE_ATTRIBUTE_VALUE    = i++,
    IN_ATTRIBUTE_VALUE_DQ     = i++, // "
    IN_ATTRIBUTE_VALUE_SQ     = i++, // '
    IN_ATTRIBUTE_VALUE_NQ     = i++,

    //declarations
    BEFORE_DECLARATION        = i++, // !
    IN_DECLARATION            = i++,

    //processing instructions
    IN_PROCESSING_INSTRUCTION = i++, // ?

    //comments
    BEFORE_COMMENT            = i++,
    IN_COMMENT                = i++,
    AFTER_COMMENT_1           = i++,
    AFTER_COMMENT_2           = i++,

    //cdata
    BEFORE_CDATA_1            = i++, // [
    BEFORE_CDATA_2            = i++, // C
    BEFORE_CDATA_3            = i++, // D
    BEFORE_CDATA_4            = i++, // A
    BEFORE_CDATA_5            = i++, // T
    BEFORE_CDATA_6            = i++, // A
    IN_CDATA                  = i++, // [
    AFTER_CDATA_1             = i++, // ]
    AFTER_CDATA_2             = i++, // ]

    //special tags
    BEFORE_SPECIAL            = i++, //S
    BEFORE_SPECIAL_END        = i++,   //S

    BEFORE_SCRIPT_1           = i++, //C
    BEFORE_SCRIPT_2           = i++, //R
    BEFORE_SCRIPT_3           = i++, //I
    BEFORE_SCRIPT_4           = i++, //P
    BEFORE_SCRIPT_5           = i++, //T
    AFTER_SCRIPT_1            = i++, //C
    AFTER_SCRIPT_2            = i++, //R
    AFTER_SCRIPT_3            = i++, //I
    AFTER_SCRIPT_4            = i++, //P
    AFTER_SCRIPT_5            = i++, //T

    BEFORE_STYLE_1            = i++, //T
    BEFORE_STYLE_2            = i++, //Y
    BEFORE_STYLE_3            = i++, //L
    BEFORE_STYLE_4            = i++, //E
    AFTER_STYLE_1             = i++, //T
    AFTER_STYLE_2             = i++, //Y
    AFTER_STYLE_3             = i++, //L
    AFTER_STYLE_4             = i++, //E

    BEFORE_ENTITY             = i++, //&
    BEFORE_NUMERIC_ENTITY     = i++, //#
    IN_NAMED_ENTITY           = i++,
    IN_NUMERIC_ENTITY         = i++,
    IN_HEX_ENTITY             = i++, //X

    j = 0,

    SPECIAL_NONE              = j++,
    SPECIAL_SCRIPT            = j++,
    SPECIAL_STYLE             = j++;

function whitespace(c){
	return c === " " || c === "\n" || c === "\t" || c === "\f" || c === "\r";
}

function characterState(char, SUCCESS){
	return function(c){
		if(c === char) this._state = SUCCESS;
	};
}

function ifElseState(upper, SUCCESS, FAILURE){
	var lower = upper.toLowerCase();

	if(upper === lower){
		return function(c){
			if(c === lower){
				this._state = SUCCESS;
			} else {
				this._state = FAILURE;
				this._index--;
			}
		};
	} else {
		return function(c){
			if(c === lower || c === upper){
				this._state = SUCCESS;
			} else {
				this._state = FAILURE;
				this._index--;
			}
		};
	}
}

function consumeSpecialNameChar(upper, NEXT_STATE){
	var lower = upper.toLowerCase();

	return function(c){
		if(c === lower || c === upper){
			this._state = NEXT_STATE;
		} else {
			this._state = IN_TAG_NAME;
			this._index--; //consume the token again
		}
	};
}

function Tokenizer(options, cbs){
	this._state = TEXT;
	this._buffer = "";
	this._sectionStart = 0;
	this._index = 0;
	this._bufferOffset = 0; //chars removed from _buffer
	this._baseState = TEXT;
	this._special = SPECIAL_NONE;
	this._cbs = cbs;
	this._running = true;
	this._ended = false;
	this._xmlMode = !!(options && options.xmlMode);
	this._decodeEntities = !!(options && options.decodeEntities);
}

Tokenizer.prototype._stateText = function(c){
	if(c === "<"){
		if(this._index > this._sectionStart){
			this._cbs.ontext(this._getSection());
		}
		this._state = BEFORE_TAG_NAME;
		this._sectionStart = this._index;
	} else if(this._decodeEntities && this._special === SPECIAL_NONE && c === "&"){
		if(this._index > this._sectionStart){
			this._cbs.ontext(this._getSection());
		}
		this._baseState = TEXT;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateBeforeTagName = function(c){
	if(c === "/"){
		this._state = BEFORE_CLOSING_TAG_NAME;
	} else if(c === "<"){
		this._cbs.ontext(this._getSection());
		this._sectionStart = this._index;
	} else if(c === ">" || this._special !== SPECIAL_NONE || whitespace(c)) {
		this._state = TEXT;
	} else if(c === "!"){
		this._state = BEFORE_DECLARATION;
		this._sectionStart = this._index + 1;
	} else if(c === "?"){
		this._state = IN_PROCESSING_INSTRUCTION;
		this._sectionStart = this._index + 1;
	} else {
		this._state = (!this._xmlMode && (c === "s" || c === "S")) ?
						BEFORE_SPECIAL : IN_TAG_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInTagName = function(c){
	if(c === "/" || c === ">" || whitespace(c)){
		this._emitToken("onopentagname");
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateBeforeCloseingTagName = function(c){
	if(whitespace(c));
	else if(c === ">"){
		this._state = TEXT;
	} else if(this._special !== SPECIAL_NONE){
		if(c === "s" || c === "S"){
			this._state = BEFORE_SPECIAL_END;
		} else {
			this._state = TEXT;
			this._index--;
		}
	} else {
		this._state = IN_CLOSING_TAG_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInCloseingTagName = function(c){
	if(c === ">" || whitespace(c)){
		this._emitToken("onclosetag");
		this._state = AFTER_CLOSING_TAG_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateAfterCloseingTagName = function(c){
	//skip everything until ">"
	if(c === ">"){
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	}
};

Tokenizer.prototype._stateBeforeAttributeName = function(c){
	if(c === ">"){
		this._cbs.onopentagend();
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(c === "/"){
		this._state = IN_SELF_CLOSING_TAG;
	} else if(!whitespace(c)){
		this._state = IN_ATTRIBUTE_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInSelfClosingTag = function(c){
	if(c === ">"){
		this._cbs.onselfclosingtag();
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(!whitespace(c)){
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateInAttributeName = function(c){
	if(c === "=" || c === "/" || c === ">" || whitespace(c)){
		this._cbs.onattribname(this._getSection());
		this._sectionStart = -1;
		this._state = AFTER_ATTRIBUTE_NAME;
		this._index--;
	}
};

Tokenizer.prototype._stateAfterAttributeName = function(c){
	if(c === "="){
		this._state = BEFORE_ATTRIBUTE_VALUE;
	} else if(c === "/" || c === ">"){
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	} else if(!whitespace(c)){
		this._cbs.onattribend();
		this._state = IN_ATTRIBUTE_NAME;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateBeforeAttributeValue = function(c){
	if(c === "\""){
		this._state = IN_ATTRIBUTE_VALUE_DQ;
		this._sectionStart = this._index + 1;
	} else if(c === "'"){
		this._state = IN_ATTRIBUTE_VALUE_SQ;
		this._sectionStart = this._index + 1;
	} else if(!whitespace(c)){
		this._state = IN_ATTRIBUTE_VALUE_NQ;
		this._sectionStart = this._index;
		this._index--; //reconsume token
	}
};

Tokenizer.prototype._stateInAttributeValueDoubleQuotes = function(c){
	if(c === "\""){
		this._emitToken("onattribdata");
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
	} else if(this._decodeEntities && c === "&"){
		this._emitToken("onattribdata");
		this._baseState = this._state;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInAttributeValueSingleQuotes = function(c){
	if(c === "'"){
		this._emitToken("onattribdata");
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
	} else if(this._decodeEntities && c === "&"){
		this._emitToken("onattribdata");
		this._baseState = this._state;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateInAttributeValueNoQuotes = function(c){
	if(whitespace(c) || c === ">"){
		this._emitToken("onattribdata");
		this._cbs.onattribend();
		this._state = BEFORE_ATTRIBUTE_NAME;
		this._index--;
	} else if(this._decodeEntities && c === "&"){
		this._emitToken("onattribdata");
		this._baseState = this._state;
		this._state = BEFORE_ENTITY;
		this._sectionStart = this._index;
	}
};

Tokenizer.prototype._stateBeforeDeclaration = function(c){
	this._state = c === "[" ? BEFORE_CDATA_1 :
					c === "-" ? BEFORE_COMMENT :
						IN_DECLARATION;
};

Tokenizer.prototype._stateInDeclaration = function(c){
	if(c === ">"){
		this._cbs.ondeclaration(this._getSection());
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	}
};

Tokenizer.prototype._stateInProcessingInstruction = function(c){
	if(c === ">"){
		this._cbs.onprocessinginstruction(this._getSection());
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	}
};

Tokenizer.prototype._stateBeforeComment = function(c){
	if(c === "-"){
		this._state = IN_COMMENT;
		this._sectionStart = this._index + 1;
	} else {
		this._state = IN_DECLARATION;
	}
};

Tokenizer.prototype._stateInComment = function(c){
	if(c === "-") this._state = AFTER_COMMENT_1;
};

Tokenizer.prototype._stateAfterComment1 = function(c){
	if(c === "-"){
		this._state = AFTER_COMMENT_2;
	} else {
		this._state = IN_COMMENT;
	}
};

Tokenizer.prototype._stateAfterComment2 = function(c){
	if(c === ">"){
		//remove 2 trailing chars
		this._cbs.oncomment(this._buffer.substring(this._sectionStart, this._index - 2));
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(c !== "-"){
		this._state = IN_COMMENT;
	}
	// else: stay in AFTER_COMMENT_2 (`--->`)
};

Tokenizer.prototype._stateBeforeCdata1 = ifElseState("C", BEFORE_CDATA_2, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata2 = ifElseState("D", BEFORE_CDATA_3, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata3 = ifElseState("A", BEFORE_CDATA_4, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata4 = ifElseState("T", BEFORE_CDATA_5, IN_DECLARATION);
Tokenizer.prototype._stateBeforeCdata5 = ifElseState("A", BEFORE_CDATA_6, IN_DECLARATION);

Tokenizer.prototype._stateBeforeCdata6 = function(c){
	if(c === "["){
		this._state = IN_CDATA;
		this._sectionStart = this._index + 1;
	} else {
		this._state = IN_DECLARATION;
		this._index--;
	}
};

Tokenizer.prototype._stateInCdata = function(c){
	if(c === "]") this._state = AFTER_CDATA_1;
};

Tokenizer.prototype._stateAfterCdata1 = characterState("]", AFTER_CDATA_2);

Tokenizer.prototype._stateAfterCdata2 = function(c){
	if(c === ">"){
		//remove 2 trailing chars
		this._cbs.oncdata(this._buffer.substring(this._sectionStart, this._index - 2));
		this._state = TEXT;
		this._sectionStart = this._index + 1;
	} else if(c !== "]") {
		this._state = IN_CDATA;
	}
	//else: stay in AFTER_CDATA_2 (`]]]>`)
};

Tokenizer.prototype._stateBeforeSpecial = function(c){
	if(c === "c" || c === "C"){
		this._state = BEFORE_SCRIPT_1;
	} else if(c === "t" || c === "T"){
		this._state = BEFORE_STYLE_1;
	} else {
		this._state = IN_TAG_NAME;
		this._index--; //consume the token again
	}
};

Tokenizer.prototype._stateBeforeSpecialEnd = function(c){
	if(this._special === SPECIAL_SCRIPT && (c === "c" || c === "C")){
		this._state = AFTER_SCRIPT_1;
	} else if(this._special === SPECIAL_STYLE && (c === "t" || c === "T")){
		this._state = AFTER_STYLE_1;
	}
	else this._state = TEXT;
};

Tokenizer.prototype._stateBeforeScript1 = consumeSpecialNameChar("R", BEFORE_SCRIPT_2);
Tokenizer.prototype._stateBeforeScript2 = consumeSpecialNameChar("I", BEFORE_SCRIPT_3);
Tokenizer.prototype._stateBeforeScript3 = consumeSpecialNameChar("P", BEFORE_SCRIPT_4);
Tokenizer.prototype._stateBeforeScript4 = consumeSpecialNameChar("T", BEFORE_SCRIPT_5);

Tokenizer.prototype._stateBeforeScript5 = function(c){
	if(c === "/" || c === ">" || whitespace(c)){
		this._special = SPECIAL_SCRIPT;
	}
	this._state = IN_TAG_NAME;
	this._index--; //consume the token again
};

Tokenizer.prototype._stateAfterScript1 = ifElseState("R", AFTER_SCRIPT_2, TEXT);
Tokenizer.prototype._stateAfterScript2 = ifElseState("I", AFTER_SCRIPT_3, TEXT);
Tokenizer.prototype._stateAfterScript3 = ifElseState("P", AFTER_SCRIPT_4, TEXT);
Tokenizer.prototype._stateAfterScript4 = ifElseState("T", AFTER_SCRIPT_5, TEXT);

Tokenizer.prototype._stateAfterScript5 = function(c){
	if(c === ">" || whitespace(c)){
		this._special = SPECIAL_NONE;
		this._state = IN_CLOSING_TAG_NAME;
		this._sectionStart = this._index - 6;
		this._index--; //reconsume the token
	}
	else this._state = TEXT;
};

Tokenizer.prototype._stateBeforeStyle1 = consumeSpecialNameChar("Y", BEFORE_STYLE_2);
Tokenizer.prototype._stateBeforeStyle2 = consumeSpecialNameChar("L", BEFORE_STYLE_3);
Tokenizer.prototype._stateBeforeStyle3 = consumeSpecialNameChar("E", BEFORE_STYLE_4);

Tokenizer.prototype._stateBeforeStyle4 = function(c){
	if(c === "/" || c === ">" || whitespace(c)){
		this._special = SPECIAL_STYLE;
	}
	this._state = IN_TAG_NAME;
	this._index--; //consume the token again
};

Tokenizer.prototype._stateAfterStyle1 = ifElseState("Y", AFTER_STYLE_2, TEXT);
Tokenizer.prototype._stateAfterStyle2 = ifElseState("L", AFTER_STYLE_3, TEXT);
Tokenizer.prototype._stateAfterStyle3 = ifElseState("E", AFTER_STYLE_4, TEXT);

Tokenizer.prototype._stateAfterStyle4 = function(c){
	if(c === ">" || whitespace(c)){
		this._special = SPECIAL_NONE;
		this._state = IN_CLOSING_TAG_NAME;
		this._sectionStart = this._index - 5;
		this._index--; //reconsume the token
	}
	else this._state = TEXT;
};

Tokenizer.prototype._stateBeforeEntity = ifElseState("#", BEFORE_NUMERIC_ENTITY, IN_NAMED_ENTITY);
Tokenizer.prototype._stateBeforeNumericEntity = ifElseState("X", IN_HEX_ENTITY, IN_NUMERIC_ENTITY);

//for entities terminated with a semicolon
Tokenizer.prototype._parseNamedEntityStrict = function(){
	//offset = 1
	if(this._sectionStart + 1 < this._index){
		var entity = this._buffer.substring(this._sectionStart + 1, this._index),
		    map = this._xmlMode ? xmlMap : entityMap;

		if(map.hasOwnProperty(entity)){
			this._emitPartial(map[entity]);
			this._sectionStart = this._index + 1;
		}
	}
};


//parses legacy entities (without trailing semicolon)
Tokenizer.prototype._parseLegacyEntity = function(){
	var start = this._sectionStart + 1,
	    limit = this._index - start;

	if(limit > 6) limit = 6; //the max length of legacy entities is 6

	while(limit >= 2){ //the min length of legacy entities is 2
		var entity = this._buffer.substr(start, limit);

		if(legacyMap.hasOwnProperty(entity)){
			this._emitPartial(legacyMap[entity]);
			this._sectionStart += limit + 1;
			return;
		} else {
			limit--;
		}
	}
};

Tokenizer.prototype._stateInNamedEntity = function(c){
	if(c === ";"){
		this._parseNamedEntityStrict();
		if(this._sectionStart + 1 < this._index && !this._xmlMode){
			this._parseLegacyEntity();
		}
		this._state = this._baseState;
	} else if((c < "a" || c > "z") && (c < "A" || c > "Z") && (c < "0" || c > "9")){
		if(this._xmlMode);
		else if(this._sectionStart + 1 === this._index);
		else if(this._baseState !== TEXT){
			if(c !== "="){
				this._parseNamedEntityStrict();
			}
		} else {
			this._parseLegacyEntity();
		}

		this._state = this._baseState;
		this._index--;
	}
};

Tokenizer.prototype._decodeNumericEntity = function(offset, base){
	var sectionStart = this._sectionStart + offset;

	if(sectionStart !== this._index){
		//parse entity
		var entity = this._buffer.substring(sectionStart, this._index);
		var parsed = parseInt(entity, base);

		this._emitPartial(decodeCodePoint(parsed));
		this._sectionStart = this._index;
	} else {
		this._sectionStart--;
	}

	this._state = this._baseState;
};

Tokenizer.prototype._stateInNumericEntity = function(c){
	if(c === ";"){
		this._decodeNumericEntity(2, 10);
		this._sectionStart++;
	} else if(c < "0" || c > "9"){
		if(!this._xmlMode){
			this._decodeNumericEntity(2, 10);
		} else {
			this._state = this._baseState;
		}
		this._index--;
	}
};

Tokenizer.prototype._stateInHexEntity = function(c){
	if(c === ";"){
		this._decodeNumericEntity(3, 16);
		this._sectionStart++;
	} else if((c < "a" || c > "f") && (c < "A" || c > "F") && (c < "0" || c > "9")){
		if(!this._xmlMode){
			this._decodeNumericEntity(3, 16);
		} else {
			this._state = this._baseState;
		}
		this._index--;
	}
};

Tokenizer.prototype._cleanup = function (){
	if(this._sectionStart < 0){
		this._buffer = "";
		this._index = 0;
		this._bufferOffset += this._index;
	} else if(this._running){
		if(this._state === TEXT){
			if(this._sectionStart !== this._index){
				this._cbs.ontext(this._buffer.substr(this._sectionStart));
			}
			this._buffer = "";
			this._bufferOffset += this._index;
			this._index = 0;
		} else if(this._sectionStart === this._index){
			//the section just started
			this._buffer = "";
			this._bufferOffset += this._index;
			this._index = 0;
		} else {
			//remove everything unnecessary
			this._buffer = this._buffer.substr(this._sectionStart);
			this._index -= this._sectionStart;
			this._bufferOffset += this._sectionStart;
		}

		this._sectionStart = 0;
	}
};

//TODO make events conditional
Tokenizer.prototype.write = function(chunk){
	if(this._ended) this._cbs.onerror(Error(".write() after done!"));

	this._buffer += chunk;
	this._parse();
};

Tokenizer.prototype._parse = function(){
	while(this._index < this._buffer.length && this._running){
		var c = this._buffer.charAt(this._index);
		if(this._state === TEXT) {
			this._stateText(c);
		} else if(this._state === BEFORE_TAG_NAME){
			this._stateBeforeTagName(c);
		} else if(this._state === IN_TAG_NAME) {
			this._stateInTagName(c);
		} else if(this._state === BEFORE_CLOSING_TAG_NAME){
			this._stateBeforeCloseingTagName(c);
		} else if(this._state === IN_CLOSING_TAG_NAME){
			this._stateInCloseingTagName(c);
		} else if(this._state === AFTER_CLOSING_TAG_NAME){
			this._stateAfterCloseingTagName(c);
		} else if(this._state === IN_SELF_CLOSING_TAG){
			this._stateInSelfClosingTag(c);
		}

		/*
		*	attributes
		*/
		else if(this._state === BEFORE_ATTRIBUTE_NAME){
			this._stateBeforeAttributeName(c);
		} else if(this._state === IN_ATTRIBUTE_NAME){
			this._stateInAttributeName(c);
		} else if(this._state === AFTER_ATTRIBUTE_NAME){
			this._stateAfterAttributeName(c);
		} else if(this._state === BEFORE_ATTRIBUTE_VALUE){
			this._stateBeforeAttributeValue(c);
		} else if(this._state === IN_ATTRIBUTE_VALUE_DQ){
			this._stateInAttributeValueDoubleQuotes(c);
		} else if(this._state === IN_ATTRIBUTE_VALUE_SQ){
			this._stateInAttributeValueSingleQuotes(c);
		} else if(this._state === IN_ATTRIBUTE_VALUE_NQ){
			this._stateInAttributeValueNoQuotes(c);
		}

		/*
		*	declarations
		*/
		else if(this._state === BEFORE_DECLARATION){
			this._stateBeforeDeclaration(c);
		} else if(this._state === IN_DECLARATION){
			this._stateInDeclaration(c);
		}

		/*
		*	processing instructions
		*/
		else if(this._state === IN_PROCESSING_INSTRUCTION){
			this._stateInProcessingInstruction(c);
		}

		/*
		*	comments
		*/
		else if(this._state === BEFORE_COMMENT){
			this._stateBeforeComment(c);
		} else if(this._state === IN_COMMENT){
			this._stateInComment(c);
		} else if(this._state === AFTER_COMMENT_1){
			this._stateAfterComment1(c);
		} else if(this._state === AFTER_COMMENT_2){
			this._stateAfterComment2(c);
		}

		/*
		*	cdata
		*/
		else if(this._state === BEFORE_CDATA_1){
			this._stateBeforeCdata1(c);
		} else if(this._state === BEFORE_CDATA_2){
			this._stateBeforeCdata2(c);
		} else if(this._state === BEFORE_CDATA_3){
			this._stateBeforeCdata3(c);
		} else if(this._state === BEFORE_CDATA_4){
			this._stateBeforeCdata4(c);
		} else if(this._state === BEFORE_CDATA_5){
			this._stateBeforeCdata5(c);
		} else if(this._state === BEFORE_CDATA_6){
			this._stateBeforeCdata6(c);
		} else if(this._state === IN_CDATA){
			this._stateInCdata(c);
		} else if(this._state === AFTER_CDATA_1){
			this._stateAfterCdata1(c);
		} else if(this._state === AFTER_CDATA_2){
			this._stateAfterCdata2(c);
		}

		/*
		* special tags
		*/
		else if(this._state === BEFORE_SPECIAL){
			this._stateBeforeSpecial(c);
		} else if(this._state === BEFORE_SPECIAL_END){
			this._stateBeforeSpecialEnd(c);
		}

		/*
		* script
		*/
		else if(this._state === BEFORE_SCRIPT_1){
			this._stateBeforeScript1(c);
		} else if(this._state === BEFORE_SCRIPT_2){
			this._stateBeforeScript2(c);
		} else if(this._state === BEFORE_SCRIPT_3){
			this._stateBeforeScript3(c);
		} else if(this._state === BEFORE_SCRIPT_4){
			this._stateBeforeScript4(c);
		} else if(this._state === BEFORE_SCRIPT_5){
			this._stateBeforeScript5(c);
		}

		else if(this._state === AFTER_SCRIPT_1){
			this._stateAfterScript1(c);
		} else if(this._state === AFTER_SCRIPT_2){
			this._stateAfterScript2(c);
		} else if(this._state === AFTER_SCRIPT_3){
			this._stateAfterScript3(c);
		} else if(this._state === AFTER_SCRIPT_4){
			this._stateAfterScript4(c);
		} else if(this._state === AFTER_SCRIPT_5){
			this._stateAfterScript5(c);
		}

		/*
		* style
		*/
		else if(this._state === BEFORE_STYLE_1){
			this._stateBeforeStyle1(c);
		} else if(this._state === BEFORE_STYLE_2){
			this._stateBeforeStyle2(c);
		} else if(this._state === BEFORE_STYLE_3){
			this._stateBeforeStyle3(c);
		} else if(this._state === BEFORE_STYLE_4){
			this._stateBeforeStyle4(c);
		}

		else if(this._state === AFTER_STYLE_1){
			this._stateAfterStyle1(c);
		} else if(this._state === AFTER_STYLE_2){
			this._stateAfterStyle2(c);
		} else if(this._state === AFTER_STYLE_3){
			this._stateAfterStyle3(c);
		} else if(this._state === AFTER_STYLE_4){
			this._stateAfterStyle4(c);
		}

		/*
		* entities
		*/
		else if(this._state === BEFORE_ENTITY){
			this._stateBeforeEntity(c);
		} else if(this._state === BEFORE_NUMERIC_ENTITY){
			this._stateBeforeNumericEntity(c);
		} else if(this._state === IN_NAMED_ENTITY){
			this._stateInNamedEntity(c);
		} else if(this._state === IN_NUMERIC_ENTITY){
			this._stateInNumericEntity(c);
		} else if(this._state === IN_HEX_ENTITY){
			this._stateInHexEntity(c);
		}

		else {
			this._cbs.onerror(Error("unknown _state"), this._state);
		}

		this._index++;
	}

	this._cleanup();
};

Tokenizer.prototype.pause = function(){
	this._running = false;
};
Tokenizer.prototype.resume = function(){
	this._running = true;

	if(this._index < this._buffer.length){
		this._parse();
	}
	if(this._ended){
		this._finish();
	}
};

Tokenizer.prototype.end = function(chunk){
	if(this._ended) this._cbs.onerror(Error(".end() after done!"));
	if(chunk) this.write(chunk);

	this._ended = true;

	if(this._running) this._finish();
};

Tokenizer.prototype._finish = function(){
	//if there is remaining data, emit it in a reasonable way
	if(this._sectionStart < this._index){
		this._handleTrailingData();
	}

	this._cbs.onend();
};

Tokenizer.prototype._handleTrailingData = function(){
	var data = this._buffer.substr(this._sectionStart);

	if(this._state === IN_CDATA || this._state === AFTER_CDATA_1 || this._state === AFTER_CDATA_2){
		this._cbs.oncdata(data);
	} else if(this._state === IN_COMMENT || this._state === AFTER_COMMENT_1 || this._state === AFTER_COMMENT_2){
		this._cbs.oncomment(data);
	} else if(this._state === IN_NAMED_ENTITY && !this._xmlMode){
		this._parseLegacyEntity();
		if(this._sectionStart < this._index){
			this._state = this._baseState;
			this._handleTrailingData();
		}
	} else if(this._state === IN_NUMERIC_ENTITY && !this._xmlMode){
		this._decodeNumericEntity(2, 10);
		if(this._sectionStart < this._index){
			this._state = this._baseState;
			this._handleTrailingData();
		}
	} else if(this._state === IN_HEX_ENTITY && !this._xmlMode){
		this._decodeNumericEntity(3, 16);
		if(this._sectionStart < this._index){
			this._state = this._baseState;
			this._handleTrailingData();
		}
	} else if(
		this._state !== IN_TAG_NAME &&
		this._state !== BEFORE_ATTRIBUTE_NAME &&
		this._state !== BEFORE_ATTRIBUTE_VALUE &&
		this._state !== AFTER_ATTRIBUTE_NAME &&
		this._state !== IN_ATTRIBUTE_NAME &&
		this._state !== IN_ATTRIBUTE_VALUE_SQ &&
		this._state !== IN_ATTRIBUTE_VALUE_DQ &&
		this._state !== IN_ATTRIBUTE_VALUE_NQ &&
		this._state !== IN_CLOSING_TAG_NAME
	){
		this._cbs.ontext(data);
	}
	//else, ignore remaining data
	//TODO add a way to remove current tag
};

Tokenizer.prototype.reset = function(){
	Tokenizer.call(this, {xmlMode: this._xmlMode, decodeEntities: this._decodeEntities}, this._cbs);
};

Tokenizer.prototype.getAbsoluteIndex = function(){
	return this._bufferOffset + this._index;
};

Tokenizer.prototype._getSection = function(){
	return this._buffer.substring(this._sectionStart, this._index);
};

Tokenizer.prototype._emitToken = function(name){
	this._cbs[name](this._getSection());
	this._sectionStart = -1;
};

Tokenizer.prototype._emitPartial = function(value){
	if(this._baseState !== TEXT){
		this._cbs.onattribdata(value); //TODO implement the new event
	} else {
		this._cbs.ontext(value);
	}
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/WritableStream.js":
/*!***********************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/WritableStream.js ***!
  \***********************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = Stream;

var Parser = __webpack_require__(/*! ./Parser.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Parser.js"),
    WritableStream = __webpack_require__(/*! stream */ "./node_modules/stream-browserify/index.js").Writable || __webpack_require__(/*! readable-stream */ 1).Writable,
    StringDecoder = __webpack_require__(/*! string_decoder */ "./node_modules/node-libs-browser/node_modules/string_decoder/lib/string_decoder.js").StringDecoder,
    Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js").Buffer;

function Stream(cbs, options){
	var parser = this._parser = new Parser(cbs, options);
	var decoder = this._decoder = new StringDecoder();

	WritableStream.call(this, {decodeStrings: false});

	this.once("finish", function(){
		parser.end(decoder.end());
	});
}

__webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js")(Stream, WritableStream);

WritableStream.prototype._write = function(chunk, encoding, cb){
	if(chunk instanceof Buffer) chunk = this._decoder.write(chunk);
	this._parser.write(chunk);
	cb();
};

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js":
/*!**************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/lib/index.js ***!
  \**************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var Parser = __webpack_require__(/*! ./Parser.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Parser.js"),
    DomHandler = __webpack_require__(/*! domhandler */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/index.js");

function defineProp(name, value){
	delete module.exports[name];
	module.exports[name] = value;
	return value;
}

module.exports = {
	Parser: Parser,
	Tokenizer: __webpack_require__(/*! ./Tokenizer.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Tokenizer.js"),
	ElementType: __webpack_require__(/*! domelementtype */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domelementtype/index.js"),
	DomHandler: DomHandler,
	get FeedHandler(){
		return defineProp("FeedHandler", __webpack_require__(/*! ./FeedHandler.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/FeedHandler.js"));
	},
	get Stream(){
		return defineProp("Stream", __webpack_require__(/*! ./Stream.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/Stream.js"));
	},
	get WritableStream(){
		return defineProp("WritableStream", __webpack_require__(/*! ./WritableStream.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/WritableStream.js"));
	},
	get ProxyHandler(){
		return defineProp("ProxyHandler", __webpack_require__(/*! ./ProxyHandler.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/ProxyHandler.js"));
	},
	get DomUtils(){
		return defineProp("DomUtils", __webpack_require__(/*! domutils */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/index.js"));
	},
	get CollectingHandler(){
		return defineProp("CollectingHandler", __webpack_require__(/*! ./CollectingHandler.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/lib/CollectingHandler.js"));
	},
	// For legacy support
	DefaultHandler: DomHandler,
	get RssHandler(){
		return defineProp("RssHandler", this.FeedHandler);
	},
	//helper methods
	parseDOM: function(data, options){
		var handler = new DomHandler(options);
		new Parser(handler, options).end(data);
		return handler.dom;
	},
	parseFeed: function(feed, options){
		var handler = new module.exports.FeedHandler(options);
		new Parser(handler, options).end(feed);
		return handler.dom;
	},
	createDomStream: function(cb, options, elementCb){
		var handler = new DomHandler(cb, options, elementCb);
		return new Parser(handler, options);
	},
	// List of all events that the parser emits
	EVENTS: { /* Format: eventname: number of arguments */
		attribute: 2,
		cdatastart: 0,
		cdataend: 0,
		text: 1,
		processinginstruction: 2,
		comment: 1,
		commentend: 0,
		closetag: 1,
		opentag: 2,
		opentagname: 1,
		error: 1,
		end: 0
	}
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domelementtype/index.js":
/*!**************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domelementtype/index.js ***!
  \**************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

//Types of elements found in the DOM
module.exports = {
	Text: "text", //Text
	Directive: "directive", //<? ... ?>
	Comment: "comment", //<!-- ... -->
	Script: "script", //<script> tags
	Style: "style", //<style> tags
	Tag: "tag", //Any tag
	CDATA: "cdata", //<![CDATA[ ... ]]>
	Doctype: "doctype",

	isTag: function(elem){
		return elem.type === "tag" || elem.type === "script" || elem.type === "style";
	}
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/index.js":
/*!**********************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/index.js ***!
  \**********************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var ElementType = __webpack_require__(/*! domelementtype */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domelementtype/index.js");

var re_whitespace = /\s+/g;
var NodePrototype = __webpack_require__(/*! ./lib/node */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/lib/node.js");
var ElementPrototype = __webpack_require__(/*! ./lib/element */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/lib/element.js");

function DomHandler(callback, options, elementCB){
	if(typeof callback === "object"){
		elementCB = options;
		options = callback;
		callback = null;
	} else if(typeof options === "function"){
		elementCB = options;
		options = defaultOpts;
	}
	this._callback = callback;
	this._options = options || defaultOpts;
	this._elementCB = elementCB;
	this.dom = [];
	this._done = false;
	this._tagStack = [];
	this._parser = this._parser || null;
}

//default options
var defaultOpts = {
	normalizeWhitespace: false, //Replace all whitespace with single spaces
	withStartIndices: false, //Add startIndex properties to nodes
};

DomHandler.prototype.onparserinit = function(parser){
	this._parser = parser;
};

//Resets the handler back to starting state
DomHandler.prototype.onreset = function(){
	DomHandler.call(this, this._callback, this._options, this._elementCB);
};

//Signals the handler that parsing is done
DomHandler.prototype.onend = function(){
	if(this._done) return;
	this._done = true;
	this._parser = null;
	this._handleCallback(null);
};

DomHandler.prototype._handleCallback =
DomHandler.prototype.onerror = function(error){
	if(typeof this._callback === "function"){
		this._callback(error, this.dom);
	} else {
		if(error) throw error;
	}
};

DomHandler.prototype.onclosetag = function(){
	//if(this._tagStack.pop().name !== name) this._handleCallback(Error("Tagname didn't match!"));
	var elem = this._tagStack.pop();
	if(this._elementCB) this._elementCB(elem);
};

DomHandler.prototype._addDomElement = function(element){
	var parent = this._tagStack[this._tagStack.length - 1];
	var siblings = parent ? parent.children : this.dom;
	var previousSibling = siblings[siblings.length - 1];

	element.next = null;

	if(this._options.withStartIndices){
		element.startIndex = this._parser.startIndex;
	}

	if (this._options.withDomLvl1) {
		element.__proto__ = element.type === "tag" ? ElementPrototype : NodePrototype;
	}

	if(previousSibling){
		element.prev = previousSibling;
		previousSibling.next = element;
	} else {
		element.prev = null;
	}

	siblings.push(element);
	element.parent = parent || null;
};

DomHandler.prototype.onopentag = function(name, attribs){
	var element = {
		type: name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag,
		name: name,
		attribs: attribs,
		children: []
	};

	this._addDomElement(element);

	this._tagStack.push(element);
};

DomHandler.prototype.ontext = function(data){
	//the ignoreWhitespace is officially dropped, but for now,
	//it's an alias for normalizeWhitespace
	var normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace;

	var lastTag;

	if(!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length-1]).type === ElementType.Text){
		if(normalize){
			lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
		} else {
			lastTag.data += data;
		}
	} else {
		if(
			this._tagStack.length &&
			(lastTag = this._tagStack[this._tagStack.length - 1]) &&
			(lastTag = lastTag.children[lastTag.children.length - 1]) &&
			lastTag.type === ElementType.Text
		){
			if(normalize){
				lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");
			} else {
				lastTag.data += data;
			}
		} else {
			if(normalize){
				data = data.replace(re_whitespace, " ");
			}

			this._addDomElement({
				data: data,
				type: ElementType.Text
			});
		}
	}
};

DomHandler.prototype.oncomment = function(data){
	var lastTag = this._tagStack[this._tagStack.length - 1];

	if(lastTag && lastTag.type === ElementType.Comment){
		lastTag.data += data;
		return;
	}

	var element = {
		data: data,
		type: ElementType.Comment
	};

	this._addDomElement(element);
	this._tagStack.push(element);
};

DomHandler.prototype.oncdatastart = function(){
	var element = {
		children: [{
			data: "",
			type: ElementType.Text
		}],
		type: ElementType.CDATA
	};

	this._addDomElement(element);
	this._tagStack.push(element);
};

DomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function(){
	this._tagStack.pop();
};

DomHandler.prototype.onprocessinginstruction = function(name, data){
	this._addDomElement({
		name: name,
		data: data,
		type: ElementType.Directive
	});
};

module.exports = DomHandler;


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/lib/element.js":
/*!****************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/lib/element.js ***!
  \****************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

// DOM-Level-1-compliant structure
var NodePrototype = __webpack_require__(/*! ./node */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/lib/node.js");
var ElementPrototype = module.exports = Object.create(NodePrototype);

var domLvl1 = {
	tagName: "name"
};

Object.keys(domLvl1).forEach(function(key) {
	var shorthand = domLvl1[key];
	Object.defineProperty(ElementPrototype, key, {
		get: function() {
			return this[shorthand] || null;
		},
		set: function(val) {
			this[shorthand] = val;
			return val;
		}
	});
});


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/lib/node.js":
/*!*************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domhandler/lib/node.js ***!
  \*************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// This object will be used as the prototype for Nodes when creating a
// DOM-Level-1-compliant structure.
var NodePrototype = module.exports = {
	get firstChild() {
		var children = this.children;
		return children && children[0] || null;
	},
	get lastChild() {
		var children = this.children;
		return children && children[children.length - 1] || null;
	},
	get nodeType() {
		return nodeTypes[this.type] || nodeTypes.element;
	}
};

var domLvl1 = {
	tagName: "name",
	childNodes: "children",
	parentNode: "parent",
	previousSibling: "prev",
	nextSibling: "next",
	nodeValue: "data"
};

var nodeTypes = {
	element: 1,
	text: 3,
	cdata: 4,
	comment: 8
};

Object.keys(domLvl1).forEach(function(key) {
	var shorthand = domLvl1[key];
	Object.defineProperty(NodePrototype, key, {
		get: function() {
			return this[shorthand] || null;
		},
		set: function(val) {
			this[shorthand] = val;
			return val;
		}
	});
});


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/index.js":
/*!********************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/index.js ***!
  \********************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var DomUtils = module.exports;

[
	__webpack_require__(/*! ./lib/stringify */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/stringify.js"),
	__webpack_require__(/*! ./lib/traversal */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/traversal.js"),
	__webpack_require__(/*! ./lib/manipulation */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/manipulation.js"),
	__webpack_require__(/*! ./lib/querying */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/querying.js"),
	__webpack_require__(/*! ./lib/legacy */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/legacy.js"),
	__webpack_require__(/*! ./lib/helpers */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/helpers.js")
].forEach(function(ext){
	Object.keys(ext).forEach(function(key){
		DomUtils[key] = ext[key].bind(DomUtils);
	});
});


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/helpers.js":
/*!**************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/helpers.js ***!
  \**************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

// removeSubsets
// Given an array of nodes, remove any member that is contained by another.
exports.removeSubsets = function(nodes) {
	var idx = nodes.length, node, ancestor, replace;

	// Check if each node (or one of its ancestors) is already contained in the
	// array.
	while (--idx > -1) {
		node = ancestor = nodes[idx];

		// Temporarily remove the node under consideration
		nodes[idx] = null;
		replace = true;

		while (ancestor) {
			if (nodes.indexOf(ancestor) > -1) {
				replace = false;
				nodes.splice(idx, 1);
				break;
			}
			ancestor = ancestor.parent;
		}

		// If the node has been found to be unique, re-insert it.
		if (replace) {
			nodes[idx] = node;
		}
	}

	return nodes;
};

// Source: http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
var POSITION = {
	DISCONNECTED: 1,
	PRECEDING: 2,
	FOLLOWING: 4,
	CONTAINS: 8,
	CONTAINED_BY: 16
};

// Compare the position of one node against another node in any other document.
// The return value is a bitmask with the following values:
//
// document order:
// > There is an ordering, document order, defined on all the nodes in the
// > document corresponding to the order in which the first character of the
// > XML representation of each node occurs in the XML representation of the
// > document after expansion of general entities. Thus, the document element
// > node will be the first node. Element nodes occur before their children.
// > Thus, document order orders element nodes in order of the occurrence of
// > their start-tag in the XML (after expansion of entities). The attribute
// > nodes of an element occur after the element and before its children. The
// > relative order of attribute nodes is implementation-dependent./
// Source:
// http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
//
// @argument {Node} nodaA The first node to use in the comparison
// @argument {Node} nodeB The second node to use in the comparison
//
// @return {Number} A bitmask describing the input nodes' relative position.
//         See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
//         a description of these values.
var comparePos = exports.compareDocumentPosition = function(nodeA, nodeB) {
	var aParents = [];
	var bParents = [];
	var current, sharedParent, siblings, aSibling, bSibling, idx;

	if (nodeA === nodeB) {
		return 0;
	}

	current = nodeA;
	while (current) {
		aParents.unshift(current);
		current = current.parent;
	}
	current = nodeB;
	while (current) {
		bParents.unshift(current);
		current = current.parent;
	}

	idx = 0;
	while (aParents[idx] === bParents[idx]) {
		idx++;
	}

	if (idx === 0) {
		return POSITION.DISCONNECTED;
	}

	sharedParent = aParents[idx - 1];
	siblings = sharedParent.children;
	aSibling = aParents[idx];
	bSibling = bParents[idx];

	if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {
		if (sharedParent === nodeB) {
			return POSITION.FOLLOWING | POSITION.CONTAINED_BY;
		}
		return POSITION.FOLLOWING;
	} else {
		if (sharedParent === nodeA) {
			return POSITION.PRECEDING | POSITION.CONTAINS;
		}
		return POSITION.PRECEDING;
	}
};

// Sort an array of nodes based on their relative position in the document and
// remove any duplicate nodes. If the array contains nodes that do not belong
// to the same document, sort order is unspecified.
//
// @argument {Array} nodes Array of DOM nodes
//
// @returns {Array} collection of unique nodes, sorted in document order
exports.uniqueSort = function(nodes) {
	var idx = nodes.length, node, position;

	nodes = nodes.slice();

	while (--idx > -1) {
		node = nodes[idx];
		position = nodes.indexOf(node);
		if (position > -1 && position < idx) {
			nodes.splice(idx, 1);
		}
	}
	nodes.sort(function(a, b) {
		var relative = comparePos(a, b);
		if (relative & POSITION.PRECEDING) {
			return -1;
		} else if (relative & POSITION.FOLLOWING) {
			return 1;
		}
		return 0;
	});

	return nodes;
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/legacy.js":
/*!*************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/legacy.js ***!
  \*************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var ElementType = __webpack_require__(/*! domelementtype */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domelementtype/index.js");
var isTag = exports.isTag = ElementType.isTag;

exports.testElement = function(options, element){
	for(var key in options){
		if(!options.hasOwnProperty(key));
		else if(key === "tag_name"){
			if(!isTag(element) || !options.tag_name(element.name)){
				return false;
			}
		} else if(key === "tag_type"){
			if(!options.tag_type(element.type)) return false;
		} else if(key === "tag_contains"){
			if(isTag(element) || !options.tag_contains(element.data)){
				return false;
			}
		} else if(!element.attribs || !options[key](element.attribs[key])){
			return false;
		}
	}
	return true;
};

var Checks = {
	tag_name: function(name){
		if(typeof name === "function"){
			return function(elem){ return isTag(elem) && name(elem.name); };
		} else if(name === "*"){
			return isTag;
		} else {
			return function(elem){ return isTag(elem) && elem.name === name; };
		}
	},
	tag_type: function(type){
		if(typeof type === "function"){
			return function(elem){ return type(elem.type); };
		} else {
			return function(elem){ return elem.type === type; };
		}
	},
	tag_contains: function(data){
		if(typeof data === "function"){
			return function(elem){ return !isTag(elem) && data(elem.data); };
		} else {
			return function(elem){ return !isTag(elem) && elem.data === data; };
		}
	}
};

function getAttribCheck(attrib, value){
	if(typeof value === "function"){
		return function(elem){ return elem.attribs && value(elem.attribs[attrib]); };
	} else {
		return function(elem){ return elem.attribs && elem.attribs[attrib] === value; };
	}
}

function combineFuncs(a, b){
	return function(elem){
		return a(elem) || b(elem);
	};
}

exports.getElements = function(options, element, recurse, limit){
	var funcs = Object.keys(options).map(function(key){
		var value = options[key];
		return key in Checks ? Checks[key](value) : getAttribCheck(key, value);
	});

	return funcs.length === 0 ? [] : this.filter(
		funcs.reduce(combineFuncs),
		element, recurse, limit
	);
};

exports.getElementById = function(id, element, recurse){
	if(!Array.isArray(element)) element = [element];
	return this.findOne(getAttribCheck("id", id), element, recurse !== false);
};

exports.getElementsByTagName = function(name, element, recurse, limit){
	return this.filter(Checks.tag_name(name), element, recurse, limit);
};

exports.getElementsByTagType = function(type, element, recurse, limit){
	return this.filter(Checks.tag_type(type), element, recurse, limit);
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/manipulation.js":
/*!*******************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/manipulation.js ***!
  \*******************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

exports.removeElement = function(elem){
	if(elem.prev) elem.prev.next = elem.next;
	if(elem.next) elem.next.prev = elem.prev;

	if(elem.parent){
		var childs = elem.parent.children;
		childs.splice(childs.lastIndexOf(elem), 1);
	}
};

exports.replaceElement = function(elem, replacement){
	var prev = replacement.prev = elem.prev;
	if(prev){
		prev.next = replacement;
	}

	var next = replacement.next = elem.next;
	if(next){
		next.prev = replacement;
	}

	var parent = replacement.parent = elem.parent;
	if(parent){
		var childs = parent.children;
		childs[childs.lastIndexOf(elem)] = replacement;
	}
};

exports.appendChild = function(elem, child){
	child.parent = elem;

	if(elem.children.push(child) !== 1){
		var sibling = elem.children[elem.children.length - 2];
		sibling.next = child;
		child.prev = sibling;
		child.next = null;
	}
};

exports.append = function(elem, next){
	var parent = elem.parent,
		currNext = elem.next;

	next.next = currNext;
	next.prev = elem;
	elem.next = next;
	next.parent = parent;

	if(currNext){
		currNext.prev = next;
		if(parent){
			var childs = parent.children;
			childs.splice(childs.lastIndexOf(currNext), 0, next);
		}
	} else if(parent){
		parent.children.push(next);
	}
};

exports.prepend = function(elem, prev){
	var parent = elem.parent;
	if(parent){
		var childs = parent.children;
		childs.splice(childs.lastIndexOf(elem), 0, prev);
	}

	if(elem.prev){
		elem.prev.next = prev;
	}
	
	prev.parent = parent;
	prev.prev = elem.prev;
	prev.next = elem;
	elem.prev = prev;
};




/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/querying.js":
/*!***************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/querying.js ***!
  \***************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var isTag = __webpack_require__(/*! domelementtype */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domelementtype/index.js").isTag;

module.exports = {
	filter: filter,
	find: find,
	findOneChild: findOneChild,
	findOne: findOne,
	existsOne: existsOne,
	findAll: findAll
};

function filter(test, element, recurse, limit){
	if(!Array.isArray(element)) element = [element];

	if(typeof limit !== "number" || !isFinite(limit)){
		limit = Infinity;
	}
	return find(test, element, recurse !== false, limit);
}

function find(test, elems, recurse, limit){
	var result = [], childs;

	for(var i = 0, j = elems.length; i < j; i++){
		if(test(elems[i])){
			result.push(elems[i]);
			if(--limit <= 0) break;
		}

		childs = elems[i].children;
		if(recurse && childs && childs.length > 0){
			childs = find(test, childs, recurse, limit);
			result = result.concat(childs);
			limit -= childs.length;
			if(limit <= 0) break;
		}
	}

	return result;
}

function findOneChild(test, elems){
	for(var i = 0, l = elems.length; i < l; i++){
		if(test(elems[i])) return elems[i];
	}

	return null;
}

function findOne(test, elems){
	var elem = null;

	for(var i = 0, l = elems.length; i < l && !elem; i++){
		if(!isTag(elems[i])){
			continue;
		} else if(test(elems[i])){
			elem = elems[i];
		} else if(elems[i].children.length > 0){
			elem = findOne(test, elems[i].children);
		}
	}

	return elem;
}

function existsOne(test, elems){
	for(var i = 0, l = elems.length; i < l; i++){
		if(
			isTag(elems[i]) && (
				test(elems[i]) || (
					elems[i].children.length > 0 &&
					existsOne(test, elems[i].children)
				)
			)
		){
			return true;
		}
	}

	return false;
}

function findAll(test, elems){
	var result = [];
	for(var i = 0, j = elems.length; i < j; i++){
		if(!isTag(elems[i])) continue;
		if(test(elems[i])) result.push(elems[i]);

		if(elems[i].children.length > 0){
			result = result.concat(findAll(test, elems[i].children));
		}
	}
	return result;
}


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/stringify.js":
/*!****************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/stringify.js ***!
  \****************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var ElementType = __webpack_require__(/*! domelementtype */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domelementtype/index.js"),
    getOuterHTML = __webpack_require__(/*! dom-serializer */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/node_modules/dom-serializer/index.js"),
    isTag = ElementType.isTag;

module.exports = {
	getInnerHTML: getInnerHTML,
	getOuterHTML: getOuterHTML,
	getText: getText
};

function getInnerHTML(elem, opts){
	return elem.children ? elem.children.map(function(elem){
		return getOuterHTML(elem, opts);
	}).join("") : "";
}

function getText(elem){
	if(Array.isArray(elem)) return elem.map(getText).join("");
	if(isTag(elem) || elem.type === ElementType.CDATA) return getText(elem.children);
	if(elem.type === ElementType.Text) return elem.data;
	return "";
}


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/traversal.js":
/*!****************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/lib/traversal.js ***!
  \****************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var getChildren = exports.getChildren = function(elem){
	return elem.children;
};

var getParent = exports.getParent = function(elem){
	return elem.parent;
};

exports.getSiblings = function(elem){
	var parent = getParent(elem);
	return parent ? getChildren(parent) : [elem];
};

exports.getAttributeValue = function(elem, name){
	return elem.attribs && elem.attribs[name];
};

exports.hasAttrib = function(elem, name){
	return !!elem.attribs && hasOwnProperty.call(elem.attribs, name);
};

exports.getName = function(elem){
	return elem.name;
};


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/node_modules/dom-serializer/index.js":
/*!************************************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/node_modules/dom-serializer/index.js ***!
  \************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/*
  Module dependencies
*/
var ElementType = __webpack_require__(/*! domelementtype */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/node_modules/dom-serializer/node_modules/domelementtype/index.js");
var entities = __webpack_require__(/*! entities */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/index.js");

/*
  Boolean Attributes
*/
var booleanAttributes = {
  __proto__: null,
  allowfullscreen: true,
  async: true,
  autofocus: true,
  autoplay: true,
  checked: true,
  controls: true,
  default: true,
  defer: true,
  disabled: true,
  hidden: true,
  ismap: true,
  loop: true,
  multiple: true,
  muted: true,
  open: true,
  readonly: true,
  required: true,
  reversed: true,
  scoped: true,
  seamless: true,
  selected: true,
  typemustmatch: true
};

var unencodedElements = {
  __proto__: null,
  style: true,
  script: true,
  xmp: true,
  iframe: true,
  noembed: true,
  noframes: true,
  plaintext: true,
  noscript: true
};

/*
  Format attributes
*/
function formatAttrs(attributes, opts) {
  if (!attributes) return;

  var output = '',
      value;

  // Loop through the attributes
  for (var key in attributes) {
    value = attributes[key];
    if (output) {
      output += ' ';
    }

    if (!value && booleanAttributes[key]) {
      output += key;
    } else {
      output += key + '="' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '"';
    }
  }

  return output;
}

/*
  Self-enclosing tags (stolen from node-htmlparser)
*/
var singleTag = {
  __proto__: null,
  area: true,
  base: true,
  basefont: true,
  br: true,
  col: true,
  command: true,
  embed: true,
  frame: true,
  hr: true,
  img: true,
  input: true,
  isindex: true,
  keygen: true,
  link: true,
  meta: true,
  param: true,
  source: true,
  track: true,
  wbr: true,
};


var render = module.exports = function(dom, opts) {
  if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];
  opts = opts || {};

  var output = '';

  for(var i = 0; i < dom.length; i++){
    var elem = dom[i];

    if (elem.type === 'root')
      output += render(elem.children, opts);
    else if (ElementType.isTag(elem))
      output += renderTag(elem, opts);
    else if (elem.type === ElementType.Directive)
      output += renderDirective(elem);
    else if (elem.type === ElementType.Comment)
      output += renderComment(elem);
    else if (elem.type === ElementType.CDATA)
      output += renderCdata(elem);
    else
      output += renderText(elem, opts);
  }

  return output;
};

function renderTag(elem, opts) {
  // Handle SVG
  if (elem.name === "svg") opts = {decodeEntities: opts.decodeEntities, xmlMode: true};

  var tag = '<' + elem.name,
      attribs = formatAttrs(elem.attribs, opts);

  if (attribs) {
    tag += ' ' + attribs;
  }

  if (
    opts.xmlMode
    && (!elem.children || elem.children.length === 0)
  ) {
    tag += '/>';
  } else {
    tag += '>';
    if (elem.children) {
      tag += render(elem.children, opts);
    }

    if (!singleTag[elem.name] || opts.xmlMode) {
      tag += '</' + elem.name + '>';
    }
  }

  return tag;
}

function renderDirective(elem) {
  return '<' + elem.data + '>';
}

function renderText(elem, opts) {
  var data = elem.data || '';

  // if entities weren't decoded, no need to encode them back
  if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) {
    data = entities.encodeXML(data);
  }

  return data;
}

function renderCdata(elem) {
  return '<![CDATA[' + elem.children[0].data + ']]>';
}

function renderComment(elem) {
  return '<!--' + elem.data + '-->';
}


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/node_modules/dom-serializer/node_modules/domelementtype/index.js":
/*!****************************************************************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/domutils/node_modules/dom-serializer/node_modules/domelementtype/index.js ***!
  \****************************************************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

//Types of elements found in the DOM
module.exports = {
	Text: "text", //Text
	Directive: "directive", //<? ... ?>
	Comment: "comment", //<!-- ... -->
	Script: "script", //<script> tags
	Style: "style", //<style> tags
	Tag: "tag", //Any tag
	CDATA: "cdata", //<![CDATA[ ... ]]>

	isTag: function(elem){
		return elem.type === "tag" || elem.type === "script" || elem.type === "style";
	}
};

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/index.js":
/*!********************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/index.js ***!
  \********************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var encode = __webpack_require__(/*! ./lib/encode.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/encode.js"),
    decode = __webpack_require__(/*! ./lib/decode.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/decode.js");

exports.decode = function(data, level){
	return (!level || level <= 0 ? decode.XML : decode.HTML)(data);
};

exports.decodeStrict = function(data, level){
	return (!level || level <= 0 ? decode.XML : decode.HTMLStrict)(data);
};

exports.encode = function(data, level){
	return (!level || level <= 0 ? encode.XML : encode.HTML)(data);
};

exports.encodeXML = encode.XML;

exports.encodeHTML4 =
exports.encodeHTML5 =
exports.encodeHTML  = encode.HTML;

exports.decodeXML =
exports.decodeXMLStrict = decode.XML;

exports.decodeHTML4 =
exports.decodeHTML5 =
exports.decodeHTML = decode.HTML;

exports.decodeHTML4Strict =
exports.decodeHTML5Strict =
exports.decodeHTMLStrict = decode.HTMLStrict;

exports.escape = encode.escape;


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/decode.js":
/*!*************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/decode.js ***!
  \*************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var entityMap = __webpack_require__(/*! ../maps/entities.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/entities.json"),
    legacyMap = __webpack_require__(/*! ../maps/legacy.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/legacy.json"),
    xmlMap    = __webpack_require__(/*! ../maps/xml.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/xml.json"),
    decodeCodePoint = __webpack_require__(/*! ./decode_codepoint.js */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/decode_codepoint.js");

var decodeXMLStrict  = getStrictDecoder(xmlMap),
    decodeHTMLStrict = getStrictDecoder(entityMap);

function getStrictDecoder(map){
	var keys = Object.keys(map).join("|"),
	    replace = getReplacer(map);

	keys += "|#[xX][\\da-fA-F]+|#\\d+";

	var re = new RegExp("&(?:" + keys + ");", "g");

	return function(str){
		return String(str).replace(re, replace);
	};
}

var decodeHTML = (function(){
	var legacy = Object.keys(legacyMap)
		.sort(sorter);

	var keys = Object.keys(entityMap)
		.sort(sorter);

	for(var i = 0, j = 0; i < keys.length; i++){
		if(legacy[j] === keys[i]){
			keys[i] += ";?";
			j++;
		} else {
			keys[i] += ";";
		}
	}

	var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"),
	    replace = getReplacer(entityMap);

	function replacer(str){
		if(str.substr(-1) !== ";") str += ";";
		return replace(str);
	}

	//TODO consider creating a merged map
	return function(str){
		return String(str).replace(re, replacer);
	};
}());

function sorter(a, b){
	return a < b ? 1 : -1;
}

function getReplacer(map){
	return function replace(str){
		if(str.charAt(1) === "#"){
			if(str.charAt(2) === "X" || str.charAt(2) === "x"){
				return decodeCodePoint(parseInt(str.substr(3), 16));
			}
			return decodeCodePoint(parseInt(str.substr(2), 10));
		}
		return map[str.slice(1, -1)];
	};
}

module.exports = {
	XML: decodeXMLStrict,
	HTML: decodeHTML,
	HTMLStrict: decodeHTMLStrict
};

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/decode_codepoint.js":
/*!***********************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/decode_codepoint.js ***!
  \***********************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var decodeMap = __webpack_require__(/*! ../maps/decode.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/decode.json");

module.exports = decodeCodePoint;

// modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
function decodeCodePoint(codePoint){

	if((codePoint >= 0xD800 && codePoint <= 0xDFFF) || codePoint > 0x10FFFF){
		return "\uFFFD";
	}

	if(codePoint in decodeMap){
		codePoint = decodeMap[codePoint];
	}

	var output = "";

	if(codePoint > 0xFFFF){
		codePoint -= 0x10000;
		output += String.fromCharCode(codePoint >>> 10 & 0x3FF | 0xD800);
		codePoint = 0xDC00 | codePoint & 0x3FF;
	}

	output += String.fromCharCode(codePoint);
	return output;
}


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/encode.js":
/*!*************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/lib/encode.js ***!
  \*************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var inverseXML = getInverseObj(__webpack_require__(/*! ../maps/xml.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/xml.json")),
    xmlReplacer = getInverseReplacer(inverseXML);

exports.XML = getInverse(inverseXML, xmlReplacer);

var inverseHTML = getInverseObj(__webpack_require__(/*! ../maps/entities.json */ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/entities.json")),
    htmlReplacer = getInverseReplacer(inverseHTML);

exports.HTML = getInverse(inverseHTML, htmlReplacer);

function getInverseObj(obj){
	return Object.keys(obj).sort().reduce(function(inverse, name){
		inverse[obj[name]] = "&" + name + ";";
		return inverse;
	}, {});
}

function getInverseReplacer(inverse){
	var single = [],
	    multiple = [];

	Object.keys(inverse).forEach(function(k){
		if(k.length === 1){
			single.push("\\" + k);
		} else {
			multiple.push(k);
		}
	});

	//TODO add ranges
	multiple.unshift("[" + single.join("") + "]");

	return new RegExp(multiple.join("|"), "g");
}

var re_nonASCII = /[^\0-\x7F]/g,
    re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;

function singleCharReplacer(c){
	return "&#x" + c.charCodeAt(0).toString(16).toUpperCase() + ";";
}

function astralReplacer(c){
	// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
	var high = c.charCodeAt(0);
	var low  = c.charCodeAt(1);
	var codePoint = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
	return "&#x" + codePoint.toString(16).toUpperCase() + ";";
}

function getInverse(inverse, re){
	function func(name){
		return inverse[name];
	}

	return function(data){
		return data
				.replace(re, func)
				.replace(re_astralSymbols, astralReplacer)
				.replace(re_nonASCII, singleCharReplacer);
	};
}

var re_xmlChars = getInverseReplacer(inverseXML);

function escapeXML(data){
	return data
			.replace(re_xmlChars, singleCharReplacer)
			.replace(re_astralSymbols, astralReplacer)
			.replace(re_nonASCII, singleCharReplacer);
}

exports.escape = escapeXML;


/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/decode.json":
/*!****************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/decode.json ***!
  \****************************************************************************************************/
/*! exports provided: 0, 128, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 142, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, default */
/***/ (function(module) {

module.exports = JSON.parse("{\"0\":65533,\"128\":8364,\"130\":8218,\"131\":402,\"132\":8222,\"133\":8230,\"134\":8224,\"135\":8225,\"136\":710,\"137\":8240,\"138\":352,\"139\":8249,\"140\":338,\"142\":381,\"145\":8216,\"146\":8217,\"147\":8220,\"148\":8221,\"149\":8226,\"150\":8211,\"151\":8212,\"152\":732,\"153\":8482,\"154\":353,\"155\":8250,\"156\":339,\"158\":382,\"159\":376}");

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/entities.json":
/*!******************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/entities.json ***!
  \******************************************************************************************************/
/*! exports provided: Aacute, aacute, Abreve, abreve, ac, acd, acE, Acirc, acirc, acute, Acy, acy, AElig, aelig, af, Afr, afr, Agrave, agrave, alefsym, aleph, Alpha, alpha, Amacr, amacr, amalg, amp, AMP, andand, And, and, andd, andslope, andv, ang, ange, angle, angmsdaa, angmsdab, angmsdac, angmsdad, angmsdae, angmsdaf, angmsdag, angmsdah, angmsd, angrt, angrtvb, angrtvbd, angsph, angst, angzarr, Aogon, aogon, Aopf, aopf, apacir, ap, apE, ape, apid, apos, ApplyFunction, approx, approxeq, Aring, aring, Ascr, ascr, Assign, ast, asymp, asympeq, Atilde, atilde, Auml, auml, awconint, awint, backcong, backepsilon, backprime, backsim, backsimeq, Backslash, Barv, barvee, barwed, Barwed, barwedge, bbrk, bbrktbrk, bcong, Bcy, bcy, bdquo, becaus, because, Because, bemptyv, bepsi, bernou, Bernoullis, Beta, beta, beth, between, Bfr, bfr, bigcap, bigcirc, bigcup, bigodot, bigoplus, bigotimes, bigsqcup, bigstar, bigtriangledown, bigtriangleup, biguplus, bigvee, bigwedge, bkarow, blacklozenge, blacksquare, blacktriangle, blacktriangledown, blacktriangleleft, blacktriangleright, blank, blk12, blk14, blk34, block, bne, bnequiv, bNot, bnot, Bopf, bopf, bot, bottom, bowtie, boxbox, boxdl, boxdL, boxDl, boxDL, boxdr, boxdR, boxDr, boxDR, boxh, boxH, boxhd, boxHd, boxhD, boxHD, boxhu, boxHu, boxhU, boxHU, boxminus, boxplus, boxtimes, boxul, boxuL, boxUl, boxUL, boxur, boxuR, boxUr, boxUR, boxv, boxV, boxvh, boxvH, boxVh, boxVH, boxvl, boxvL, boxVl, boxVL, boxvr, boxvR, boxVr, boxVR, bprime, breve, Breve, brvbar, bscr, Bscr, bsemi, bsim, bsime, bsolb, bsol, bsolhsub, bull, bullet, bump, bumpE, bumpe, Bumpeq, bumpeq, Cacute, cacute, capand, capbrcup, capcap, cap, Cap, capcup, capdot, CapitalDifferentialD, caps, caret, caron, Cayleys, ccaps, Ccaron, ccaron, Ccedil, ccedil, Ccirc, ccirc, Cconint, ccups, ccupssm, Cdot, cdot, cedil, Cedilla, cemptyv, cent, centerdot, CenterDot, cfr, Cfr, CHcy, chcy, check, checkmark, Chi, chi, circ, circeq, circlearrowleft, circlearrowright, circledast, circledcirc, circleddash, CircleDot, circledR, circledS, CircleMinus, CirclePlus, CircleTimes, cir, cirE, cire, cirfnint, cirmid, cirscir, ClockwiseContourIntegral, CloseCurlyDoubleQuote, CloseCurlyQuote, clubs, clubsuit, colon, Colon, Colone, colone, coloneq, comma, commat, comp, compfn, complement, complexes, cong, congdot, Congruent, conint, Conint, ContourIntegral, copf, Copf, coprod, Coproduct, copy, COPY, copysr, CounterClockwiseContourIntegral, crarr, cross, Cross, Cscr, cscr, csub, csube, csup, csupe, ctdot, cudarrl, cudarrr, cuepr, cuesc, cularr, cularrp, cupbrcap, cupcap, CupCap, cup, Cup, cupcup, cupdot, cupor, cups, curarr, curarrm, curlyeqprec, curlyeqsucc, curlyvee, curlywedge, curren, curvearrowleft, curvearrowright, cuvee, cuwed, cwconint, cwint, cylcty, dagger, Dagger, daleth, darr, Darr, dArr, dash, Dashv, dashv, dbkarow, dblac, Dcaron, dcaron, Dcy, dcy, ddagger, ddarr, DD, dd, DDotrahd, ddotseq, deg, Del, Delta, delta, demptyv, dfisht, Dfr, dfr, dHar, dharl, dharr, DiacriticalAcute, DiacriticalDot, DiacriticalDoubleAcute, DiacriticalGrave, DiacriticalTilde, diam, diamond, Diamond, diamondsuit, diams, die, DifferentialD, digamma, disin, div, divide, divideontimes, divonx, DJcy, djcy, dlcorn, dlcrop, dollar, Dopf, dopf, Dot, dot, DotDot, doteq, doteqdot, DotEqual, dotminus, dotplus, dotsquare, doublebarwedge, DoubleContourIntegral, DoubleDot, DoubleDownArrow, DoubleLeftArrow, DoubleLeftRightArrow, DoubleLeftTee, DoubleLongLeftArrow, DoubleLongLeftRightArrow, DoubleLongRightArrow, DoubleRightArrow, DoubleRightTee, DoubleUpArrow, DoubleUpDownArrow, DoubleVerticalBar, DownArrowBar, downarrow, DownArrow, Downarrow, DownArrowUpArrow, DownBreve, downdownarrows, downharpoonleft, downharpoonright, DownLeftRightVector, DownLeftTeeVector, DownLeftVectorBar, DownLeftVector, DownRightTeeVector, DownRightVectorBar, DownRightVector, DownTeeArrow, DownTee, drbkarow, drcorn, drcrop, Dscr, dscr, DScy, dscy, dsol, Dstrok, dstrok, dtdot, dtri, dtrif, duarr, duhar, dwangle, DZcy, dzcy, dzigrarr, Eacute, eacute, easter, Ecaron, ecaron, Ecirc, ecirc, ecir, ecolon, Ecy, ecy, eDDot, Edot, edot, eDot, ee, efDot, Efr, efr, eg, Egrave, egrave, egs, egsdot, el, Element, elinters, ell, els, elsdot, Emacr, emacr, empty, emptyset, EmptySmallSquare, emptyv, EmptyVerySmallSquare, emsp13, emsp14, emsp, ENG, eng, ensp, Eogon, eogon, Eopf, eopf, epar, eparsl, eplus, epsi, Epsilon, epsilon, epsiv, eqcirc, eqcolon, eqsim, eqslantgtr, eqslantless, Equal, equals, EqualTilde, equest, Equilibrium, equiv, equivDD, eqvparsl, erarr, erDot, escr, Escr, esdot, Esim, esim, Eta, eta, ETH, eth, Euml, euml, euro, excl, exist, Exists, expectation, exponentiale, ExponentialE, fallingdotseq, Fcy, fcy, female, ffilig, fflig, ffllig, Ffr, ffr, filig, FilledSmallSquare, FilledVerySmallSquare, fjlig, flat, fllig, fltns, fnof, Fopf, fopf, forall, ForAll, fork, forkv, Fouriertrf, fpartint, frac12, frac13, frac14, frac15, frac16, frac18, frac23, frac25, frac34, frac35, frac38, frac45, frac56, frac58, frac78, frasl, frown, fscr, Fscr, gacute, Gamma, gamma, Gammad, gammad, gap, Gbreve, gbreve, Gcedil, Gcirc, gcirc, Gcy, gcy, Gdot, gdot, ge, gE, gEl, gel, geq, geqq, geqslant, gescc, ges, gesdot, gesdoto, gesdotol, gesl, gesles, Gfr, gfr, gg, Gg, ggg, gimel, GJcy, gjcy, gla, gl, glE, glj, gnap, gnapprox, gne, gnE, gneq, gneqq, gnsim, Gopf, gopf, grave, GreaterEqual, GreaterEqualLess, GreaterFullEqual, GreaterGreater, GreaterLess, GreaterSlantEqual, GreaterTilde, Gscr, gscr, gsim, gsime, gsiml, gtcc, gtcir, gt, GT, Gt, gtdot, gtlPar, gtquest, gtrapprox, gtrarr, gtrdot, gtreqless, gtreqqless, gtrless, gtrsim, gvertneqq, gvnE, Hacek, hairsp, half, hamilt, HARDcy, hardcy, harrcir, harr, hArr, harrw, Hat, hbar, Hcirc, hcirc, hearts, heartsuit, hellip, hercon, hfr, Hfr, HilbertSpace, hksearow, hkswarow, hoarr, homtht, hookleftarrow, hookrightarrow, hopf, Hopf, horbar, HorizontalLine, hscr, Hscr, hslash, Hstrok, hstrok, HumpDownHump, HumpEqual, hybull, hyphen, Iacute, iacute, ic, Icirc, icirc, Icy, icy, Idot, IEcy, iecy, iexcl, iff, ifr, Ifr, Igrave, igrave, ii, iiiint, iiint, iinfin, iiota, IJlig, ijlig, Imacr, imacr, image, ImaginaryI, imagline, imagpart, imath, Im, imof, imped, Implies, incare, in, infin, infintie, inodot, intcal, int, Int, integers, Integral, intercal, Intersection, intlarhk, intprod, InvisibleComma, InvisibleTimes, IOcy, iocy, Iogon, iogon, Iopf, iopf, Iota, iota, iprod, iquest, iscr, Iscr, isin, isindot, isinE, isins, isinsv, isinv, it, Itilde, itilde, Iukcy, iukcy, Iuml, iuml, Jcirc, jcirc, Jcy, jcy, Jfr, jfr, jmath, Jopf, jopf, Jscr, jscr, Jsercy, jsercy, Jukcy, jukcy, Kappa, kappa, kappav, Kcedil, kcedil, Kcy, kcy, Kfr, kfr, kgreen, KHcy, khcy, KJcy, kjcy, Kopf, kopf, Kscr, kscr, lAarr, Lacute, lacute, laemptyv, lagran, Lambda, lambda, lang, Lang, langd, langle, lap, Laplacetrf, laquo, larrb, larrbfs, larr, Larr, lArr, larrfs, larrhk, larrlp, larrpl, larrsim, larrtl, latail, lAtail, lat, late, lates, lbarr, lBarr, lbbrk, lbrace, lbrack, lbrke, lbrksld, lbrkslu, Lcaron, lcaron, Lcedil, lcedil, lceil, lcub, Lcy, lcy, ldca, ldquo, ldquor, ldrdhar, ldrushar, ldsh, le, lE, LeftAngleBracket, LeftArrowBar, leftarrow, LeftArrow, Leftarrow, LeftArrowRightArrow, leftarrowtail, LeftCeiling, LeftDoubleBracket, LeftDownTeeVector, LeftDownVectorBar, LeftDownVector, LeftFloor, leftharpoondown, leftharpoonup, leftleftarrows, leftrightarrow, LeftRightArrow, Leftrightarrow, leftrightarrows, leftrightharpoons, leftrightsquigarrow, LeftRightVector, LeftTeeArrow, LeftTee, LeftTeeVector, leftthreetimes, LeftTriangleBar, LeftTriangle, LeftTriangleEqual, LeftUpDownVector, LeftUpTeeVector, LeftUpVectorBar, LeftUpVector, LeftVectorBar, LeftVector, lEg, leg, leq, leqq, leqslant, lescc, les, lesdot, lesdoto, lesdotor, lesg, lesges, lessapprox, lessdot, lesseqgtr, lesseqqgtr, LessEqualGreater, LessFullEqual, LessGreater, lessgtr, LessLess, lesssim, LessSlantEqual, LessTilde, lfisht, lfloor, Lfr, lfr, lg, lgE, lHar, lhard, lharu, lharul, lhblk, LJcy, ljcy, llarr, ll, Ll, llcorner, Lleftarrow, llhard, lltri, Lmidot, lmidot, lmoustache, lmoust, lnap, lnapprox, lne, lnE, lneq, lneqq, lnsim, loang, loarr, lobrk, longleftarrow, LongLeftArrow, Longleftarrow, longleftrightarrow, LongLeftRightArrow, Longleftrightarrow, longmapsto, longrightarrow, LongRightArrow, Longrightarrow, looparrowleft, looparrowright, lopar, Lopf, lopf, loplus, lotimes, lowast, lowbar, LowerLeftArrow, LowerRightArrow, loz, lozenge, lozf, lpar, lparlt, lrarr, lrcorner, lrhar, lrhard, lrm, lrtri, lsaquo, lscr, Lscr, lsh, Lsh, lsim, lsime, lsimg, lsqb, lsquo, lsquor, Lstrok, lstrok, ltcc, ltcir, lt, LT, Lt, ltdot, lthree, ltimes, ltlarr, ltquest, ltri, ltrie, ltrif, ltrPar, lurdshar, luruhar, lvertneqq, lvnE, macr, male, malt, maltese, Map, map, mapsto, mapstodown, mapstoleft, mapstoup, marker, mcomma, Mcy, mcy, mdash, mDDot, measuredangle, MediumSpace, Mellintrf, Mfr, mfr, mho, micro, midast, midcir, mid, middot, minusb, minus, minusd, minusdu, MinusPlus, mlcp, mldr, mnplus, models, Mopf, mopf, mp, mscr, Mscr, mstpos, Mu, mu, multimap, mumap, nabla, Nacute, nacute, nang, nap, napE, napid, napos, napprox, natural, naturals, natur, nbsp, nbump, nbumpe, ncap, Ncaron, ncaron, Ncedil, ncedil, ncong, ncongdot, ncup, Ncy, ncy, ndash, nearhk, nearr, neArr, nearrow, ne, nedot, NegativeMediumSpace, NegativeThickSpace, NegativeThinSpace, NegativeVeryThinSpace, nequiv, nesear, nesim, NestedGreaterGreater, NestedLessLess, NewLine, nexist, nexists, Nfr, nfr, ngE, nge, ngeq, ngeqq, ngeqslant, nges, nGg, ngsim, nGt, ngt, ngtr, nGtv, nharr, nhArr, nhpar, ni, nis, nisd, niv, NJcy, njcy, nlarr, nlArr, nldr, nlE, nle, nleftarrow, nLeftarrow, nleftrightarrow, nLeftrightarrow, nleq, nleqq, nleqslant, nles, nless, nLl, nlsim, nLt, nlt, nltri, nltrie, nLtv, nmid, NoBreak, NonBreakingSpace, nopf, Nopf, Not, not, NotCongruent, NotCupCap, NotDoubleVerticalBar, NotElement, NotEqual, NotEqualTilde, NotExists, NotGreater, NotGreaterEqual, NotGreaterFullEqual, NotGreaterGreater, NotGreaterLess, NotGreaterSlantEqual, NotGreaterTilde, NotHumpDownHump, NotHumpEqual, notin, notindot, notinE, notinva, notinvb, notinvc, NotLeftTriangleBar, NotLeftTriangle, NotLeftTriangleEqual, NotLess, NotLessEqual, NotLessGreater, NotLessLess, NotLessSlantEqual, NotLessTilde, NotNestedGreaterGreater, NotNestedLessLess, notni, notniva, notnivb, notnivc, NotPrecedes, NotPrecedesEqual, NotPrecedesSlantEqual, NotReverseElement, NotRightTriangleBar, NotRightTriangle, NotRightTriangleEqual, NotSquareSubset, NotSquareSubsetEqual, NotSquareSuperset, NotSquareSupersetEqual, NotSubset, NotSubsetEqual, NotSucceeds, NotSucceedsEqual, NotSucceedsSlantEqual, NotSucceedsTilde, NotSuperset, NotSupersetEqual, NotTilde, NotTildeEqual, NotTildeFullEqual, NotTildeTilde, NotVerticalBar, nparallel, npar, nparsl, npart, npolint, npr, nprcue, nprec, npreceq, npre, nrarrc, nrarr, nrArr, nrarrw, nrightarrow, nRightarrow, nrtri, nrtrie, nsc, nsccue, nsce, Nscr, nscr, nshortmid, nshortparallel, nsim, nsime, nsimeq, nsmid, nspar, nsqsube, nsqsupe, nsub, nsubE, nsube, nsubset, nsubseteq, nsubseteqq, nsucc, nsucceq, nsup, nsupE, nsupe, nsupset, nsupseteq, nsupseteqq, ntgl, Ntilde, ntilde, ntlg, ntriangleleft, ntrianglelefteq, ntriangleright, ntrianglerighteq, Nu, nu, num, numero, numsp, nvap, nvdash, nvDash, nVdash, nVDash, nvge, nvgt, nvHarr, nvinfin, nvlArr, nvle, nvlt, nvltrie, nvrArr, nvrtrie, nvsim, nwarhk, nwarr, nwArr, nwarrow, nwnear, Oacute, oacute, oast, Ocirc, ocirc, ocir, Ocy, ocy, odash, Odblac, odblac, odiv, odot, odsold, OElig, oelig, ofcir, Ofr, ofr, ogon, Ograve, ograve, ogt, ohbar, ohm, oint, olarr, olcir, olcross, oline, olt, Omacr, omacr, Omega, omega, Omicron, omicron, omid, ominus, Oopf, oopf, opar, OpenCurlyDoubleQuote, OpenCurlyQuote, operp, oplus, orarr, Or, or, ord, order, orderof, ordf, ordm, origof, oror, orslope, orv, oS, Oscr, oscr, Oslash, oslash, osol, Otilde, otilde, otimesas, Otimes, otimes, Ouml, ouml, ovbar, OverBar, OverBrace, OverBracket, OverParenthesis, para, parallel, par, parsim, parsl, part, PartialD, Pcy, pcy, percnt, period, permil, perp, pertenk, Pfr, pfr, Phi, phi, phiv, phmmat, phone, Pi, pi, pitchfork, piv, planck, planckh, plankv, plusacir, plusb, pluscir, plus, plusdo, plusdu, pluse, PlusMinus, plusmn, plussim, plustwo, pm, Poincareplane, pointint, popf, Popf, pound, prap, Pr, pr, prcue, precapprox, prec, preccurlyeq, Precedes, PrecedesEqual, PrecedesSlantEqual, PrecedesTilde, preceq, precnapprox, precneqq, precnsim, pre, prE, precsim, prime, Prime, primes, prnap, prnE, prnsim, prod, Product, profalar, profline, profsurf, prop, Proportional, Proportion, propto, prsim, prurel, Pscr, pscr, Psi, psi, puncsp, Qfr, qfr, qint, qopf, Qopf, qprime, Qscr, qscr, quaternions, quatint, quest, questeq, quot, QUOT, rAarr, race, Racute, racute, radic, raemptyv, rang, Rang, rangd, range, rangle, raquo, rarrap, rarrb, rarrbfs, rarrc, rarr, Rarr, rArr, rarrfs, rarrhk, rarrlp, rarrpl, rarrsim, Rarrtl, rarrtl, rarrw, ratail, rAtail, ratio, rationals, rbarr, rBarr, RBarr, rbbrk, rbrace, rbrack, rbrke, rbrksld, rbrkslu, Rcaron, rcaron, Rcedil, rcedil, rceil, rcub, Rcy, rcy, rdca, rdldhar, rdquo, rdquor, rdsh, real, realine, realpart, reals, Re, rect, reg, REG, ReverseElement, ReverseEquilibrium, ReverseUpEquilibrium, rfisht, rfloor, rfr, Rfr, rHar, rhard, rharu, rharul, Rho, rho, rhov, RightAngleBracket, RightArrowBar, rightarrow, RightArrow, Rightarrow, RightArrowLeftArrow, rightarrowtail, RightCeiling, RightDoubleBracket, RightDownTeeVector, RightDownVectorBar, RightDownVector, RightFloor, rightharpoondown, rightharpoonup, rightleftarrows, rightleftharpoons, rightrightarrows, rightsquigarrow, RightTeeArrow, RightTee, RightTeeVector, rightthreetimes, RightTriangleBar, RightTriangle, RightTriangleEqual, RightUpDownVector, RightUpTeeVector, RightUpVectorBar, RightUpVector, RightVectorBar, RightVector, ring, risingdotseq, rlarr, rlhar, rlm, rmoustache, rmoust, rnmid, roang, roarr, robrk, ropar, ropf, Ropf, roplus, rotimes, RoundImplies, rpar, rpargt, rppolint, rrarr, Rrightarrow, rsaquo, rscr, Rscr, rsh, Rsh, rsqb, rsquo, rsquor, rthree, rtimes, rtri, rtrie, rtrif, rtriltri, RuleDelayed, ruluhar, rx, Sacute, sacute, sbquo, scap, Scaron, scaron, Sc, sc, sccue, sce, scE, Scedil, scedil, Scirc, scirc, scnap, scnE, scnsim, scpolint, scsim, Scy, scy, sdotb, sdot, sdote, searhk, searr, seArr, searrow, sect, semi, seswar, setminus, setmn, sext, Sfr, sfr, sfrown, sharp, SHCHcy, shchcy, SHcy, shcy, ShortDownArrow, ShortLeftArrow, shortmid, shortparallel, ShortRightArrow, ShortUpArrow, shy, Sigma, sigma, sigmaf, sigmav, sim, simdot, sime, simeq, simg, simgE, siml, simlE, simne, simplus, simrarr, slarr, SmallCircle, smallsetminus, smashp, smeparsl, smid, smile, smt, smte, smtes, SOFTcy, softcy, solbar, solb, sol, Sopf, sopf, spades, spadesuit, spar, sqcap, sqcaps, sqcup, sqcups, Sqrt, sqsub, sqsube, sqsubset, sqsubseteq, sqsup, sqsupe, sqsupset, sqsupseteq, square, Square, SquareIntersection, SquareSubset, SquareSubsetEqual, SquareSuperset, SquareSupersetEqual, SquareUnion, squarf, squ, squf, srarr, Sscr, sscr, ssetmn, ssmile, sstarf, Star, star, starf, straightepsilon, straightphi, strns, sub, Sub, subdot, subE, sube, subedot, submult, subnE, subne, subplus, subrarr, subset, Subset, subseteq, subseteqq, SubsetEqual, subsetneq, subsetneqq, subsim, subsub, subsup, succapprox, succ, succcurlyeq, Succeeds, SucceedsEqual, SucceedsSlantEqual, SucceedsTilde, succeq, succnapprox, succneqq, succnsim, succsim, SuchThat, sum, Sum, sung, sup1, sup2, sup3, sup, Sup, supdot, supdsub, supE, supe, supedot, Superset, SupersetEqual, suphsol, suphsub, suplarr, supmult, supnE, supne, supplus, supset, Supset, supseteq, supseteqq, supsetneq, supsetneqq, supsim, supsub, supsup, swarhk, swarr, swArr, swarrow, swnwar, szlig, Tab, target, Tau, tau, tbrk, Tcaron, tcaron, Tcedil, tcedil, Tcy, tcy, tdot, telrec, Tfr, tfr, there4, therefore, Therefore, Theta, theta, thetasym, thetav, thickapprox, thicksim, ThickSpace, ThinSpace, thinsp, thkap, thksim, THORN, thorn, tilde, Tilde, TildeEqual, TildeFullEqual, TildeTilde, timesbar, timesb, times, timesd, tint, toea, topbot, topcir, top, Topf, topf, topfork, tosa, tprime, trade, TRADE, triangle, triangledown, triangleleft, trianglelefteq, triangleq, triangleright, trianglerighteq, tridot, trie, triminus, TripleDot, triplus, trisb, tritime, trpezium, Tscr, tscr, TScy, tscy, TSHcy, tshcy, Tstrok, tstrok, twixt, twoheadleftarrow, twoheadrightarrow, Uacute, uacute, uarr, Uarr, uArr, Uarrocir, Ubrcy, ubrcy, Ubreve, ubreve, Ucirc, ucirc, Ucy, ucy, udarr, Udblac, udblac, udhar, ufisht, Ufr, ufr, Ugrave, ugrave, uHar, uharl, uharr, uhblk, ulcorn, ulcorner, ulcrop, ultri, Umacr, umacr, uml, UnderBar, UnderBrace, UnderBracket, UnderParenthesis, Union, UnionPlus, Uogon, uogon, Uopf, uopf, UpArrowBar, uparrow, UpArrow, Uparrow, UpArrowDownArrow, updownarrow, UpDownArrow, Updownarrow, UpEquilibrium, upharpoonleft, upharpoonright, uplus, UpperLeftArrow, UpperRightArrow, upsi, Upsi, upsih, Upsilon, upsilon, UpTeeArrow, UpTee, upuparrows, urcorn, urcorner, urcrop, Uring, uring, urtri, Uscr, uscr, utdot, Utilde, utilde, utri, utrif, uuarr, Uuml, uuml, uwangle, vangrt, varepsilon, varkappa, varnothing, varphi, varpi, varpropto, varr, vArr, varrho, varsigma, varsubsetneq, varsubsetneqq, varsupsetneq, varsupsetneqq, vartheta, vartriangleleft, vartriangleright, vBar, Vbar, vBarv, Vcy, vcy, vdash, vDash, Vdash, VDash, Vdashl, veebar, vee, Vee, veeeq, vellip, verbar, Verbar, vert, Vert, VerticalBar, VerticalLine, VerticalSeparator, VerticalTilde, VeryThinSpace, Vfr, vfr, vltri, vnsub, vnsup, Vopf, vopf, vprop, vrtri, Vscr, vscr, vsubnE, vsubne, vsupnE, vsupne, Vvdash, vzigzag, Wcirc, wcirc, wedbar, wedge, Wedge, wedgeq, weierp, Wfr, wfr, Wopf, wopf, wp, wr, wreath, Wscr, wscr, xcap, xcirc, xcup, xdtri, Xfr, xfr, xharr, xhArr, Xi, xi, xlarr, xlArr, xmap, xnis, xodot, Xopf, xopf, xoplus, xotime, xrarr, xrArr, Xscr, xscr, xsqcup, xuplus, xutri, xvee, xwedge, Yacute, yacute, YAcy, yacy, Ycirc, ycirc, Ycy, ycy, yen, Yfr, yfr, YIcy, yicy, Yopf, yopf, Yscr, yscr, YUcy, yucy, yuml, Yuml, Zacute, zacute, Zcaron, zcaron, Zcy, zcy, Zdot, zdot, zeetrf, ZeroWidthSpace, Zeta, zeta, zfr, Zfr, ZHcy, zhcy, zigrarr, zopf, Zopf, Zscr, zscr, zwj, zwnj, default */
/***/ (function(module) {

module.exports = JSON.parse("{\"Aacute\":\"Á\",\"aacute\":\"á\",\"Abreve\":\"Ă\",\"abreve\":\"ă\",\"ac\":\"∾\",\"acd\":\"∿\",\"acE\":\"∾̳\",\"Acirc\":\"Â\",\"acirc\":\"â\",\"acute\":\"´\",\"Acy\":\"А\",\"acy\":\"а\",\"AElig\":\"Æ\",\"aelig\":\"æ\",\"af\":\"⁡\",\"Afr\":\"𝔄\",\"afr\":\"𝔞\",\"Agrave\":\"À\",\"agrave\":\"à\",\"alefsym\":\"ℵ\",\"aleph\":\"ℵ\",\"Alpha\":\"Α\",\"alpha\":\"α\",\"Amacr\":\"Ā\",\"amacr\":\"ā\",\"amalg\":\"⨿\",\"amp\":\"&\",\"AMP\":\"&\",\"andand\":\"⩕\",\"And\":\"⩓\",\"and\":\"∧\",\"andd\":\"⩜\",\"andslope\":\"⩘\",\"andv\":\"⩚\",\"ang\":\"∠\",\"ange\":\"⦤\",\"angle\":\"∠\",\"angmsdaa\":\"⦨\",\"angmsdab\":\"⦩\",\"angmsdac\":\"⦪\",\"angmsdad\":\"⦫\",\"angmsdae\":\"⦬\",\"angmsdaf\":\"⦭\",\"angmsdag\":\"⦮\",\"angmsdah\":\"⦯\",\"angmsd\":\"∡\",\"angrt\":\"∟\",\"angrtvb\":\"⊾\",\"angrtvbd\":\"⦝\",\"angsph\":\"∢\",\"angst\":\"Å\",\"angzarr\":\"⍼\",\"Aogon\":\"Ą\",\"aogon\":\"ą\",\"Aopf\":\"𝔸\",\"aopf\":\"𝕒\",\"apacir\":\"⩯\",\"ap\":\"≈\",\"apE\":\"⩰\",\"ape\":\"≊\",\"apid\":\"≋\",\"apos\":\"'\",\"ApplyFunction\":\"⁡\",\"approx\":\"≈\",\"approxeq\":\"≊\",\"Aring\":\"Å\",\"aring\":\"å\",\"Ascr\":\"𝒜\",\"ascr\":\"𝒶\",\"Assign\":\"≔\",\"ast\":\"*\",\"asymp\":\"≈\",\"asympeq\":\"≍\",\"Atilde\":\"Ã\",\"atilde\":\"ã\",\"Auml\":\"Ä\",\"auml\":\"ä\",\"awconint\":\"∳\",\"awint\":\"⨑\",\"backcong\":\"≌\",\"backepsilon\":\"϶\",\"backprime\":\"‵\",\"backsim\":\"∽\",\"backsimeq\":\"⋍\",\"Backslash\":\"∖\",\"Barv\":\"⫧\",\"barvee\":\"⊽\",\"barwed\":\"⌅\",\"Barwed\":\"⌆\",\"barwedge\":\"⌅\",\"bbrk\":\"⎵\",\"bbrktbrk\":\"⎶\",\"bcong\":\"≌\",\"Bcy\":\"Б\",\"bcy\":\"б\",\"bdquo\":\"„\",\"becaus\":\"∵\",\"because\":\"∵\",\"Because\":\"∵\",\"bemptyv\":\"⦰\",\"bepsi\":\"϶\",\"bernou\":\"ℬ\",\"Bernoullis\":\"ℬ\",\"Beta\":\"Β\",\"beta\":\"β\",\"beth\":\"ℶ\",\"between\":\"≬\",\"Bfr\":\"𝔅\",\"bfr\":\"𝔟\",\"bigcap\":\"⋂\",\"bigcirc\":\"◯\",\"bigcup\":\"⋃\",\"bigodot\":\"⨀\",\"bigoplus\":\"⨁\",\"bigotimes\":\"⨂\",\"bigsqcup\":\"⨆\",\"bigstar\":\"★\",\"bigtriangledown\":\"▽\",\"bigtriangleup\":\"△\",\"biguplus\":\"⨄\",\"bigvee\":\"⋁\",\"bigwedge\":\"⋀\",\"bkarow\":\"⤍\",\"blacklozenge\":\"⧫\",\"blacksquare\":\"▪\",\"blacktriangle\":\"▴\",\"blacktriangledown\":\"▾\",\"blacktriangleleft\":\"◂\",\"blacktriangleright\":\"▸\",\"blank\":\"␣\",\"blk12\":\"▒\",\"blk14\":\"░\",\"blk34\":\"▓\",\"block\":\"█\",\"bne\":\"=⃥\",\"bnequiv\":\"≡⃥\",\"bNot\":\"⫭\",\"bnot\":\"⌐\",\"Bopf\":\"𝔹\",\"bopf\":\"𝕓\",\"bot\":\"⊥\",\"bottom\":\"⊥\",\"bowtie\":\"⋈\",\"boxbox\":\"⧉\",\"boxdl\":\"┐\",\"boxdL\":\"╕\",\"boxDl\":\"╖\",\"boxDL\":\"╗\",\"boxdr\":\"┌\",\"boxdR\":\"╒\",\"boxDr\":\"╓\",\"boxDR\":\"╔\",\"boxh\":\"─\",\"boxH\":\"═\",\"boxhd\":\"┬\",\"boxHd\":\"╤\",\"boxhD\":\"╥\",\"boxHD\":\"╦\",\"boxhu\":\"┴\",\"boxHu\":\"╧\",\"boxhU\":\"╨\",\"boxHU\":\"╩\",\"boxminus\":\"⊟\",\"boxplus\":\"⊞\",\"boxtimes\":\"⊠\",\"boxul\":\"┘\",\"boxuL\":\"╛\",\"boxUl\":\"╜\",\"boxUL\":\"╝\",\"boxur\":\"└\",\"boxuR\":\"╘\",\"boxUr\":\"╙\",\"boxUR\":\"╚\",\"boxv\":\"│\",\"boxV\":\"║\",\"boxvh\":\"┼\",\"boxvH\":\"╪\",\"boxVh\":\"╫\",\"boxVH\":\"╬\",\"boxvl\":\"┤\",\"boxvL\":\"╡\",\"boxVl\":\"╢\",\"boxVL\":\"╣\",\"boxvr\":\"├\",\"boxvR\":\"╞\",\"boxVr\":\"╟\",\"boxVR\":\"╠\",\"bprime\":\"‵\",\"breve\":\"˘\",\"Breve\":\"˘\",\"brvbar\":\"¦\",\"bscr\":\"𝒷\",\"Bscr\":\"ℬ\",\"bsemi\":\"⁏\",\"bsim\":\"∽\",\"bsime\":\"⋍\",\"bsolb\":\"⧅\",\"bsol\":\"\\\\\",\"bsolhsub\":\"⟈\",\"bull\":\"•\",\"bullet\":\"•\",\"bump\":\"≎\",\"bumpE\":\"⪮\",\"bumpe\":\"≏\",\"Bumpeq\":\"≎\",\"bumpeq\":\"≏\",\"Cacute\":\"Ć\",\"cacute\":\"ć\",\"capand\":\"⩄\",\"capbrcup\":\"⩉\",\"capcap\":\"⩋\",\"cap\":\"∩\",\"Cap\":\"⋒\",\"capcup\":\"⩇\",\"capdot\":\"⩀\",\"CapitalDifferentialD\":\"ⅅ\",\"caps\":\"∩︀\",\"caret\":\"⁁\",\"caron\":\"ˇ\",\"Cayleys\":\"ℭ\",\"ccaps\":\"⩍\",\"Ccaron\":\"Č\",\"ccaron\":\"č\",\"Ccedil\":\"Ç\",\"ccedil\":\"ç\",\"Ccirc\":\"Ĉ\",\"ccirc\":\"ĉ\",\"Cconint\":\"∰\",\"ccups\":\"⩌\",\"ccupssm\":\"⩐\",\"Cdot\":\"Ċ\",\"cdot\":\"ċ\",\"cedil\":\"¸\",\"Cedilla\":\"¸\",\"cemptyv\":\"⦲\",\"cent\":\"¢\",\"centerdot\":\"·\",\"CenterDot\":\"·\",\"cfr\":\"𝔠\",\"Cfr\":\"ℭ\",\"CHcy\":\"Ч\",\"chcy\":\"ч\",\"check\":\"✓\",\"checkmark\":\"✓\",\"Chi\":\"Χ\",\"chi\":\"χ\",\"circ\":\"ˆ\",\"circeq\":\"≗\",\"circlearrowleft\":\"↺\",\"circlearrowright\":\"↻\",\"circledast\":\"⊛\",\"circledcirc\":\"⊚\",\"circleddash\":\"⊝\",\"CircleDot\":\"⊙\",\"circledR\":\"®\",\"circledS\":\"Ⓢ\",\"CircleMinus\":\"⊖\",\"CirclePlus\":\"⊕\",\"CircleTimes\":\"⊗\",\"cir\":\"○\",\"cirE\":\"⧃\",\"cire\":\"≗\",\"cirfnint\":\"⨐\",\"cirmid\":\"⫯\",\"cirscir\":\"⧂\",\"ClockwiseContourIntegral\":\"∲\",\"CloseCurlyDoubleQuote\":\"”\",\"CloseCurlyQuote\":\"’\",\"clubs\":\"♣\",\"clubsuit\":\"♣\",\"colon\":\":\",\"Colon\":\"∷\",\"Colone\":\"⩴\",\"colone\":\"≔\",\"coloneq\":\"≔\",\"comma\":\",\",\"commat\":\"@\",\"comp\":\"∁\",\"compfn\":\"∘\",\"complement\":\"∁\",\"complexes\":\"ℂ\",\"cong\":\"≅\",\"congdot\":\"⩭\",\"Congruent\":\"≡\",\"conint\":\"∮\",\"Conint\":\"∯\",\"ContourIntegral\":\"∮\",\"copf\":\"𝕔\",\"Copf\":\"ℂ\",\"coprod\":\"∐\",\"Coproduct\":\"∐\",\"copy\":\"©\",\"COPY\":\"©\",\"copysr\":\"℗\",\"CounterClockwiseContourIntegral\":\"∳\",\"crarr\":\"↵\",\"cross\":\"✗\",\"Cross\":\"⨯\",\"Cscr\":\"𝒞\",\"cscr\":\"𝒸\",\"csub\":\"⫏\",\"csube\":\"⫑\",\"csup\":\"⫐\",\"csupe\":\"⫒\",\"ctdot\":\"⋯\",\"cudarrl\":\"⤸\",\"cudarrr\":\"⤵\",\"cuepr\":\"⋞\",\"cuesc\":\"⋟\",\"cularr\":\"↶\",\"cularrp\":\"⤽\",\"cupbrcap\":\"⩈\",\"cupcap\":\"⩆\",\"CupCap\":\"≍\",\"cup\":\"∪\",\"Cup\":\"⋓\",\"cupcup\":\"⩊\",\"cupdot\":\"⊍\",\"cupor\":\"⩅\",\"cups\":\"∪︀\",\"curarr\":\"↷\",\"curarrm\":\"⤼\",\"curlyeqprec\":\"⋞\",\"curlyeqsucc\":\"⋟\",\"curlyvee\":\"⋎\",\"curlywedge\":\"⋏\",\"curren\":\"¤\",\"curvearrowleft\":\"↶\",\"curvearrowright\":\"↷\",\"cuvee\":\"⋎\",\"cuwed\":\"⋏\",\"cwconint\":\"∲\",\"cwint\":\"∱\",\"cylcty\":\"⌭\",\"dagger\":\"†\",\"Dagger\":\"‡\",\"daleth\":\"ℸ\",\"darr\":\"↓\",\"Darr\":\"↡\",\"dArr\":\"⇓\",\"dash\":\"‐\",\"Dashv\":\"⫤\",\"dashv\":\"⊣\",\"dbkarow\":\"⤏\",\"dblac\":\"˝\",\"Dcaron\":\"Ď\",\"dcaron\":\"ď\",\"Dcy\":\"Д\",\"dcy\":\"д\",\"ddagger\":\"‡\",\"ddarr\":\"⇊\",\"DD\":\"ⅅ\",\"dd\":\"ⅆ\",\"DDotrahd\":\"⤑\",\"ddotseq\":\"⩷\",\"deg\":\"°\",\"Del\":\"∇\",\"Delta\":\"Δ\",\"delta\":\"δ\",\"demptyv\":\"⦱\",\"dfisht\":\"⥿\",\"Dfr\":\"𝔇\",\"dfr\":\"𝔡\",\"dHar\":\"⥥\",\"dharl\":\"⇃\",\"dharr\":\"⇂\",\"DiacriticalAcute\":\"´\",\"DiacriticalDot\":\"˙\",\"DiacriticalDoubleAcute\":\"˝\",\"DiacriticalGrave\":\"`\",\"DiacriticalTilde\":\"˜\",\"diam\":\"⋄\",\"diamond\":\"⋄\",\"Diamond\":\"⋄\",\"diamondsuit\":\"♦\",\"diams\":\"♦\",\"die\":\"¨\",\"DifferentialD\":\"ⅆ\",\"digamma\":\"ϝ\",\"disin\":\"⋲\",\"div\":\"÷\",\"divide\":\"÷\",\"divideontimes\":\"⋇\",\"divonx\":\"⋇\",\"DJcy\":\"Ђ\",\"djcy\":\"ђ\",\"dlcorn\":\"⌞\",\"dlcrop\":\"⌍\",\"dollar\":\"$\",\"Dopf\":\"𝔻\",\"dopf\":\"𝕕\",\"Dot\":\"¨\",\"dot\":\"˙\",\"DotDot\":\"⃜\",\"doteq\":\"≐\",\"doteqdot\":\"≑\",\"DotEqual\":\"≐\",\"dotminus\":\"∸\",\"dotplus\":\"∔\",\"dotsquare\":\"⊡\",\"doublebarwedge\":\"⌆\",\"DoubleContourIntegral\":\"∯\",\"DoubleDot\":\"¨\",\"DoubleDownArrow\":\"⇓\",\"DoubleLeftArrow\":\"⇐\",\"DoubleLeftRightArrow\":\"⇔\",\"DoubleLeftTee\":\"⫤\",\"DoubleLongLeftArrow\":\"⟸\",\"DoubleLongLeftRightArrow\":\"⟺\",\"DoubleLongRightArrow\":\"⟹\",\"DoubleRightArrow\":\"⇒\",\"DoubleRightTee\":\"⊨\",\"DoubleUpArrow\":\"⇑\",\"DoubleUpDownArrow\":\"⇕\",\"DoubleVerticalBar\":\"∥\",\"DownArrowBar\":\"⤓\",\"downarrow\":\"↓\",\"DownArrow\":\"↓\",\"Downarrow\":\"⇓\",\"DownArrowUpArrow\":\"⇵\",\"DownBreve\":\"̑\",\"downdownarrows\":\"⇊\",\"downharpoonleft\":\"⇃\",\"downharpoonright\":\"⇂\",\"DownLeftRightVector\":\"⥐\",\"DownLeftTeeVector\":\"⥞\",\"DownLeftVectorBar\":\"⥖\",\"DownLeftVector\":\"↽\",\"DownRightTeeVector\":\"⥟\",\"DownRightVectorBar\":\"⥗\",\"DownRightVector\":\"⇁\",\"DownTeeArrow\":\"↧\",\"DownTee\":\"⊤\",\"drbkarow\":\"⤐\",\"drcorn\":\"⌟\",\"drcrop\":\"⌌\",\"Dscr\":\"𝒟\",\"dscr\":\"𝒹\",\"DScy\":\"Ѕ\",\"dscy\":\"ѕ\",\"dsol\":\"⧶\",\"Dstrok\":\"Đ\",\"dstrok\":\"đ\",\"dtdot\":\"⋱\",\"dtri\":\"▿\",\"dtrif\":\"▾\",\"duarr\":\"⇵\",\"duhar\":\"⥯\",\"dwangle\":\"⦦\",\"DZcy\":\"Џ\",\"dzcy\":\"џ\",\"dzigrarr\":\"⟿\",\"Eacute\":\"É\",\"eacute\":\"é\",\"easter\":\"⩮\",\"Ecaron\":\"Ě\",\"ecaron\":\"ě\",\"Ecirc\":\"Ê\",\"ecirc\":\"ê\",\"ecir\":\"≖\",\"ecolon\":\"≕\",\"Ecy\":\"Э\",\"ecy\":\"э\",\"eDDot\":\"⩷\",\"Edot\":\"Ė\",\"edot\":\"ė\",\"eDot\":\"≑\",\"ee\":\"ⅇ\",\"efDot\":\"≒\",\"Efr\":\"𝔈\",\"efr\":\"𝔢\",\"eg\":\"⪚\",\"Egrave\":\"È\",\"egrave\":\"è\",\"egs\":\"⪖\",\"egsdot\":\"⪘\",\"el\":\"⪙\",\"Element\":\"∈\",\"elinters\":\"⏧\",\"ell\":\"ℓ\",\"els\":\"⪕\",\"elsdot\":\"⪗\",\"Emacr\":\"Ē\",\"emacr\":\"ē\",\"empty\":\"∅\",\"emptyset\":\"∅\",\"EmptySmallSquare\":\"◻\",\"emptyv\":\"∅\",\"EmptyVerySmallSquare\":\"▫\",\"emsp13\":\" \",\"emsp14\":\" \",\"emsp\":\" \",\"ENG\":\"Ŋ\",\"eng\":\"ŋ\",\"ensp\":\" \",\"Eogon\":\"Ę\",\"eogon\":\"ę\",\"Eopf\":\"𝔼\",\"eopf\":\"𝕖\",\"epar\":\"⋕\",\"eparsl\":\"⧣\",\"eplus\":\"⩱\",\"epsi\":\"ε\",\"Epsilon\":\"Ε\",\"epsilon\":\"ε\",\"epsiv\":\"ϵ\",\"eqcirc\":\"≖\",\"eqcolon\":\"≕\",\"eqsim\":\"≂\",\"eqslantgtr\":\"⪖\",\"eqslantless\":\"⪕\",\"Equal\":\"⩵\",\"equals\":\"=\",\"EqualTilde\":\"≂\",\"equest\":\"≟\",\"Equilibrium\":\"⇌\",\"equiv\":\"≡\",\"equivDD\":\"⩸\",\"eqvparsl\":\"⧥\",\"erarr\":\"⥱\",\"erDot\":\"≓\",\"escr\":\"ℯ\",\"Escr\":\"ℰ\",\"esdot\":\"≐\",\"Esim\":\"⩳\",\"esim\":\"≂\",\"Eta\":\"Η\",\"eta\":\"η\",\"ETH\":\"Ð\",\"eth\":\"ð\",\"Euml\":\"Ë\",\"euml\":\"ë\",\"euro\":\"€\",\"excl\":\"!\",\"exist\":\"∃\",\"Exists\":\"∃\",\"expectation\":\"ℰ\",\"exponentiale\":\"ⅇ\",\"ExponentialE\":\"ⅇ\",\"fallingdotseq\":\"≒\",\"Fcy\":\"Ф\",\"fcy\":\"ф\",\"female\":\"♀\",\"ffilig\":\"ﬃ\",\"fflig\":\"ﬀ\",\"ffllig\":\"ﬄ\",\"Ffr\":\"𝔉\",\"ffr\":\"𝔣\",\"filig\":\"ﬁ\",\"FilledSmallSquare\":\"◼\",\"FilledVerySmallSquare\":\"▪\",\"fjlig\":\"fj\",\"flat\":\"♭\",\"fllig\":\"ﬂ\",\"fltns\":\"▱\",\"fnof\":\"ƒ\",\"Fopf\":\"𝔽\",\"fopf\":\"𝕗\",\"forall\":\"∀\",\"ForAll\":\"∀\",\"fork\":\"⋔\",\"forkv\":\"⫙\",\"Fouriertrf\":\"ℱ\",\"fpartint\":\"⨍\",\"frac12\":\"½\",\"frac13\":\"⅓\",\"frac14\":\"¼\",\"frac15\":\"⅕\",\"frac16\":\"⅙\",\"frac18\":\"⅛\",\"frac23\":\"⅔\",\"frac25\":\"⅖\",\"frac34\":\"¾\",\"frac35\":\"⅗\",\"frac38\":\"⅜\",\"frac45\":\"⅘\",\"frac56\":\"⅚\",\"frac58\":\"⅝\",\"frac78\":\"⅞\",\"frasl\":\"⁄\",\"frown\":\"⌢\",\"fscr\":\"𝒻\",\"Fscr\":\"ℱ\",\"gacute\":\"ǵ\",\"Gamma\":\"Γ\",\"gamma\":\"γ\",\"Gammad\":\"Ϝ\",\"gammad\":\"ϝ\",\"gap\":\"⪆\",\"Gbreve\":\"Ğ\",\"gbreve\":\"ğ\",\"Gcedil\":\"Ģ\",\"Gcirc\":\"Ĝ\",\"gcirc\":\"ĝ\",\"Gcy\":\"Г\",\"gcy\":\"г\",\"Gdot\":\"Ġ\",\"gdot\":\"ġ\",\"ge\":\"≥\",\"gE\":\"≧\",\"gEl\":\"⪌\",\"gel\":\"⋛\",\"geq\":\"≥\",\"geqq\":\"≧\",\"geqslant\":\"⩾\",\"gescc\":\"⪩\",\"ges\":\"⩾\",\"gesdot\":\"⪀\",\"gesdoto\":\"⪂\",\"gesdotol\":\"⪄\",\"gesl\":\"⋛︀\",\"gesles\":\"⪔\",\"Gfr\":\"𝔊\",\"gfr\":\"𝔤\",\"gg\":\"≫\",\"Gg\":\"⋙\",\"ggg\":\"⋙\",\"gimel\":\"ℷ\",\"GJcy\":\"Ѓ\",\"gjcy\":\"ѓ\",\"gla\":\"⪥\",\"gl\":\"≷\",\"glE\":\"⪒\",\"glj\":\"⪤\",\"gnap\":\"⪊\",\"gnapprox\":\"⪊\",\"gne\":\"⪈\",\"gnE\":\"≩\",\"gneq\":\"⪈\",\"gneqq\":\"≩\",\"gnsim\":\"⋧\",\"Gopf\":\"𝔾\",\"gopf\":\"𝕘\",\"grave\":\"`\",\"GreaterEqual\":\"≥\",\"GreaterEqualLess\":\"⋛\",\"GreaterFullEqual\":\"≧\",\"GreaterGreater\":\"⪢\",\"GreaterLess\":\"≷\",\"GreaterSlantEqual\":\"⩾\",\"GreaterTilde\":\"≳\",\"Gscr\":\"𝒢\",\"gscr\":\"ℊ\",\"gsim\":\"≳\",\"gsime\":\"⪎\",\"gsiml\":\"⪐\",\"gtcc\":\"⪧\",\"gtcir\":\"⩺\",\"gt\":\">\",\"GT\":\">\",\"Gt\":\"≫\",\"gtdot\":\"⋗\",\"gtlPar\":\"⦕\",\"gtquest\":\"⩼\",\"gtrapprox\":\"⪆\",\"gtrarr\":\"⥸\",\"gtrdot\":\"⋗\",\"gtreqless\":\"⋛\",\"gtreqqless\":\"⪌\",\"gtrless\":\"≷\",\"gtrsim\":\"≳\",\"gvertneqq\":\"≩︀\",\"gvnE\":\"≩︀\",\"Hacek\":\"ˇ\",\"hairsp\":\" \",\"half\":\"½\",\"hamilt\":\"ℋ\",\"HARDcy\":\"Ъ\",\"hardcy\":\"ъ\",\"harrcir\":\"⥈\",\"harr\":\"↔\",\"hArr\":\"⇔\",\"harrw\":\"↭\",\"Hat\":\"^\",\"hbar\":\"ℏ\",\"Hcirc\":\"Ĥ\",\"hcirc\":\"ĥ\",\"hearts\":\"♥\",\"heartsuit\":\"♥\",\"hellip\":\"…\",\"hercon\":\"⊹\",\"hfr\":\"𝔥\",\"Hfr\":\"ℌ\",\"HilbertSpace\":\"ℋ\",\"hksearow\":\"⤥\",\"hkswarow\":\"⤦\",\"hoarr\":\"⇿\",\"homtht\":\"∻\",\"hookleftarrow\":\"↩\",\"hookrightarrow\":\"↪\",\"hopf\":\"𝕙\",\"Hopf\":\"ℍ\",\"horbar\":\"―\",\"HorizontalLine\":\"─\",\"hscr\":\"𝒽\",\"Hscr\":\"ℋ\",\"hslash\":\"ℏ\",\"Hstrok\":\"Ħ\",\"hstrok\":\"ħ\",\"HumpDownHump\":\"≎\",\"HumpEqual\":\"≏\",\"hybull\":\"⁃\",\"hyphen\":\"‐\",\"Iacute\":\"Í\",\"iacute\":\"í\",\"ic\":\"⁣\",\"Icirc\":\"Î\",\"icirc\":\"î\",\"Icy\":\"И\",\"icy\":\"и\",\"Idot\":\"İ\",\"IEcy\":\"Е\",\"iecy\":\"е\",\"iexcl\":\"¡\",\"iff\":\"⇔\",\"ifr\":\"𝔦\",\"Ifr\":\"ℑ\",\"Igrave\":\"Ì\",\"igrave\":\"ì\",\"ii\":\"ⅈ\",\"iiiint\":\"⨌\",\"iiint\":\"∭\",\"iinfin\":\"⧜\",\"iiota\":\"℩\",\"IJlig\":\"Ĳ\",\"ijlig\":\"ĳ\",\"Imacr\":\"Ī\",\"imacr\":\"ī\",\"image\":\"ℑ\",\"ImaginaryI\":\"ⅈ\",\"imagline\":\"ℐ\",\"imagpart\":\"ℑ\",\"imath\":\"ı\",\"Im\":\"ℑ\",\"imof\":\"⊷\",\"imped\":\"Ƶ\",\"Implies\":\"⇒\",\"incare\":\"℅\",\"in\":\"∈\",\"infin\":\"∞\",\"infintie\":\"⧝\",\"inodot\":\"ı\",\"intcal\":\"⊺\",\"int\":\"∫\",\"Int\":\"∬\",\"integers\":\"ℤ\",\"Integral\":\"∫\",\"intercal\":\"⊺\",\"Intersection\":\"⋂\",\"intlarhk\":\"⨗\",\"intprod\":\"⨼\",\"InvisibleComma\":\"⁣\",\"InvisibleTimes\":\"⁢\",\"IOcy\":\"Ё\",\"iocy\":\"ё\",\"Iogon\":\"Į\",\"iogon\":\"į\",\"Iopf\":\"𝕀\",\"iopf\":\"𝕚\",\"Iota\":\"Ι\",\"iota\":\"ι\",\"iprod\":\"⨼\",\"iquest\":\"¿\",\"iscr\":\"𝒾\",\"Iscr\":\"ℐ\",\"isin\":\"∈\",\"isindot\":\"⋵\",\"isinE\":\"⋹\",\"isins\":\"⋴\",\"isinsv\":\"⋳\",\"isinv\":\"∈\",\"it\":\"⁢\",\"Itilde\":\"Ĩ\",\"itilde\":\"ĩ\",\"Iukcy\":\"І\",\"iukcy\":\"і\",\"Iuml\":\"Ï\",\"iuml\":\"ï\",\"Jcirc\":\"Ĵ\",\"jcirc\":\"ĵ\",\"Jcy\":\"Й\",\"jcy\":\"й\",\"Jfr\":\"𝔍\",\"jfr\":\"𝔧\",\"jmath\":\"ȷ\",\"Jopf\":\"𝕁\",\"jopf\":\"𝕛\",\"Jscr\":\"𝒥\",\"jscr\":\"𝒿\",\"Jsercy\":\"Ј\",\"jsercy\":\"ј\",\"Jukcy\":\"Є\",\"jukcy\":\"є\",\"Kappa\":\"Κ\",\"kappa\":\"κ\",\"kappav\":\"ϰ\",\"Kcedil\":\"Ķ\",\"kcedil\":\"ķ\",\"Kcy\":\"К\",\"kcy\":\"к\",\"Kfr\":\"𝔎\",\"kfr\":\"𝔨\",\"kgreen\":\"ĸ\",\"KHcy\":\"Х\",\"khcy\":\"х\",\"KJcy\":\"Ќ\",\"kjcy\":\"ќ\",\"Kopf\":\"𝕂\",\"kopf\":\"𝕜\",\"Kscr\":\"𝒦\",\"kscr\":\"𝓀\",\"lAarr\":\"⇚\",\"Lacute\":\"Ĺ\",\"lacute\":\"ĺ\",\"laemptyv\":\"⦴\",\"lagran\":\"ℒ\",\"Lambda\":\"Λ\",\"lambda\":\"λ\",\"lang\":\"⟨\",\"Lang\":\"⟪\",\"langd\":\"⦑\",\"langle\":\"⟨\",\"lap\":\"⪅\",\"Laplacetrf\":\"ℒ\",\"laquo\":\"«\",\"larrb\":\"⇤\",\"larrbfs\":\"⤟\",\"larr\":\"←\",\"Larr\":\"↞\",\"lArr\":\"⇐\",\"larrfs\":\"⤝\",\"larrhk\":\"↩\",\"larrlp\":\"↫\",\"larrpl\":\"⤹\",\"larrsim\":\"⥳\",\"larrtl\":\"↢\",\"latail\":\"⤙\",\"lAtail\":\"⤛\",\"lat\":\"⪫\",\"late\":\"⪭\",\"lates\":\"⪭︀\",\"lbarr\":\"⤌\",\"lBarr\":\"⤎\",\"lbbrk\":\"❲\",\"lbrace\":\"{\",\"lbrack\":\"[\",\"lbrke\":\"⦋\",\"lbrksld\":\"⦏\",\"lbrkslu\":\"⦍\",\"Lcaron\":\"Ľ\",\"lcaron\":\"ľ\",\"Lcedil\":\"Ļ\",\"lcedil\":\"ļ\",\"lceil\":\"⌈\",\"lcub\":\"{\",\"Lcy\":\"Л\",\"lcy\":\"л\",\"ldca\":\"⤶\",\"ldquo\":\"“\",\"ldquor\":\"„\",\"ldrdhar\":\"⥧\",\"ldrushar\":\"⥋\",\"ldsh\":\"↲\",\"le\":\"≤\",\"lE\":\"≦\",\"LeftAngleBracket\":\"⟨\",\"LeftArrowBar\":\"⇤\",\"leftarrow\":\"←\",\"LeftArrow\":\"←\",\"Leftarrow\":\"⇐\",\"LeftArrowRightArrow\":\"⇆\",\"leftarrowtail\":\"↢\",\"LeftCeiling\":\"⌈\",\"LeftDoubleBracket\":\"⟦\",\"LeftDownTeeVector\":\"⥡\",\"LeftDownVectorBar\":\"⥙\",\"LeftDownVector\":\"⇃\",\"LeftFloor\":\"⌊\",\"leftharpoondown\":\"↽\",\"leftharpoonup\":\"↼\",\"leftleftarrows\":\"⇇\",\"leftrightarrow\":\"↔\",\"LeftRightArrow\":\"↔\",\"Leftrightarrow\":\"⇔\",\"leftrightarrows\":\"⇆\",\"leftrightharpoons\":\"⇋\",\"leftrightsquigarrow\":\"↭\",\"LeftRightVector\":\"⥎\",\"LeftTeeArrow\":\"↤\",\"LeftTee\":\"⊣\",\"LeftTeeVector\":\"⥚\",\"leftthreetimes\":\"⋋\",\"LeftTriangleBar\":\"⧏\",\"LeftTriangle\":\"⊲\",\"LeftTriangleEqual\":\"⊴\",\"LeftUpDownVector\":\"⥑\",\"LeftUpTeeVector\":\"⥠\",\"LeftUpVectorBar\":\"⥘\",\"LeftUpVector\":\"↿\",\"LeftVectorBar\":\"⥒\",\"LeftVector\":\"↼\",\"lEg\":\"⪋\",\"leg\":\"⋚\",\"leq\":\"≤\",\"leqq\":\"≦\",\"leqslant\":\"⩽\",\"lescc\":\"⪨\",\"les\":\"⩽\",\"lesdot\":\"⩿\",\"lesdoto\":\"⪁\",\"lesdotor\":\"⪃\",\"lesg\":\"⋚︀\",\"lesges\":\"⪓\",\"lessapprox\":\"⪅\",\"lessdot\":\"⋖\",\"lesseqgtr\":\"⋚\",\"lesseqqgtr\":\"⪋\",\"LessEqualGreater\":\"⋚\",\"LessFullEqual\":\"≦\",\"LessGreater\":\"≶\",\"lessgtr\":\"≶\",\"LessLess\":\"⪡\",\"lesssim\":\"≲\",\"LessSlantEqual\":\"⩽\",\"LessTilde\":\"≲\",\"lfisht\":\"⥼\",\"lfloor\":\"⌊\",\"Lfr\":\"𝔏\",\"lfr\":\"𝔩\",\"lg\":\"≶\",\"lgE\":\"⪑\",\"lHar\":\"⥢\",\"lhard\":\"↽\",\"lharu\":\"↼\",\"lharul\":\"⥪\",\"lhblk\":\"▄\",\"LJcy\":\"Љ\",\"ljcy\":\"љ\",\"llarr\":\"⇇\",\"ll\":\"≪\",\"Ll\":\"⋘\",\"llcorner\":\"⌞\",\"Lleftarrow\":\"⇚\",\"llhard\":\"⥫\",\"lltri\":\"◺\",\"Lmidot\":\"Ŀ\",\"lmidot\":\"ŀ\",\"lmoustache\":\"⎰\",\"lmoust\":\"⎰\",\"lnap\":\"⪉\",\"lnapprox\":\"⪉\",\"lne\":\"⪇\",\"lnE\":\"≨\",\"lneq\":\"⪇\",\"lneqq\":\"≨\",\"lnsim\":\"⋦\",\"loang\":\"⟬\",\"loarr\":\"⇽\",\"lobrk\":\"⟦\",\"longleftarrow\":\"⟵\",\"LongLeftArrow\":\"⟵\",\"Longleftarrow\":\"⟸\",\"longleftrightarrow\":\"⟷\",\"LongLeftRightArrow\":\"⟷\",\"Longleftrightarrow\":\"⟺\",\"longmapsto\":\"⟼\",\"longrightarrow\":\"⟶\",\"LongRightArrow\":\"⟶\",\"Longrightarrow\":\"⟹\",\"looparrowleft\":\"↫\",\"looparrowright\":\"↬\",\"lopar\":\"⦅\",\"Lopf\":\"𝕃\",\"lopf\":\"𝕝\",\"loplus\":\"⨭\",\"lotimes\":\"⨴\",\"lowast\":\"∗\",\"lowbar\":\"_\",\"LowerLeftArrow\":\"↙\",\"LowerRightArrow\":\"↘\",\"loz\":\"◊\",\"lozenge\":\"◊\",\"lozf\":\"⧫\",\"lpar\":\"(\",\"lparlt\":\"⦓\",\"lrarr\":\"⇆\",\"lrcorner\":\"⌟\",\"lrhar\":\"⇋\",\"lrhard\":\"⥭\",\"lrm\":\"‎\",\"lrtri\":\"⊿\",\"lsaquo\":\"‹\",\"lscr\":\"𝓁\",\"Lscr\":\"ℒ\",\"lsh\":\"↰\",\"Lsh\":\"↰\",\"lsim\":\"≲\",\"lsime\":\"⪍\",\"lsimg\":\"⪏\",\"lsqb\":\"[\",\"lsquo\":\"‘\",\"lsquor\":\"‚\",\"Lstrok\":\"Ł\",\"lstrok\":\"ł\",\"ltcc\":\"⪦\",\"ltcir\":\"⩹\",\"lt\":\"<\",\"LT\":\"<\",\"Lt\":\"≪\",\"ltdot\":\"⋖\",\"lthree\":\"⋋\",\"ltimes\":\"⋉\",\"ltlarr\":\"⥶\",\"ltquest\":\"⩻\",\"ltri\":\"◃\",\"ltrie\":\"⊴\",\"ltrif\":\"◂\",\"ltrPar\":\"⦖\",\"lurdshar\":\"⥊\",\"luruhar\":\"⥦\",\"lvertneqq\":\"≨︀\",\"lvnE\":\"≨︀\",\"macr\":\"¯\",\"male\":\"♂\",\"malt\":\"✠\",\"maltese\":\"✠\",\"Map\":\"⤅\",\"map\":\"↦\",\"mapsto\":\"↦\",\"mapstodown\":\"↧\",\"mapstoleft\":\"↤\",\"mapstoup\":\"↥\",\"marker\":\"▮\",\"mcomma\":\"⨩\",\"Mcy\":\"М\",\"mcy\":\"м\",\"mdash\":\"—\",\"mDDot\":\"∺\",\"measuredangle\":\"∡\",\"MediumSpace\":\" \",\"Mellintrf\":\"ℳ\",\"Mfr\":\"𝔐\",\"mfr\":\"𝔪\",\"mho\":\"℧\",\"micro\":\"µ\",\"midast\":\"*\",\"midcir\":\"⫰\",\"mid\":\"∣\",\"middot\":\"·\",\"minusb\":\"⊟\",\"minus\":\"−\",\"minusd\":\"∸\",\"minusdu\":\"⨪\",\"MinusPlus\":\"∓\",\"mlcp\":\"⫛\",\"mldr\":\"…\",\"mnplus\":\"∓\",\"models\":\"⊧\",\"Mopf\":\"𝕄\",\"mopf\":\"𝕞\",\"mp\":\"∓\",\"mscr\":\"𝓂\",\"Mscr\":\"ℳ\",\"mstpos\":\"∾\",\"Mu\":\"Μ\",\"mu\":\"μ\",\"multimap\":\"⊸\",\"mumap\":\"⊸\",\"nabla\":\"∇\",\"Nacute\":\"Ń\",\"nacute\":\"ń\",\"nang\":\"∠⃒\",\"nap\":\"≉\",\"napE\":\"⩰̸\",\"napid\":\"≋̸\",\"napos\":\"ŉ\",\"napprox\":\"≉\",\"natural\":\"♮\",\"naturals\":\"ℕ\",\"natur\":\"♮\",\"nbsp\":\" \",\"nbump\":\"≎̸\",\"nbumpe\":\"≏̸\",\"ncap\":\"⩃\",\"Ncaron\":\"Ň\",\"ncaron\":\"ň\",\"Ncedil\":\"Ņ\",\"ncedil\":\"ņ\",\"ncong\":\"≇\",\"ncongdot\":\"⩭̸\",\"ncup\":\"⩂\",\"Ncy\":\"Н\",\"ncy\":\"н\",\"ndash\":\"–\",\"nearhk\":\"⤤\",\"nearr\":\"↗\",\"neArr\":\"⇗\",\"nearrow\":\"↗\",\"ne\":\"≠\",\"nedot\":\"≐̸\",\"NegativeMediumSpace\":\"​\",\"NegativeThickSpace\":\"​\",\"NegativeThinSpace\":\"​\",\"NegativeVeryThinSpace\":\"​\",\"nequiv\":\"≢\",\"nesear\":\"⤨\",\"nesim\":\"≂̸\",\"NestedGreaterGreater\":\"≫\",\"NestedLessLess\":\"≪\",\"NewLine\":\"\\n\",\"nexist\":\"∄\",\"nexists\":\"∄\",\"Nfr\":\"𝔑\",\"nfr\":\"𝔫\",\"ngE\":\"≧̸\",\"nge\":\"≱\",\"ngeq\":\"≱\",\"ngeqq\":\"≧̸\",\"ngeqslant\":\"⩾̸\",\"nges\":\"⩾̸\",\"nGg\":\"⋙̸\",\"ngsim\":\"≵\",\"nGt\":\"≫⃒\",\"ngt\":\"≯\",\"ngtr\":\"≯\",\"nGtv\":\"≫̸\",\"nharr\":\"↮\",\"nhArr\":\"⇎\",\"nhpar\":\"⫲\",\"ni\":\"∋\",\"nis\":\"⋼\",\"nisd\":\"⋺\",\"niv\":\"∋\",\"NJcy\":\"Њ\",\"njcy\":\"њ\",\"nlarr\":\"↚\",\"nlArr\":\"⇍\",\"nldr\":\"‥\",\"nlE\":\"≦̸\",\"nle\":\"≰\",\"nleftarrow\":\"↚\",\"nLeftarrow\":\"⇍\",\"nleftrightarrow\":\"↮\",\"nLeftrightarrow\":\"⇎\",\"nleq\":\"≰\",\"nleqq\":\"≦̸\",\"nleqslant\":\"⩽̸\",\"nles\":\"⩽̸\",\"nless\":\"≮\",\"nLl\":\"⋘̸\",\"nlsim\":\"≴\",\"nLt\":\"≪⃒\",\"nlt\":\"≮\",\"nltri\":\"⋪\",\"nltrie\":\"⋬\",\"nLtv\":\"≪̸\",\"nmid\":\"∤\",\"NoBreak\":\"⁠\",\"NonBreakingSpace\":\" \",\"nopf\":\"𝕟\",\"Nopf\":\"ℕ\",\"Not\":\"⫬\",\"not\":\"¬\",\"NotCongruent\":\"≢\",\"NotCupCap\":\"≭\",\"NotDoubleVerticalBar\":\"∦\",\"NotElement\":\"∉\",\"NotEqual\":\"≠\",\"NotEqualTilde\":\"≂̸\",\"NotExists\":\"∄\",\"NotGreater\":\"≯\",\"NotGreaterEqual\":\"≱\",\"NotGreaterFullEqual\":\"≧̸\",\"NotGreaterGreater\":\"≫̸\",\"NotGreaterLess\":\"≹\",\"NotGreaterSlantEqual\":\"⩾̸\",\"NotGreaterTilde\":\"≵\",\"NotHumpDownHump\":\"≎̸\",\"NotHumpEqual\":\"≏̸\",\"notin\":\"∉\",\"notindot\":\"⋵̸\",\"notinE\":\"⋹̸\",\"notinva\":\"∉\",\"notinvb\":\"⋷\",\"notinvc\":\"⋶\",\"NotLeftTriangleBar\":\"⧏̸\",\"NotLeftTriangle\":\"⋪\",\"NotLeftTriangleEqual\":\"⋬\",\"NotLess\":\"≮\",\"NotLessEqual\":\"≰\",\"NotLessGreater\":\"≸\",\"NotLessLess\":\"≪̸\",\"NotLessSlantEqual\":\"⩽̸\",\"NotLessTilde\":\"≴\",\"NotNestedGreaterGreater\":\"⪢̸\",\"NotNestedLessLess\":\"⪡̸\",\"notni\":\"∌\",\"notniva\":\"∌\",\"notnivb\":\"⋾\",\"notnivc\":\"⋽\",\"NotPrecedes\":\"⊀\",\"NotPrecedesEqual\":\"⪯̸\",\"NotPrecedesSlantEqual\":\"⋠\",\"NotReverseElement\":\"∌\",\"NotRightTriangleBar\":\"⧐̸\",\"NotRightTriangle\":\"⋫\",\"NotRightTriangleEqual\":\"⋭\",\"NotSquareSubset\":\"⊏̸\",\"NotSquareSubsetEqual\":\"⋢\",\"NotSquareSuperset\":\"⊐̸\",\"NotSquareSupersetEqual\":\"⋣\",\"NotSubset\":\"⊂⃒\",\"NotSubsetEqual\":\"⊈\",\"NotSucceeds\":\"⊁\",\"NotSucceedsEqual\":\"⪰̸\",\"NotSucceedsSlantEqual\":\"⋡\",\"NotSucceedsTilde\":\"≿̸\",\"NotSuperset\":\"⊃⃒\",\"NotSupersetEqual\":\"⊉\",\"NotTilde\":\"≁\",\"NotTildeEqual\":\"≄\",\"NotTildeFullEqual\":\"≇\",\"NotTildeTilde\":\"≉\",\"NotVerticalBar\":\"∤\",\"nparallel\":\"∦\",\"npar\":\"∦\",\"nparsl\":\"⫽⃥\",\"npart\":\"∂̸\",\"npolint\":\"⨔\",\"npr\":\"⊀\",\"nprcue\":\"⋠\",\"nprec\":\"⊀\",\"npreceq\":\"⪯̸\",\"npre\":\"⪯̸\",\"nrarrc\":\"⤳̸\",\"nrarr\":\"↛\",\"nrArr\":\"⇏\",\"nrarrw\":\"↝̸\",\"nrightarrow\":\"↛\",\"nRightarrow\":\"⇏\",\"nrtri\":\"⋫\",\"nrtrie\":\"⋭\",\"nsc\":\"⊁\",\"nsccue\":\"⋡\",\"nsce\":\"⪰̸\",\"Nscr\":\"𝒩\",\"nscr\":\"𝓃\",\"nshortmid\":\"∤\",\"nshortparallel\":\"∦\",\"nsim\":\"≁\",\"nsime\":\"≄\",\"nsimeq\":\"≄\",\"nsmid\":\"∤\",\"nspar\":\"∦\",\"nsqsube\":\"⋢\",\"nsqsupe\":\"⋣\",\"nsub\":\"⊄\",\"nsubE\":\"⫅̸\",\"nsube\":\"⊈\",\"nsubset\":\"⊂⃒\",\"nsubseteq\":\"⊈\",\"nsubseteqq\":\"⫅̸\",\"nsucc\":\"⊁\",\"nsucceq\":\"⪰̸\",\"nsup\":\"⊅\",\"nsupE\":\"⫆̸\",\"nsupe\":\"⊉\",\"nsupset\":\"⊃⃒\",\"nsupseteq\":\"⊉\",\"nsupseteqq\":\"⫆̸\",\"ntgl\":\"≹\",\"Ntilde\":\"Ñ\",\"ntilde\":\"ñ\",\"ntlg\":\"≸\",\"ntriangleleft\":\"⋪\",\"ntrianglelefteq\":\"⋬\",\"ntriangleright\":\"⋫\",\"ntrianglerighteq\":\"⋭\",\"Nu\":\"Ν\",\"nu\":\"ν\",\"num\":\"#\",\"numero\":\"№\",\"numsp\":\" \",\"nvap\":\"≍⃒\",\"nvdash\":\"⊬\",\"nvDash\":\"⊭\",\"nVdash\":\"⊮\",\"nVDash\":\"⊯\",\"nvge\":\"≥⃒\",\"nvgt\":\">⃒\",\"nvHarr\":\"⤄\",\"nvinfin\":\"⧞\",\"nvlArr\":\"⤂\",\"nvle\":\"≤⃒\",\"nvlt\":\"<⃒\",\"nvltrie\":\"⊴⃒\",\"nvrArr\":\"⤃\",\"nvrtrie\":\"⊵⃒\",\"nvsim\":\"∼⃒\",\"nwarhk\":\"⤣\",\"nwarr\":\"↖\",\"nwArr\":\"⇖\",\"nwarrow\":\"↖\",\"nwnear\":\"⤧\",\"Oacute\":\"Ó\",\"oacute\":\"ó\",\"oast\":\"⊛\",\"Ocirc\":\"Ô\",\"ocirc\":\"ô\",\"ocir\":\"⊚\",\"Ocy\":\"О\",\"ocy\":\"о\",\"odash\":\"⊝\",\"Odblac\":\"Ő\",\"odblac\":\"ő\",\"odiv\":\"⨸\",\"odot\":\"⊙\",\"odsold\":\"⦼\",\"OElig\":\"Œ\",\"oelig\":\"œ\",\"ofcir\":\"⦿\",\"Ofr\":\"𝔒\",\"ofr\":\"𝔬\",\"ogon\":\"˛\",\"Ograve\":\"Ò\",\"ograve\":\"ò\",\"ogt\":\"⧁\",\"ohbar\":\"⦵\",\"ohm\":\"Ω\",\"oint\":\"∮\",\"olarr\":\"↺\",\"olcir\":\"⦾\",\"olcross\":\"⦻\",\"oline\":\"‾\",\"olt\":\"⧀\",\"Omacr\":\"Ō\",\"omacr\":\"ō\",\"Omega\":\"Ω\",\"omega\":\"ω\",\"Omicron\":\"Ο\",\"omicron\":\"ο\",\"omid\":\"⦶\",\"ominus\":\"⊖\",\"Oopf\":\"𝕆\",\"oopf\":\"𝕠\",\"opar\":\"⦷\",\"OpenCurlyDoubleQuote\":\"“\",\"OpenCurlyQuote\":\"‘\",\"operp\":\"⦹\",\"oplus\":\"⊕\",\"orarr\":\"↻\",\"Or\":\"⩔\",\"or\":\"∨\",\"ord\":\"⩝\",\"order\":\"ℴ\",\"orderof\":\"ℴ\",\"ordf\":\"ª\",\"ordm\":\"º\",\"origof\":\"⊶\",\"oror\":\"⩖\",\"orslope\":\"⩗\",\"orv\":\"⩛\",\"oS\":\"Ⓢ\",\"Oscr\":\"𝒪\",\"oscr\":\"ℴ\",\"Oslash\":\"Ø\",\"oslash\":\"ø\",\"osol\":\"⊘\",\"Otilde\":\"Õ\",\"otilde\":\"õ\",\"otimesas\":\"⨶\",\"Otimes\":\"⨷\",\"otimes\":\"⊗\",\"Ouml\":\"Ö\",\"ouml\":\"ö\",\"ovbar\":\"⌽\",\"OverBar\":\"‾\",\"OverBrace\":\"⏞\",\"OverBracket\":\"⎴\",\"OverParenthesis\":\"⏜\",\"para\":\"¶\",\"parallel\":\"∥\",\"par\":\"∥\",\"parsim\":\"⫳\",\"parsl\":\"⫽\",\"part\":\"∂\",\"PartialD\":\"∂\",\"Pcy\":\"П\",\"pcy\":\"п\",\"percnt\":\"%\",\"period\":\".\",\"permil\":\"‰\",\"perp\":\"⊥\",\"pertenk\":\"‱\",\"Pfr\":\"𝔓\",\"pfr\":\"𝔭\",\"Phi\":\"Φ\",\"phi\":\"φ\",\"phiv\":\"ϕ\",\"phmmat\":\"ℳ\",\"phone\":\"☎\",\"Pi\":\"Π\",\"pi\":\"π\",\"pitchfork\":\"⋔\",\"piv\":\"ϖ\",\"planck\":\"ℏ\",\"planckh\":\"ℎ\",\"plankv\":\"ℏ\",\"plusacir\":\"⨣\",\"plusb\":\"⊞\",\"pluscir\":\"⨢\",\"plus\":\"+\",\"plusdo\":\"∔\",\"plusdu\":\"⨥\",\"pluse\":\"⩲\",\"PlusMinus\":\"±\",\"plusmn\":\"±\",\"plussim\":\"⨦\",\"plustwo\":\"⨧\",\"pm\":\"±\",\"Poincareplane\":\"ℌ\",\"pointint\":\"⨕\",\"popf\":\"𝕡\",\"Popf\":\"ℙ\",\"pound\":\"£\",\"prap\":\"⪷\",\"Pr\":\"⪻\",\"pr\":\"≺\",\"prcue\":\"≼\",\"precapprox\":\"⪷\",\"prec\":\"≺\",\"preccurlyeq\":\"≼\",\"Precedes\":\"≺\",\"PrecedesEqual\":\"⪯\",\"PrecedesSlantEqual\":\"≼\",\"PrecedesTilde\":\"≾\",\"preceq\":\"⪯\",\"precnapprox\":\"⪹\",\"precneqq\":\"⪵\",\"precnsim\":\"⋨\",\"pre\":\"⪯\",\"prE\":\"⪳\",\"precsim\":\"≾\",\"prime\":\"′\",\"Prime\":\"″\",\"primes\":\"ℙ\",\"prnap\":\"⪹\",\"prnE\":\"⪵\",\"prnsim\":\"⋨\",\"prod\":\"∏\",\"Product\":\"∏\",\"profalar\":\"⌮\",\"profline\":\"⌒\",\"profsurf\":\"⌓\",\"prop\":\"∝\",\"Proportional\":\"∝\",\"Proportion\":\"∷\",\"propto\":\"∝\",\"prsim\":\"≾\",\"prurel\":\"⊰\",\"Pscr\":\"𝒫\",\"pscr\":\"𝓅\",\"Psi\":\"Ψ\",\"psi\":\"ψ\",\"puncsp\":\" \",\"Qfr\":\"𝔔\",\"qfr\":\"𝔮\",\"qint\":\"⨌\",\"qopf\":\"𝕢\",\"Qopf\":\"ℚ\",\"qprime\":\"⁗\",\"Qscr\":\"𝒬\",\"qscr\":\"𝓆\",\"quaternions\":\"ℍ\",\"quatint\":\"⨖\",\"quest\":\"?\",\"questeq\":\"≟\",\"quot\":\"\\\"\",\"QUOT\":\"\\\"\",\"rAarr\":\"⇛\",\"race\":\"∽̱\",\"Racute\":\"Ŕ\",\"racute\":\"ŕ\",\"radic\":\"√\",\"raemptyv\":\"⦳\",\"rang\":\"⟩\",\"Rang\":\"⟫\",\"rangd\":\"⦒\",\"range\":\"⦥\",\"rangle\":\"⟩\",\"raquo\":\"»\",\"rarrap\":\"⥵\",\"rarrb\":\"⇥\",\"rarrbfs\":\"⤠\",\"rarrc\":\"⤳\",\"rarr\":\"→\",\"Rarr\":\"↠\",\"rArr\":\"⇒\",\"rarrfs\":\"⤞\",\"rarrhk\":\"↪\",\"rarrlp\":\"↬\",\"rarrpl\":\"⥅\",\"rarrsim\":\"⥴\",\"Rarrtl\":\"⤖\",\"rarrtl\":\"↣\",\"rarrw\":\"↝\",\"ratail\":\"⤚\",\"rAtail\":\"⤜\",\"ratio\":\"∶\",\"rationals\":\"ℚ\",\"rbarr\":\"⤍\",\"rBarr\":\"⤏\",\"RBarr\":\"⤐\",\"rbbrk\":\"❳\",\"rbrace\":\"}\",\"rbrack\":\"]\",\"rbrke\":\"⦌\",\"rbrksld\":\"⦎\",\"rbrkslu\":\"⦐\",\"Rcaron\":\"Ř\",\"rcaron\":\"ř\",\"Rcedil\":\"Ŗ\",\"rcedil\":\"ŗ\",\"rceil\":\"⌉\",\"rcub\":\"}\",\"Rcy\":\"Р\",\"rcy\":\"р\",\"rdca\":\"⤷\",\"rdldhar\":\"⥩\",\"rdquo\":\"”\",\"rdquor\":\"”\",\"rdsh\":\"↳\",\"real\":\"ℜ\",\"realine\":\"ℛ\",\"realpart\":\"ℜ\",\"reals\":\"ℝ\",\"Re\":\"ℜ\",\"rect\":\"▭\",\"reg\":\"®\",\"REG\":\"®\",\"ReverseElement\":\"∋\",\"ReverseEquilibrium\":\"⇋\",\"ReverseUpEquilibrium\":\"⥯\",\"rfisht\":\"⥽\",\"rfloor\":\"⌋\",\"rfr\":\"𝔯\",\"Rfr\":\"ℜ\",\"rHar\":\"⥤\",\"rhard\":\"⇁\",\"rharu\":\"⇀\",\"rharul\":\"⥬\",\"Rho\":\"Ρ\",\"rho\":\"ρ\",\"rhov\":\"ϱ\",\"RightAngleBracket\":\"⟩\",\"RightArrowBar\":\"⇥\",\"rightarrow\":\"→\",\"RightArrow\":\"→\",\"Rightarrow\":\"⇒\",\"RightArrowLeftArrow\":\"⇄\",\"rightarrowtail\":\"↣\",\"RightCeiling\":\"⌉\",\"RightDoubleBracket\":\"⟧\",\"RightDownTeeVector\":\"⥝\",\"RightDownVectorBar\":\"⥕\",\"RightDownVector\":\"⇂\",\"RightFloor\":\"⌋\",\"rightharpoondown\":\"⇁\",\"rightharpoonup\":\"⇀\",\"rightleftarrows\":\"⇄\",\"rightleftharpoons\":\"⇌\",\"rightrightarrows\":\"⇉\",\"rightsquigarrow\":\"↝\",\"RightTeeArrow\":\"↦\",\"RightTee\":\"⊢\",\"RightTeeVector\":\"⥛\",\"rightthreetimes\":\"⋌\",\"RightTriangleBar\":\"⧐\",\"RightTriangle\":\"⊳\",\"RightTriangleEqual\":\"⊵\",\"RightUpDownVector\":\"⥏\",\"RightUpTeeVector\":\"⥜\",\"RightUpVectorBar\":\"⥔\",\"RightUpVector\":\"↾\",\"RightVectorBar\":\"⥓\",\"RightVector\":\"⇀\",\"ring\":\"˚\",\"risingdotseq\":\"≓\",\"rlarr\":\"⇄\",\"rlhar\":\"⇌\",\"rlm\":\"‏\",\"rmoustache\":\"⎱\",\"rmoust\":\"⎱\",\"rnmid\":\"⫮\",\"roang\":\"⟭\",\"roarr\":\"⇾\",\"robrk\":\"⟧\",\"ropar\":\"⦆\",\"ropf\":\"𝕣\",\"Ropf\":\"ℝ\",\"roplus\":\"⨮\",\"rotimes\":\"⨵\",\"RoundImplies\":\"⥰\",\"rpar\":\")\",\"rpargt\":\"⦔\",\"rppolint\":\"⨒\",\"rrarr\":\"⇉\",\"Rrightarrow\":\"⇛\",\"rsaquo\":\"›\",\"rscr\":\"𝓇\",\"Rscr\":\"ℛ\",\"rsh\":\"↱\",\"Rsh\":\"↱\",\"rsqb\":\"]\",\"rsquo\":\"’\",\"rsquor\":\"’\",\"rthree\":\"⋌\",\"rtimes\":\"⋊\",\"rtri\":\"▹\",\"rtrie\":\"⊵\",\"rtrif\":\"▸\",\"rtriltri\":\"⧎\",\"RuleDelayed\":\"⧴\",\"ruluhar\":\"⥨\",\"rx\":\"℞\",\"Sacute\":\"Ś\",\"sacute\":\"ś\",\"sbquo\":\"‚\",\"scap\":\"⪸\",\"Scaron\":\"Š\",\"scaron\":\"š\",\"Sc\":\"⪼\",\"sc\":\"≻\",\"sccue\":\"≽\",\"sce\":\"⪰\",\"scE\":\"⪴\",\"Scedil\":\"Ş\",\"scedil\":\"ş\",\"Scirc\":\"Ŝ\",\"scirc\":\"ŝ\",\"scnap\":\"⪺\",\"scnE\":\"⪶\",\"scnsim\":\"⋩\",\"scpolint\":\"⨓\",\"scsim\":\"≿\",\"Scy\":\"С\",\"scy\":\"с\",\"sdotb\":\"⊡\",\"sdot\":\"⋅\",\"sdote\":\"⩦\",\"searhk\":\"⤥\",\"searr\":\"↘\",\"seArr\":\"⇘\",\"searrow\":\"↘\",\"sect\":\"§\",\"semi\":\";\",\"seswar\":\"⤩\",\"setminus\":\"∖\",\"setmn\":\"∖\",\"sext\":\"✶\",\"Sfr\":\"𝔖\",\"sfr\":\"𝔰\",\"sfrown\":\"⌢\",\"sharp\":\"♯\",\"SHCHcy\":\"Щ\",\"shchcy\":\"щ\",\"SHcy\":\"Ш\",\"shcy\":\"ш\",\"ShortDownArrow\":\"↓\",\"ShortLeftArrow\":\"←\",\"shortmid\":\"∣\",\"shortparallel\":\"∥\",\"ShortRightArrow\":\"→\",\"ShortUpArrow\":\"↑\",\"shy\":\"­\",\"Sigma\":\"Σ\",\"sigma\":\"σ\",\"sigmaf\":\"ς\",\"sigmav\":\"ς\",\"sim\":\"∼\",\"simdot\":\"⩪\",\"sime\":\"≃\",\"simeq\":\"≃\",\"simg\":\"⪞\",\"simgE\":\"⪠\",\"siml\":\"⪝\",\"simlE\":\"⪟\",\"simne\":\"≆\",\"simplus\":\"⨤\",\"simrarr\":\"⥲\",\"slarr\":\"←\",\"SmallCircle\":\"∘\",\"smallsetminus\":\"∖\",\"smashp\":\"⨳\",\"smeparsl\":\"⧤\",\"smid\":\"∣\",\"smile\":\"⌣\",\"smt\":\"⪪\",\"smte\":\"⪬\",\"smtes\":\"⪬︀\",\"SOFTcy\":\"Ь\",\"softcy\":\"ь\",\"solbar\":\"⌿\",\"solb\":\"⧄\",\"sol\":\"/\",\"Sopf\":\"𝕊\",\"sopf\":\"𝕤\",\"spades\":\"♠\",\"spadesuit\":\"♠\",\"spar\":\"∥\",\"sqcap\":\"⊓\",\"sqcaps\":\"⊓︀\",\"sqcup\":\"⊔\",\"sqcups\":\"⊔︀\",\"Sqrt\":\"√\",\"sqsub\":\"⊏\",\"sqsube\":\"⊑\",\"sqsubset\":\"⊏\",\"sqsubseteq\":\"⊑\",\"sqsup\":\"⊐\",\"sqsupe\":\"⊒\",\"sqsupset\":\"⊐\",\"sqsupseteq\":\"⊒\",\"square\":\"□\",\"Square\":\"□\",\"SquareIntersection\":\"⊓\",\"SquareSubset\":\"⊏\",\"SquareSubsetEqual\":\"⊑\",\"SquareSuperset\":\"⊐\",\"SquareSupersetEqual\":\"⊒\",\"SquareUnion\":\"⊔\",\"squarf\":\"▪\",\"squ\":\"□\",\"squf\":\"▪\",\"srarr\":\"→\",\"Sscr\":\"𝒮\",\"sscr\":\"𝓈\",\"ssetmn\":\"∖\",\"ssmile\":\"⌣\",\"sstarf\":\"⋆\",\"Star\":\"⋆\",\"star\":\"☆\",\"starf\":\"★\",\"straightepsilon\":\"ϵ\",\"straightphi\":\"ϕ\",\"strns\":\"¯\",\"sub\":\"⊂\",\"Sub\":\"⋐\",\"subdot\":\"⪽\",\"subE\":\"⫅\",\"sube\":\"⊆\",\"subedot\":\"⫃\",\"submult\":\"⫁\",\"subnE\":\"⫋\",\"subne\":\"⊊\",\"subplus\":\"⪿\",\"subrarr\":\"⥹\",\"subset\":\"⊂\",\"Subset\":\"⋐\",\"subseteq\":\"⊆\",\"subseteqq\":\"⫅\",\"SubsetEqual\":\"⊆\",\"subsetneq\":\"⊊\",\"subsetneqq\":\"⫋\",\"subsim\":\"⫇\",\"subsub\":\"⫕\",\"subsup\":\"⫓\",\"succapprox\":\"⪸\",\"succ\":\"≻\",\"succcurlyeq\":\"≽\",\"Succeeds\":\"≻\",\"SucceedsEqual\":\"⪰\",\"SucceedsSlantEqual\":\"≽\",\"SucceedsTilde\":\"≿\",\"succeq\":\"⪰\",\"succnapprox\":\"⪺\",\"succneqq\":\"⪶\",\"succnsim\":\"⋩\",\"succsim\":\"≿\",\"SuchThat\":\"∋\",\"sum\":\"∑\",\"Sum\":\"∑\",\"sung\":\"♪\",\"sup1\":\"¹\",\"sup2\":\"²\",\"sup3\":\"³\",\"sup\":\"⊃\",\"Sup\":\"⋑\",\"supdot\":\"⪾\",\"supdsub\":\"⫘\",\"supE\":\"⫆\",\"supe\":\"⊇\",\"supedot\":\"⫄\",\"Superset\":\"⊃\",\"SupersetEqual\":\"⊇\",\"suphsol\":\"⟉\",\"suphsub\":\"⫗\",\"suplarr\":\"⥻\",\"supmult\":\"⫂\",\"supnE\":\"⫌\",\"supne\":\"⊋\",\"supplus\":\"⫀\",\"supset\":\"⊃\",\"Supset\":\"⋑\",\"supseteq\":\"⊇\",\"supseteqq\":\"⫆\",\"supsetneq\":\"⊋\",\"supsetneqq\":\"⫌\",\"supsim\":\"⫈\",\"supsub\":\"⫔\",\"supsup\":\"⫖\",\"swarhk\":\"⤦\",\"swarr\":\"↙\",\"swArr\":\"⇙\",\"swarrow\":\"↙\",\"swnwar\":\"⤪\",\"szlig\":\"ß\",\"Tab\":\"\\t\",\"target\":\"⌖\",\"Tau\":\"Τ\",\"tau\":\"τ\",\"tbrk\":\"⎴\",\"Tcaron\":\"Ť\",\"tcaron\":\"ť\",\"Tcedil\":\"Ţ\",\"tcedil\":\"ţ\",\"Tcy\":\"Т\",\"tcy\":\"т\",\"tdot\":\"⃛\",\"telrec\":\"⌕\",\"Tfr\":\"𝔗\",\"tfr\":\"𝔱\",\"there4\":\"∴\",\"therefore\":\"∴\",\"Therefore\":\"∴\",\"Theta\":\"Θ\",\"theta\":\"θ\",\"thetasym\":\"ϑ\",\"thetav\":\"ϑ\",\"thickapprox\":\"≈\",\"thicksim\":\"∼\",\"ThickSpace\":\"  \",\"ThinSpace\":\" \",\"thinsp\":\" \",\"thkap\":\"≈\",\"thksim\":\"∼\",\"THORN\":\"Þ\",\"thorn\":\"þ\",\"tilde\":\"˜\",\"Tilde\":\"∼\",\"TildeEqual\":\"≃\",\"TildeFullEqual\":\"≅\",\"TildeTilde\":\"≈\",\"timesbar\":\"⨱\",\"timesb\":\"⊠\",\"times\":\"×\",\"timesd\":\"⨰\",\"tint\":\"∭\",\"toea\":\"⤨\",\"topbot\":\"⌶\",\"topcir\":\"⫱\",\"top\":\"⊤\",\"Topf\":\"𝕋\",\"topf\":\"𝕥\",\"topfork\":\"⫚\",\"tosa\":\"⤩\",\"tprime\":\"‴\",\"trade\":\"™\",\"TRADE\":\"™\",\"triangle\":\"▵\",\"triangledown\":\"▿\",\"triangleleft\":\"◃\",\"trianglelefteq\":\"⊴\",\"triangleq\":\"≜\",\"triangleright\":\"▹\",\"trianglerighteq\":\"⊵\",\"tridot\":\"◬\",\"trie\":\"≜\",\"triminus\":\"⨺\",\"TripleDot\":\"⃛\",\"triplus\":\"⨹\",\"trisb\":\"⧍\",\"tritime\":\"⨻\",\"trpezium\":\"⏢\",\"Tscr\":\"𝒯\",\"tscr\":\"𝓉\",\"TScy\":\"Ц\",\"tscy\":\"ц\",\"TSHcy\":\"Ћ\",\"tshcy\":\"ћ\",\"Tstrok\":\"Ŧ\",\"tstrok\":\"ŧ\",\"twixt\":\"≬\",\"twoheadleftarrow\":\"↞\",\"twoheadrightarrow\":\"↠\",\"Uacute\":\"Ú\",\"uacute\":\"ú\",\"uarr\":\"↑\",\"Uarr\":\"↟\",\"uArr\":\"⇑\",\"Uarrocir\":\"⥉\",\"Ubrcy\":\"Ў\",\"ubrcy\":\"ў\",\"Ubreve\":\"Ŭ\",\"ubreve\":\"ŭ\",\"Ucirc\":\"Û\",\"ucirc\":\"û\",\"Ucy\":\"У\",\"ucy\":\"у\",\"udarr\":\"⇅\",\"Udblac\":\"Ű\",\"udblac\":\"ű\",\"udhar\":\"⥮\",\"ufisht\":\"⥾\",\"Ufr\":\"𝔘\",\"ufr\":\"𝔲\",\"Ugrave\":\"Ù\",\"ugrave\":\"ù\",\"uHar\":\"⥣\",\"uharl\":\"↿\",\"uharr\":\"↾\",\"uhblk\":\"▀\",\"ulcorn\":\"⌜\",\"ulcorner\":\"⌜\",\"ulcrop\":\"⌏\",\"ultri\":\"◸\",\"Umacr\":\"Ū\",\"umacr\":\"ū\",\"uml\":\"¨\",\"UnderBar\":\"_\",\"UnderBrace\":\"⏟\",\"UnderBracket\":\"⎵\",\"UnderParenthesis\":\"⏝\",\"Union\":\"⋃\",\"UnionPlus\":\"⊎\",\"Uogon\":\"Ų\",\"uogon\":\"ų\",\"Uopf\":\"𝕌\",\"uopf\":\"𝕦\",\"UpArrowBar\":\"⤒\",\"uparrow\":\"↑\",\"UpArrow\":\"↑\",\"Uparrow\":\"⇑\",\"UpArrowDownArrow\":\"⇅\",\"updownarrow\":\"↕\",\"UpDownArrow\":\"↕\",\"Updownarrow\":\"⇕\",\"UpEquilibrium\":\"⥮\",\"upharpoonleft\":\"↿\",\"upharpoonright\":\"↾\",\"uplus\":\"⊎\",\"UpperLeftArrow\":\"↖\",\"UpperRightArrow\":\"↗\",\"upsi\":\"υ\",\"Upsi\":\"ϒ\",\"upsih\":\"ϒ\",\"Upsilon\":\"Υ\",\"upsilon\":\"υ\",\"UpTeeArrow\":\"↥\",\"UpTee\":\"⊥\",\"upuparrows\":\"⇈\",\"urcorn\":\"⌝\",\"urcorner\":\"⌝\",\"urcrop\":\"⌎\",\"Uring\":\"Ů\",\"uring\":\"ů\",\"urtri\":\"◹\",\"Uscr\":\"𝒰\",\"uscr\":\"𝓊\",\"utdot\":\"⋰\",\"Utilde\":\"Ũ\",\"utilde\":\"ũ\",\"utri\":\"▵\",\"utrif\":\"▴\",\"uuarr\":\"⇈\",\"Uuml\":\"Ü\",\"uuml\":\"ü\",\"uwangle\":\"⦧\",\"vangrt\":\"⦜\",\"varepsilon\":\"ϵ\",\"varkappa\":\"ϰ\",\"varnothing\":\"∅\",\"varphi\":\"ϕ\",\"varpi\":\"ϖ\",\"varpropto\":\"∝\",\"varr\":\"↕\",\"vArr\":\"⇕\",\"varrho\":\"ϱ\",\"varsigma\":\"ς\",\"varsubsetneq\":\"⊊︀\",\"varsubsetneqq\":\"⫋︀\",\"varsupsetneq\":\"⊋︀\",\"varsupsetneqq\":\"⫌︀\",\"vartheta\":\"ϑ\",\"vartriangleleft\":\"⊲\",\"vartriangleright\":\"⊳\",\"vBar\":\"⫨\",\"Vbar\":\"⫫\",\"vBarv\":\"⫩\",\"Vcy\":\"В\",\"vcy\":\"в\",\"vdash\":\"⊢\",\"vDash\":\"⊨\",\"Vdash\":\"⊩\",\"VDash\":\"⊫\",\"Vdashl\":\"⫦\",\"veebar\":\"⊻\",\"vee\":\"∨\",\"Vee\":\"⋁\",\"veeeq\":\"≚\",\"vellip\":\"⋮\",\"verbar\":\"|\",\"Verbar\":\"‖\",\"vert\":\"|\",\"Vert\":\"‖\",\"VerticalBar\":\"∣\",\"VerticalLine\":\"|\",\"VerticalSeparator\":\"❘\",\"VerticalTilde\":\"≀\",\"VeryThinSpace\":\" \",\"Vfr\":\"𝔙\",\"vfr\":\"𝔳\",\"vltri\":\"⊲\",\"vnsub\":\"⊂⃒\",\"vnsup\":\"⊃⃒\",\"Vopf\":\"𝕍\",\"vopf\":\"𝕧\",\"vprop\":\"∝\",\"vrtri\":\"⊳\",\"Vscr\":\"𝒱\",\"vscr\":\"𝓋\",\"vsubnE\":\"⫋︀\",\"vsubne\":\"⊊︀\",\"vsupnE\":\"⫌︀\",\"vsupne\":\"⊋︀\",\"Vvdash\":\"⊪\",\"vzigzag\":\"⦚\",\"Wcirc\":\"Ŵ\",\"wcirc\":\"ŵ\",\"wedbar\":\"⩟\",\"wedge\":\"∧\",\"Wedge\":\"⋀\",\"wedgeq\":\"≙\",\"weierp\":\"℘\",\"Wfr\":\"𝔚\",\"wfr\":\"𝔴\",\"Wopf\":\"𝕎\",\"wopf\":\"𝕨\",\"wp\":\"℘\",\"wr\":\"≀\",\"wreath\":\"≀\",\"Wscr\":\"𝒲\",\"wscr\":\"𝓌\",\"xcap\":\"⋂\",\"xcirc\":\"◯\",\"xcup\":\"⋃\",\"xdtri\":\"▽\",\"Xfr\":\"𝔛\",\"xfr\":\"𝔵\",\"xharr\":\"⟷\",\"xhArr\":\"⟺\",\"Xi\":\"Ξ\",\"xi\":\"ξ\",\"xlarr\":\"⟵\",\"xlArr\":\"⟸\",\"xmap\":\"⟼\",\"xnis\":\"⋻\",\"xodot\":\"⨀\",\"Xopf\":\"𝕏\",\"xopf\":\"𝕩\",\"xoplus\":\"⨁\",\"xotime\":\"⨂\",\"xrarr\":\"⟶\",\"xrArr\":\"⟹\",\"Xscr\":\"𝒳\",\"xscr\":\"𝓍\",\"xsqcup\":\"⨆\",\"xuplus\":\"⨄\",\"xutri\":\"△\",\"xvee\":\"⋁\",\"xwedge\":\"⋀\",\"Yacute\":\"Ý\",\"yacute\":\"ý\",\"YAcy\":\"Я\",\"yacy\":\"я\",\"Ycirc\":\"Ŷ\",\"ycirc\":\"ŷ\",\"Ycy\":\"Ы\",\"ycy\":\"ы\",\"yen\":\"¥\",\"Yfr\":\"𝔜\",\"yfr\":\"𝔶\",\"YIcy\":\"Ї\",\"yicy\":\"ї\",\"Yopf\":\"𝕐\",\"yopf\":\"𝕪\",\"Yscr\":\"𝒴\",\"yscr\":\"𝓎\",\"YUcy\":\"Ю\",\"yucy\":\"ю\",\"yuml\":\"ÿ\",\"Yuml\":\"Ÿ\",\"Zacute\":\"Ź\",\"zacute\":\"ź\",\"Zcaron\":\"Ž\",\"zcaron\":\"ž\",\"Zcy\":\"З\",\"zcy\":\"з\",\"Zdot\":\"Ż\",\"zdot\":\"ż\",\"zeetrf\":\"ℨ\",\"ZeroWidthSpace\":\"​\",\"Zeta\":\"Ζ\",\"zeta\":\"ζ\",\"zfr\":\"𝔷\",\"Zfr\":\"ℨ\",\"ZHcy\":\"Ж\",\"zhcy\":\"ж\",\"zigrarr\":\"⇝\",\"zopf\":\"𝕫\",\"Zopf\":\"ℤ\",\"Zscr\":\"𝒵\",\"zscr\":\"𝓏\",\"zwj\":\"‍\",\"zwnj\":\"‌\"}");

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/legacy.json":
/*!****************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/legacy.json ***!
  \****************************************************************************************************/
/*! exports provided: Aacute, aacute, Acirc, acirc, acute, AElig, aelig, Agrave, agrave, amp, AMP, Aring, aring, Atilde, atilde, Auml, auml, brvbar, Ccedil, ccedil, cedil, cent, copy, COPY, curren, deg, divide, Eacute, eacute, Ecirc, ecirc, Egrave, egrave, ETH, eth, Euml, euml, frac12, frac14, frac34, gt, GT, Iacute, iacute, Icirc, icirc, iexcl, Igrave, igrave, iquest, Iuml, iuml, laquo, lt, LT, macr, micro, middot, nbsp, not, Ntilde, ntilde, Oacute, oacute, Ocirc, ocirc, Ograve, ograve, ordf, ordm, Oslash, oslash, Otilde, otilde, Ouml, ouml, para, plusmn, pound, quot, QUOT, raquo, reg, REG, sect, shy, sup1, sup2, sup3, szlig, THORN, thorn, times, Uacute, uacute, Ucirc, ucirc, Ugrave, ugrave, uml, Uuml, uuml, Yacute, yacute, yen, yuml, default */
/***/ (function(module) {

module.exports = JSON.parse("{\"Aacute\":\"Á\",\"aacute\":\"á\",\"Acirc\":\"Â\",\"acirc\":\"â\",\"acute\":\"´\",\"AElig\":\"Æ\",\"aelig\":\"æ\",\"Agrave\":\"À\",\"agrave\":\"à\",\"amp\":\"&\",\"AMP\":\"&\",\"Aring\":\"Å\",\"aring\":\"å\",\"Atilde\":\"Ã\",\"atilde\":\"ã\",\"Auml\":\"Ä\",\"auml\":\"ä\",\"brvbar\":\"¦\",\"Ccedil\":\"Ç\",\"ccedil\":\"ç\",\"cedil\":\"¸\",\"cent\":\"¢\",\"copy\":\"©\",\"COPY\":\"©\",\"curren\":\"¤\",\"deg\":\"°\",\"divide\":\"÷\",\"Eacute\":\"É\",\"eacute\":\"é\",\"Ecirc\":\"Ê\",\"ecirc\":\"ê\",\"Egrave\":\"È\",\"egrave\":\"è\",\"ETH\":\"Ð\",\"eth\":\"ð\",\"Euml\":\"Ë\",\"euml\":\"ë\",\"frac12\":\"½\",\"frac14\":\"¼\",\"frac34\":\"¾\",\"gt\":\">\",\"GT\":\">\",\"Iacute\":\"Í\",\"iacute\":\"í\",\"Icirc\":\"Î\",\"icirc\":\"î\",\"iexcl\":\"¡\",\"Igrave\":\"Ì\",\"igrave\":\"ì\",\"iquest\":\"¿\",\"Iuml\":\"Ï\",\"iuml\":\"ï\",\"laquo\":\"«\",\"lt\":\"<\",\"LT\":\"<\",\"macr\":\"¯\",\"micro\":\"µ\",\"middot\":\"·\",\"nbsp\":\" \",\"not\":\"¬\",\"Ntilde\":\"Ñ\",\"ntilde\":\"ñ\",\"Oacute\":\"Ó\",\"oacute\":\"ó\",\"Ocirc\":\"Ô\",\"ocirc\":\"ô\",\"Ograve\":\"Ò\",\"ograve\":\"ò\",\"ordf\":\"ª\",\"ordm\":\"º\",\"Oslash\":\"Ø\",\"oslash\":\"ø\",\"Otilde\":\"Õ\",\"otilde\":\"õ\",\"Ouml\":\"Ö\",\"ouml\":\"ö\",\"para\":\"¶\",\"plusmn\":\"±\",\"pound\":\"£\",\"quot\":\"\\\"\",\"QUOT\":\"\\\"\",\"raquo\":\"»\",\"reg\":\"®\",\"REG\":\"®\",\"sect\":\"§\",\"shy\":\"­\",\"sup1\":\"¹\",\"sup2\":\"²\",\"sup3\":\"³\",\"szlig\":\"ß\",\"THORN\":\"Þ\",\"thorn\":\"þ\",\"times\":\"×\",\"Uacute\":\"Ú\",\"uacute\":\"ú\",\"Ucirc\":\"Û\",\"ucirc\":\"û\",\"Ugrave\":\"Ù\",\"ugrave\":\"ù\",\"uml\":\"¨\",\"Uuml\":\"Ü\",\"uuml\":\"ü\",\"Yacute\":\"Ý\",\"yacute\":\"ý\",\"yen\":\"¥\",\"yuml\":\"ÿ\"}");

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/xml.json":
/*!*************************************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/htmlparser2/node_modules/entities/maps/xml.json ***!
  \*************************************************************************************************/
/*! exports provided: amp, apos, gt, lt, quot, default */
/***/ (function(module) {

module.exports = JSON.parse("{\"amp\":\"&\",\"apos\":\"'\",\"gt\":\">\",\"lt\":\"<\",\"quot\":\"\\\"\"}");

/***/ }),

/***/ "./node_modules/sanitize-html/node_modules/regexp-quote/regexp-quote.js":
/*!******************************************************************************!*\
  !*** ./node_modules/sanitize-html/node_modules/regexp-quote/regexp-quote.js ***!
  \******************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = function (string) {
  return string.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&")
}


/***/ }),

/***/ "./node_modules/setimmediate/setImmediate.js":
/*!***************************************************!*\
  !*** ./node_modules/setimmediate/setImmediate.js ***!
  \***************************************************/
/*! no static exports found */
/***/ (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(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../process/browser.js */ "./node_modules/process/browser.js")))

/***/ }),

/***/ "./node_modules/stream-browserify/index.js":
/*!*************************************************!*\
  !*** ./node_modules/stream-browserify/index.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (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__(/*! events */ "./node_modules/events/events.js").EventEmitter;
var inherits = __webpack_require__(/*! inherits */ "./node_modules/inherits/inherits_browser.js");

inherits(Stream, EE);
Stream.Readable = __webpack_require__(/*! readable-stream/readable.js */ "./node_modules/readable-stream/readable.js");
Stream.Writable = __webpack_require__(/*! readable-stream/writable.js */ "./node_modules/readable-stream/writable.js");
Stream.Duplex = __webpack_require__(/*! readable-stream/duplex.js */ "./node_modules/readable-stream/duplex.js");
Stream.Transform = __webpack_require__(/*! readable-stream/transform.js */ "./node_modules/readable-stream/transform.js");
Stream.PassThrough = __webpack_require__(/*! readable-stream/passthrough.js */ "./node_modules/readable-stream/passthrough.js");

// 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;
};


/***/ }),

/***/ "./node_modules/timers-browserify/main.js":
/*!************************************************!*\
  !*** ./node_modules/timers-browserify/main.js ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) ||
            (typeof self !== "undefined" && self) ||
            window;
var apply = Function.prototype.apply;

// DOM APIs, for completeness

exports.setTimeout = function() {
  return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);
};
exports.setInterval = function() {
  return new Timeout(apply.call(setInterval, scope, 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(scope, 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__(/*! setimmediate */ "./node_modules/setimmediate/setImmediate.js");
// On some exotic environments, it's not clear which object `setimmediate` was
// able to install onto.  Search each possibility in the same order as the
// `setimmediate` library.
exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) ||
                       (typeof global !== "undefined" && global.setImmediate) ||
                       (this && this.setImmediate);
exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) ||
                         (typeof global !== "undefined" && global.clearImmediate) ||
                         (this && this.clearImmediate);

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/util-deprecate/browser.js":
/*!************************************************!*\
  !*** ./node_modules/util-deprecate/browser.js ***!
  \************************************************/
/*! no static exports found */
/***/ (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(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./node_modules/webpack/buildin/global.js":
/*!***********************************!*\
  !*** (webpack)/buildin/global.js ***!
  \***********************************/
/*! no static exports found */
/***/ (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 || new Function("return 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;


/***/ }),

/***/ "./node_modules/xtend/immutable.js":
/*!*****************************************!*\
  !*** ./node_modules/xtend/immutable.js ***!
  \*****************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = extend

var hasOwnProperty = Object.prototype.hasOwnProperty;

function extend() {
    var target = {}

    for (var i = 0; i < arguments.length; i++) {
        var source = arguments[i]

        for (var key in source) {
            if (hasOwnProperty.call(source, key)) {
                target[key] = source[key]
            }
        }
    }

    return target
}


/***/ }),

/***/ "./src/Common/Libraries/common.libraries.propogateIframeEvents.js":
/*!************************************************************************!*\
  !*** ./src/Common/Libraries/common.libraries.propogateIframeEvents.js ***!
  \************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return propogateIframeEvents; });
// IFrame elements swallow mouse events. This interfere with
// code in the parent frame that rely on catching mouse 
// events such as the Fullscreen menu directive, specifically
// dragging the menu over the iframe, and the viewer's user 
// activity detection over the iframe
function propogateIframeEvents(iframe) {
  iframe.addEventListener("load", function () {
    ["mousemove", "mousedown", "mouseup", "click"].forEach(function (mouseEventType) {
      iframe.contentWindow.addEventListener(mouseEventType, function (mouseEvent) {
        bubbleUpMouseEvent(iframe, mouseEvent);
      }, true);
    });
    ["keydown", "keyup", "keypress"].forEach(function (keyboardEventType) {
      iframe.contentWindow.addEventListener(keyboardEventType, function (keyboardEvent) {
        bubbleUpKeyboardEvent(iframe, keyboardEvent);
      }, true);
    });
  });
}

function bubbleUpKeyboardEvent(iframe, keyboardEvent) {
  try {
    var customEvent = new KeyboardEvent(keyboardEvent.type, {
      bubbles: true,
      cancelable: false,
      key: keyboardEvent.key,
      code: keyboardEvent.code,
      location: keyboardEvent.location,
      ctrlKey: keyboardEvent.ctrlKey,
      shiftKey: keyboardEvent.shiftKey,
      altKey: keyboardEvent.altKey,
      metaKey: keyboardEvent.metaKey,
      repeat: keyboardEvent.repeat,
      isComposing: keyboardEvent.isComposing,
      charCode: keyboardEvent.charCode,
      keyCode: keyboardEvent.keyCode,
      which: keyboardEvent.which
    });
    iframe.dispatchEvent(customEvent);
  } catch (e) {
    var _customEvent = document.createEvent("KeyboardEvent");

    var modifierList = [keyboardEvent.altKey ? "Alt" : "", keyboardEvent.ctrlKey ? "Control" : "", keyboardEvent.metaKey ? "Meta" : "", keyboardEvent.shiftKey ? "Shift" : ""].filter(function (a) {
      return a;
    }).join(" ");

    _customEvent.initKeyboardEvent(keyboardEvent.type, true,
    /* canBubble */
    false,
    /* cancelable */
    null,
    /* view (WindowProxy) */
    keyboardEvent.char, keyboardEvent.key, keyboardEvent.location, modifierList, keyboardEvent.repeat);

    iframe.dispatchEvent(_customEvent);
  }
}

function bubbleUpMouseEvent(iframe, mouseEvent) {
  var boundingClientRect = iframe.getBoundingClientRect();

  try {
    var customEvent = new CustomEvent(mouseEvent.type, {
      bubbles: true,
      cancelable: false
    });
    customEvent.detail = mouseEvent.detail;
    customEvent.screenX = mouseEvent.screenX;
    customEvent.screenY = mouseEvent.screenY;
    customEvent.clientX = mouseEvent.clientX + boundingClientRect.left;
    customEvent.clientY = mouseEvent.clientY + boundingClientRect.top;
    customEvent.ctrlKey = mouseEvent.ctrlKey;
    customEvent.altKey = mouseEvent.altKey;
    customEvent.shiftKey = mouseEvent.shiftKey;
    customEvent.metaKey = mouseEvent.metaKey;
    customEvent.button = mouseEvent.button;
    iframe.dispatchEvent(customEvent);
  } catch (e) {
    // IE 11 way:
    var _customEvent2 = document.createEvent("MouseEvents");

    _customEvent2.initMouseEvent(mouseEvent.type, true, // bubbles
    false, // not cancelable
    window, mouseEvent.detail, mouseEvent.screenX, mouseEvent.screenY, mouseEvent.clientX + boundingClientRect.left, mouseEvent.clientY + boundingClientRect.top, mouseEvent.ctrlKey, mouseEvent.altKey, mouseEvent.shiftKey, mouseEvent.metaKey, mouseEvent.button, null // no related element
    );

    iframe.dispatchEvent(_customEvent2);
  }
}

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.constants.js":
/*!********************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.constants.js ***!
  \********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _controls_sparkClient_keyboards__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./controls.sparkClient.keyboards */ "./src/Controls/SparkClient/controls.sparkClient.keyboards.js");

/* harmony default export */ __webpack_exports__["default"] = ({
  localStorageKey: 'SelectedKeyboardForSmartAccessRdp',
  DefaultKeyboardValue: _controls_sparkClient_keyboards__WEBPACK_IMPORTED_MODULE_0__["default"]["English (United States)"],
  DefaultVncKeyboard: "us",
  TimeoutTime: 5000
});

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.js":
/*!**********************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.js ***!
  \**********************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var sanitize_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sanitize-html */ "./node_modules/sanitize-html/index.js");
/* harmony import */ var sanitize_html__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sanitize_html__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _iframe_sparkClient_iframe_files__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./iframe/sparkClient.iframe.files */ "./src/Controls/SparkClient/iframe/sparkClient.iframe.files.js");
/* harmony import */ var _controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controls.sparkClient.states */ "./src/Controls/SparkClient/controls.sparkClient.states.js");
/* harmony import */ var _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controls.sparkClient.protocols */ "./src/Controls/SparkClient/controls.sparkClient.protocols.js");
/* harmony import */ var _controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controls.sparkClient.constants */ "./src/Controls/SparkClient/controls.sparkClient.constants.js");
/* harmony import */ var _controls_sparkError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./controls.sparkError */ "./src/Controls/SparkClient/controls.sparkError.js");
/* harmony import */ var _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./controls.sparkClient.soundConfig.enum */ "./src/Controls/SparkClient/controls.sparkClient.soundConfig.enum.js");
/* harmony import */ var _controls_sparkTextSender__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./controls.sparkTextSender */ "./src/Controls/SparkClient/controls.sparkTextSender.js");
/* harmony import */ var Common_Libraries_common_libraries_propogateIframeEvents__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! Common/Libraries/common.libraries.propogateIframeEvents */ "./src/Common/Libraries/common.libraries.propogateIframeEvents.js");
/* harmony import */ var _controls_sparkClient_navigationAction_enum__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./controls.sparkClient.navigationAction.enum */ "./src/Controls/SparkClient/controls.sparkClient.navigationAction.enum.js");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }












var SparkClient =
/*#__PURE__*/
function () {
  function SparkClient(options) {
    _classCallCheck(this, SparkClient);

    this._checkOptions(options); // update
    // Internal data


    this._clientAdapter = null;
    this._sparkTextSender = null;
    this._iframeWrapperElement = null;
    this._inputDisabled = !!options.disableInput;
    this._sendTextPromise = null; // Events

    this._onstatechange = options.onstatechange || function () {};

    this._onclipboard = options.onclipboard || function () {};

    this._onerror = options.onerror || function () {};

    this._onresize = options.onresize || function () {};

    this._onsync = options.onsync || function () {};

    this._onlogsync = options.onlogsync || function () {};

    this._ontimeout = options.ontimeout || function () {}; // Server Data


    this._sessionNumericId = options.connectionId || null;
    this._gateway = options.hostname;
    this._protocol = options.protocol;
    this._server = options.server;
    this._port = options.port || this._getDefaultProtocolPort(options.protocol);
    this._user = options.user;
    this._domain = options.domain;
    this._password = options.password;
    this._cursorLabel = options.cursorLabel || "";
    this._machineId = options.machineId || null;
    this._envId = options.envId || null;
    this._userEmail = options.userEmail || null;
    this._classId = options.classId || null;
    this._studentId = options.studentId || null;
    this._node = options.node || null;
    this._rdpWallpaper = options.rdpWallpaper || null;
    this._rdpThemes = options.rdpThemes || null;
    this._rdpFontSmoothing = options.rdpFontSmoothing || null;
    this._rdpSoundConfig = options.rdpSoundConfig || null;
    this._useKeyfile = options.useKeyfile || false;
    this._externalCloudType = options.externalCloudType || null;
    this._remoteAccessSessionId = options.remoteAccessSessionId || null; // Client Data

    this._rootElement = options.rootElement;
    this._reconnectOnResize = !!options.reconnectOnResize;
    this._height = options.fitScreen ? null : options.height;
    this._width = options.fitScreen ? null : options.width;
    this._fitScreen = options.fitScreen;
    this._notSecure = options.notSecure;
    this._colorDepth = options.colorDepth;
    this._keyboardId = options.keyboardId || _controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_4__["default"].DefaultKeyboardValue;
    this._vncKeyboard = options.vncKeyboard || _controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_4__["default"].DefaultVncKeyboard;
    this._currentScale = 1;
    this._allowTlsV1 = !!options.allowTlsV1;
    this._sendTextOnPaste = !!options.sendTextOnPaste;
    this._credSSP = options.credSSP !== false;
    this._sshFontSize = options.sshFontSize;
    this._sshLineHeight = options.sshLineHeight;
    this._keyOverrides = options.keyOverrides || null;
    this._connectingTimeoutId = null;
    this._connectingTimeoutSeconds = options.connectingTimeoutSeconds || null; // TBD

    this._mouse = null;
    this._resolveDisconnect = null;
    this._resolveConnect = null;
    this._rejectConnect = null;
    this._connected = false;
    this._lastError = null;
    this.STATES = _controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"];

    this._setCurrentState(_controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"].IDLE);

    this._sanitizeHtml = this._createHtmlSanitizeFunction();
  }

  _createClass(SparkClient, [{
    key: "setupAndConnect",
    value: function setupAndConnect() {
      var _this = this;

      this.disconnect();

      this._setCurrentState(_controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"].CONNECTING);

      if (this._connectingTimeoutSeconds) {
        this._resetConnectingTimeoutId();

        this._connectingTimeoutId = setTimeout(function () {
          _this._ontimeout();

          _this.setupAndConnect();
        }, this._connectingTimeoutSeconds * 1000);
      }

      return this._injectIframeAndGetClientAdapter().then(function () {
        _this._registerToEvents();

        _this._clientAdapter.connect({
          sessionNumericId: _this._sessionNumericId,
          protocol: _this.getProtocolName(_this._protocol),
          gateway: _this._gateway,
          server: _this._server,
          port: _this._port,
          user: _this._user,
          domain: _this._domain,
          password: _this._password,
          notSecure: _this._notSecure,
          reconnectOnResize: _this._reconnectOnResize,
          colorDepth: _this._colorDepth,
          useWorker: false,
          keyboard: _this._keyboardId,
          machineId: _this._machineId,
          cursorLabel: _this._cursorLabel,
          userEmail: _this._userEmail,
          envId: _this._envId,
          classId: _this._classId,
          studentId: _this._studentId,
          node: _this._node,
          rdpWallpaper: _this._rdpWallpaper,
          rdpThemes: _this._rdpThemes,
          rdpFontSmoothing: _this._rdpFontSmoothing,
          playSound: _this._rdpSoundConfigToPlaySound(_this._rdpSoundConfig),
          soundPref: _this._rdpSoundConfigToSoundPerf(_this._rdpSoundConfig),
          allowTlsV1: _this._allowTlsV1,
          keyOverrides: _this._keyOverrides,
          useKeyfile: _this._useKeyfile,
          externalCloudType: _this._externalCloudType,
          credSSP: _this._credSSP,
          sshFontSize: _this._sshFontSize,
          sshLineHeight: _this._sshLineHeight,
          remoteAccessSessionId: _this._remoteAccessSessionId
        });
      });
    }
  }, {
    key: "disconnect",
    value: function disconnect() {
      if (this._currentState !== _controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"].IDLE) {
        this._setCurrentState(_controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"].DISCONNECTED);
      }

      if (this._clientAdapter) {
        this._clientAdapter.close();
      }

      this._rootElement.innerHTML = "";
    }
  }, {
    key: "sendText",
    value: function sendText(text) {
      var _this2 = this;

      if (this._sparkTextSender.isRunning()) {
        return;
      }

      if (this._protocol === _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].Vnc) {
        var previousInputDisabledValue = this.inputDisabled;
        this.inputDisabled = false;

        this._clientAdapter.setSurfaceReadOnly(true);

        this._sendTextPromise = this._sparkTextSender.sendText(text, this._vncKeyboard).then(function () {
          _this2._clientAdapter.setSurfaceReadOnly(false);

          _this2.inputDisabled = previousInputDisabledValue;
          _this2._sendTextPromise = null;
        });
      } else {
        this._clientAdapter.writeText(text);
      }
    }
  }, {
    key: "sendKey",
    value: function sendKey(key, down) {
      if (this._sparkTextSender.isRunning()) {
        return;
      }

      this._clientAdapter.writeKeyCode(down, key);
    }
  }, {
    key: "sendCtrlAltDelete",
    value: function sendCtrlAltDelete() {
      if (this._sparkTextSender.isRunning()) {
        return;
      }

      this._clientAdapter.writeKeyComb("Ctrl+Alt+Del", 0);
    }
  }, {
    key: "sendCtrlW",
    value: function sendCtrlW() {
      if (this._sparkTextSender.isRunning()) {
        return;
      }

      this._clientAdapter.writeKeyComb("Ctrl+w", 0);
    }
  }, {
    key: "sendNavigationAction",
    value: function sendNavigationAction(navigationAction) {
      if (!navigationAction || this._sparkTextSender.isRunning()) {
        return;
      }

      switch (navigationAction) {
        case _controls_sparkClient_navigationAction_enum__WEBPACK_IMPORTED_MODULE_9__["default"].home:
          this._clientAdapter.writeKeyComb("Alt+home", 0);

          break;

        case _controls_sparkClient_navigationAction_enum__WEBPACK_IMPORTED_MODULE_9__["default"].back:
          this._clientAdapter.writeKeyComb("Alt+left", 0);

          break;

        case _controls_sparkClient_navigationAction_enum__WEBPACK_IMPORTED_MODULE_9__["default"].forward:
          this._clientAdapter.writeKeyComb("Alt+right", 0);

          break;

        default:
          throw new Error("missing navigation type mapping");
      }
    }
  }, {
    key: "sendWindowsKey",
    value: function sendWindowsKey() {
      if (this._sparkTextSender.isRunning()) {
        return;
      }

      this._clientAdapter.writeKeyComb("windows", 0);
    }
  }, {
    key: "getThumbnail",
    value: function getThumbnail(width) {
      return this._clientAdapter.getThumbnail(width);
    }
  }, {
    key: "setClipboard",
    value: function setClipboard(text) {
      this._clientAdapter.copyToClip(text);
    }
  }, {
    key: "scale",
    value: function scale(value) {
      this._currentScale = value;

      this._scaleByMaxWidthAndHeight(this._iframeWrapperElement, value);
    }
  }, {
    key: "getScale",
    value: function getScale() {
      return this._currentScale;
    }
  }, {
    key: "getProtocolName",
    value: function getProtocolName() {
      switch (this._protocol) {
        case _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].Rdp:
          return "rdp";

        case _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].Vnc:
          return "vnc";

        case _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].Ssh:
          return "ssh";

        case _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].WebConsole:
          return "webconsole";

        default:
          return null;
      }
    }
  }, {
    key: "getElement",
    value: function getElement() {
      return this._rootElement;
    }
  }, {
    key: "setSendTextOnPaste",
    value: function setSendTextOnPaste(value) {
      this._sendTextOnPaste = value;

      if (this._clientAdapter) {
        this._clientAdapter.setSendTextOnPaste(value);
      }
    }
  }, {
    key: "getRemoteAccessSessionId",
    value: function getRemoteAccessSessionId() {
      return this._remoteAccessSessionId;
    }
  }, {
    key: "_checkOptions",
    value: function _checkOptions(options) {
      // TBD
      if (!options) {
        throw new Error('Missing options object parameter');
      }

      if (!options.hostname && !options.sessionNumericId) {
        throw new Error('Missing hostname parameter');
      }
    }
  }, {
    key: "_registerToEvents",
    value: function _registerToEvents() {
      var _this3 = this;

      if (!this._clientAdapter) {
        return;
      }

      this._clientAdapter.onclose = function () {
        console.log('onclose');

        _this3._setCurrentState(_controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"].DISCONNECTED);
      };

      this._clientAdapter.onerror = function (error) {
        console.log('onerror', error);

        _this3._onerror(new _controls_sparkError__WEBPACK_IMPORTED_MODULE_5__["default"](error), _this3);
      };

      this._clientAdapter.onloggedin = function () {
        console.log('onloggedin');

        _this3._setCurrentState(_controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"].CONNECTEDANDLOGGEDIN);
      };

      this._clientAdapter.beforeupload = function (file, path) {
        console.log('beforeupload', file, path);
      };

      this._clientAdapter.onfileuploaded = function (fileName) {
        console.log('onfileuploaded', fileName);
      };

      this._clientAdapter.onuploaded = function () {
        console.log('onuploaded');
      };

      this._clientAdapter.onsessionjoin = function (appInfo) {
        console.log('onsessionjoin', appInfo);
      };

      this._clientAdapter.onsessionexit = function (appInfo) {
        console.log('onsessionexit', appInfo);
      };

      this._clientAdapter.ongivecontrol = function (appInfo) {
        console.log('ongivecontrol', appInfo);
      };

      this._clientAdapter.ontakebackcontrol = function (appInfo) {
        console.log('ontakebackcontrol', appInfo);
      };

      this._clientAdapter.onrequirecontrol = function (appInfo) {
        console.log('onrequirecontrol', appInfo);
      };

      this._clientAdapter.onremoteappstart = function (e) {
        console.log('onremoteappstart', e);
      };

      this._clientAdapter.onactivity = function () {//console.log('onactivity', input);
      };

      this._clientAdapter.onurlredirection = function (URL) {
        console.log('onurlredirection', URL);
      };

      this._clientAdapter.ontitlechange = function (title) {
        console.log('ontitlechange', title);
      };

      this._clientAdapter.onsessionstart = function (sessionInfo) {
        console.log('onsessionstart', sessionInfo);

        _this3._setCurrentState(_controls_sparkClient_states__WEBPACK_IMPORTED_MODULE_2__["default"].CONNECTED);
      };

      this._clientAdapter.onrequestcredential = function (info) {
        console.log('onrequestcredential', info);
      };

      this._clientAdapter.onresolutionchange = function (width, height) {
        console.log('onresolutionchange', width, height);

        if (!_this3._fitScreen) {
          _this3._iframeWrapperElement.style.width = width + "px";
          _this3._iframeWrapperElement.style.height = height + "px";
        }

        _this3._onresize(width, height);
      };

      this._clientAdapter.onnoresponse = function () {
        console.log('onnoresponse');

        _this3._onerror(new _controls_sparkError__WEBPACK_IMPORTED_MODULE_5__["default"]("No response"), _this3);
      };

      this._clientAdapter.onservercopy = function (text) {
        console.log('onservercopy');

        var clipboardContent = _this3._parseOnservercopyData(text);

        _this3._onclipboard(clipboardContent);
      };

      this._clientAdapter.onautherror = function (error) {
        console.log("onautherror", error);

        _this3._onerror(new _controls_sparkError__WEBPACK_IMPORTED_MODULE_5__["default"]("Auth error"), _this3);
      };

      this._clientAdapter.onsendtextrequest = function (localClipboardText) {
        _this3.sendText(localClipboardText, _this3._vncKeyboard);
      };
    }
  }, {
    key: "_setCurrentState",
    value: function _setCurrentState(state) {
      if (this._currentState !== state) {
        this._currentState = state;

        this._onstatechange(state, this);

        console.log('state changed ' + state);

        this._resetConnectingTimeoutId();
      }
    }
  }, {
    key: "_resetConnectingTimeoutId",
    value: function _resetConnectingTimeoutId() {
      clearTimeout(this._connectingTimeoutId);
      this._connectingTimeoutId = null;
    }
  }, {
    key: "_parseOnservercopyData",
    value: function _parseOnservercopyData(text) {
      if (!text) {
        return text;
      }

      if (text.indexOf('text/plain;') === 0) {
        return text.substring('text/plain;'.length);
      } else if (text.indexOf('text/html;') === 0) {
        var html = text.substring('text/html;'.length);
        var el = document.createElement("div");
        el.innerHTML = this._sanitizeHtml(html);
        return el.textContent;
      }

      return "";
    }
  }, {
    key: "_createHtmlSanitizeFunction",
    value: function _createHtmlSanitizeFunction() {
      var config = {
        allowedTags: ["img", "h1", "h2", "span", "u", "font", "h3", "h4", "h5", "h6", "blockquote", "p", "a", "ul", "ol", "nl", "li", "b", "i", "strong", "em", "strike", "code", "hr", "br", "div", "table", "thead", "caption", "tbody", "tr", "th", "td", "pre"],
        allowedAttributes: {
          a: ["href", "name", "target"],
          img: ["src"],
          "*": ["alt", "dir", "src", "style", "href", "target", "cellpadding", "cellspacing", "id", "colspan", "class", "face", "color", "ref", "align", "lang", "border", "scope", "height", "title", "width"]
        },
        selfClosing: ["img", "br", "hr", "area", "base", "basefont", "input", "link", "meta"],
        allowedSchemes: ["http", "https", "ftp", "mailto"],
        allowedSchemesByTag: {}
      };
      return function (html) {
        return sanitize_html__WEBPACK_IMPORTED_MODULE_0___default()(html, config);
      };
    }
  }, {
    key: "_injectIframeAndGetClientAdapter",
    value: function _injectIframeAndGetClientAdapter() {
      var _this4 = this;

      return new Promise(function (resolve) {
        _this4._iframeWrapperElement = _this4._createIframeWrapper();

        var verticalAlignerElement = _this4._createVerticalAligner();

        var iframeElement = _this4._createIframe(resolve);

        _this4._iframeWrapperElement.appendChild(iframeElement);

        _this4._rootElement.innerHTML = "";

        _this4._rootElement.appendChild(_this4._iframeWrapperElement);

        _this4._rootElement.appendChild(verticalAlignerElement);
      });
    }
  }, {
    key: "_createIframeWrapper",
    value: function _createIframeWrapper() {
      var iframeWrapper = document.createElement("div");
      iframeWrapper.style.transformOrigin = "center 0";
      iframeWrapper.style.WebkitTransformOrigin = "center 0";
      iframeWrapper.style.MozTransformOrigin = "center 0";
      iframeWrapper.style.MsTransformOrigin = "center 0";
      iframeWrapper.style.minWidth = "80px";
      iframeWrapper.style.minHeight = "80px";

      if (this._fitScreen) {
        iframeWrapper.style.width = "100%";
        iframeWrapper.style.height = "100%";
      } else if (this._width && this._height) {
        iframeWrapper.style.width = this._width + "px";
        iframeWrapper.style.height = this._height + "px";
      } else {
        iframeWrapper.style.width = "700px";
        iframeWrapper.style.height = "500px";
      }

      if (this._sessionNumericId != null) {
        iframeWrapper.style.maxWidth = "100%";
        iframeWrapper.style.maxHeight = "100%";
      }

      iframeWrapper.style.display = "inline-block";
      iframeWrapper.style.position = "relative";
      iframeWrapper.style.verticalAlign = "middle";
      return iframeWrapper;
    }
  }, {
    key: "_createIframe",
    value: function _createIframe(resolve) {
      var _this5 = this;

      var iframe = document.createElement("iframe");
      iframe.setAttribute("telemetry-input", "spark-client-iframe");
      iframe.style.width = "100%";
      iframe.style.height = "100%";
      iframe.style.border = "none";
      iframe.style.position = "absolute";
      iframe.style.top = "0";
      iframe.style.left = "0";
      iframe.src = _iframe_sparkClient_iframe_files__WEBPACK_IMPORTED_MODULE_1__["default"];
      iframe.addEventListener("load", function () {
        var iframeWindow = iframe.contentWindow;
        _this5._clientAdapter = new iframeWindow.SparkClientAdapter(_this5._inputDisabled, _this5._sendTextOnPaste, _this5._keyOverrides);
        _this5._sparkTextSender = new _controls_sparkTextSender__WEBPACK_IMPORTED_MODULE_7__["default"](_this5._clientAdapter);

        _this5._clientAdapter.listenOnReady(function () {
          resolve(_this5._clientAdapter);
        });
      });
      Object(Common_Libraries_common_libraries_propogateIframeEvents__WEBPACK_IMPORTED_MODULE_8__["default"])(iframe);
      return iframe;
    }
  }, {
    key: "_createVerticalAligner",
    value: function _createVerticalAligner() {
      var div = document.createElement("div");
      div.style.display = "inline-block";
      div.style.height = "100%";
      div.style.verticalAlign = "middle";
      return div;
    }
  }, {
    key: "_getDefaultProtocolPort",
    value: function _getDefaultProtocolPort(protocolNumber) {
      switch (protocolNumber) {
        case _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].Rdp:
          return 3389;

        case _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].Vnc:
          return 5901;

        case _controls_sparkClient_protocols__WEBPACK_IMPORTED_MODULE_3__["default"].Ssh:
          return 22;
      }
    }
  }, {
    key: "_scaleByMaxWidthAndHeight",
    value: function _scaleByMaxWidthAndHeight(element, scale) {
      var elementRect = element.getBoundingClientRect();
      element.style.maxWidth = "".concat(elementRect.width * scale | 0, "px");
      element.style.maxHeight = "".concat(elementRect.height * scale | 0, "px");
    }
  }, {
    key: "_rdpSoundConfigToPlaySound",
    value: function _rdpSoundConfigToPlaySound(rdpSoundConfig) {
      switch (rdpSoundConfig) {
        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].enabledOnRemoteOnly:
          return 2;

        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].enabledLowQuality:
        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].enabledHighQuality:
          return 0;

        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].disabled:
        default:
          return 1;
      }
    }
  }, {
    key: "_rdpSoundConfigToSoundPerf",
    value: function _rdpSoundConfigToSoundPerf(rdpSoundConfig) {
      switch (rdpSoundConfig) {
        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].enabledHighQuality:
          return 1;

        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].enabledLowQuality:
        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].enabledOnRemoteOnly:
        case _controls_sparkClient_soundConfig_enum__WEBPACK_IMPORTED_MODULE_6__["default"].disabled:
        default:
          return 0;
      }
    }
  }, {
    key: "reconnectOnResize",
    get: function get() {
      if (this._clientAdapter) {
        return this._clientAdapter.getReconnectOnResize();
      }

      return false;
    },
    set: function set(val) {
      this._reconnectOnResize = val;

      this._clientAdapter.setReconnectOnResize(val);

      this._clientAdapter.pause();
    }
  }, {
    key: "hostname",
    get: function get() {
      return this._gateway;
    }
  }, {
    key: "inputDisabled",
    get: function get() {
      return this._inputDisabled;
    },
    set: function set(val) {
      var _this6 = this;

      if (this._sparkTextSender && this._sparkTextSender.isRunning()) {
        this._sendTextPromise.then(function () {
          _this6.inputDisabled = val;
        });

        return;
      }

      this._inputDisabled = val;

      if (this._clientAdapter) {
        this._clientAdapter.setInputDisabled(val);
      }
    }
  }, {
    key: "currentState",
    get: function get() {
      return this._currentState;
    }
  }]);

  return SparkClient;
}();

/* harmony default export */ __webpack_exports__["default"] = (SparkClient);

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.keyCombMap.js":
/*!*********************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.keyCombMap.js ***!
  \*********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony default export */ __webpack_exports__["default"] = ({
  "us": {
    "~": "Shift+`",
    "!": "Shift+1",
    "@": "Shift+2",
    "#": "Shift+3",
    "$": "Shift+4",
    "%": "Shift+5",
    "^": "Shift+6",
    "&": "Shift+7",
    "*": "Shift+8",
    "(": "Shift+9",
    ")": "Shift+0",
    "_": "Shift+-",
    "+": "Shift+=",
    "{": "Shift+[",
    "}": "Shift+]",
    "|": "Shift+\\",
    ":": "Shift+;",
    "\"": "Shift+'",
    "<": "Shift+,",
    ">": "Shift+.",
    "?": "Shift+/",
    "A": "Shift+a",
    "B": "Shift+b",
    "C": "Shift+c",
    "D": "Shift+d",
    "E": "Shift+e",
    "F": "Shift+f",
    "G": "Shift+g",
    "H": "Shift+h",
    "I": "Shift+i",
    "J": "Shift+j",
    "K": "Shift+k",
    "L": "Shift+l",
    "M": "Shift+m",
    "N": "Shift+n",
    "O": "Shift+o",
    "P": "Shift+p",
    "Q": "Shift+q",
    "R": "Shift+r",
    "S": "Shift+s",
    "T": "Shift+t",
    "U": "Shift+u",
    "V": "Shift+v",
    "W": "Shift+w",
    "X": "Shift+x",
    "Y": "Shift+y",
    "Z": "Shift+z"
  },
  "fr-be": {
    "1": "Shift+&",
    "2": "Shift+2",
    "3": "Shift+\"",
    "4": "Shift+'",
    "5": "Shift+(",
    "6": "Shift+§",
    "7": "Shift+7",
    "8": "Shift+!",
    "9": "Shift+9",
    "0": "Shift+0",
    "°": "Shift+)",
    "_": "Shift+-",
    "*": "Shift+$",
    "£": "Shift+\\",
    "%": "Shift+'",
    "³": "Shift+²",
    "?": "Shift+,",
    ".": "Shift+;",
    "/": "Shift+:",
    "+": "Shift+=",
    ">": "Shift+<",
    "A": "Shift+a",
    "B": "Shift+b",
    "C": "Shift+c",
    "D": "Shift+d",
    "E": "Shift+e",
    "F": "Shift+f",
    "G": "Shift+g",
    "H": "Shift+h",
    "I": "Shift+i",
    "J": "Shift+j",
    "K": "Shift+k",
    "L": "Shift+l",
    "M": "Shift+m",
    "N": "Shift+n",
    "O": "Shift+o",
    "P": "Shift+p",
    "Q": "Shift+q",
    "R": "Shift+r",
    "S": "Shift+s",
    "T": "Shift+t",
    "U": "Shift+u",
    "V": "Shift+v",
    "W": "Shift+w",
    "X": "Shift+x",
    "Y": "Shift+y",
    "Z": "Shift+z",
    "|": "AltGr+&",
    "@": "AltGr+2",
    "#": "AltGr+\"",
    "{": "AltGr+9",
    "}": "AltGr+0",
    "€": "AltGr+e",
    "[": "AltGr+[",
    // doesn't work with VMWare VNC
    "]": "AltGr+]",
    "~": ["AltGr+=", "Space"],
    "`": ["AltGr+\\", "Space"],
    // doesn't work with VMWare VNC
    "´": ["AltGr+`", "Space"] // doesn't work with VMWare VNC

  }
});

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.keyboards.js":
/*!********************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.keyboards.js ***!
  \********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony default export */ __webpack_exports__["default"] = ({
  "Unicode (Universal QWERTY)": 99999,
  "Unicode (Universal AZERTY)": 99998,
  "Unicode (Universal QWERTZ)": 99997,
  "English (United States)": 1033,
  "English (United Kingdom)": 2057,
  "English (Canadian French)": 4105,
  "Arabic (Saudi Arabia)": 1025,
  "Chinese (Simplified)": 2052,
  "Chinese (Traditional)": 1028,
  "Dutch (Belgium)": 2067,
  "Dutch (Netherlands)": 1043,
  "French (Belgium)": 2060,
  "French (Canada Legacy)": 3084,
  "French (France)": 1036,
  "French (Switzerland)": 4108,
  "German (Germany)": 1031,
  "German (Switzerland)": 2055,
  "German (IBM)": 66567,
  "Hebrew": 1037,
  "Icelandic": 1039,
  "Irish (Ireland)": 6153,
  "Italian (Italy)": 1040,
  "Italian (142) (Italy)": 66576,
  "Japanese (Japan)": 3758162961,
  "Korean (Korea)": 3758162962,
  "Norwegian (Bokmal)": 1044,
  "Norwegian with Sami": 1083,
  "Portuguese": 2070,
  "Portuguese (Brazil ABNT)": 1046,
  "Portuguese (Brazil ABNT2)": 66582,
  "Russian (Russia)": 1049,
  "Spanish (International Sort)": 1034,
  "Spanish (Variation)": 66570,
  "Spanish (Mexico/Latin American)": 2058,
  "Swedish (Sweden)": 1053,
  "Turkish": 1055
});

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.navigationAction.enum.js":
/*!********************************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.navigationAction.enum.js ***!
  \********************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony default export */ __webpack_exports__["default"] = ({
  home: 1,
  // i started at 1 because I dont want the value of 0 which is falsey
  back: 2,
  forward: 3
});

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.protocols.js":
/*!********************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.protocols.js ***!
  \********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
var SparkProtocols = {
  Rdp: 0,
  Vnc: 1,
  Ssh: 2,
  Telnet: 3,
  WebConsole: 4
};
/* harmony default export */ __webpack_exports__["default"] = (SparkProtocols);

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.soundConfig.enum.js":
/*!***************************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.soundConfig.enum.js ***!
  \***************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony default export */ __webpack_exports__["default"] = ({
  disabled: "Disabled",
  enabledOnRemoteOnly: "EnabledOnRemoteOnly",
  enabledLowQuality: "EnabledLowQuality",
  enabledHighQuality: "EnabledHighQuality"
});

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkClient.states.js":
/*!*****************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkClient.states.js ***!
  \*****************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
var SparkStates = {
  IDLE: 0,
  CONNECTING: 1,
  WAITING: 2,
  CONNECTED: 3,
  DISCONNECTING: 4,
  DISCONNECTED: 5,
  CONNECTEDANDLOGGEDIN: 6
};
/* harmony default export */ __webpack_exports__["default"] = (SparkStates);

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkError.js":
/*!*********************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkError.js ***!
  \*********************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var exports_loader_window_getSparkI18n_imports_loader_windows_this_externals_SparkModule_strings_en__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! exports-loader?window.getSparkI18n!imports-loader?windows=>this!../../../externals/SparkModule/strings-en */ "./node_modules/exports-loader/index.js?window.getSparkI18n!./node_modules/imports-loader/index.js?windows=>this!./externals/SparkModule/strings-en.js");
/* harmony import */ var exports_loader_window_getSparkI18n_imports_loader_windows_this_externals_SparkModule_strings_en__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(exports_loader_window_getSparkI18n_imports_loader_windows_this_externals_SparkModule_strings_en__WEBPACK_IMPORTED_MODULE_0__);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }



var SparkError =
/*#__PURE__*/
function () {
  function SparkError(onErrorArg) {
    _classCallCheck(this, SparkError);

    this._onErrorArg = onErrorArg;
    this.sparkStrings = exports_loader_window_getSparkI18n_imports_loader_windows_this_externals_SparkModule_strings_en__WEBPACK_IMPORTED_MODULE_0___default()();
  }

  _createClass(SparkError, [{
    key: "toLogString",
    value: function toLogString() {
      var arg = this._onErrorArg;

      if (arg && arg.name && arg.message != null) {
        var untranslatedMessage = this.sparkStrings.errorCode[arg.name] || this.sparkStrings.errorCode["S" + arg.name];

        if (!untranslatedMessage || untranslatedMessage === arg.message) {
          return "Status(".concat(arg.name, ", ").concat(arg.message, ")");
        } else {
          return "Status(".concat(arg.name, ", ").concat(arg.message, ", ").concat(untranslatedMessage, ")");
        }
      } else if (typeof arg === "string") {
        return arg;
      } else if (arg) {
        return JSON.stringify(arg);
      } else {
        return "";
      }
    }
  }, {
    key: "shouldReconnect",
    value: function shouldReconnect() {
      var errorCode = this._onErrorArg && this._onErrorArg.name;
      return !errorCode || !preventAutoReconnectErrorCodes[errorCode];
    }
  }, {
    key: "toClientString",
    value: function toClientString() {
      var arg = this._onErrorArg;

      if (arg && arg.message) {
        return arg.message;
      } else {
        return "";
      }
    }
  }]);

  return SparkError;
}();

var preventAutoReconnectErrorCodes = {
  '5': 'Another user connected to the server, forcing the disconnection of the current connection.',
  '9': 'The user cannot connect to the server due to insufficient access privileges.',
  'C': 'The disconnection was initiated by the user logging off his or her session on the server.'
};
/* harmony default export */ __webpack_exports__["default"] = (SparkError);

/***/ }),

/***/ "./src/Controls/SparkClient/controls.sparkTextSender.js":
/*!**************************************************************!*\
  !*** ./src/Controls/SparkClient/controls.sparkTextSender.js ***!
  \**************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _controls_sparkClient_keyCombMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./controls.sparkClient.keyCombMap */ "./src/Controls/SparkClient/controls.sparkClient.keyCombMap.js");
/* harmony import */ var _controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controls.sparkClient.constants */ "./src/Controls/SparkClient/controls.sparkClient.constants.js");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }



var maxTextSize = 1024;
var longTextThreshold = 100;
var longTextWaitMs = 500;
var shortTextWaitMs = 1;

var SparkTextSender =
/*#__PURE__*/
function () {
  function SparkTextSender(clientAdapter) {
    _classCallCheck(this, SparkTextSender);

    this._clientAdapter = clientAdapter;
    this._running = false;
  }

  _createClass(SparkTextSender, [{
    key: "sendText",
    value: function sendText(text, keyboard) {
      var _this = this;

      this._running = true;
      return new StatefulSparkTextSender(this._clientAdapter, text, keyboard).sendText().then(function () {
        _this._running = false;
      });
    }
  }, {
    key: "isRunning",
    value: function isRunning() {
      return this._running;
    }
  }]);

  return SparkTextSender;
}();

var StatefulSparkTextSender =
/*#__PURE__*/
function () {
  function StatefulSparkTextSender(clientAdapter, text, keyboard) {
    _classCallCheck(this, StatefulSparkTextSender);

    this._clientAdapter = clientAdapter;
    this._text = text;
    this._keyboard = keyboard || _controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_1__["default"].DefaultVncKeyboard;
    this._orderIndex = 0;
    this._orders = [];
    this._textAccum = "";
  }

  _createClass(StatefulSparkTextSender, [{
    key: "sendText",
    value: function sendText() {
      var _this2 = this;

      return new Promise(function (resolve) {
        _this2._fillOrdersArray();

        _this2._execOrderInDelay(resolve);
      }).catch(function () {// ignore exceptions
      });
    }
  }, {
    key: "_fillOrdersArray",
    value: function _fillOrdersArray() {
      var _this3 = this;

      for (var i = 0; i < this._text.length; ++i) {
        var c = this._text[i];

        var keyComb = this._toKeyComb(c);

        if (c === "\n") {
          this._flushTextAccum();

          this._orders.push({
            keyComb: true,
            content: "Enter"
          });
        } else if (keyComb) {
          this._flushTextAccum();

          if (typeof keyComb === "string") {
            this._orders.push({
              keyComb: true,
              content: keyComb
            });
          } else {
            keyComb.forEach(function (kc) {
              _this3._orders.push({
                keyComb: true,
                content: kc
              });
            });
          }
        } else {
          this._textAccum += c;

          if (this._textAccum.length === maxTextSize) {
            this._flushTextAccum();
          }
        }
      }

      this._flushTextAccum();
    }
  }, {
    key: "_flushTextAccum",
    value: function _flushTextAccum() {
      if (this._textAccum.length === 0) {
        return;
      }

      this._orders.push({
        keyComb: false,
        content: this._textAccum
      });

      this._textAccum = "";
    }
  }, {
    key: "_execOrder",
    value: function _execOrder(callback) {
      var order = this._orders[this._orderIndex];

      if (order.keyComb) {
        this._clientAdapter.writeKeyComb(order.content, 0);
      } else {
        this._clientAdapter.writeText(order.content);
      }

      if (this._orderIndex < this._orders.length - 1) {
        this._orderIndex += 1;

        if (order.content.length > longTextThreshold) {
          this._execOrderInDelay(callback, longTextWaitMs);
        } else {
          this._execOrderInDelay(callback, shortTextWaitMs);
        }
      } else if (callback) {
        callback();
      }
    }
  }, {
    key: "_execOrderInDelay",
    value: function _execOrderInDelay(callback, delayMs) {
      var _this4 = this;

      setTimeout(function () {
        try {
          _this4._execOrder(callback);
        } catch (e) {
          // ignore exceptions
          if (callback) {
            callback();
          }
        }
      }, delayMs);
    }
  }, {
    key: "_toKeyComb",
    value: function _toKeyComb(c) {
      var map = _controls_sparkClient_keyCombMap__WEBPACK_IMPORTED_MODULE_0__["default"][this._keyboard] || _controls_sparkClient_keyCombMap__WEBPACK_IMPORTED_MODULE_0__["default"][_controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_1__["default"].DefaultVncKeyboard];
      return map[c];
    }
  }]);

  return StatefulSparkTextSender;
}();

/* harmony default export */ __webpack_exports__["default"] = (SparkTextSender);

/***/ }),

/***/ "./src/Controls/SparkClient/iframe/sparkClient.iframe.files.js":
/*!*********************************************************************!*\
  !*** ./src/Controls/SparkClient/iframe/sparkClient.iframe.files.js ***!
  \*********************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_html__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!./sparkClient.iframe.html */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.html");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_html__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_sparkClient_iframe_html__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_adapter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!./sparkClient.iframe.adapter */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.adapter.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_adapter__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_sparkClient_iframe_adapter__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_wmksKeyCodeMap__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!./sparkClient.iframe.wmksKeyCodeMap */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.wmksKeyCodeMap.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_wmksKeyCodeMap__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_sparkClient_iframe_wmksKeyCodeMap__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_wmksVscanCodeMap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!./sparkClient.iframe.wmksVscanCodeMap */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./src/Controls/SparkClient/iframe/sparkClient.iframe.wmksVscanCodeMap.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_sparkClient_iframe_wmksVscanCodeMap__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_sparkClient_iframe_wmksVscanCodeMap__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/hi5.css */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5.css");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5_css__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5_css__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdp_css__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/rdp.css */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdp.css");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdp_css__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdp_css__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_kbd_png__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/kbd.png */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/kbd.png");
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_kbd_png__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_file_loader_name_sparkIframe_name_ext_externals_SparkModule_kbd_png__WEBPACK_IMPORTED_MODULE_6__);
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_cloud_png__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! !file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/cloud.png */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/cloud.png");
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_cloud_png__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_file_loader_name_sparkIframe_name_ext_externals_SparkModule_cloud_png__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_info_png__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! !file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/info.png */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/info.png");
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_info_png__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_file_loader_name_sparkIframe_name_ext_externals_SparkModule_info_png__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_handle_png__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! !file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/handle.png */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/handle.png");
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_handle_png__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_file_loader_name_sparkIframe_name_ext_externals_SparkModule_handle_png__WEBPACK_IMPORTED_MODULE_9__);
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_del_png__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! !file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/del.png */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/del.png");
/* harmony import */ var _file_loader_name_sparkIframe_name_ext_externals_SparkModule_del_png__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_file_loader_name_sparkIframe_name_ext_externals_SparkModule_del_png__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_resource__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/resource */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/resource.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_resource__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_resource__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_strings_en__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/strings-en */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/strings-en.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_strings_en__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_strings_en__WEBPACK_IMPORTED_MODULE_12__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_appcfg__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/appcfg */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/appcfg.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_appcfg__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_appcfg__WEBPACK_IMPORTED_MODULE_13__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5core_min__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/hi5core_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5core_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5core_min__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5core_min__WEBPACK_IMPORTED_MODULE_14__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5_min__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/hi5_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/hi5_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5_min__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_hi5_min__WEBPACK_IMPORTED_MODULE_15__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_surface_min__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/surface_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/surface_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_surface_min__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_surface_min__WEBPACK_IMPORTED_MODULE_16__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdpcore_min__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/rdpcore_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdpcore_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdpcore_min__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdpcore_min__WEBPACK_IMPORTED_MODULE_17__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdp_min__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/rdp_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdp_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdp_min__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdp_min__WEBPACK_IMPORTED_MODULE_18__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdpworker_min__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/rdpworker_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/rdpworker_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdpworker_min__WEBPACK_IMPORTED_MODULE_19___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_rdpworker_min__WEBPACK_IMPORTED_MODULE_19__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_ssh_min__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/ssh_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/ssh_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_ssh_min__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_ssh_min__WEBPACK_IMPORTED_MODULE_20__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vnc_min__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/vnc_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vnc_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vnc_min__WEBPACK_IMPORTED_MODULE_21___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_vnc_min__WEBPACK_IMPORTED_MODULE_21__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vncutil_min__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/vncutil_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vncutil_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vncutil_min__WEBPACK_IMPORTED_MODULE_22___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_vncutil_min__WEBPACK_IMPORTED_MODULE_22__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_wmks_min__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/vmware/wmks.min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/wmks.min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_wmks_min__WEBPACK_IMPORTED_MODULE_23___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_wmks_min__WEBPACK_IMPORTED_MODULE_23__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_jquery_3_4_1_min__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/vmware/jquery-3.4.1.min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/jquery-3.4.1.min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_jquery_3_4_1_min__WEBPACK_IMPORTED_MODULE_24___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_jquery_3_4_1_min__WEBPACK_IMPORTED_MODULE_24__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_jquery_ui_1_12_0_min__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/vmware/jquery-ui-1.12.0.min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/vmware/jquery-ui-1.12.0.min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_jquery_ui_1_12_0_min__WEBPACK_IMPORTED_MODULE_25___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_vmware_jquery_ui_1_12_0_min__WEBPACK_IMPORTED_MODULE_25__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_recording_min__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/recording_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/recording_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_recording_min__WEBPACK_IMPORTED_MODULE_26___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_recording_min__WEBPACK_IMPORTED_MODULE_26__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_plugin_swf__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/plugin.swf */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/plugin.swf");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_plugin_swf__WEBPACK_IMPORTED_MODULE_27___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_plugin_swf__WEBPACK_IMPORTED_MODULE_27__);
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_audiorecorder_min__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! file-loader?name=sparkIframe/[name].[ext]!../../../../externals/SparkModule/audiorecorder_min */ "./node_modules/file-loader/dist/cjs.js?name=sparkIframe/[name].[ext]!./externals/SparkModule/audiorecorder_min.js");
/* harmony import */ var file_loader_name_sparkIframe_name_ext_externals_SparkModule_audiorecorder_min__WEBPACK_IMPORTED_MODULE_28___default = /*#__PURE__*/__webpack_require__.n(file_loader_name_sparkIframe_name_ext_externals_SparkModule_audiorecorder_min__WEBPACK_IMPORTED_MODULE_28__);





























/* harmony default export */ __webpack_exports__["default"] = (file_loader_name_sparkIframe_name_ext_sparkClient_iframe_html__WEBPACK_IMPORTED_MODULE_0___default.a);

/***/ }),

/***/ "./src/Controls/SparkClient/index.deploy.js":
/*!**************************************************!*\
  !*** ./src/Controls/SparkClient/index.deploy.js ***!
  \**************************************************/
/*! exports provided: SparkClient, SparkKeyboards, SparkConstants */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _controls_sparkClient__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./controls.sparkClient */ "./src/Controls/SparkClient/controls.sparkClient.js");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SparkClient", function() { return _controls_sparkClient__WEBPACK_IMPORTED_MODULE_0__["default"]; });

/* harmony import */ var _controls_sparkClient_keyboards__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controls.sparkClient.keyboards */ "./src/Controls/SparkClient/controls.sparkClient.keyboards.js");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SparkKeyboards", function() { return _controls_sparkClient_keyboards__WEBPACK_IMPORTED_MODULE_1__["default"]; });

/* harmony import */ var _controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controls.sparkClient.constants */ "./src/Controls/SparkClient/controls.sparkClient.constants.js");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SparkConstants", function() { return _controls_sparkClient_constants__WEBPACK_IMPORTED_MODULE_2__["default"]; });






/***/ }),

/***/ 0:
/*!**********************!*\
  !*** util (ignored) ***!
  \**********************/
/*! no static exports found */
/***/ (function(module, exports) {

/* (ignored) */

/***/ }),

/***/ 1:
/*!*********************************!*\
  !*** readable-stream (ignored) ***!
  \*********************************/
/*! no static exports found */
/***/ (function(module, exports) {

/* (ignored) */

/***/ })

/******/ });
//# sourceMappingURL=spark-client.js.map
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2).Buffer))

/***/ }),
/* 141 */
/***/ (function(module, exports, __webpack_require__) {

var Bottle = __webpack_require__(13);
var bottle = new Bottle();

bottle.factory('CloudShareClient', function() { return __webpack_require__(12); });
bottle.service('SymkeyService', __webpack_require__(144));
bottle.service('CloudShareSpark', __webpack_require__(142), 'CloudShareClient');

module.exports = bottle;

/***/ }),
/* 142 */
/***/ (function(module, exports, __webpack_require__) {

var Promise = __webpack_require__(5).Promise;
var SparkStates = __webpack_require__(143);
var SparkClient = __webpack_require__(140);

function CloudShareSpark(csclient) {
	this.csclient = csclient;
	this.sparkClients = {};
	this.STATES = SparkStates;
	this.KEYBOARDS = SparkClient.SparkKeyboards;
	this.CONSTANTS = SparkClient.SparkConstants;
	this._optionsPerClient = {};
	this.connectionAttemptsCount = 0;
	this.MAX_CONNECTION_ATTEMPTS_NUM = 12;
	this.IDLE_TIME_BETWEEN_CONNECTION_ATTEMPTS_SEC = 5;
}

CloudShareSpark.prototype.connect = function(options) {
	var self = this;
	return new Promise(function(resolve) {
		checkOptions(options);
		if (!isClientConnected(self, options.id)){
		  self.connectionAttemptsCount = 0;
			resolve(requestPasswordAndConnect(self, options));
		} else
			resolve();
	});
};

CloudShareSpark.prototype.disconnect = function(id) {
	var self = this;
	return new Promise(function(resolve) {
		var client = self.sparkClients[id];
		if (client) {
			client.disconnect();
		}
		setTimeout(resolve, 500);
	});
};

CloudShareSpark.prototype.setClipboard = function(id, text) {
	var client = this.sparkClients[id];
	if (client)
		client.setClipboard(text);
};

CloudShareSpark.prototype.sendText = function(id, text) {
	var client = this.sparkClients[id];
	if (!client)
		return;

	client.sendText(text);
};

CloudShareSpark.prototype.sendCtrlAltDelete = function(id) {
	var client = this.sparkClients[id];
	if (!client)
		return;
	client.sendCtrlAltDelete();
}

CloudShareSpark.prototype.sendCtrlW = function(id) {
	var client = this.sparkClients[id];
	if (!client)
		return;
	client.sendCtrlW();
}

CloudShareSpark.prototype.sendWindowsKey = function(id) {
	var client = this.sparkClients[id];
	if (!client)
		return;
	client.sendWindowsKey();
}

CloudShareSpark.prototype.resize = function(id, width, height) {
	var client = this.sparkClients[id];

	var options = this._optionsPerClient[id];
	if (client && options) {
		options.width = width;
		options.height = height;

		this.connect(options);
	}
};

CloudShareSpark.prototype.scale = function(id, scale) {
	var client = this.sparkClients[id];
	if (client)
		client.scale(scale);
};

CloudShareSpark.prototype.getScale = function(id) {
	var client = this.sparkClients[id];
	if (client)
		return client.getScale();
	else
		return 1;
};

CloudShareSpark.prototype.getShareProtocol = function(id) {
	var client = this.sparkClients[id];
	if (client)
		return client.getProtocolName();
	else
		return null;
};

CloudShareSpark.prototype.getFlattenedCanvas = function(id) {
	var client = this.sparkClients[id];
	if (client)
		return {
			toDataURL: function() {
				return client.getThumbnail(400); // TBD - take width from configuration
			}
		};
};

CloudShareSpark.prototype.disableInputs = function(id) {
	var client = this.sparkClients[id];
	if (client)
		client.inputDisabled = true;
};

CloudShareSpark.prototype.enableInputs = function(id) {
	var client = this.sparkClients[id];
	if (client)
		client.inputDisabled = false;
};

CloudShareSpark.prototype.getConnectionType = function(id) {

	if (id === null || id === undefined || !(this.sparkClients[id]))
		return null;

	return 'WebSocket';
};

CloudShareSpark.prototype.setSendTextOnPaste = function(id, value) {
	var client = this.sparkClients[id];
	if (client)
		client.setSendTextOnPaste(value);
};

function requestPasswordAndConnect(self, options) {
	return requestPassword(self, options)
		.then(function(response) {

			_mergeClientSideData(options, response.content);

			response.content.containerElement = options.containerElement;
			response.content.rootElement = options.containerElement;
			response.content.id = options.id;
			response.content.machineId = options.connectionConfiguration.machineToken;
			response.content.envId = options.connectionConfiguration.envId;
			response.content.classId = options.connectionConfiguration.classId;
			response.content.studentId = options.connectionConfiguration.studentId;
			response.content.userEmail = options.connectionConfiguration.userEmail;
			response.content.keyboardId = options.connectionConfiguration.keyboardId;
			response.content.cursorLabel = options.connectionConfiguration.cursorLabel;
			
			var client = createNewSparkClient(self,
				response.content,
				response.content.host,
				response.content.httpFallBackHost,
				response.content.protocol);

			self._optionsPerClient[options.id] = response.content;

			return client.setupAndConnect();
		})
		.catch(function (){
			// This catch with retry attempts was added, 
			// to handle the case where a connect attempt fails because it's made before the student (viewer) managed to connect to the machine. 
		
			if (self.connectionAttemptsCount < self.MAX_CONNECTION_ATTEMPTS_NUM){
				setTimeout(() => {
					self.connectionAttemptsCount++;
					return requestPasswordAndConnect(self, options);
				}, self.IDLE_TIME_BETWEEN_CONNECTION_ATTEMPTS_SEC * 1000);
			}
		});
}

function _mergeClientSideData(from, to) {
	to.width = from.connectionConfiguration.parameters.width;
	to.height = from.connectionConfiguration.parameters.height;
	to.colorDepth = from.connectionConfiguration.parameters["color-depth"];
	to.fitScreen = from.connectionConfiguration.parameters.fitScreen;
	to.rdpSoundConfig = from.connectionConfiguration.rdpSoundConfig;
	to.sendTextOnPaste = from.connectionConfiguration.sendTextOnPaste;
	to.allowTlsV1 = from.connectionConfiguration.parameters.allowTlsV1;
	to.useKeyfile = from.connectionConfiguration.parameters.useKeyfile;
	to.disableInput = from.disableInput;
	to.onstatechange = from.onstatechange;
	to.onerror = from.onerror;
	to.onclipboard = from.onclipboard;
	to.onresize = from.onresize;
	to.ontimeout = from.ontimeout;
	to.credSSP = from.connectionConfiguration.parameters.credSSP;
	to.sshFontSize = from.connectionConfiguration.parameters.sshFontSize;
	to.sshLineHeight = from.connectionConfiguration.parameters.sshLineHeight;
}

function isClientConnected(self, id) {
	var client = self.sparkClients[id];
	if (!client)
		return false;
	return client.currentState === SparkStates.CONNECTING ||
		client.currentState === SparkStates.WAITING ||
		client.currentState === SparkStates.CONNECTED ||
		client.currentState === SparkStates.CONNECTEDANDLOGGEDIN;
}

function createNewSparkClient(self, options, overrideHostname, overrideHttpHostname, shareProtocol) {
	if (self.sparkClients[options.id]) {
		self.disconnect(options.id);
		self.sparkClients[options.id] = undefined;
	}

	var client = createSparkClient(self, options, overrideHostname, overrideHttpHostname, shareProtocol);
	self.sparkClients[options.id] = client;
	self.lastUsedHostName = client.hostname;

	return self.sparkClients[options.id];
}

function createSparkClient(self, options, overrideHostname, overrideHttpHostname, shareProtocol) {
	return new SparkClient.SparkClient(options);
}

function requestPassword(self, options) {
	return self.csclient.req({
		hostname: options.cloudShareHostname,
		method: 'POST',
		path: 'RemoteAccessConnection',
		apiId: options.apiId,
		apiKey: options.apiKey,
		content: options.connectionConfiguration
	});
}

function checkOptions(options) {
	if (!options)
		throw new Error('Missing options');
	else if (options.id !== 0 && !options.id)
		throw new Error('Missing ID parameter');
	else if (!options.hostname)
		throw new Error('Missing hostname parameter');
	else if (!options.containerElement)
		throw new Error('Missing containerElement parameter');
	else if (!options.connectionConfiguration)
		throw new Error('Missing connectionConfiguration parameter');
	else if (!options.cloudShareHostname)
		throw new Error('Missing cloudShareHostname parameter');
}

function sendKeyStrokes(client, keyStrokes) {
	for (var i = 0; i < keyStrokes.length; ++i) {
		var k = keyStrokes[i];
		if (k.isDown)
			client.sendSymkeyDown(k.symkey);
		else
			client.sendSymkeyUp(k.symkey);
	}
}

module.exports = CloudShareSpark;

/***/ }),
/* 143 */
/***/ (function(module, exports) {

module.exports = {
	IDLE: 0,
	CONNECTING: 1,
	WAITING: 2,
	CONNECTED: 3,
	DISCONNECTING: 4,
	DISCONNECTED: 5,
	CONNECTEDANDLOGGEDIN: 6
};

/***/ }),
/* 144 */
/***/ (function(module, exports) {

function SymkeyService() {
	
}

SymkeyService.prototype.toSymKey = function(text) {
	var charcode = text.charCodeAt(0);
	if (isControlCharacter(charcode))
		return 0xFF00 | charcode;
	if (isASCII(charcode))
		return charcode;
	if (isUnicodeCharacter(charcode))
		return 0x01000000 | charcode;
	return null;
};

function isASCII(charcode) {
	return charcode >= 0x00 && charcode <= 0xFF;
}

function isControlCharacter(charcode) {
    return charcode <= 0x1F || (charcode >= 0x7F && charcode <= 0x9F);
}

function isUnicodeCharacter(charcode) {
	return charcode > 0xFF && charcode < 0x110000;
}

module.exports = SymkeyService;

/***/ }),
/* 145 */
/***/ (function(module, exports) {

/* (ignored) */

/***/ }),
/* 146 */
/***/ (function(module, exports) {

/* (ignored) */

/***/ }),
/* 147 */
/***/ (function(module, exports) {

/* (ignored) */

/***/ }),
/* 148 */
/***/ (function(module, exports, __webpack_require__) {

 var HtmlSanitizer = __webpack_require__(45);

window.cs = window.cs || {};

if (!window.cs.sparkclient)
	window.cs.sparkclient = __webpack_require__(46);

if (!window.cs.csclient)
	window.cs.csclient = __webpack_require__(12);

window.cs.guacclient = __webpack_require__(43);
window.cs.chocolateyclient = __webpack_require__(40);
window.cs.heartbeatsoverws = __webpack_require__(44);

if (!window.cs.tourService)
	window.cs.tourService = __webpack_require__(41);

if (!window.cs.htmlSanitizer)
	window.cs.htmlSanitizer = new HtmlSanitizer();

if (!window.cs.csws) {
	window.cs.csws = __webpack_require__(25).csws;
}

if (!window.cs.connectivityTestFailureInformation) {
	window.cs.connectivityTestFailureInformation = __webpack_require__(42).directiveFunction;
}

if (!window.cs.browserSessionProvider) {
	var BrowserSessionProvider = __webpack_require__(39).BrowserSessionProvider;
	window.cs.browserSessionProvider = new BrowserSessionProvider();
}

module.exports = window.cs;


/***/ })
/******/ ]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgYWZiNDdkMTQxNDk5OTU5YzFhMzciLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nob2NvbGF0ZXktY2xpZW50L25nLW1vZHVsZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9idWZmZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzIiwid2VicGFjazovLy8od2VicGFjaykvYnVpbGRpbi9nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9lczYtcHJvbWlzZS9kaXN0L2VzNi1wcm9taXNlLmpzIiwid2VicGFjazovLy8uL34vcHJvY2Vzcy9icm93c2VyLmpzIiwid2VicGFjazovLy8uL34vY29yZS11dGlsLWlzL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL34vZG9tZWxlbWVudHR5cGUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovLy8uL34vaHRtbHBhcnNlcjIvbGliL2luZGV4LmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImpRdWVyeVwiIiwid2VicGFjazovLy8uL3NyYy9jcy1zZGsvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9ib3R0bGVqcy9kaXN0L2JvdHRsZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2Nzcy1sb2FkZXIvY3NzVG9TdHJpbmcuanMiLCJ3ZWJwYWNrOi8vLy4vfi9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9idWZmZXItc2hpbXMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9lbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb24iLCJ3ZWJwYWNrOi8vLy4vfi9lbnRpdGllcy9tYXBzL3htbC5qc29uIiwid2VicGFjazovLy8uL34vcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzIiwid2VicGFjazovLy8uL34vcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwid2VicGFjazovLy8uL34vc3RyaW5nX2RlY29kZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiX1wiIiwid2VicGFjazovLy8uL3NyYy9jc3dzLmpzIiwid2VicGFjazovLy8uL34vZG9taGFuZGxlci9saWIvbm9kZS5qcyIsIndlYnBhY2s6Ly8vLi9+L2VudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzIiwid2VicGFjazovLy8uL34vZW50aXRpZXMvbWFwcy9sZWdhY3kuanNvbiIsIndlYnBhY2s6Ly8vLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9ndWFjYW1vbGUtY29tbW9uLWpzLTFjMGVlNDEuanMiLCJ3ZWJwYWNrOi8vLy4vfi9odG1scGFyc2VyMi9saWIvUGFyc2VyLmpzIiwid2VicGFjazovLy8uL34vaHRtbHBhcnNlcjIvbGliL1Rva2VuaXplci5qcyIsIndlYnBhY2s6Ly8vLi9+L2h0bWxwYXJzZXIyL2xpYi9Xcml0YWJsZVN0cmVhbS5qcyIsIndlYnBhY2s6Ly8vLi9+L2lzYXJyYXkvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2d1YWNhbW9sZS1jbGllbnQvY29udHJvbC1zeW1rZXlzLmpzIiwid2VicGFjazovLy8uL3NyYy9ndWFjYW1vbGUtY2xpZW50L2d1YWNhbW9sZS1zdGF0ZXMuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiYW5ndWxhclwiIiwid2VicGFjazovLy8uL3NyYy9icm93c2VyU2Vzc2lvblByb3ZpZGVyLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NyYy9jb25uZWN0aXZpdHktdGVzdC1mYWlsdXJlLWluZm9ybWF0aW9uLmpzIiwid2VicGFjazovLy8uL3NyYy9ndWFjYW1vbGUtY2xpZW50L2luZGV4LmpzIiwid2VicGFjazovLy8uL3NyYy9oZWFydGJlYXQtb3Zlci13cy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvaHRtbC1zYW5pdGl6ZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NwYXJrLWNsaWVudC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2Jhc2U2NC1qcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvc3R5bGVzL3N0eWxlLmNzcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL2Jvb3RzdHJhcC10b3VyL2Jvb3RzdHJhcC10b3VyLmNzcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9GbG93VGVtcGxhdGUuY3NzIiwid2VicGFjazovLy8uL3NyYy9jbG91ZHNoYXJlLXRvdXIvdGVtcGxhdGVzL0ltYWdlRmxvd01vZGFsLmNzcyIsIndlYnBhY2s6Ly8vLi9+L2RvbS1zZXJpYWxpemVyL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vZG9tLXNlcmlhbGl6ZXIvfi9kb21lbGVtZW50dHlwZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2RvbWhhbmRsZXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9kb21oYW5kbGVyL2xpYi9lbGVtZW50LmpzIiwid2VicGFjazovLy8uL34vZG9tdXRpbHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9kb211dGlscy9saWIvaGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9+L2RvbXV0aWxzL2xpYi9sZWdhY3kuanMiLCJ3ZWJwYWNrOi8vLy4vfi9kb211dGlscy9saWIvbWFuaXB1bGF0aW9uLmpzIiwid2VicGFjazovLy8uL34vZG9tdXRpbHMvbGliL3F1ZXJ5aW5nLmpzIiwid2VicGFjazovLy8uL34vZG9tdXRpbHMvbGliL3N0cmluZ2lmeS5qcyIsIndlYnBhY2s6Ly8vLi9+L2RvbXV0aWxzL2xpYi90cmF2ZXJzYWwuanMiLCJ3ZWJwYWNrOi8vLy4vfi9lbnRpdGllcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L2VudGl0aWVzL2xpYi9kZWNvZGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9lbnRpdGllcy9saWIvZW5jb2RlLmpzIiwid2VicGFjazovLy8uL34vZW50aXRpZXMvbWFwcy9kZWNvZGUuanNvbiIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL2Jvb3RzdHJhcC10b3VyL2Jvb3RzdHJhcC10b3VyLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL2Nob2NvbGF0ZXktYnV0dG9uLmh0bWwiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nob2NvbGF0ZXktY2xpZW50L2RpcmVjdGl2ZXMvY2hvY29sYXRleS1jbGllbnQuaHRtbCIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9kZXRhaWxzLXBhbmUuaHRtbCIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9tYXJrZG93bi5odG1sIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2UtZGV0YWlsZWQtaXRlbS5odG1sIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2UtaXRlbS5odG1sIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2UtbGlzdC5odG1sIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2VzLXBhbmUuaHRtbCIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9zZWFyY2gtaW5wdXQuaHRtbCIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9zcGlubmVyLmh0bWwiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvRmxvd1RlbXBsYXRlLmh0bWwiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvRmxvd1RlbXBsYXRlV2l0aEVuZC5odG1sIiwid2VicGFjazovLy8uL3NyYy9jbG91ZHNoYXJlLXRvdXIvdGVtcGxhdGVzL0Zsb3dUZW1wbGF0ZVdpdGhOZXh0Lmh0bWwiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvRmxvd1RlbXBsYXRlV2l0aE5leHRBbmRFbmQuaHRtbCIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9GbG93V2l0aG91dEV4aXRUZW1wbGF0ZS5odG1sIiwid2VicGFjazovLy8uL3NyYy9jbG91ZHNoYXJlLXRvdXIvdGVtcGxhdGVzL0ltYWdlRmxvd01vZGFsLmh0bWwiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvU2hvd09uY2VGbG93VGVtcGxhdGUuaHRtbCIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9TaG93T25jZUZsb3dUZW1wbGF0ZVdpdGhOZXh0Lmh0bWwiLCJ3ZWJwYWNrOi8vLy4vfi9odG1scGFyc2VyMi9saWIvQ29sbGVjdGluZ0hhbmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9odG1scGFyc2VyMi9saWIvRmVlZEhhbmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vfi9odG1scGFyc2VyMi9saWIvUHJveHlIYW5kbGVyLmpzIiwid2VicGFjazovLy8uL34vaHRtbHBhcnNlcjIvbGliL1N0cmVhbS5qcyIsIndlYnBhY2s6Ly8vLi9+L2llZWU3NTQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9qc3NoYS9zcmMvc2hhLmpzIiwid2VicGFjazovLy8uL34vbWFya2VkL2xpYi9tYXJrZWQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzIiwid2VicGFjazovLy8uL34vcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzIiwid2VicGFjazovLy8uL34vcmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzIiwid2VicGFjazovLy8uL34vcmVnZXhwLXF1b3RlL3JlZ2V4cC1xdW90ZS5qcyIsIndlYnBhY2s6Ly8vLi9+L3Nhbml0aXplLWh0bWwvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9zZXRpbW1lZGlhdGUvc2V0SW1tZWRpYXRlLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9zdHlsZXMvc3R5bGUuY3NzPzFiMWEiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nsb3Vkc2hhcmUtdG91ci9ib290c3RyYXAtdG91ci9ib290c3RyYXAtdG91ci5jc3M/ZDIyNSIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9GbG93VGVtcGxhdGUuY3NzPzk5ZDkiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvSW1hZ2VGbG93TW9kYWwuY3NzPzkyOGYiLCJ3ZWJwYWNrOi8vLy4vfi90aW1lcnMtYnJvd3NlcmlmeS9tYWluLmpzIiwid2VicGFjazovLy8uL34vdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vbW9kdWxlLmpzIiwid2VicGFjazovLy8uL34veHRlbmQvaW1tdXRhYmxlLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9jaG9jb2xhdGV5LXBhY2thZ2VzLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL2Nob2NvbGF0ZXktYnV0dG9uLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL2Nob2NvbGF0ZXktY2xpZW50LmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL2RldGFpbHMtcGFuZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9tYXJrZG93bi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9wYWNrYWdlLWRldGFpbGVkLWl0ZW0uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nob2NvbGF0ZXktY2xpZW50L2RpcmVjdGl2ZXMvcGFja2FnZS1pdGVtLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2UtbGlzdC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9wYWNrYWdlcy1wYW5lLmpzIiwid2VicGFjazovLy8uL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3NlYXJjaC1pbnB1dC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9zcGlubmVyLmpzIiwid2VicGFjazovLy8uL3NyYy9jbG91ZHNoYXJlLXRvdXIvYm9vdHN0cmFwLXRvdXIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Nsb3Vkc2hhcmUtdG91ci9ib3R0bGUtbWFwcGluZy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL2NzLXRvdXItc2VydmljZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY2xvdWRzaGFyZS10b3VyL21haW4uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NzLXNkay9hdXRoZW50aWNhdGlvbi1wYXJhbWV0ZXItcHJvdmlkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NzLXNkay9ib3R0bGUuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2NzLXNkay9jbG91ZHNoYXJlLWNsaWVudC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY3Mtc2RrL2htYWMtc2VydmljZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvY3Mtc2RrL2h0dHAuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2d1YWNhbW9sZS1jbGllbnQvYm90dGxlLmpzIiwid2VicGFjazovLy8uL3NyYy9ndWFjYW1vbGUtY2xpZW50L2Nsb3Vkc2hhcmUtZ3VhY2Ftb2xlLmpzIiwid2VicGFjazovLy8uL3NyYy9ndWFjYW1vbGUtY2xpZW50L2d1YWNhbW9sZS1jbGllbnQtZmFjdG9yeS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9ndWFjYW1vbGUtY2xpZW50LmpzIiwid2VicGFjazovLy8uL3NyYy9ndWFjYW1vbGUtY2xpZW50L2d1YWNhbW9sZS1lcnJvci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9rZXktc3Ryb2tlcy1zZXJ2aWNlLmpzIiwid2VicGFjazovLy8uL3NyYy9ndWFjYW1vbGUtY2xpZW50L3N5bWtleS1zZXJ2aWNlLmpzIiwid2VicGFjazovLy8uL3NyYy9ndWFjYW1vbGUtY2xpZW50L3dlYnAtZGV0ZWN0LmpzIiwid2VicGFjazovLy8uL3NyYy9oZWFydGJlYXQtb3Zlci13cy9oZWFydGJlYXRzLWRpc3BhdGNoZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2hlYXJ0YmVhdC1vdmVyLXdzL3dlYnNvY2tldHMtY29ubmVjdG9yLmpzIiwid2VicGFjazovLy8uL3NyYy9zcGFyay1jbGllbnQtY29yZS9zcGFyay1jbGllbnQuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NwYXJrLWNsaWVudC9ib3R0bGUuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3NwYXJrLWNsaWVudC9jbG91ZHNoYXJlLXNwYXJrLmpzIiwid2VicGFjazovLy8uL3NyYy9zcGFyay1jbGllbnQvc3Bhcmstc3RhdGVzLmpzIiwid2VicGFjazovLy8uL3NyYy9zcGFyay1jbGllbnQvc3lta2V5LXNlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vL3ZlcnR4IChpZ25vcmVkKSIsIndlYnBhY2s6Ly8vcmVhZGFibGUtc3RyZWFtIChpZ25vcmVkKSIsIndlYnBhY2s6Ly8vdXRpbCAoaWdub3JlZCkiLCJ3ZWJwYWNrOi8vLy4vc3JjL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxtREFBMkMsY0FBYzs7QUFFekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDaEVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOzs7Ozs7OztBQ3pCRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsbURBQW1EO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsVUFBVTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLHVDQUF1QyxTQUFTO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxpQkFBaUI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELEVBQUU7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGVBQWU7QUFDdkM7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0Esd0JBQXdCLFFBQVE7QUFDaEM7QUFDQSxxQkFBcUIsZUFBZTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFCQUFxQixTQUFTO0FBQzlCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQixTQUFTO0FBQzlCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1REFBdUQsT0FBTztBQUM5RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdURBQXVELE9BQU87QUFDOUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCO0FBQ2xCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLFFBQVE7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixZQUFZO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FDNXZEQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsT0FBTztBQUN2QztBQUNBO0FBQ0EsQzs7Ozs7O0FDMUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0Q0FBNEM7O0FBRTVDOzs7Ozs7O3VEQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMscUJBQXFCOztBQUV0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpRkFBaUY7O0FBRWpGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsc0JBQXNCOztBQUVoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBLENBQUM7QUFDRDtBQUNBLENBQUM7QUFDRDtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLFVBQVUsSUFBSTtBQUNkO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsd0JBQXdCO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLHVDQUF1QztBQUN4RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLFVBQVUsTUFBTTtBQUNoQixVQUFVLE9BQU87QUFDakI7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsVUFBVSxNQUFNO0FBQ2hCO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBO0FBQ0EscUJBQXFCLFlBQVk7QUFDakM7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQSxVQUFVLElBQUk7QUFDZDtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQSxVQUFVLFNBQVM7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsWUFBWSxTQUFTO0FBQ3JCLFlBQVksU0FBUztBQUNyQjtBQUNBLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQSxZQUFZLFNBQVM7QUFDckI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUM7QUFDRCxvQzs7Ozs7OztBQ2pvQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsVUFBVTs7Ozs7OztBQ25MdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxHQUFHO0FBQ0gsb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7QUM3U0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDbkVBLHdCOzs7Ozs7QUNBQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1EOzs7Ozs7c0RDbEJBLG1DQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQ7QUFDNUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQStCLGVBQWUsRUFBRTtBQUFBO0FBQ2hELFNBQVM7QUFDVDtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7O0FBRUwsQ0FBQyxhOzs7Ozs7O0FDanBCRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQTtBQUNBLHdDQUF3QyxnQkFBZ0I7QUFDeEQsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEM7Ozs7OztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7OztBQUlBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7QUM5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQixtQkFBbUI7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHNCQUFzQjtBQUN0QztBQUNBO0FBQ0Esa0JBQWtCLDJCQUEyQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxlQUFlLG1CQUFtQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQiwyQkFBMkI7QUFDNUM7QUFDQTtBQUNBLFFBQVEsdUJBQXVCO0FBQy9CO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxpQkFBaUIsdUJBQXVCO0FBQ3hDO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQSxnQ0FBZ0Msc0JBQXNCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDs7QUFFQSw2QkFBNkIsbUJBQW1COztBQUVoRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7OzhDQzFOQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDM0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDOWtFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7OytDQ05BOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7Ozs7Ozs7OztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxZQUFZO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLLEVBQUU7QUFDUCxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EsQzs7Ozs7OztBQ3JMQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRyxhQUFhO0FBQ2hCO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0wsR0FBRztBQUNILENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlDQUFpQzs7QUFFakM7O0FBRUEsMkNBQTJDO0FBQzNDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9DQUFvQzs7QUFFcEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxvREFBb0Q7QUFDcEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QztBQUM1QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDOzs7Ozs7O0FDdGlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUSxPQUFPO0FBQ2Y7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDNU5BLG1COzs7Ozs7QUNBQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxnQ0FBZ0M7QUFDbEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGtCQUFrQjtBQUNsRjtBQUNBLHlEQUF5RCxjQUFjO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELGlDQUFpQztBQUNsRix3SEFBd0gsbUJBQW1CLEVBQUU7QUFDN0k7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDBCQUEwQixFQUFFO0FBQy9ELHlDQUF5QyxlQUFlO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsK0RBQStEO0FBQzdIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUpBQWlKO0FBQ2pKO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUssV0FBVyxlQUFlO0FBQy9CO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLGVBQWU7QUFDeEI7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0EsOEJBQThCO0FBQzlCLDZCQUE2QjtBQUM3QiwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLFNBQVMsK0JBQStCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLHNDQUFzQztBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMEJBQTBCLFNBQVM7QUFDbkM7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsa0JBQWtCLEVBQUU7O0FBRTdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRyxVQUFVO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixPQUFPO0FBQzdCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QiwwQkFBMEI7QUFDMUIsMEJBQTBCO0FBQzFCLHFCQUFxQjtBQUNyQjtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZEQUE2RCxPQUFPO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QixxQkFBcUI7QUFDckIsMEJBQTBCO0FBQzFCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsMEJBQTBCO0FBQzFCO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPLGtDQUFrQyxnQ0FBZ0MsYUFBYTtBQUN0Riw2QkFBNkIsbUNBQW1DLGFBQWE7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBLGdEQUFnRCxpQkFBaUIsRUFBRTtBQUNuRTtBQUNBLDBEQUEwRCxhQUFhLEVBQUU7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsMEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNkJBQTZCO0FBQzdCLHFDQUFxQzs7QUFFckMsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQ0FBaUMsUUFBUSxnQkFBZ0IsVUFBVSxHQUFHO0FBQ3RFLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFGQUFxRix1QkFBdUI7QUFDNUcsbUVBQW1FO0FBQ25FLGdFQUFnRTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2QsY0FBYztBQUNkLGNBQWM7QUFDZCxjQUFjO0FBQ2QsZUFBZTtBQUNmLGVBQWU7QUFDZixlQUFlO0FBQ2YsZ0JBQWdCO0FBQ2hCOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSyxVQUFVO0FBQ2YsR0FBRztBQUNIOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixVQUFVO0FBQ3JDO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHFDQUFxQztBQUNuRTtBQUNBO0FBQ0EseUJBQXlCLGdDQUFnQztBQUN6RDtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxpQkFBaUIsRUFBRTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGdCQUFnQjtBQUNoRjtBQUNBO0FBQ0EsR0FBRywyQ0FBMkMsZ0NBQWdDO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7O0FBRXZDLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUlBQXVJLGdCQUFnQixVQUFVLEdBQUc7QUFDcEssQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFNQUFxTSxhQUFhLEVBQUU7O0FBRXBOO0FBQ0EscURBQXFELDBCQUEwQjtBQUMvRTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCLGFBQWE7O0FBRXpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0Msb0NBQW9DO0FBQzVFLDRDQUE0QyxvQ0FBb0M7QUFDaEYsS0FBSywyQkFBMkIsb0NBQW9DO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsbUJBQW1CO0FBQ25DO0FBQ0E7QUFDQSxpQ0FBaUMsMkJBQTJCO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0IscUJBQXFCO0FBQ3BELCtCQUErQixTQUFTLEVBQUU7QUFDMUMsQ0FBQyxVQUFVOztBQUVYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixTQUFTLG1CQUFtQjtBQUN2RCwrQkFBK0IsYUFBYTtBQUM1QztBQUNBLEdBQUcsVUFBVTtBQUNiO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxVQUFVO0FBQ1Y7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQ7QUFDakQsQ0FBQztBQUNEO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsU0FBUztBQUNULElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELGdCQUFnQixFQUFFO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsdUNBQXVDLG9CQUFvQixFQUFFO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxVQUFVLEVBQUU7QUFDOUMsbUJBQW1CLHNDQUFzQztBQUN6RCxDQUFDLG9DQUFvQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRyxVQUFVO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxhQUFhO0FBQ3pEO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRyxVQUFVO0FBQ2I7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7O0FBRWxCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWM7O0FBRWQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0EsbURBQW1ELE9BQU8sRUFBRTtBQUM1RDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixXQUFXO0FBQzlCO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTyxVQUFVLGNBQWM7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxHQUFHO0FBQ1I7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixhQUFhO0FBQ2pDLEdBQUc7QUFDSDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrRUFBa0UsK0JBQStCO0FBQ2pHOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBLHVDQUF1QztBQUN2Qzs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEMsR0FBRztBQUNIOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdGQUF3RjtBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sTUFBTTtBQUNiO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLDRCQUE0QjtBQUM1QixHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0IsMEJBQTBCLEdBQUc7QUFDOUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxnQ0FBZ0M7QUFDeEY7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLDRFQUE0RSxZQUFZO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdURBQXVELDZDQUE2QyxFQUFFOztBQUV0RztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsaURBQWlEO0FBQ2pEO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsbUNBQW1DO0FBQ25DO0FBQ0EsS0FBSztBQUNMLHNFQUFzRTtBQUN0RTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMLDREQUE0RDtBQUM1RDtBQUNBLEtBQUs7QUFDTCxzRUFBc0U7QUFDdEU7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVILHNCQUFzQixzQkFBc0IsRUFBRSxFQUFFO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRDQUE0QztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGFBQWE7QUFDNUM7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLDBCQUEwQjtBQUM5QyxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQiwyQkFBMkI7QUFDM0IsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsYUFBYTtBQUNyQyxPQUFPO0FBQ1A7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBOztBQUVBOztBQUVBLHVEQUF1RCxVQUFVOztBQUVqRTs7QUFFQSw0RkFBNEYsd0JBQXdCOztBQUVwSDtBQUNBO0FBQ0EsS0FBSyxVQUFVLGNBQWM7O0FBRTdCO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLLFdBQVcsZ0NBQWdDOztBQUVoRDtBQUNBO0FBQ0E7QUFDQSxDQUFDLGtDQUFrQzs7QUFFbkMsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFdBQVc7QUFDbEI7QUFDQTtBQUNBLE9BQU8sVUFBVTtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sV0FBVztBQUNsQjtBQUNBO0FBQ0E7QUFDQSxPQUFPLFdBQVc7QUFDbEI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlCQUF5QixnQkFBZ0IsdUJBQXVCLEdBQUc7QUFDbkU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsV0FBVztBQUMzQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0EscUJBQXFCO0FBQ3JCLEdBQUc7QUFDSCx5QkFBeUI7QUFDekIsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELGlCQUFpQjtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQsc0JBQXNCO0FBQ2hGLGdGQUFnRixzQkFBc0I7QUFDdEc7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDZCQUE2QixvSEFBb0g7O0FBRWpKOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw2QkFBNkIsZ0dBQWdHOztBQUU3SDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxnQkFBZ0IsRUFBRTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsZ0JBQWdCLEVBQUU7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNElBQTRJLGtCQUFrQixFQUFFO0FBQ2hLO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9ELGdDQUFnQztBQUNwRjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsaUNBQWlDLGdCQUFnQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOzs7QUFHRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDZCQUE2QiwrRkFBK0Y7O0FBRTVILE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEMsY0FBYztBQUNkLGlCQUFpQjtBQUNqQjtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxXQUFXO0FBQ3BCO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxVQUFVO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw0QkFBNEIsZ0JBQWdCLDZCQUE2QixHQUFHOztBQUU1RSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHdFQUF3RSx3QkFBd0IsVUFBVSxHQUFHO0FBQzdHLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGdDQUFnQyxvRkFBb0Y7O0FBRXBILE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0SkFBNEo7QUFDNUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUYsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLG1FQUFtRTtBQUMzRixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlFQUF5RSxhQUFhOztBQUV0RixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxpRUFBaUUsY0FBYzs7QUFFL0UsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsNEJBQTRCLGlHQUFpRzs7QUFFN0gsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw0QkFBNEIsOEZBQThGOztBQUUxSCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRCxLQUFLO0FBQ0w7QUFDQSx1Q0FBdUMsY0FBYyxPQUFPO0FBQzVELHVDQUF1QyxjQUFjLE9BQU87QUFDNUQ7QUFDQTtBQUNBLG1FQUFtRSxPQUFPO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QywwQkFBMEIsRUFBRTtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLGlCQUFpQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsOEJBQThCLDBCQUEwQjs7QUFFeEQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDhCQUE4QixxR0FBcUc7O0FBRW5JLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDhCQUE4QixtQ0FBbUM7O0FBRWpFLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsOEJBQThCLG9DQUFvQzs7QUFFbEUsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsK0VBQStFLHdCQUF3Qjs7QUFFdkcsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkVBQTJFLG9CQUFvQjs7QUFFL0YsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQSxzQkFBc0I7QUFDdEIsQ0FBQztBQUNEO0FBQ0E7QUFDQSxrRztBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDBDQUEwQyx3R0FBd0c7O0FBRWxKLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsd0dBQXdHOztBQUV0SSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EseUlBQXlJLDRHQUE0Rzs7QUFFclAsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHlJQUF5SSwwR0FBMEc7O0FBRW5QLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhCQUE4Qiw4RkFBOEY7O0FBRTVILE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsNEdBQTRHOztBQUUxSSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsd0JBQXdCOztBQUV0RixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQsb0JBQW9COztBQUU5RSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0MsMkdBQTJHLG9CQUFvQjtBQUM5SztBQUNBO0FBQ0EsR0FBRyxVQUFVO0FBQ2IsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDO0FBQzNDO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsbUJBQW1CLGdDQUFnQztBQUNuRCxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsZUFBZSxxQ0FBcUM7QUFDcEQ7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qix3QkFBd0I7QUFDL0M7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxrQkFBa0IsdUJBQXVCLEtBQUs7QUFDOUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakIsd0JBQXdCO0FBQ3hCLGdCQUFnQjtBQUNoQixvQkFBb0I7QUFDcEIsd0JBQXdCO0FBQ3hCLGdCQUFnQjtBQUNoQixvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBEQUEwRCxrQkFBa0I7QUFDNUU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdIQUFnSDtBQUNoSDtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpSEFBaUg7O0FBRWpIO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLENBQUM7QUFDRDtBQUNBLHlCQUF5QjtBQUN6QixDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdDQUFnQyxNQUFNLFNBQVMsT0FBTyxTQUFTO0FBQy9ELENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEMsR0FBRztBQUNILFVBQVU7QUFDVixDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLFNBQVM7O0FBRXhDLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsK0JBQStCLCtGQUErRjs7QUFFOUgsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0IsU0FBUzs7QUFFeEMsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0Isa0JBQWtCLEVBQUU7QUFDMUMsd0JBQXdCLGdCQUFnQjtBQUN4QyxLQUFLO0FBQ0w7QUFDQSxtQ0FBbUMsaUJBQWlCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQiwyQkFBMkI7QUFDakQsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRkFBaUY7QUFDakY7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEZBQThGLHdCQUF3Qix3QkFBd0IsWUFBWSxFQUFFO0FBQzVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixtRUFBbUU7QUFDM0YsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQztBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCLGNBQWM7QUFDZDtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBLFVBQVU7QUFDVixDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLG9CQUFvQix1QkFBdUIsU0FBUyxJQUFJO0FBQ3hELEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEO0FBQ0EsS0FBSztBQUNMO0FBQ0Esc0JBQXNCLGlDQUFpQztBQUN2RCxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsOEJBQThCO0FBQzVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwwREFBMEQsZ0JBQWdCOztBQUUxRTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0Isb0JBQW9COztBQUV4QywwQ0FBMEMsb0JBQW9COztBQUU5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsd0JBQXdCLGVBQWUsRUFBRTtBQUN6Qyx3QkFBd0IsZ0JBQWdCO0FBQ3hDLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCxLQUFLLFFBQVEsaUNBQWlDO0FBQ2xHLENBQUM7QUFDRDtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNkVBQTZFLDBCQUEwQjs7QUFFdkc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsMkZBQTJGO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLDRCQUE0QixtRUFBbUU7QUFDL0YsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHVDQUF1Qyx5SEFBeUg7O0FBRWhLLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLDZEQUE2RDtBQUN2RztBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLDZEQUE2RDtBQUN2RztBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0VBQXdFLDRCQUE0QjtBQUNwRztBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSx1Q0FBdUM7QUFDdkMsc0NBQXNDLHlCQUF5QjtBQUMvRCxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBLE9BQU87QUFDUCx3QkFBd0IsYUFBYTtBQUNyQyxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsMERBQTBELE9BQU87QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isa0JBQWtCO0FBQzFDO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQSxPQUFPO0FBQ1Asd0JBQXdCLGFBQWE7QUFDckMsS0FBSztBQUNMO0FBQ0EsQ0FBQzs7QUFFRCxtREFBbUQsYUFBYSxFQUFFOztBQUVsRSxvQkFBb0Isd0JBQXdCOztBQUU1Qzs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjO0FBQ2Q7QUFDQSxFQUFFOztBQUVGLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjO0FBQ2Q7QUFDQSxFQUFFOztBQUVGLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsY0FBYztBQUNkO0FBQ0EsRUFBRTs7QUFFRixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjO0FBQ2Q7QUFDQSxFQUFFOztBQUVGLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsRUFBRTs7QUFFRixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxjQUFjO0FBQ2Q7QUFDQSxFQUFFOztBQUVGLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsRUFBRTs7QUFFRixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUYsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx1Q0FBdUMseUhBQXlIOztBQUVoSyxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1YsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsOEJBQThCLDBGQUEwRjs7QUFFeEgsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdHQUF3RyxPQUFPO0FBQy9HO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUVBQXFFO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpR0FBaUcsNkJBQTZCLEVBQUU7QUFDaEksaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdkosMkNBQTJDLGdCQUFnQixrQkFBa0IsT0FBTywyQkFBMkIsd0RBQXdELGdDQUFnQyx1REFBdUQsMkRBQTJELEVBQUU7O0FBRTNULDZEQUE2RCxzRUFBc0UsOERBQThELG9CQUFvQjs7QUFFck47QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDOzs7O0FBSUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhGQUE4RixhQUFhLEVBQUU7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlHQUFpRyxnQkFBZ0IsRUFBRTtBQUNuSCwyR0FBMkcsMEJBQTBCLEVBQUU7QUFDdkk7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUdBQWlHLHdCQUF3QixFQUFFO0FBQzNIO0FBQ0EsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdkosMkNBQTJDLGdCQUFnQixrQkFBa0IsT0FBTywyQkFBMkIsd0RBQXdELGdDQUFnQyx1REFBdUQsMkRBQTJELEVBQUU7O0FBRTNULDZEQUE2RCxzRUFBc0UsOERBQThELG9CQUFvQjs7O0FBR3JOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFdBQVc7QUFDWDs7QUFFQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7Ozs7QUFJRCxPQUFPOztBQUVQLFVBQVU7QUFDVixnQzs7Ozs7O0FDdm5TQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0YsQ0FBQzs7Ozs7OztBQzNDRDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsc0JBQXNCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLGlCQUFpQjtBQUN0Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsWUFBWTtBQUMzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyx1QkFBdUI7QUFDbEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxXQUFXO0FBQzFCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxxQkFBcUIsb0JBQW9CO0FBQ3pDOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLDJDQUEyQztBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkLGlCQUFpQjtBQUNqQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsdUJBQXVCO0FBQ3RDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIscUJBQXFCO0FBQ25EO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRDtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHNCQUFzQjtBQUNqQztBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsc0JBQXNCO0FBQ2pDO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGNBQWM7QUFDN0I7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0Msc0JBQXNCOztBQUV0RDtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsMkJBQTJCO0FBQzVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxZQUFZO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFlBQVk7QUFDM0I7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QiwyQkFBMkI7O0FBRXhEOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkIsYUFBYTtBQUN4QztBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQ7QUFDbkQ7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsdUJBQXVCO0FBQ2xDO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyx1QkFBdUI7QUFDbEM7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsYUFBYTtBQUM1QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLFVBQVU7QUFDckM7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsWUFBWTtBQUMzQjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCLDJCQUEyQjs7QUFFeEQ7O0FBRUE7QUFDQTtBQUNBLDJCQUEyQixnQkFBZ0I7QUFDM0M7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0JBQXNCLGlCQUFpQjs7QUFFdkM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLG1CQUFtQjtBQUM5QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQ7QUFDbkQ7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHNCQUFzQjtBQUNqQztBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsNkNBQTZDLGlCQUFpQjtBQUM5RDs7QUFFQTtBQUNBO0FBQ0Esd0NBQXdDLGlCQUFpQjtBQUN6RDs7QUFFQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLGlCQUFpQjtBQUN0Qzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0IsS0FBSztBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyx1QkFBdUI7QUFDbEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLG9DQUFvQztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLG9DQUFvQztBQUN4RDtBQUNBO0FBQ0E7QUFDQSxlQUFlLEtBQUs7QUFDcEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLG9DQUFvQztBQUM1RDtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0Isb0NBQW9DO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHVDQUF1Qyx1QkFBdUI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGlCQUFpQjtBQUM1QjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsZUFBZTtBQUNwQzs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLHVCQUF1QjtBQUN2QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixnQkFBZ0IsdUJBQXVCO0FBQ3ZDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGdCQUFnQix1QkFBdUI7QUFDdkM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7QUFDQSxlQUFlLCtCQUErQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHNCQUFzQjtBQUNyQztBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSwrQ0FBK0M7QUFDOUQ7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7O0FBRUE7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdURBQXVEOztBQUV2RCxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0RBQXNEOztBQUV0RCxTQUFTOztBQUVUOztBQUVBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7O0FBRUE7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7O0FBRUE7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsc0JBQXNCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0EscUNBQXFDOztBQUVyQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGtCQUFrQjtBQUNqQyxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsUzs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsUUFBUTtBQUM3QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBeUIsa0JBQWtCO0FBQzNDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EseUJBQXlCLGtCQUFrQjtBQUMzQzs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLEtBQUs7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLCtCQUErQjtBQUMvQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLCtCQUErQjtBQUMvQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLCtCQUErQjtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixnQkFBZ0I7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsZ0JBQWdCO0FBQy9CO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsTUFBTTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxTQUFTOztBQUVUOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsUUFBUTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEI7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLGdCQUFnQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxnQkFBZ0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsK0JBQStCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLCtCQUErQjtBQUM5QztBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLCtCQUErQjtBQUM5QztBQUNBO0FBQ0EsZUFBZSwrQkFBK0I7QUFDOUM7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsK0JBQStCO0FBQzlDO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixrQkFBa0I7QUFDbEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsYUFBYTs7QUFFYjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLG1CQUFtQjtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDOztBQUU1QztBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSwrQkFBK0I7QUFDOUMsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGlCQUFpQjtBQUM1QixXQUFXLE9BQU87QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsc0JBQXNCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUU7O0FBRWpFO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCLHFCQUFxQjs7QUFFckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGNBQWM7QUFDN0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBDQUEwQztBQUMxQywwQ0FBMEM7QUFDMUMsMENBQTBDO0FBQzFDOztBQUVBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUMsMENBQTBDO0FBQzFDOztBQUVBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUMsMENBQTBDO0FBQzFDOztBQUVBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUMsMENBQTBDO0FBQzFDOztBQUVBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUMsMENBQTBDO0FBQzFDOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDLDBDQUEwQztBQUMxQywwQ0FBMEM7QUFDMUMsMENBQTBDO0FBQzFDOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQywwQkFBMEI7QUFDM0Q7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsU0FBUzs7QUFFVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxjQUFjO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGNBQWM7QUFDekIsYUFBYSxpQ0FBaUM7QUFDOUM7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE1BQU07QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQixlQUFlOztBQUVwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0IsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFnQjtBQUMvQixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsUUFBUTtBQUN2QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLGdCQUFnQjtBQUMvQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQWdCO0FBQy9CO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQSxLQUFLOztBQUVMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsS0FBSzs7QUFFTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSx5Q0FBeUMsK0NBQStDOztBQUV4RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxhQUFhOztBQUViO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGFBQWE7O0FBRWI7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxrQkFBa0I7QUFDakMsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQjtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHNCQUFzQjtBQUNyQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHNCQUFzQjtBQUNyQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlCQUFpQjs7QUFFakI7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLEtBQUs7O0FBRUw7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxLQUFLOztBQUVMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHNCQUFzQjtBQUNyQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsV0FBVztBQUMxQixnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFdBQVc7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7O0FBRUEsU0FBUzs7QUFFVCxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQsS0FBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsaUJBQWlCO0FBQzVCO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxrQ0FBa0M7QUFDN0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QjtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLGtCQUFrQjs7QUFFdkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUNBQXFDLFFBQVE7O0FBRTdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQix5QkFBeUI7QUFDOUM7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxlQUFlLDhFQUE4RTtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLG1CQUFtQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsK0ZBQStGO0FBQzlHO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QjtBQUNBO0FBQ0EsZUFBZSwyQkFBMkI7QUFDMUM7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsbUJBQW1CO0FBQ3hDOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixpQkFBaUI7O0FBRTFDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUMseUJBQXlCO0FBQzFEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFdBQVc7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFdBQVc7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFdBQVc7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFdBQVc7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHlDQUF5QztBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxzQ0FBc0M7QUFDakQ7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsaUJBQWlCO0FBQzVCLFdBQVcsT0FBTztBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLG9DQUFvQzs7QUFFcEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxNQUFNO0FBQ3JCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxnQ0FBZ0M7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUJBQW1CLHVCQUF1Qjs7QUFFMUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsZ0RBQWdELHVCQUF1QjtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGlCQUFpQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx1QkFBdUIsK0JBQStCO0FBQ3REO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsZ0NBQWdDLGlCQUFpQjs7QUFFakQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLHFCQUFxQjtBQUNuQzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBLFdBQVcsZ0RBQWdEO0FBQzNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0EsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRTtBQUN0RTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLDZCQUE2QjtBQUNwRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxzQkFBc0I7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFlBQVk7QUFDM0IsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHFCQUFxQixnQkFBZ0I7O0FBRXJDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsdUJBQXVCO0FBQ2xDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGdCQUFnQixXQUFXO0FBQzNCO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsZUFBZTtBQUNwQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7O0FBRUEsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLDJCQUEyQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxLQUFLO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEIsZUFBZSxNQUFNO0FBQ3JCO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBO0FBQ0EsZ0Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLG9CQUFvQjtBQUN6Qzs7QUFFQTtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVHQUF1Rzs7QUFFdkc7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixnQ0FBZ0M7O0FBRWpEO0FBQ0EsdUJBQXVCLGNBQWM7O0FBRXJDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUIsdUNBQXVDOztBQUU1RDtBQUNBLDJCQUEyQixRQUFROztBQUVuQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw2Q0FBNkM7O0FBRTdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlCQUFpQjs7QUFFakI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxtR0FBbUc7QUFDbkc7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBO0FBQ0EsZ0Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLG9CQUFvQjtBQUN6Qzs7QUFFQTtBQUNBLHFCQUFxQjs7QUFFckI7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFDQUFxQzs7QUFFckM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTs7QUFFYjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxLQUFLO0FBQ2hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLG9CQUFvQjtBQUNyQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHNCQUFzQjtBQUNqQztBQUNBO0FBQ0EsV0FBVywrQkFBK0I7QUFDMUM7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOzs7QUFHQTtBQUNBLDJCOzs7Ozs7QUM5NVlBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQVksNEJBQTRCO0FBQ3hDLFlBQVksVUFBVTtBQUN0QixZQUFZLCtCQUErQjtBQUMzQyxZQUFZLG9DQUFvQztBQUNoRCxZQUFZLFVBQVU7QUFDdEIsWUFBWSxTQUFTO0FBQ3JCLFlBQVksU0FBUztBQUNyQixZQUFZLFNBQVM7QUFDckIsWUFBWSxTQUFTO0FBQ3JCLFlBQVksU0FBUztBQUNyQixZQUFZLFNBQVM7QUFDckIsWUFBWSxTQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksY0FBYztBQUMxQixZQUFZO0FBQ1o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ2hXQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBLEVBQUU7QUFDRjtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHlCQUF5Qjs7QUFFekIsbUJBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLDZEQUE2RDtBQUNwRjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEMsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7Ozs7OztBQ3o0QkE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDRCQUE0QixxQkFBcUI7O0FBRWpEO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUN4QkEsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7Ozs7Ozs7O0FDSkE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRTs7Ozs7OzsrQ0N6QkE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRyxhQUFhO0FBQ2hCO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkVBQTJFLDZFQUE2RTtBQUN4SjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLHNEQUFzRDs7QUFFdEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQ7QUFDN0Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNDQUFzQzs7QUFFdEM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSwrQ0FBK0M7O0FBRS9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRFQUE0RTs7QUFFNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0EsbURBQW1ELGlFQUFpRTtBQUNwSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2QyxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2QyxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDLE9BQU87QUFDdkM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDLE9BQU87QUFDdkM7QUFDQTtBQUNBO0FBQ0EsQzs7Ozs7OztBQzU2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ1BBLHlCOzs7Ozs7QUNBQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxnQ0FBZ0M7QUFDbEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGtCQUFrQjtBQUNsRjtBQUNBLHlEQUF5RCxjQUFjO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELGlDQUFpQztBQUNsRix3SEFBd0gsbUJBQW1CLEVBQUU7QUFDN0k7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDBCQUEwQixFQUFFO0FBQy9ELHlDQUF5QyxlQUFlO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsK0RBQStEO0FBQzdIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLDhDQUE4QyxjQUFjO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLDhDQUE4QyxjQUFjO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsVUFBVTtBQUN2QywrQkFBK0IsK0JBQStCO0FBQzlEO0FBQ0EsdUJBQXVCLFNBQVM7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7O0FBR0EsT0FBTzs7QUFFUCxVQUFVO0FBQ1Ysa0Q7Ozs7OztBQzNLQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQSwwQkFBcUIsc0ZBQXNGO0FBQzNHO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxDOzs7Ozs7QUMzQkE7QUFDQTs7QUFFQSw4QztBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7Ozs7Ozs7QUNQQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxnQ0FBZ0M7QUFDbEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGtCQUFrQjtBQUNsRjtBQUNBLHlEQUF5RCxjQUFjO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELGlDQUFpQztBQUNsRix3SEFBd0gsbUJBQW1CLEVBQUU7QUFDN0k7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDBCQUEwQixFQUFFO0FBQy9ELHlDQUF5QyxlQUFlO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsK0RBQStEO0FBQzdIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpREFBaUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUV2SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMnBEQUEycEQsWUFBWSxrQkFBa0IsYUFBYSxxUEFBcVAsYUFBYSwybUNBQTJtQyxZQUFZLFdBQVcsYUFBYSwrUkFBK1IsYUFBYSxvV0FBb1csWUFBWSxXQUFXLGFBQWEsaVhBQWlYLGFBQWEsMGFBQTBhLFlBQVksa0JBQWtCLGFBQWEsdVpBQXVaLGFBQWE7O0FBRWxnSyxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwwR0FBMEcsK0ZBQStGLEVBQUU7Ozs7O0FBSzNNLE9BQU87O0FBRVAsVUFBVTtBQUNWLGlFOzs7Ozs7QUNqTEE7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE07QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOzs7Ozs7O0FDZEE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwrQjs7Ozs7O0FDckZBOztBQUVBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUNKQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0NBQWtDLFNBQVM7QUFDM0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLG9CQUFvQixPQUFPO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixTQUFTO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBMEMsVUFBVTtBQUNwRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7Ozs7OztBQ2pIQTtBQUNBLDhDQUErQywyQ0FBMkMseUJBQXlCLEtBQUssc0NBQXNDLDRCQUE0QixrQkFBa0IsS0FBSywrQkFBK0IsOEJBQThCLDRCQUE0QixLQUFLLDBDQUEwQyx5QkFBeUIsS0FBSywwREFBMEQseUJBQXlCLG1CQUFtQixLQUFLLDZEQUE2RCw0QkFBNEIseUJBQXlCLGVBQWUsZ0JBQWdCLHNDQUFzQyx1Q0FBdUMsMENBQTBDLGtDQUFrQyxLQUFLLCtDQUErQywwQkFBMEIsaUJBQWlCLDRCQUE0Qix1QkFBdUIsS0FBSyxvREFBb0QsbUJBQW1CLHlCQUF5QixLQUFLLDhEQUE4RCw0QkFBNEIsc0JBQXNCLHVCQUF1QixLQUFLLDBDQUEwQywwQkFBMEIsa0JBQWtCLDRCQUE0QixLQUFLLGtEQUFrRCx5QkFBeUIsa0RBQWtELEtBQUssZ0RBQWdELGtCQUFrQixLQUFLLGdEQUFnRCwwQkFBMEIsa0JBQWtCLEtBQUssZ0RBQWdELDBCQUEwQixLQUFLLHVEQUF1RCxtQkFBbUIsc0JBQXNCLHNCQUFzQixLQUFLLHlEQUF5RCxvQkFBb0Isc0JBQXNCLEtBQUssNkRBQTZELHNCQUFzQixxQkFBcUIsS0FBSyxtREFBbUQsNkJBQTZCLHdCQUF3QixLQUFLLG1DQUFtQywyQ0FBMkMsMkNBQTJDLHlCQUF5QixtQkFBbUIsMEJBQTBCLHVCQUF1QixvQkFBb0Isc0JBQXNCLHNCQUFzQixLQUFLLHFDQUFxQywwQ0FBMEMsMENBQTBDLEtBQUssNkNBQTZDLDJDQUEyQywyQ0FBMkMsc0JBQXNCLG1CQUFtQixLQUFLLG9EQUFvRCxrQkFBa0Isc0JBQXNCLEtBQUssMENBQTBDLHlCQUF5QixrQkFBa0IseUJBQXlCLG1CQUFtQixLQUFLLDJEQUEyRCxpQkFBaUIsMkNBQTJDLHlCQUF5Qix5QkFBeUIsdUJBQXVCLDBCQUEwQixzQkFBc0IscUJBQXFCLEtBQUssbURBQW1ELHlCQUF5QixLQUFLLHNDQUFzQyx3RUFBd0UsMkVBQTJFLG1FQUFtRSxLQUFLLGdFQUFnRSw0QkFBNEIsaUJBQWlCLHVCQUF1QixLQUFLLGtEQUFrRCx5QkFBeUIscUJBQXFCLEtBQUssd0RBQXdELG9CQUFvQix5QkFBeUIsY0FBYyxlQUFlLEtBQUssc0VBQXNFLHlCQUF5QiwwQkFBMEIsc0JBQXNCLG9CQUFvQixLQUFLLHlFQUF5RSw0QkFBNEIsc0JBQXNCLDZCQUE2QixLQUFLLHdFQUF3RSw0QkFBNEIsbUJBQW1CLDZCQUE2QixLQUFLLDRFQUE0RSxrQkFBa0IsS0FBSywwRUFBMEUsNEJBQTRCLHdCQUF3Qiw2QkFBNkIsS0FBSyw0REFBNEQsb0NBQW9DLHdCQUF3QixrQkFBa0IsdUJBQXVCLEtBQUssMERBQTBELDBCQUEwQixLQUFLLDREQUE0RCw2QkFBNkIsS0FBSyxxQ0FBcUMseUJBQXlCLEtBQUssNEJBQTRCLHlCQUF5Qiw0QkFBNEIsa0JBQWtCLG1CQUFtQixLQUFLLHFDQUFxQyx5QkFBeUIsYUFBYSxjQUFjLGtCQUFrQixtQkFBbUIsc0NBQXNDLDJCQUEyQixtQ0FBbUMscUNBQXFDLGtDQUFrQyxzQkFBc0IsbUJBQW1CLHdCQUF3QixLQUFLLDJDQUEyQyxnQ0FBZ0MsS0FBSyx5REFBeUQsb0JBQW9CLHlCQUF5QixhQUFhLGNBQWMsa0JBQWtCLG1CQUFtQixnQ0FBZ0MsbUJBQW1CLHNCQUFzQix5QkFBeUIsS0FBSyxROzs7Ozs7QUNEM3dMO0FBQ0Esc2FBQXVhLCttQkFBK21CLHNCQUFzQixhQUFhLGVBQWUsZ0JBQWdCLGNBQWMsaUJBQWlCLDZCQUE2QixtQkFBbUIsZ0NBQWdDLEtBQUsseUJBQXlCLHlCQUF5QixpQkFBaUIsS0FBSyw4QkFBOEIseUJBQXlCLGlCQUFpQixLQUFLLHNDQUFzQywyQkFBMkIsS0FBSywyQkFBMkIsb0NBQW9DLGlCQUFpQiwwQkFBMEIseUJBQXlCLEtBQUssZ0NBQWdDLG1CQUFtQixLQUFLLG9EQUFvRCx3QkFBd0IsS0FBSyx5RUFBeUUsbUJBQW1CLEtBQUssMk5BQTJOLHNCQUFzQixLQUFLLHNQQUFzUCxzQkFBc0IsS0FBSyx1Q0FBdUMsc0JBQXNCLG9CQUFvQixLQUFLLDhDQUE4QyxvQkFBb0IsS0FBSyxnQkFBZ0Isc0JBQXNCLEtBQUssUTs7Ozs7O0FDRHgrRTtBQUNBLHNEQUF1RCwyQkFBMkIsaUJBQWlCLG1CQUFtQix3QkFBd0Isb0JBQW9CLHdCQUF3QixLQUFLLDJDQUEyQyw4QkFBOEIsS0FBSyxzQ0FBc0MsNEJBQTRCLEtBQUssUTs7Ozs7O0FDRHBWO0FBQ0EsK0NBQWdELHdCQUF3QixlQUFlLGdCQUFnQixvQkFBb0IscUJBQXFCLG1CQUFtQiwyQkFBMkIsS0FBSyxnREFBZ0QsOEJBQThCLHFCQUFxQiwrQkFBK0IsS0FBSyw4Q0FBOEMsMkJBQTJCLGVBQWUsZ0JBQWdCLG9CQUFvQixxQkFBcUIsZ0NBQWdDLHFCQUFxQixtQkFBbUIsS0FBSywrQ0FBK0MsMkJBQTJCLDhCQUE4QixnQ0FBZ0MsMkJBQTJCLHlCQUF5Qix3Q0FBd0Msd0JBQXdCLCtCQUErQiw0Q0FBNEMseUNBQXlDLG9DQUFvQyxpQkFBaUIsS0FBSyxpREFBaUQsa0NBQWtDLHlDQUF5QywrQ0FBK0Msd0JBQXdCLHVCQUF1Qix1QkFBdUIsS0FBSywwREFBMEQsMkJBQTJCLG9CQUFvQixxQkFBcUIsS0FBSyw4REFBOEQsd0JBQXdCLEtBQUssNEVBQTRFLDJCQUEyQiw4QkFBOEIsb0JBQW9CLHFCQUFxQixLQUFLLFE7Ozs7OztBQ0R6bEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGdCQUFnQixnQkFBZ0I7QUFDaEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DOztBQUVuQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDakxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNiQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7Ozs7Ozs7QUNyTEE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGLENBQUM7Ozs7Ozs7QUNuQkQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0YsQ0FBQzs7Ozs7OztBQ2JEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxLQUFLO0FBQ25CLGNBQWMsS0FBSztBQUNuQjtBQUNBLFlBQVksT0FBTztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsTUFBTTtBQUNwQjtBQUNBLGFBQWEsTUFBTTtBQUNuQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOzs7Ozs7O0FDNUlBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLHVDQUF1QztBQUNoRSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0gseUJBQXlCLDBDQUEwQztBQUNuRTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EseUJBQXlCLHdCQUF3QjtBQUNqRCxHQUFHO0FBQ0gseUJBQXlCLDJCQUEyQjtBQUNwRDtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EseUJBQXlCLHdDQUF3QztBQUNqRSxHQUFHO0FBQ0gseUJBQXlCLDJDQUEyQztBQUNwRTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixvREFBb0Q7QUFDNUUsRUFBRTtBQUNGLHdCQUF3Qix1REFBdUQ7QUFDL0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7Ozs7QUN0RkE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQzFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlDQUFpQyxPQUFPO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQyxPQUFPO0FBQ3hDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlDQUFpQyxnQkFBZ0I7QUFDakQ7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQyxPQUFPO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUNBQWlDLE9BQU87QUFDeEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUM3RkE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDdkJBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSx3Q0FBd0M7O0FBRXhDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHNCQUFzQixpQkFBaUI7QUFDdkM7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxHQUFHO0FBQ0gsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUEsbUVBQW1FLFFBQVE7QUFDM0U7O0FBRUE7QUFDQSwwQkFBMEIsWUFBWTtBQUN0QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ3ZFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBLEVBQUUsSUFBSTtBQUNOOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSwrREFBK0Q7QUFDL0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RDtBQUN6RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUN4RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzUkFBc1IsbUZBQW1GO0FBQ3pXLHNEQUFzRDtBQUN0RCxzREFBc0Q7QUFDdEQsa0RBQWtEO0FBQ2xELDBDQUEwQztBQUMxQyx3Q0FBd0M7QUFDeEMseUNBQXlDO0FBQ3pDLDBDQUEwQztBQUMxQyx5Q0FBeUM7QUFDekMsMkNBQTJDO0FBQzNDLHlDQUF5QztBQUN6Qyx5Q0FBeUM7QUFDekMsb0RBQW9EO0FBQ3BELHFEQUFxRDtBQUNyRDtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkNBQTZDLFdBQVc7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCw2RUFBNkU7QUFDckk7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakIsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDLFdBQVc7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0IsZ0RBQWdEO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQSw2Qjs7Ozs7O0FDdGdDQSwrSjs7Ozs7O0FDQUEsd2hCOzs7Ozs7QUNBQSxzSUFBc0ksMkJBQTJCLGtJQUFrSSxpQkFBaUIsMFdBQTBXLGdIQUFnSCw2VDs7Ozs7O0FDQTl3QixxRjs7Ozs7O0FDQUEsbUVBQW1FLHFCQUFxQixzckJBQXNyQiwyQkFBMkIsb1FBQW9RLG9CQUFvQix3cEJBQXdwQix5Ujs7Ozs7O0FDQXp0RCxnSUFBZ0ksaUJBQWlCLG9aQUFvWiwwUkFBMFIsNEpBQTRKLHdGOzs7Ozs7QUNBMzlCLDBEQUEwRCxxQkFBcUIsd2lCOzs7Ozs7QUNBL0UsbTBEOzs7Ozs7QUNBQSxnSjs7Ozs7O0FDQUEsa0U7Ozs7OztBQ0FBLDJFQUEyRSx5SUFBeUksNkQ7Ozs7OztBQ0FwTiwyRUFBMkUsb1JBQW9SLCtDOzs7Ozs7QUNBL1YsMkVBQTJFLHlJQUF5SSx1Tjs7Ozs7O0FDQXBOLDJFQUEyRSwyVkFBMlYsK0M7Ozs7OztBQ0F0YSwyRUFBMkUsd0k7Ozs7OztBQ0EzRSx5Uzs7Ozs7O0FDQUEsMkVBQTJFLG9SQUFvUiw4Qzs7Ozs7O0FDQS9WLDJFQUEyRSw2UUFBNlEscUdBQXFHLG9CQUFvQiwyQzs7Ozs7O0FDQWpkOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEseUNBQXlDLFNBQVM7QUFDbEQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdERBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQjs7QUFFbEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQjs7QUFFbEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDOUZBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQyxFOzs7Ozs7QUMxQkQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLENBQUMsRTs7Ozs7O0FDbENEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFdBQVc7O0FBRW5CO0FBQ0E7QUFDQTtBQUNBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBLFFBQVEsVUFBVTs7QUFFbEI7QUFDQTs7Ozs7Ozs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDYSxhQUFhLGtCQUFrQixzQ0FBc0MsOEZBQThGLGNBQWMsMEVBQTBFLE9BQU8sV0FBVyxVQUFVLDhEQUE4RCw4Q0FBOEMsZ0RBQWdEO0FBQ2hjLCtCQUErQiw2QkFBNkIsZ0ZBQWdGLGdFQUFnRSxVQUFVLGVBQWUsTUFBTSxlQUFlLE1BQU0saUJBQWlCLE1BQU0sa0RBQWtELHVCQUF1QixJQUFJLG9CQUFvQiw4QkFBOEIsSUFBSSxzQkFBc0IsOEJBQThCLElBQUksc0JBQXNCO0FBQ3hlLFVBQVUsSUFBSSxzQkFBc0IsOEJBQThCLElBQUksc0JBQXNCLGdEQUFnRCxrQkFBa0IsaUNBQWlDLHNCQUFzQixPQUFPLFVBQVUsZUFBZSxNQUFNLGVBQWUsTUFBTSxpQkFBaUIsTUFBTSx3REFBd0QsMEJBQTBCLGlDQUFpQyxpQ0FBaUMsa0NBQWtDO0FBQzdkLFVBQVUsZ0RBQWdELHlDQUF5Qyw4REFBOEQsOENBQThDLGdEQUFnRCxnRUFBZ0UsTUFBTSxRQUFRLFVBQVUsa0NBQWtDLFlBQVksV0FBVyxpQkFBaUIsZUFBZSxLQUFLLFlBQVksV0FBVyxpQkFBaUIsUUFBUSxLQUFLO0FBQzFlLCtCQUErQiwwRkFBMEYsa0JBQWtCLGdCQUFnQixTQUFTLFNBQVMsZ0JBQWdCLDBCQUEwQixzQkFBc0IsV0FBVztBQUN4UCxJQUFJLFdBQVcsTUFBTSxZQUFZLFlBQVksV0FBVyxxQkFBcUIsS0FBSyw2Q0FBNkMsV0FBVyxNQUFNLGtCQUFrQixxQ0FBcUMsWUFBWSxZQUFZLFdBQVcsa0JBQWtCLEtBQUssT0FBTyxvQkFBb0IsY0FBYywwQkFBMEIsZ0VBQWdFLFFBQVEsSUFBSSxNQUFNLDZCQUE2QjtBQUNuYixZQUFZLFlBQVksV0FBVyxzQkFBc0IsT0FBTyxvQkFBb0IsY0FBYyxlQUFlLFFBQVEsV0FBVyx3RUFBd0UsT0FBTywyQkFBMkIsY0FBYyx1QkFBdUIsa0ZBQWtGLGlCQUFpQixzQkFBc0IsaUVBQWlFLFFBQVEsV0FBVyxNQUFNO0FBQ3RlLFVBQVUsV0FBVyxxR0FBcUcsUUFBUSxhQUFhLE1BQU0sWUFBWSxZQUFZLFdBQVcsaUNBQWlDLE1BQU0sT0FBTyxvQkFBb0IsZ0JBQWdCLDBCQUEwQixRQUFRLElBQUksbUdBQW1HLHVDQUF1QyxnQkFBZ0IsNEJBQTRCLFFBQVEsSUFBSTtBQUNsZiwwSkFBMEosSUFBSSxtSUFBbUksU0FBUyxjQUFjLDBCQUEwQixRQUFRLElBQUksMERBQTBELFNBQVMsY0FBYyxPQUFPLDJCQUEyQixJQUFJO0FBQ3JkLDhFQUE4RSxVQUFVLGlGQUFpRixzRUFBc0UsU0FBUyxnQkFBZ0IscUJBQXFCLGdCQUFnQixxQkFBcUIsZ0JBQWdCLDRCQUE0QjtBQUM5VyxjQUFjLGdCQUFnQixXQUFXLCtFQUErRSxrQkFBa0IsZ0JBQWdCLGtCQUFrQixnREFBZ0Qsa0JBQWtCLG1CQUFtQixrQkFBa0IsOERBQThELGNBQWMsOEJBQThCLGVBQWUsd0JBQXdCLFVBQVUsc0NBQXNDLGVBQWU7QUFDbmUsWUFBWSxlQUFlLHdCQUF3QixVQUFVLHNDQUFzQyxlQUFlLDRCQUE0QixlQUFlLHNCQUFzQixTQUFTLHNDQUFzQyxlQUFlLDhCQUE4QixlQUFlLHdCQUF3QixTQUFTLHNDQUFzQyxnQkFBZ0IsMEJBQTBCLHFEQUFxRCxxQkFBcUI7QUFDemQsaUJBQWlCLHVFQUF1RSxzQkFBc0Isd0RBQXdELGdGQUFnRixpQkFBaUIsVUFBVSwwQkFBMEIsaUNBQWlDLHdCQUF3QixtQ0FBbUMsaUNBQWlDLHNDQUFzQyxxQkFBcUIsVUFBVTtBQUM3ZSxvQ0FBb0MsdURBQXVELHdCQUF3QiwyREFBMkQsdURBQXVELHNDQUFzQyx1QkFBdUIsVUFBVSw4REFBOEQsa0VBQWtFLHdCQUF3QjtBQUNwYyxxQkFBcUIsa0VBQWtFLHNDQUFzQyxnQkFBZ0IscUZBQXFGLHVCQUF1QixZQUFZLFdBQVcsdUJBQXVCLGtCQUFrQixzQkFBc0IsV0FBVyxRQUFRLElBQUksT0FBTyxPQUFPLE9BQU8sT0FBTyxPQUFPLE9BQU8sUUFBUSxLQUFLO0FBQzdaLG1KQUFtSixlQUFlLGVBQWUsZUFBZSxlQUFlLGVBQWUsU0FBUyxrQkFBa0I7QUFDelAsOGVBQThlO0FBQzllLDRFQUE0RSwyRkFBMkYsc0lBQXNJO0FBQzdTO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNk9BQTZPLHFEQUFxRCxLQUFLLFlBQVksV0FBVyx1QkFBdUIsa0JBQWtCLHNCQUFzQixXQUFXLFFBQVEsSUFBSSxNQUFNLE9BQU8sT0FBTyxPQUFPLE9BQU8sT0FBTyxPQUFPLE9BQU8sT0FBTyxRQUFRLElBQUk7QUFDOWQsMkxBQTJMLGVBQWUsZUFBZSxlQUFlLGVBQWUsZUFBZSxlQUFlLGVBQWUsZUFBZSx3REFBd0QsMEJBQTBCLDhHQUE4RztBQUNuZixzSEFBc0gscURBQXFELFNBQVMsbURBQXlELFNBQVM7QUFBQSwyTkFBd0g7Ozs7Ozs7QUNuQzlXO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsRUFBRTtBQUNmO0FBQ0Esa0JBQWtCLEdBQUc7QUFDckIsa0JBQWtCLElBQUk7QUFDdEI7QUFDQSxnQ0FBZ0MsR0FBRztBQUNuQztBQUNBLDBDQUEwQyxHQUFHO0FBQzdDLGtEQUFrRCxHQUFHLHNCQUFzQixHQUFHO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUNBQWlDLEdBQUc7QUFDcEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHVCQUF1Qjs7QUFFdkI7QUFDQTtBQUNBOztBQUVBLG9CQUFvQjtBQUNwQixpQkFBaUIsR0FBRyxHQUFHLEdBQUc7QUFDMUI7QUFDQSxrQkFBa0IsSUFBSTtBQUN0QixDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsRUFBRTtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLHVCQUF1QjtBQUN4QztBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsdUJBQXVCO0FBQ3hDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87O0FBRVA7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLFlBQVksT0FBTztBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLGdCQUFnQjtBQUMxRCwrQkFBK0IsSUFBSTtBQUNuQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsdUJBQXVCO0FBQ3hDO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBLGlCQUFpQix1QkFBdUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsR0FBRztBQUNiO0FBQ0EsbUNBQW1DLEdBQUc7QUFDdEM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHdCQUF3Qjs7QUFFeEI7QUFDQTtBQUNBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCO0FBQ3JCO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQSx3QkFBd0I7QUFDeEIsMkJBQTJCLEdBQUc7QUFDOUIsbUNBQW1DLEdBQUc7QUFDdEMsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixFQUFFO0FBQ25COztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUSxPQUFPO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsOEJBQThCO0FBQy9DLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsNkJBQTZCO0FBQzlDOztBQUVBO0FBQ0EsbUJBQW1CLGdCQUFnQjtBQUNuQztBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGtDQUFrQyxrQkFBa0I7QUFDcEQsd0JBQXdCO0FBQ3hCLHdCQUF3QjtBQUN4QiwwQkFBMEI7QUFDMUIseUJBQXlCO0FBQ3pCOztBQUVBO0FBQ0E7QUFDQSw4REFBOEQ7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUSxzQkFBc0I7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0IsNEJBQTRCOztBQUU5QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLFVBQVUsbUJBQW1CO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQztBQUNELHFCQUFxQixlQUFlLEVBQUU7QUFDdEMsQ0FBQztBQUNEO0FBQ0E7O0FBRUEsQ0FBQztBQUNEO0FBQ0EsQ0FBQzs7Ozs7Ozs7QUNyd0NEOzs7Ozs7OztBQ0FBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxlQUFlO0FBQ2YsOENBQThDO0FBQzlDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUMvREE7Ozs7Ozs7QUNBQTtBQUNBO0FBQ0EsbUNBQWtDO0FBQ2xDLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7OztBQ2ZBOzs7Ozs7O0FDQUE7Ozs7Ozs7QUNBQTtBQUNBLDJDQUEyQztBQUMzQzs7Ozs7OztBQ0ZBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLFlBQVk7QUFDWjs7QUFFQTs7QUFFQSw4QkFBOEI7QUFDOUI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUI7O0FBRW5CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0Msc0JBQXNCLHVCQUF1Qix5QkFBeUI7QUFDeEc7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2xYQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsaUJBQWlCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwwQ0FBMEMsc0JBQXNCLEVBQUU7QUFDbEU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFVBQVU7QUFDVjtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7Ozs7Ozs7O0FDekxEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQW9GO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsZ0NBQWdDLFVBQVUsRUFBRTtBQUM1QyxDOzs7Ozs7QUNwQkE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBb0Y7QUFDcEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxnQ0FBZ0MsVUFBVSxFQUFFO0FBQzVDLEM7Ozs7OztBQ3BCQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFvRjtBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLGdDQUFnQyxVQUFVLEVBQUU7QUFDNUMsQzs7Ozs7O0FDcEJBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQW9GO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsZ0NBQWdDLFVBQVUsRUFBRTtBQUM1QyxDOzs7Ozs7QUNwQkE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUNuREE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQixXQUFXLE9BQU87QUFDbEIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNyQkE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBLG9DOzs7Ozs7QUNqREE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsRzs7Ozs7O0FDZkQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsb0NBQW9DO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEc7Ozs7OztBQ3JDRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUMsRzs7Ozs7O0FDbENEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQyxFOzs7Ozs7QUNsQkQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixHQUFHO0FBQ0g7QUFDQTtBQUNBLEc7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEc7Ozs7OztBQ2xHRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEc7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDLEc7Ozs7OztBQ25DRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSixHQUFHO0FBQ0g7QUFDQSxHO0FBQ0EsQ0FBQyxFOzs7Ozs7QUNwQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEc7Ozs7OztBQ2xIRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsSUFBSTtBQUNKLEdBQUc7QUFDSDtBQUNBLEc7QUFDQSxDQUFDLEc7Ozs7OztBQ3hCRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHO0FBQ0EsQ0FBQyxHOzs7Ozs7QUNiRDtBQUNBLHlDOzs7Ozs7QUNEQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsZ0JBQWdCO0FBQ2hCLGdCQUFnQjtBQUNoQixnQkFBZ0I7QUFDaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLGFBQWE7QUFDYixTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBLDZCQUE2Qjs7QUFFN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2I7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQSxrRUFBa0U7QUFDbEUsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCx1QkFBdUI7QUFDNUUsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw2QkFBNkIsVUFBVTtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQSxxQkFBcUI7QUFDckI7O0FBRUE7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7OztBQUdBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7O0FBRUw7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsOENBQThDO0FBQzNFO0FBQ0EsNEJBQTRCLDhDQUE4QztBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBLDZCOzs7Ozs7QUM3dUJBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVELDhDOzs7Ozs7O0FDTEE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHdDQUF3QyxtQ0FBbUMsMkJBQTJCO0FBQ3RHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTs7Ozs7OztBQ2pEQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdCOzs7Ozs7QUNSQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7Ozs7QUN0R0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDZCOzs7Ozs7QUNYQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxxQ0FBcUM7QUFDaEQ7QUFDQSxVQUFVLHFDQUFxQztBQUMvQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQix3QkFBd0I7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNCOzs7Ozs7QUN2R0E7QUFDQTs7QUFFQSwrQ0FBK0MsZ0NBQTZCLEVBQUU7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsd0I7Ozs7OztBQ1RBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLDJDQUEyQztBQUM5QyxHQUFHLDBDQUEwQztBQUM3QyxHQUFHLDZDQUE2QztBQUNoRCxHQUFHLDRDQUE0QztBQUMvQyxHQUFHLDJDQUEyQztBQUM5QyxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRywwQ0FBMEM7QUFDN0MsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwrQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVEO0FBQ3ZELDJDQUEyQztBQUMzQyxtREFBbUQ7QUFDbkQsNkNBQTZDO0FBQzdDO0FBQ0EseUNBQXlDO0FBQ3pDLCtDQUErQztBQUMvQyx5REFBeUQ7QUFDekQsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdCQUFnQix1QkFBdUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUM7Ozs7OztBQ3BPQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx3Qzs7Ozs7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdUM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLDJCQUEyQjtBQUNyQyxVQUFVLDJCQUEyQjtBQUNyQyxVQUFVLDJCQUEyQjtBQUNyQyxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlDOzs7Ozs7QUN2WkE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0M7Ozs7OztBQ2pMQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1QztBQUNBOztBQUVBO0FBQ0EsMEJBQTBCO0FBQzFCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUM7Ozs7OztBQ2hGQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwrQjs7Ozs7O0FDM0JBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9COztBQUVBOztBQUVBOzs7Ozs7O0FDakJBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7O0FDMUZBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUEscUM7Ozs7OztBQ3RFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxnQ0FBZ0M7QUFDbEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGtCQUFrQjtBQUNsRjtBQUNBLHlEQUF5RCxjQUFjO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELGlDQUFpQztBQUNsRix3SEFBd0gsbUJBQW1CLEVBQUU7QUFDN0k7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDBCQUEwQixFQUFFO0FBQy9ELHlDQUF5QyxlQUFlO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsK0RBQStEO0FBQzdIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0NBQWtDLFNBQVM7QUFDM0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBDQUEwQyxVQUFVO0FBQ3BEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCQUE0Qjs7QUFFNUIsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsbURBQW1EO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsVUFBVTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLHVDQUF1QyxTQUFTO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxpQkFBaUI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELEVBQUU7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGVBQWU7QUFDdkM7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0Esd0JBQXdCLFFBQVE7QUFDaEM7QUFDQSxxQkFBcUIsZUFBZTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFCQUFxQixTQUFTO0FBQzlCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQixTQUFTO0FBQzlCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1REFBdUQsT0FBTztBQUM5RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdURBQXVELE9BQU87QUFDOUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCO0FBQ2xCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLFFBQVE7QUFDN0I7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixZQUFZO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsWUFBWTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEI7O0FBRTVCLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDhDQUE4QztBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCOztBQUU1QixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixzQkFBc0I7QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQSxpQ0FBaUMsUUFBUTtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLHNDQUFzQyxRQUFRO0FBQzlDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxRQUFRLHlCQUF5QjtBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxrQ0FBa0MsRUFBRTtBQUNwQyxrQ0FBa0MsWUFBWTtBQUM5QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLENBQUM7OztBQUdEO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBUSxXQUFXOztBQUVuQjtBQUNBO0FBQ0E7QUFDQSxRQUFRLFdBQVc7O0FBRW5CO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxRQUFRLFdBQVc7O0FBRW5CO0FBQ0E7QUFDQSxRQUFRLFVBQVU7O0FBRWxCO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLHNDQUFzQyxzQ0FBc0M7QUFDekc7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsNEJBQTRCOztBQUU1QixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDOztBQUVyQztBQUNBO0FBQ0E7O0FBRUEsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixVQUFVOzs7QUFHdEMsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsT0FBTztBQUN2QztBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRyxhQUFhO0FBQ2hCO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkVBQTJFLDZFQUE2RTtBQUN4SjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLHNEQUFzRDs7QUFFdEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQ7QUFDN0Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNDQUFzQzs7QUFFdEM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSwrQ0FBK0M7O0FBRS9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRFQUE0RTs7QUFFNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbURBQW1EO0FBQ25EO0FBQ0EsbURBQW1ELGlFQUFpRTtBQUNwSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2QyxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2QyxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDLE9BQU87QUFDdkM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDLE9BQU87QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7O0FBRTVCLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEMsWUFBWTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLLEVBQUU7QUFDUCxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2REFBNkQ7QUFDN0Q7QUFDQTs7OztBQUlBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUcsYUFBYTtBQUNoQjtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMLEdBQUc7QUFDSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0RBQWtEOztBQUVsRDs7QUFFQSwyQ0FBMkM7QUFDM0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQ7QUFDbkQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DOztBQUVwQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLG9EQUFvRDtBQUNwRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0Qjs7QUFFNUIsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxlQUFlO0FBQ2YsOENBQThDO0FBQzlDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsK0NBQStDO0FBQy9DO0FBQ0EsMEZBQTBGO0FBQzFGLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDRCQUE0Qjs7QUFFNUIsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7O0FBRUE7O0FBRUEsOEJBQThCO0FBQzlCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1COztBQUVuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLHNCQUFzQix1QkFBdUIseUJBQXlCO0FBQ3hHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx5Q0FBeUMsU0FBUztBQUNsRDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQjs7QUFFbEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQjs7QUFFbEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFZLDRCQUE0QjtBQUN4QyxZQUFZLFVBQVU7QUFDdEIsWUFBWSwrQkFBK0I7QUFDM0MsWUFBWSxvQ0FBb0M7QUFDaEQsWUFBWSxVQUFVO0FBQ3RCLFlBQVksU0FBUztBQUNyQixZQUFZLFNBQVM7QUFDckIsWUFBWSxTQUFTO0FBQ3JCLFlBQVksU0FBUztBQUNyQixZQUFZLFNBQVM7QUFDckIsWUFBWSxTQUFTO0FBQ3JCLFlBQVksU0FBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGNBQWM7QUFDMUIsWUFBWTtBQUNaOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBLEVBQUU7QUFDRjtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHlCQUF5Qjs7QUFFekIsbUJBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLDZEQUE2RDtBQUNwRjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEMsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDRCQUE0QixxQkFBcUI7O0FBRWpEO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRixDQUFDOzs7QUFHRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0YsQ0FBQzs7O0FBR0QsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0YsQ0FBQzs7O0FBR0QsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEtBQUs7QUFDbkIsY0FBYyxLQUFLO0FBQ25CO0FBQ0EsWUFBWSxPQUFPO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxNQUFNO0FBQ3BCO0FBQ0EsYUFBYSxNQUFNO0FBQ25CO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLHVDQUF1QztBQUNoRSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0gseUJBQXlCLDBDQUEwQztBQUNuRTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EseUJBQXlCLHdCQUF3QjtBQUNqRCxHQUFHO0FBQ0gseUJBQXlCLDJCQUEyQjtBQUNwRDtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EseUJBQXlCLHdDQUF3QztBQUNqRSxHQUFHO0FBQ0gseUJBQXlCLDJDQUEyQztBQUNwRTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixvREFBb0Q7QUFDNUUsRUFBRTtBQUNGLHdCQUF3Qix1REFBdUQ7QUFDL0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUNBQWlDLE9BQU87QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUNBQWlDLE9BQU87QUFDeEM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUNBQWlDLGdCQUFnQjtBQUNqRDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUNBQWlDLE9BQU87QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQ0FBaUMsT0FBTztBQUN4QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGdCQUFnQixnQkFBZ0I7QUFDaEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DOztBQUVuQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSx3Q0FBd0M7O0FBRXhDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHNCQUFzQixpQkFBaUI7QUFDdkM7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxHQUFHO0FBQ0gsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUEsbUVBQW1FLFFBQVE7QUFDM0U7O0FBRUE7QUFDQSwwQkFBMEIsWUFBWTtBQUN0QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQSxFQUFFLElBQUk7QUFDTjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsK0RBQStEO0FBQy9EOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5REFBeUQ7QUFDekQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4QkFBOEIsaVdBQWlXOztBQUUvWCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4QkFBOEIsMnljQUEyeWMsd0tBQXdLLDR2WEFBNHZYLHdLQUF3SyxnNUVBQWc1RSwyK1BBQTIrUDs7QUFFaHhwQyxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4QkFBOEIsb3BEQUFvcEQ7O0FBRWxyRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4QkFBOEIseUVBQXlFOztBQUV2RyxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUEyQztBQUMzQzs7O0FBR0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsdURBQXVEO0FBQ3ZEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsaUJBQWlCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwwQ0FBMEMsc0JBQXNCLEVBQUU7QUFDbEU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFVBQVU7QUFDVjtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQsNEJBQTRCOztBQUU1QixPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7QUFJQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEI7O0FBRTVCLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQixXQUFXLE9BQU87QUFDbEIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCQUE0Qjs7QUFFNUIsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0Q0FBNEM7O0FBRTVDOzs7QUFHQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLG1CQUFtQixzQkFBc0I7QUFDekM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpR0FBaUcsOEJBQThCLEVBQUU7QUFDakk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUV2SiwyQ0FBMkMsZ0JBQWdCLGtCQUFrQixPQUFPLDJCQUEyQix3REFBd0QsZ0NBQWdDLHVEQUF1RCwyREFBMkQsRUFBRTs7QUFFM1QsNkRBQTZELHNFQUFzRSw4REFBOEQsb0JBQW9COzs7Ozs7Ozs7Ozs7O0FBYXJOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0NBQWdDO0FBQ2hDOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQzs7QUFFakM7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsMERBQTBEOzs7QUFHMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0VBQXdFOztBQUV4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEVBQThFOztBQUU5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsb0RBQW9EO0FBQ3BEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQ0FBbUM7QUFDbkMsMENBQTBDO0FBQzFDLE9BQU8sa0NBQWtDO0FBQ3pDLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDOztBQUVEOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ04sTUFBTTtBQUNOO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCwwQ0FBMEMsMERBQTBELEVBQUU7O0FBRXZKLDJDQUEyQyxnQkFBZ0Isa0JBQWtCLE9BQU8sMkJBQTJCLHdEQUF3RCxnQ0FBZ0MsdURBQXVELDJEQUEyRCxFQUFFOztBQUUzVCw2REFBNkQsc0VBQXNFLDhEQUE4RCxvQkFBb0I7Ozs7QUFJck47QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdkosMkNBQTJDLGdCQUFnQixrQkFBa0IsT0FBTywyQkFBMkIsd0RBQXdELGdDQUFnQyx1REFBdUQsMkRBQTJELEVBQUU7O0FBRTNULDZEQUE2RCxzRUFBc0UsOERBQThELG9CQUFvQjs7OztBQUlyTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPLHFCQUFxQjtBQUM1QixPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLHFCQUFxQix1QkFBdUI7QUFDNUM7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZixhQUFhO0FBQ2I7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE4QkE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0dBQW9HLHNFQUFzRSxFQUFFOztBQUU1SztBQUNBLHVHQUF1RyxnRkFBZ0YsRUFBRTs7QUFFekw7QUFDQSx1R0FBdUcsZ0ZBQWdGLEVBQUU7Ozs7Ozs7QUFPekwsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsT0FBTzs7QUFFUCxVQUFVO0FBQ1Ysd0M7Ozs7Ozs7QUNueFdBO0FBQ0E7O0FBRUEsK0NBQStDLGdDQUE2QixFQUFFO0FBQzlFO0FBQ0E7O0FBRUEsd0I7Ozs7OztBQ1BBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLHVCQUF1QjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQzs7Ozs7O0FDM1FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNSQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwrQjs7Ozs7O0FDM0JBLGU7Ozs7OztBQ0FBLGU7Ozs7OztBQ0FBLGU7Ozs7OztBQ0FBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEiLCJmaWxlIjoid2VicGFja2VkLmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGlkZW50aXR5IGZ1bmN0aW9uIGZvciBjYWxsaW5nIGhhcm1vbnkgaW1wb3J0cyB3aXRoIHRoZSBjb3JyZWN0IGNvbnRleHRcbiBcdF9fd2VicGFja19yZXF1aXJlX18uaSA9IGZ1bmN0aW9uKHZhbHVlKSB7IHJldHVybiB2YWx1ZTsgfTtcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7XG4gXHRcdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbiBcdFx0XHRcdGdldDogZ2V0dGVyXG4gXHRcdFx0fSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiL3Jlc291cmNlcy9qcy9cIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAxNDgpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHdlYnBhY2svYm9vdHN0cmFwIGFmYjQ3ZDE0MTQ5OTk1OWMxYTM3IiwidmFyIENob2NvbGF0ZXlQYWNrYWdlcyA9IHJlcXVpcmUoJy4vY2hvY29sYXRleS1wYWNrYWdlcycpO1xyXG52YXIgY3NzZGsgPSByZXF1aXJlKCcuLi9jcy1zZGsnKTtcclxuXHJcbnZhciBhbmd1bGFyID0gcmVxdWlyZSgnYW5ndWxhcicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhbmd1bGFyLm1vZHVsZShcImNob2NvbGF0ZXlDbGllbnRcIiwgWyduZ1Nhbml0aXplJ10pXHJcbi5mYWN0b3J5KFwiY2hvY29sYXRleVBhY2thZ2VzXCIsIFtcImNob2NvbGF0ZXlDbGllbnRDb25maWdcIiwgZnVuY3Rpb24oY2hvY29sYXRleUNsaWVudENvbmZpZykge1xyXG5cdHJldHVybiBuZXcgQ2hvY29sYXRleVBhY2thZ2VzKGNzc2RrLCBjaG9jb2xhdGV5Q2xpZW50Q29uZmlnKTtcclxufV0pXHJcbi5wcm92aWRlcihcImNob2NvbGF0ZXlDbGllbnRDb25maWdcIiwgZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5jbG91ZFNoYXJlSG9zdG5hbWUgPSB3aW5kb3cubG9jYXRpb24uaG9zdDtcclxuXHR0aGlzLmFwaUlkID0gbnVsbDtcclxuXHR0aGlzLmFwaUtleSA9IG51bGw7XHJcblx0dGhpcy5jaG9jb2xhdGV5SWNvblNtYWxsSW1hZ2VQYXRoID0gXCIvcmVzb3VyY2VzL2ltZ3MvY2hvY29sYXRleWljb25fd2hpdGVfc21hbGwucG5nXCI7XHJcblx0dGhpcy5wcmVsb2FkZXJJbWFnZVBhdGggPSBcIi9yZXNvdXJjZXMvaW1ncy9jc2FwcC9jcmVhdGUvcHJlbG9hZGVyLmdpZlwiO1xyXG5cclxuXHR0aGlzLiRnZXQgPSBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdGNsb3VkU2hhcmVIb3N0bmFtZTogdGhpcy5jbG91ZFNoYXJlSG9zdG5hbWUsXHJcblx0XHRcdGFwaUlkOiB0aGlzLmFwaUlkLFxyXG5cdFx0XHRhcGlLZXk6IHRoaXMuYXBpS2V5LFxyXG5cdFx0XHRjaG9jb2xhdGV5SWNvblNtYWxsSW1hZ2VQYXRoOiB0aGlzLmNob2NvbGF0ZXlJY29uU21hbGxJbWFnZVBhdGgsXHJcblx0XHRcdHByZWxvYWRlckltYWdlUGF0aDogdGhpcy5wcmVsb2FkZXJJbWFnZVBhdGhcclxuXHRcdH07XHJcblx0fTtcclxufSk7XHJcblxyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9uZy1tb2R1bGUuanNcbi8vIG1vZHVsZSBpZCA9IDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuLypcbiAqIEV4cG9ydCBrTWF4TGVuZ3RoIGFmdGVyIHR5cGVkIGFycmF5IHN1cHBvcnQgaXMgZGV0ZXJtaW5lZC5cbiAqL1xuZXhwb3J0cy5rTWF4TGVuZ3RoID0ga01heExlbmd0aCgpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0ge19fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfX1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAodGhhdCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2MobnVsbCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplIDwgMCA/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+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGlzbmFuICh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gdmFsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vYnVmZmVyL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSAyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGEgZHVwbGV4IHN0cmVhbSBpcyBqdXN0IGEgc3RyZWFtIHRoYXQgaXMgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUuXG4vLyBTaW5jZSBKUyBkb2Vzbid0IGhhdmUgbXVsdGlwbGUgcHJvdG90eXBhbCBpbmhlcml0YW5jZSwgdGhpcyBjbGFzc1xuLy8gcHJvdG90eXBhbGx5IGluaGVyaXRzIGZyb20gUmVhZGFibGUsIGFuZCB0aGVuIHBhcmFzaXRpY2FsbHkgZnJvbVxuLy8gV3JpdGFibGUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBrZXlzLnB1c2goa2V5KTtcbiAgfXJldHVybiBrZXlzO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFJlYWRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3JlYWRhYmxlJyk7XG52YXIgV3JpdGFibGUgPSByZXF1aXJlKCcuL19zdHJlYW1fd3JpdGFibGUnKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxudmFyIGtleXMgPSBvYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7XG5mb3IgKHZhciB2ID0gMDsgdiA8IGtleXMubGVuZ3RoOyB2KyspIHtcbiAgdmFyIG1ldGhvZCA9IGtleXNbdl07XG4gIGlmICghRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKSBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgcHJvY2Vzc05leHRUaWNrKG9uRW5kTlQsIHRoaXMpO1xufVxuXG5mdW5jdGlvbiBvbkVuZE5UKHNlbGYpIHtcbiAgc2VsZi5lbmQoKTtcbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanNcbi8vIG1vZHVsZSBpZCA9IDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGc7XHJcblxyXG4vLyBUaGlzIHdvcmtzIGluIG5vbi1zdHJpY3QgbW9kZVxyXG5nID0gKGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiB0aGlzO1xyXG59KSgpO1xyXG5cclxudHJ5IHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIGV2YWwgaXMgYWxsb3dlZCAoc2VlIENTUClcclxuXHRnID0gZyB8fCBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKCkgfHwgKDEsZXZhbCkoXCJ0aGlzXCIpO1xyXG59IGNhdGNoKGUpIHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxyXG5cdGlmKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIpXHJcblx0XHRnID0gd2luZG93O1xyXG59XHJcblxyXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXHJcbi8vIFdlIHJldHVybiB1bmRlZmluZWQsIGluc3RlYWQgb2Ygbm90aGluZyBoZXJlLCBzbyBpdCdzXHJcbi8vIGVhc2llciB0byBoYW5kbGUgdGhpcyBjYXNlLiBpZighZ2xvYmFsKSB7IC4uLn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZztcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzXG4vLyBtb2R1bGUgaWQgPSA0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIVxuICogQG92ZXJ2aWV3IGVzNi1wcm9taXNlIC0gYSB0aW55IGltcGxlbWVudGF0aW9uIG9mIFByb21pc2VzL0ErLlxuICogQGNvcHlyaWdodCBDb3B5cmlnaHQgKGMpIDIwMTQgWWVodWRhIEthdHosIFRvbSBEYWxlLCBTdGVmYW4gUGVubmVyIGFuZCBjb250cmlidXRvcnMgKENvbnZlcnNpb24gdG8gRVM2IEFQSSBieSBKYWtlIEFyY2hpYmFsZClcbiAqIEBsaWNlbnNlICAgTGljZW5zZWQgdW5kZXIgTUlUIGxpY2Vuc2VcbiAqICAgICAgICAgICAgU2VlIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9zdGVmYW5wZW5uZXIvZXM2LXByb21pc2UvbWFzdGVyL0xJQ0VOU0VcbiAqIEB2ZXJzaW9uICAgMy4zLjFcbiAqL1xuXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICAgIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuICAgIChnbG9iYWwuRVM2UHJvbWlzZSA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gb2JqZWN0T3JGdW5jdGlvbih4KSB7XG4gIHJldHVybiB0eXBlb2YgeCA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbih4KSB7XG4gIHJldHVybiB0eXBlb2YgeCA9PT0gJ2Z1bmN0aW9uJztcbn1cblxudmFyIF9pc0FycmF5ID0gdW5kZWZpbmVkO1xuaWYgKCFBcnJheS5pc0FycmF5KSB7XG4gIF9pc0FycmF5ID0gZnVuY3Rpb24gKHgpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHgpID09PSAnW29iamVjdCBBcnJheV0nO1xuICB9O1xufSBlbHNlIHtcbiAgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xufVxuXG52YXIgaXNBcnJheSA9IF9pc0FycmF5O1xuXG52YXIgbGVuID0gMDtcbnZhciB2ZXJ0eE5leHQgPSB1bmRlZmluZWQ7XG52YXIgY3VzdG9tU2NoZWR1bGVyRm4gPSB1bmRlZmluZWQ7XG5cbnZhciBhc2FwID0gZnVuY3Rpb24gYXNhcChjYWxsYmFjaywgYXJnKSB7XG4gIHF1ZXVlW2xlbl0gPSBjYWxsYmFjaztcbiAgcXVldWVbbGVuICsgMV0gPSBhcmc7XG4gIGxlbiArPSAyO1xuICBpZiAobGVuID09PSAyKSB7XG4gICAgLy8gSWYgbGVuIGlzIDIsIHRoYXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHNjaGVkdWxlIGFuIGFzeW5jIGZsdXNoLlxuICAgIC8vIElmIGFkZGl0aW9uYWwgY2FsbGJhY2tzIGFyZSBxdWV1ZWQgYmVmb3JlIHRoZSBxdWV1ZSBpcyBmbHVzaGVkLCB0aGV5XG4gICAgLy8gd2lsbCBiZSBwcm9jZXNzZWQgYnkgdGhpcyBmbHVzaCB0aGF0IHdlIGFyZSBzY2hlZHVsaW5nLlxuICAgIGlmIChjdXN0b21TY2hlZHVsZXJGbikge1xuICAgICAgY3VzdG9tU2NoZWR1bGVyRm4oZmx1c2gpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2hlZHVsZUZsdXNoKCk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBzZXRTY2hlZHVsZXIoc2NoZWR1bGVGbikge1xuICBjdXN0b21TY2hlZHVsZXJGbiA9IHNjaGVkdWxlRm47XG59XG5cbmZ1bmN0aW9uIHNldEFzYXAoYXNhcEZuKSB7XG4gIGFzYXAgPSBhc2FwRm47XG59XG5cbnZhciBicm93c2VyV2luZG93ID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB1bmRlZmluZWQ7XG52YXIgYnJvd3Nlckdsb2JhbCA9IGJyb3dzZXJXaW5kb3cgfHwge307XG52YXIgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIgPSBicm93c2VyR2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgYnJvd3Nlckdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xudmFyIGlzTm9kZSA9IHR5cGVvZiBzZWxmID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgKHt9KS50b1N0cmluZy5jYWxsKHByb2Nlc3MpID09PSAnW29iamVjdCBwcm9jZXNzXSc7XG5cbi8vIHRlc3QgZm9yIHdlYiB3b3JrZXIgYnV0IG5vdCBpbiBJRTEwXG52YXIgaXNXb3JrZXIgPSB0eXBlb2YgVWludDhDbGFtcGVkQXJyYXkgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBpbXBvcnRTY3JpcHRzICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgTWVzc2FnZUNoYW5uZWwgIT09ICd1bmRlZmluZWQnO1xuXG4vLyBub2RlXG5mdW5jdGlvbiB1c2VOZXh0VGljaygpIHtcbiAgLy8gbm9kZSB2ZXJzaW9uIDAuMTAueCBkaXNwbGF5cyBhIGRlcHJlY2F0aW9uIHdhcm5pbmcgd2hlbiBuZXh0VGljayBpcyB1c2VkIHJlY3Vyc2l2ZWx5XG4gIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vY3Vqb2pzL3doZW4vaXNzdWVzLzQxMCBmb3IgZGV0YWlsc1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZsdXNoKTtcbiAgfTtcbn1cblxuLy8gdmVydHhcbmZ1bmN0aW9uIHVzZVZlcnR4VGltZXIoKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmVydHhOZXh0KGZsdXNoKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gdXNlTXV0YXRpb25PYnNlcnZlcigpIHtcbiAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICB2YXIgb2JzZXJ2ZXIgPSBuZXcgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIoZmx1c2gpO1xuICB2YXIgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgb2JzZXJ2ZXIub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBub2RlLmRhdGEgPSBpdGVyYXRpb25zID0gKytpdGVyYXRpb25zICUgMjtcbiAgfTtcbn1cblxuLy8gd2ViIHdvcmtlclxuZnVuY3Rpb24gdXNlTWVzc2FnZUNoYW5uZWwoKSB7XG4gIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZmx1c2g7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHVzZVNldFRpbWVvdXQoKSB7XG4gIC8vIFN0b3JlIHNldFRpbWVvdXQgcmVmZXJlbmNlIHNvIGVzNi1wcm9taXNlIHdpbGwgYmUgdW5hZmZlY3RlZCBieVxuICAvLyBvdGhlciBjb2RlIG1vZGlmeWluZyBzZXRUaW1lb3V0IChsaWtlIHNpbm9uLnVzZUZha2VUaW1lcnMoKSlcbiAgdmFyIGdsb2JhbFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBnbG9iYWxTZXRUaW1lb3V0KGZsdXNoLCAxKTtcbiAgfTtcbn1cblxudmFyIHF1ZXVlID0gbmV3IEFycmF5KDEwMDApO1xuZnVuY3Rpb24gZmx1c2goKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICB2YXIgY2FsbGJhY2sgPSBxdWV1ZVtpXTtcbiAgICB2YXIgYXJnID0gcXVldWVbaSArIDFdO1xuXG4gICAgY2FsbGJhY2soYXJnKTtcblxuICAgIHF1ZXVlW2ldID0gdW5kZWZpbmVkO1xuICAgIHF1ZXVlW2kgKyAxXSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIGF0dGVtcHRWZXJ0eCgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgciA9IHJlcXVpcmU7XG4gICAgdmFyIHZlcnR4ID0gcigndmVydHgnKTtcbiAgICB2ZXJ0eE5leHQgPSB2ZXJ0eC5ydW5Pbkxvb3AgfHwgdmVydHgucnVuT25Db250ZXh0O1xuICAgIHJldHVybiB1c2VWZXJ0eFRpbWVyKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gdXNlU2V0VGltZW91dCgpO1xuICB9XG59XG5cbnZhciBzY2hlZHVsZUZsdXNoID0gdW5kZWZpbmVkO1xuLy8gRGVjaWRlIHdoYXQgYXN5bmMgbWV0aG9kIHRvIHVzZSB0byB0cmlnZ2VyaW5nIHByb2Nlc3Npbmcgb2YgcXVldWVkIGNhbGxiYWNrczpcbmlmIChpc05vZGUpIHtcbiAgc2NoZWR1bGVGbHVzaCA9IHVzZU5leHRUaWNrKCk7XG59IGVsc2UgaWYgKEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyKSB7XG4gIHNjaGVkdWxlRmx1c2ggPSB1c2VNdXRhdGlvbk9ic2VydmVyKCk7XG59IGVsc2UgaWYgKGlzV29ya2VyKSB7XG4gIHNjaGVkdWxlRmx1c2ggPSB1c2VNZXNzYWdlQ2hhbm5lbCgpO1xufSBlbHNlIGlmIChicm93c2VyV2luZG93ID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicpIHtcbiAgc2NoZWR1bGVGbHVzaCA9IGF0dGVtcHRWZXJ0eCgpO1xufSBlbHNlIHtcbiAgc2NoZWR1bGVGbHVzaCA9IHVzZVNldFRpbWVvdXQoKTtcbn1cblxuZnVuY3Rpb24gdGhlbihvbkZ1bGZpbGxtZW50LCBvblJlamVjdGlvbikge1xuICB2YXIgX2FyZ3VtZW50cyA9IGFyZ3VtZW50cztcblxuICB2YXIgcGFyZW50ID0gdGhpcztcblxuICB2YXIgY2hpbGQgPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcihub29wKTtcblxuICBpZiAoY2hpbGRbUFJPTUlTRV9JRF0gPT09IHVuZGVmaW5lZCkge1xuICAgIG1ha2VQcm9taXNlKGNoaWxkKTtcbiAgfVxuXG4gIHZhciBfc3RhdGUgPSBwYXJlbnQuX3N0YXRlO1xuXG4gIGlmIChfc3RhdGUpIHtcbiAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGNhbGxiYWNrID0gX2FyZ3VtZW50c1tfc3RhdGUgLSAxXTtcbiAgICAgIGFzYXAoZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gaW52b2tlQ2FsbGJhY2soX3N0YXRlLCBjaGlsZCwgY2FsbGJhY2ssIHBhcmVudC5fcmVzdWx0KTtcbiAgICAgIH0pO1xuICAgIH0pKCk7XG4gIH0gZWxzZSB7XG4gICAgc3Vic2NyaWJlKHBhcmVudCwgY2hpbGQsIG9uRnVsZmlsbG1lbnQsIG9uUmVqZWN0aW9uKTtcbiAgfVxuXG4gIHJldHVybiBjaGlsZDtcbn1cblxuLyoqXG4gIGBQcm9taXNlLnJlc29sdmVgIHJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCBiZWNvbWUgcmVzb2x2ZWQgd2l0aCB0aGVcbiAgcGFzc2VkIGB2YWx1ZWAuIEl0IGlzIHNob3J0aGFuZCBmb3IgdGhlIGZvbGxvd2luZzpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICByZXNvbHZlKDEpO1xuICB9KTtcblxuICBwcm9taXNlLnRoZW4oZnVuY3Rpb24odmFsdWUpe1xuICAgIC8vIHZhbHVlID09PSAxXG4gIH0pO1xuICBgYGBcblxuICBJbnN0ZWFkIG9mIHdyaXRpbmcgdGhlIGFib3ZlLCB5b3VyIGNvZGUgbm93IHNpbXBseSBiZWNvbWVzIHRoZSBmb2xsb3dpbmc6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgxKTtcblxuICBwcm9taXNlLnRoZW4oZnVuY3Rpb24odmFsdWUpe1xuICAgIC8vIHZhbHVlID09PSAxXG4gIH0pO1xuICBgYGBcblxuICBAbWV0aG9kIHJlc29sdmVcbiAgQHN0YXRpY1xuICBAcGFyYW0ge0FueX0gdmFsdWUgdmFsdWUgdGhhdCB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGJlIHJlc29sdmVkIHdpdGhcbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgdGhhdCB3aWxsIGJlY29tZSBmdWxmaWxsZWQgd2l0aCB0aGUgZ2l2ZW5cbiAgYHZhbHVlYFxuKi9cbmZ1bmN0aW9uIHJlc29sdmUob2JqZWN0KSB7XG4gIC8qanNoaW50IHZhbGlkdGhpczp0cnVlICovXG4gIHZhciBDb25zdHJ1Y3RvciA9IHRoaXM7XG5cbiAgaWYgKG9iamVjdCAmJiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJiBvYmplY3QuY29uc3RydWN0b3IgPT09IENvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuXG4gIHZhciBwcm9taXNlID0gbmV3IENvbnN0cnVjdG9yKG5vb3ApO1xuICBfcmVzb2x2ZShwcm9taXNlLCBvYmplY3QpO1xuICByZXR1cm4gcHJvbWlzZTtcbn1cblxudmFyIFBST01JU0VfSUQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMTYpO1xuXG5mdW5jdGlvbiBub29wKCkge31cblxudmFyIFBFTkRJTkcgPSB2b2lkIDA7XG52YXIgRlVMRklMTEVEID0gMTtcbnZhciBSRUpFQ1RFRCA9IDI7XG5cbnZhciBHRVRfVEhFTl9FUlJPUiA9IG5ldyBFcnJvck9iamVjdCgpO1xuXG5mdW5jdGlvbiBzZWxmRnVsZmlsbG1lbnQoKSB7XG4gIHJldHVybiBuZXcgVHlwZUVycm9yKFwiWW91IGNhbm5vdCByZXNvbHZlIGEgcHJvbWlzZSB3aXRoIGl0c2VsZlwiKTtcbn1cblxuZnVuY3Rpb24gY2Fubm90UmV0dXJuT3duKCkge1xuICByZXR1cm4gbmV3IFR5cGVFcnJvcignQSBwcm9taXNlcyBjYWxsYmFjayBjYW5ub3QgcmV0dXJuIHRoYXQgc2FtZSBwcm9taXNlLicpO1xufVxuXG5mdW5jdGlvbiBnZXRUaGVuKHByb21pc2UpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcHJvbWlzZS50aGVuO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIEdFVF9USEVOX0VSUk9SLmVycm9yID0gZXJyb3I7XG4gICAgcmV0dXJuIEdFVF9USEVOX0VSUk9SO1xuICB9XG59XG5cbmZ1bmN0aW9uIHRyeVRoZW4odGhlbiwgdmFsdWUsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcikge1xuICB0cnkge1xuICAgIHRoZW4uY2FsbCh2YWx1ZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSwgdGhlbikge1xuICBhc2FwKGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgdmFyIHNlYWxlZCA9IGZhbHNlO1xuICAgIHZhciBlcnJvciA9IHRyeVRoZW4odGhlbiwgdGhlbmFibGUsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgaWYgKHNlYWxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgaWYgKHRoZW5hYmxlICE9PSB2YWx1ZSkge1xuICAgICAgICBfcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmdWxmaWxsKHByb21pc2UsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICBpZiAoc2VhbGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNlYWxlZCA9IHRydWU7XG5cbiAgICAgIF9yZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICB9LCAnU2V0dGxlOiAnICsgKHByb21pc2UuX2xhYmVsIHx8ICcgdW5rbm93biBwcm9taXNlJykpO1xuXG4gICAgaWYgKCFzZWFsZWQgJiYgZXJyb3IpIHtcbiAgICAgIHNlYWxlZCA9IHRydWU7XG4gICAgICBfcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgICB9XG4gIH0sIHByb21pc2UpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVPd25UaGVuYWJsZShwcm9taXNlLCB0aGVuYWJsZSkge1xuICBpZiAodGhlbmFibGUuX3N0YXRlID09PSBGVUxGSUxMRUQpIHtcbiAgICBmdWxmaWxsKHByb21pc2UsIHRoZW5hYmxlLl9yZXN1bHQpO1xuICB9IGVsc2UgaWYgKHRoZW5hYmxlLl9zdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICBfcmVqZWN0KHByb21pc2UsIHRoZW5hYmxlLl9yZXN1bHQpO1xuICB9IGVsc2Uge1xuICAgIHN1YnNjcmliZSh0aGVuYWJsZSwgdW5kZWZpbmVkLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHJldHVybiBfcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSk7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgcmV0dXJuIF9yZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUsIHRoZW4kJCkge1xuICBpZiAobWF5YmVUaGVuYWJsZS5jb25zdHJ1Y3RvciA9PT0gcHJvbWlzZS5jb25zdHJ1Y3RvciAmJiB0aGVuJCQgPT09IHRoZW4gJiYgbWF5YmVUaGVuYWJsZS5jb25zdHJ1Y3Rvci5yZXNvbHZlID09PSByZXNvbHZlKSB7XG4gICAgaGFuZGxlT3duVGhlbmFibGUocHJvbWlzZSwgbWF5YmVUaGVuYWJsZSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoZW4kJCA9PT0gR0VUX1RIRU5fRVJST1IpIHtcbiAgICAgIF9yZWplY3QocHJvbWlzZSwgR0VUX1RIRU5fRVJST1IuZXJyb3IpO1xuICAgIH0gZWxzZSBpZiAodGhlbiQkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZ1bGZpbGwocHJvbWlzZSwgbWF5YmVUaGVuYWJsZSk7XG4gICAgfSBlbHNlIGlmIChpc0Z1bmN0aW9uKHRoZW4kJCkpIHtcbiAgICAgIGhhbmRsZUZvcmVpZ25UaGVuYWJsZShwcm9taXNlLCBtYXliZVRoZW5hYmxlLCB0aGVuJCQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmdWxmaWxsKHByb21pc2UsIG1heWJlVGhlbmFibGUpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBfcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSkge1xuICBpZiAocHJvbWlzZSA9PT0gdmFsdWUpIHtcbiAgICBfcmVqZWN0KHByb21pc2UsIHNlbGZGdWxmaWxsbWVudCgpKTtcbiAgfSBlbHNlIGlmIChvYmplY3RPckZ1bmN0aW9uKHZhbHVlKSkge1xuICAgIGhhbmRsZU1heWJlVGhlbmFibGUocHJvbWlzZSwgdmFsdWUsIGdldFRoZW4odmFsdWUpKTtcbiAgfSBlbHNlIHtcbiAgICBmdWxmaWxsKHByb21pc2UsIHZhbHVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwdWJsaXNoUmVqZWN0aW9uKHByb21pc2UpIHtcbiAgaWYgKHByb21pc2UuX29uZXJyb3IpIHtcbiAgICBwcm9taXNlLl9vbmVycm9yKHByb21pc2UuX3Jlc3VsdCk7XG4gIH1cblxuICBwdWJsaXNoKHByb21pc2UpO1xufVxuXG5mdW5jdGlvbiBmdWxmaWxsKHByb21pc2UsIHZhbHVlKSB7XG4gIGlmIChwcm9taXNlLl9zdGF0ZSAhPT0gUEVORElORykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHByb21pc2UuX3Jlc3VsdCA9IHZhbHVlO1xuICBwcm9taXNlLl9zdGF0ZSA9IEZVTEZJTExFRDtcblxuICBpZiAocHJvbWlzZS5fc3Vic2NyaWJlcnMubGVuZ3RoICE9PSAwKSB7XG4gICAgYXNhcChwdWJsaXNoLCBwcm9taXNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfcmVqZWN0KHByb21pc2UsIHJlYXNvbikge1xuICBpZiAocHJvbWlzZS5fc3RhdGUgIT09IFBFTkRJTkcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcHJvbWlzZS5fc3RhdGUgPSBSRUpFQ1RFRDtcbiAgcHJvbWlzZS5fcmVzdWx0ID0gcmVhc29uO1xuXG4gIGFzYXAocHVibGlzaFJlamVjdGlvbiwgcHJvbWlzZSk7XG59XG5cbmZ1bmN0aW9uIHN1YnNjcmliZShwYXJlbnQsIGNoaWxkLCBvbkZ1bGZpbGxtZW50LCBvblJlamVjdGlvbikge1xuICB2YXIgX3N1YnNjcmliZXJzID0gcGFyZW50Ll9zdWJzY3JpYmVycztcbiAgdmFyIGxlbmd0aCA9IF9zdWJzY3JpYmVycy5sZW5ndGg7XG5cbiAgcGFyZW50Ll9vbmVycm9yID0gbnVsbDtcblxuICBfc3Vic2NyaWJlcnNbbGVuZ3RoXSA9IGNoaWxkO1xuICBfc3Vic2NyaWJlcnNbbGVuZ3RoICsgRlVMRklMTEVEXSA9IG9uRnVsZmlsbG1lbnQ7XG4gIF9zdWJzY3JpYmVyc1tsZW5ndGggKyBSRUpFQ1RFRF0gPSBvblJlamVjdGlvbjtcblxuICBpZiAobGVuZ3RoID09PSAwICYmIHBhcmVudC5fc3RhdGUpIHtcbiAgICBhc2FwKHB1Ymxpc2gsIHBhcmVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHVibGlzaChwcm9taXNlKSB7XG4gIHZhciBzdWJzY3JpYmVycyA9IHByb21pc2UuX3N1YnNjcmliZXJzO1xuICB2YXIgc2V0dGxlZCA9IHByb21pc2UuX3N0YXRlO1xuXG4gIGlmIChzdWJzY3JpYmVycy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgY2hpbGQgPSB1bmRlZmluZWQsXG4gICAgICBjYWxsYmFjayA9IHVuZGVmaW5lZCxcbiAgICAgIGRldGFpbCA9IHByb21pc2UuX3Jlc3VsdDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN1YnNjcmliZXJzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgY2hpbGQgPSBzdWJzY3JpYmVyc1tpXTtcbiAgICBjYWxsYmFjayA9IHN1YnNjcmliZXJzW2kgKyBzZXR0bGVkXTtcblxuICAgIGlmIChjaGlsZCkge1xuICAgICAgaW52b2tlQ2FsbGJhY2soc2V0dGxlZCwgY2hpbGQsIGNhbGxiYWNrLCBkZXRhaWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayhkZXRhaWwpO1xuICAgIH1cbiAgfVxuXG4gIHByb21pc2UuX3N1YnNjcmliZXJzLmxlbmd0aCA9IDA7XG59XG5cbmZ1bmN0aW9uIEVycm9yT2JqZWN0KCkge1xuICB0aGlzLmVycm9yID0gbnVsbDtcbn1cblxudmFyIFRSWV9DQVRDSF9FUlJPUiA9IG5ldyBFcnJvck9iamVjdCgpO1xuXG5mdW5jdGlvbiB0cnlDYXRjaChjYWxsYmFjaywgZGV0YWlsKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKGRldGFpbCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBUUllfQ0FUQ0hfRVJST1IuZXJyb3IgPSBlO1xuICAgIHJldHVybiBUUllfQ0FUQ0hfRVJST1I7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW52b2tlQ2FsbGJhY2soc2V0dGxlZCwgcHJvbWlzZSwgY2FsbGJhY2ssIGRldGFpbCkge1xuICB2YXIgaGFzQ2FsbGJhY2sgPSBpc0Z1bmN0aW9uKGNhbGxiYWNrKSxcbiAgICAgIHZhbHVlID0gdW5kZWZpbmVkLFxuICAgICAgZXJyb3IgPSB1bmRlZmluZWQsXG4gICAgICBzdWNjZWVkZWQgPSB1bmRlZmluZWQsXG4gICAgICBmYWlsZWQgPSB1bmRlZmluZWQ7XG5cbiAgaWYgKGhhc0NhbGxiYWNrKSB7XG4gICAgdmFsdWUgPSB0cnlDYXRjaChjYWxsYmFjaywgZGV0YWlsKTtcblxuICAgIGlmICh2YWx1ZSA9PT0gVFJZX0NBVENIX0VSUk9SKSB7XG4gICAgICBmYWlsZWQgPSB0cnVlO1xuICAgICAgZXJyb3IgPSB2YWx1ZS5lcnJvcjtcbiAgICAgIHZhbHVlID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3VjY2VlZGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocHJvbWlzZSA9PT0gdmFsdWUpIHtcbiAgICAgIF9yZWplY3QocHJvbWlzZSwgY2Fubm90UmV0dXJuT3duKCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9IGRldGFpbDtcbiAgICBzdWNjZWVkZWQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgLy8gbm9vcFxuICB9IGVsc2UgaWYgKGhhc0NhbGxiYWNrICYmIHN1Y2NlZWRlZCkge1xuICAgICAgX3Jlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoZmFpbGVkKSB7XG4gICAgICBfcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgICB9IGVsc2UgaWYgKHNldHRsZWQgPT09IEZVTEZJTExFRCkge1xuICAgICAgZnVsZmlsbChwcm9taXNlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChzZXR0bGVkID09PSBSRUpFQ1RFRCkge1xuICAgICAgX3JlamVjdChwcm9taXNlLCB2YWx1ZSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplUHJvbWlzZShwcm9taXNlLCByZXNvbHZlcikge1xuICB0cnkge1xuICAgIHJlc29sdmVyKGZ1bmN0aW9uIHJlc29sdmVQcm9taXNlKHZhbHVlKSB7XG4gICAgICBfcmVzb2x2ZShwcm9taXNlLCB2YWx1ZSk7XG4gICAgfSwgZnVuY3Rpb24gcmVqZWN0UHJvbWlzZShyZWFzb24pIHtcbiAgICAgIF9yZWplY3QocHJvbWlzZSwgcmVhc29uKTtcbiAgICB9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIF9yZWplY3QocHJvbWlzZSwgZSk7XG4gIH1cbn1cblxudmFyIGlkID0gMDtcbmZ1bmN0aW9uIG5leHRJZCgpIHtcbiAgcmV0dXJuIGlkKys7XG59XG5cbmZ1bmN0aW9uIG1ha2VQcm9taXNlKHByb21pc2UpIHtcbiAgcHJvbWlzZVtQUk9NSVNFX0lEXSA9IGlkKys7XG4gIHByb21pc2UuX3N0YXRlID0gdW5kZWZpbmVkO1xuICBwcm9taXNlLl9yZXN1bHQgPSB1bmRlZmluZWQ7XG4gIHByb21pc2UuX3N1YnNjcmliZXJzID0gW107XG59XG5cbmZ1bmN0aW9uIEVudW1lcmF0b3IoQ29uc3RydWN0b3IsIGlucHV0KSB7XG4gIHRoaXMuX2luc3RhbmNlQ29uc3RydWN0b3IgPSBDb25zdHJ1Y3RvcjtcbiAgdGhpcy5wcm9taXNlID0gbmV3IENvbnN0cnVjdG9yKG5vb3ApO1xuXG4gIGlmICghdGhpcy5wcm9taXNlW1BST01JU0VfSURdKSB7XG4gICAgbWFrZVByb21pc2UodGhpcy5wcm9taXNlKTtcbiAgfVxuXG4gIGlmIChpc0FycmF5KGlucHV0KSkge1xuICAgIHRoaXMuX2lucHV0ID0gaW5wdXQ7XG4gICAgdGhpcy5sZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gICAgdGhpcy5fcmVtYWluaW5nID0gaW5wdXQubGVuZ3RoO1xuXG4gICAgdGhpcy5fcmVzdWx0ID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoKTtcblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZnVsZmlsbCh0aGlzLnByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGVuZ3RoID0gdGhpcy5sZW5ndGggfHwgMDtcbiAgICAgIHRoaXMuX2VudW1lcmF0ZSgpO1xuICAgICAgaWYgKHRoaXMuX3JlbWFpbmluZyA9PT0gMCkge1xuICAgICAgICBmdWxmaWxsKHRoaXMucHJvbWlzZSwgdGhpcy5fcmVzdWx0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgX3JlamVjdCh0aGlzLnByb21pc2UsIHZhbGlkYXRpb25FcnJvcigpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0aW9uRXJyb3IoKSB7XG4gIHJldHVybiBuZXcgRXJyb3IoJ0FycmF5IE1ldGhvZHMgbXVzdCBiZSBwcm92aWRlZCBhbiBBcnJheScpO1xufTtcblxuRW51bWVyYXRvci5wcm90b3R5cGUuX2VudW1lcmF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICB2YXIgX2lucHV0ID0gdGhpcy5faW5wdXQ7XG5cbiAgZm9yICh2YXIgaSA9IDA7IHRoaXMuX3N0YXRlID09PSBQRU5ESU5HICYmIGkgPCBsZW5ndGg7IGkrKykge1xuICAgIHRoaXMuX2VhY2hFbnRyeShfaW5wdXRbaV0sIGkpO1xuICB9XG59O1xuXG5FbnVtZXJhdG9yLnByb3RvdHlwZS5fZWFjaEVudHJ5ID0gZnVuY3Rpb24gKGVudHJ5LCBpKSB7XG4gIHZhciBjID0gdGhpcy5faW5zdGFuY2VDb25zdHJ1Y3RvcjtcbiAgdmFyIHJlc29sdmUkJCA9IGMucmVzb2x2ZTtcblxuICBpZiAocmVzb2x2ZSQkID09PSByZXNvbHZlKSB7XG4gICAgdmFyIF90aGVuID0gZ2V0VGhlbihlbnRyeSk7XG5cbiAgICBpZiAoX3RoZW4gPT09IHRoZW4gJiYgZW50cnkuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgICB0aGlzLl9zZXR0bGVkQXQoZW50cnkuX3N0YXRlLCBpLCBlbnRyeS5fcmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBfdGhlbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5fcmVtYWluaW5nLS07XG4gICAgICB0aGlzLl9yZXN1bHRbaV0gPSBlbnRyeTtcbiAgICB9IGVsc2UgaWYgKGMgPT09IFByb21pc2UpIHtcbiAgICAgIHZhciBwcm9taXNlID0gbmV3IGMobm9vcCk7XG4gICAgICBoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIGVudHJ5LCBfdGhlbik7XG4gICAgICB0aGlzLl93aWxsU2V0dGxlQXQocHJvbWlzZSwgaSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3dpbGxTZXR0bGVBdChuZXcgYyhmdW5jdGlvbiAocmVzb2x2ZSQkKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlJCQoZW50cnkpO1xuICAgICAgfSksIGkpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aGlzLl93aWxsU2V0dGxlQXQocmVzb2x2ZSQkKGVudHJ5KSwgaSk7XG4gIH1cbn07XG5cbkVudW1lcmF0b3IucHJvdG90eXBlLl9zZXR0bGVkQXQgPSBmdW5jdGlvbiAoc3RhdGUsIGksIHZhbHVlKSB7XG4gIHZhciBwcm9taXNlID0gdGhpcy5wcm9taXNlO1xuXG4gIGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gUEVORElORykge1xuICAgIHRoaXMuX3JlbWFpbmluZy0tO1xuXG4gICAgaWYgKHN0YXRlID09PSBSRUpFQ1RFRCkge1xuICAgICAgX3JlamVjdChwcm9taXNlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3Jlc3VsdFtpXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0aGlzLl9yZW1haW5pbmcgPT09IDApIHtcbiAgICBmdWxmaWxsKHByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gIH1cbn07XG5cbkVudW1lcmF0b3IucHJvdG90eXBlLl93aWxsU2V0dGxlQXQgPSBmdW5jdGlvbiAocHJvbWlzZSwgaSkge1xuICB2YXIgZW51bWVyYXRvciA9IHRoaXM7XG5cbiAgc3Vic2NyaWJlKHByb21pc2UsIHVuZGVmaW5lZCwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIGVudW1lcmF0b3IuX3NldHRsZWRBdChGVUxGSUxMRUQsIGksIHZhbHVlKTtcbiAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiBlbnVtZXJhdG9yLl9zZXR0bGVkQXQoUkVKRUNURUQsIGksIHJlYXNvbik7XG4gIH0pO1xufTtcblxuLyoqXG4gIGBQcm9taXNlLmFsbGAgYWNjZXB0cyBhbiBhcnJheSBvZiBwcm9taXNlcywgYW5kIHJldHVybnMgYSBuZXcgcHJvbWlzZSB3aGljaFxuICBpcyBmdWxmaWxsZWQgd2l0aCBhbiBhcnJheSBvZiBmdWxmaWxsbWVudCB2YWx1ZXMgZm9yIHRoZSBwYXNzZWQgcHJvbWlzZXMsIG9yXG4gIHJlamVjdGVkIHdpdGggdGhlIHJlYXNvbiBvZiB0aGUgZmlyc3QgcGFzc2VkIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQuIEl0IGNhc3RzIGFsbFxuICBlbGVtZW50cyBvZiB0aGUgcGFzc2VkIGl0ZXJhYmxlIHRvIHByb21pc2VzIGFzIGl0IHJ1bnMgdGhpcyBhbGdvcml0aG0uXG5cbiAgRXhhbXBsZTpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlMSA9IHJlc29sdmUoMSk7XG4gIGxldCBwcm9taXNlMiA9IHJlc29sdmUoMik7XG4gIGxldCBwcm9taXNlMyA9IHJlc29sdmUoMyk7XG4gIGxldCBwcm9taXNlcyA9IFsgcHJvbWlzZTEsIHByb21pc2UyLCBwcm9taXNlMyBdO1xuXG4gIFByb21pc2UuYWxsKHByb21pc2VzKS50aGVuKGZ1bmN0aW9uKGFycmF5KXtcbiAgICAvLyBUaGUgYXJyYXkgaGVyZSB3b3VsZCBiZSBbIDEsIDIsIDMgXTtcbiAgfSk7XG4gIGBgYFxuXG4gIElmIGFueSBvZiB0aGUgYHByb21pc2VzYCBnaXZlbiB0byBgYWxsYCBhcmUgcmVqZWN0ZWQsIHRoZSBmaXJzdCBwcm9taXNlXG4gIHRoYXQgaXMgcmVqZWN0ZWQgd2lsbCBiZSBnaXZlbiBhcyBhbiBhcmd1bWVudCB0byB0aGUgcmV0dXJuZWQgcHJvbWlzZXMnc1xuICByZWplY3Rpb24gaGFuZGxlci4gRm9yIGV4YW1wbGU6XG5cbiAgRXhhbXBsZTpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlMSA9IHJlc29sdmUoMSk7XG4gIGxldCBwcm9taXNlMiA9IHJlamVjdChuZXcgRXJyb3IoXCIyXCIpKTtcbiAgbGV0IHByb21pc2UzID0gcmVqZWN0KG5ldyBFcnJvcihcIjNcIikpO1xuICBsZXQgcHJvbWlzZXMgPSBbIHByb21pc2UxLCBwcm9taXNlMiwgcHJvbWlzZTMgXTtcblxuICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihmdW5jdGlvbihhcnJheSl7XG4gICAgLy8gQ29kZSBoZXJlIG5ldmVyIHJ1bnMgYmVjYXVzZSB0aGVyZSBhcmUgcmVqZWN0ZWQgcHJvbWlzZXMhXG4gIH0sIGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgLy8gZXJyb3IubWVzc2FnZSA9PT0gXCIyXCJcbiAgfSk7XG4gIGBgYFxuXG4gIEBtZXRob2QgYWxsXG4gIEBzdGF0aWNcbiAgQHBhcmFtIHtBcnJheX0gZW50cmllcyBhcnJheSBvZiBwcm9taXNlc1xuICBAcGFyYW0ge1N0cmluZ30gbGFiZWwgb3B0aW9uYWwgc3RyaW5nIGZvciBsYWJlbGluZyB0aGUgcHJvbWlzZS5cbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHRoYXQgaXMgZnVsZmlsbGVkIHdoZW4gYWxsIGBwcm9taXNlc2AgaGF2ZSBiZWVuXG4gIGZ1bGZpbGxlZCwgb3IgcmVqZWN0ZWQgaWYgYW55IG9mIHRoZW0gYmVjb21lIHJlamVjdGVkLlxuICBAc3RhdGljXG4qL1xuZnVuY3Rpb24gYWxsKGVudHJpZXMpIHtcbiAgcmV0dXJuIG5ldyBFbnVtZXJhdG9yKHRoaXMsIGVudHJpZXMpLnByb21pc2U7XG59XG5cbi8qKlxuICBgUHJvbWlzZS5yYWNlYCByZXR1cm5zIGEgbmV3IHByb21pc2Ugd2hpY2ggaXMgc2V0dGxlZCBpbiB0aGUgc2FtZSB3YXkgYXMgdGhlXG4gIGZpcnN0IHBhc3NlZCBwcm9taXNlIHRvIHNldHRsZS5cblxuICBFeGFtcGxlOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UxID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICByZXNvbHZlKCdwcm9taXNlIDEnKTtcbiAgICB9LCAyMDApO1xuICB9KTtcblxuICBsZXQgcHJvbWlzZTIgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJlc29sdmUoJ3Byb21pc2UgMicpO1xuICAgIH0sIDEwMCk7XG4gIH0pO1xuXG4gIFByb21pc2UucmFjZShbcHJvbWlzZTEsIHByb21pc2UyXSkudGhlbihmdW5jdGlvbihyZXN1bHQpe1xuICAgIC8vIHJlc3VsdCA9PT0gJ3Byb21pc2UgMicgYmVjYXVzZSBpdCB3YXMgcmVzb2x2ZWQgYmVmb3JlIHByb21pc2UxXG4gICAgLy8gd2FzIHJlc29sdmVkLlxuICB9KTtcbiAgYGBgXG5cbiAgYFByb21pc2UucmFjZWAgaXMgZGV0ZXJtaW5pc3RpYyBpbiB0aGF0IG9ubHkgdGhlIHN0YXRlIG9mIHRoZSBmaXJzdFxuICBzZXR0bGVkIHByb21pc2UgbWF0dGVycy4gRm9yIGV4YW1wbGUsIGV2ZW4gaWYgb3RoZXIgcHJvbWlzZXMgZ2l2ZW4gdG8gdGhlXG4gIGBwcm9taXNlc2AgYXJyYXkgYXJndW1lbnQgYXJlIHJlc29sdmVkLCBidXQgdGhlIGZpcnN0IHNldHRsZWQgcHJvbWlzZSBoYXNcbiAgYmVjb21lIHJlamVjdGVkIGJlZm9yZSB0aGUgb3RoZXIgcHJvbWlzZXMgYmVjYW1lIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gIHByb21pc2Ugd2lsbCBiZWNvbWUgcmVqZWN0ZWQ6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZTEgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJlc29sdmUoJ3Byb21pc2UgMScpO1xuICAgIH0sIDIwMCk7XG4gIH0pO1xuXG4gIGxldCBwcm9taXNlMiA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcigncHJvbWlzZSAyJykpO1xuICAgIH0sIDEwMCk7XG4gIH0pO1xuXG4gIFByb21pc2UucmFjZShbcHJvbWlzZTEsIHByb21pc2UyXSkudGhlbihmdW5jdGlvbihyZXN1bHQpe1xuICAgIC8vIENvZGUgaGVyZSBuZXZlciBydW5zXG4gIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgLy8gcmVhc29uLm1lc3NhZ2UgPT09ICdwcm9taXNlIDInIGJlY2F1c2UgcHJvbWlzZSAyIGJlY2FtZSByZWplY3RlZCBiZWZvcmVcbiAgICAvLyBwcm9taXNlIDEgYmVjYW1lIGZ1bGZpbGxlZFxuICB9KTtcbiAgYGBgXG5cbiAgQW4gZXhhbXBsZSByZWFsLXdvcmxkIHVzZSBjYXNlIGlzIGltcGxlbWVudGluZyB0aW1lb3V0czpcblxuICBgYGBqYXZhc2NyaXB0XG4gIFByb21pc2UucmFjZShbYWpheCgnZm9vLmpzb24nKSwgdGltZW91dCg1MDAwKV0pXG4gIGBgYFxuXG4gIEBtZXRob2QgcmFjZVxuICBAc3RhdGljXG4gIEBwYXJhbSB7QXJyYXl9IHByb21pc2VzIGFycmF5IG9mIHByb21pc2VzIHRvIG9ic2VydmVcbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2Ugd2hpY2ggc2V0dGxlcyBpbiB0aGUgc2FtZSB3YXkgYXMgdGhlIGZpcnN0IHBhc3NlZFxuICBwcm9taXNlIHRvIHNldHRsZS5cbiovXG5mdW5jdGlvbiByYWNlKGVudHJpZXMpIHtcbiAgLypqc2hpbnQgdmFsaWR0aGlzOnRydWUgKi9cbiAgdmFyIENvbnN0cnVjdG9yID0gdGhpcztcblxuICBpZiAoIWlzQXJyYXkoZW50cmllcykpIHtcbiAgICByZXR1cm4gbmV3IENvbnN0cnVjdG9yKGZ1bmN0aW9uIChfLCByZWplY3QpIHtcbiAgICAgIHJldHVybiByZWplY3QobmV3IFR5cGVFcnJvcignWW91IG11c3QgcGFzcyBhbiBhcnJheSB0byByYWNlLicpKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IENvbnN0cnVjdG9yKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBsZW5ndGggPSBlbnRyaWVzLmxlbmd0aDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgQ29uc3RydWN0b3IucmVzb2x2ZShlbnRyaWVzW2ldKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gIGBQcm9taXNlLnJlamVjdGAgcmV0dXJucyBhIHByb21pc2UgcmVqZWN0ZWQgd2l0aCB0aGUgcGFzc2VkIGByZWFzb25gLlxuICBJdCBpcyBzaG9ydGhhbmQgZm9yIHRoZSBmb2xsb3dpbmc6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgcmVqZWN0KG5ldyBFcnJvcignV0hPT1BTJykpO1xuICB9KTtcblxuICBwcm9taXNlLnRoZW4oZnVuY3Rpb24odmFsdWUpe1xuICAgIC8vIENvZGUgaGVyZSBkb2Vzbid0IHJ1biBiZWNhdXNlIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkIVxuICB9LCBmdW5jdGlvbihyZWFzb24pe1xuICAgIC8vIHJlYXNvbi5tZXNzYWdlID09PSAnV0hPT1BTJ1xuICB9KTtcbiAgYGBgXG5cbiAgSW5zdGVhZCBvZiB3cml0aW5nIHRoZSBhYm92ZSwgeW91ciBjb2RlIG5vdyBzaW1wbHkgYmVjb21lcyB0aGUgZm9sbG93aW5nOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UgPSBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ1dIT09QUycpKTtcblxuICBwcm9taXNlLnRoZW4oZnVuY3Rpb24odmFsdWUpe1xuICAgIC8vIENvZGUgaGVyZSBkb2Vzbid0IHJ1biBiZWNhdXNlIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkIVxuICB9LCBmdW5jdGlvbihyZWFzb24pe1xuICAgIC8vIHJlYXNvbi5tZXNzYWdlID09PSAnV0hPT1BTJ1xuICB9KTtcbiAgYGBgXG5cbiAgQG1ldGhvZCByZWplY3RcbiAgQHN0YXRpY1xuICBAcGFyYW0ge0FueX0gcmVhc29uIHZhbHVlIHRoYXQgdGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCBiZSByZWplY3RlZCB3aXRoLlxuICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSByZWplY3RlZCB3aXRoIHRoZSBnaXZlbiBgcmVhc29uYC5cbiovXG5mdW5jdGlvbiByZWplY3QocmVhc29uKSB7XG4gIC8qanNoaW50IHZhbGlkdGhpczp0cnVlICovXG4gIHZhciBDb25zdHJ1Y3RvciA9IHRoaXM7XG4gIHZhciBwcm9taXNlID0gbmV3IENvbnN0cnVjdG9yKG5vb3ApO1xuICBfcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBuZWVkc1Jlc29sdmVyKCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdZb3UgbXVzdCBwYXNzIGEgcmVzb2x2ZXIgZnVuY3Rpb24gYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZSBwcm9taXNlIGNvbnN0cnVjdG9yJyk7XG59XG5cbmZ1bmN0aW9uIG5lZWRzTmV3KCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRmFpbGVkIHRvIGNvbnN0cnVjdCAnUHJvbWlzZSc6IFBsZWFzZSB1c2UgdGhlICduZXcnIG9wZXJhdG9yLCB0aGlzIG9iamVjdCBjb25zdHJ1Y3RvciBjYW5ub3QgYmUgY2FsbGVkIGFzIGEgZnVuY3Rpb24uXCIpO1xufVxuXG4vKipcbiAgUHJvbWlzZSBvYmplY3RzIHJlcHJlc2VudCB0aGUgZXZlbnR1YWwgcmVzdWx0IG9mIGFuIGFzeW5jaHJvbm91cyBvcGVyYXRpb24uIFRoZVxuICBwcmltYXJ5IHdheSBvZiBpbnRlcmFjdGluZyB3aXRoIGEgcHJvbWlzZSBpcyB0aHJvdWdoIGl0cyBgdGhlbmAgbWV0aG9kLCB3aGljaFxuICByZWdpc3RlcnMgY2FsbGJhY2tzIHRvIHJlY2VpdmUgZWl0aGVyIGEgcHJvbWlzZSdzIGV2ZW50dWFsIHZhbHVlIG9yIHRoZSByZWFzb25cbiAgd2h5IHRoZSBwcm9taXNlIGNhbm5vdCBiZSBmdWxmaWxsZWQuXG5cbiAgVGVybWlub2xvZ3lcbiAgLS0tLS0tLS0tLS1cblxuICAtIGBwcm9taXNlYCBpcyBhbiBvYmplY3Qgb3IgZnVuY3Rpb24gd2l0aCBhIGB0aGVuYCBtZXRob2Qgd2hvc2UgYmVoYXZpb3IgY29uZm9ybXMgdG8gdGhpcyBzcGVjaWZpY2F0aW9uLlxuICAtIGB0aGVuYWJsZWAgaXMgYW4gb2JqZWN0IG9yIGZ1bmN0aW9uIHRoYXQgZGVmaW5lcyBhIGB0aGVuYCBtZXRob2QuXG4gIC0gYHZhbHVlYCBpcyBhbnkgbGVnYWwgSmF2YVNjcmlwdCB2YWx1ZSAoaW5jbHVkaW5nIHVuZGVmaW5lZCwgYSB0aGVuYWJsZSwgb3IgYSBwcm9taXNlKS5cbiAgLSBgZXhjZXB0aW9uYCBpcyBhIHZhbHVlIHRoYXQgaXMgdGhyb3duIHVzaW5nIHRoZSB0aHJvdyBzdGF0ZW1lbnQuXG4gIC0gYHJlYXNvbmAgaXMgYSB2YWx1ZSB0aGF0IGluZGljYXRlcyB3aHkgYSBwcm9taXNlIHdhcyByZWplY3RlZC5cbiAgLSBgc2V0dGxlZGAgdGhlIGZpbmFsIHJlc3Rpbmcgc3RhdGUgb2YgYSBwcm9taXNlLCBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG5cbiAgQSBwcm9taXNlIGNhbiBiZSBpbiBvbmUgb2YgdGhyZWUgc3RhdGVzOiBwZW5kaW5nLCBmdWxmaWxsZWQsIG9yIHJlamVjdGVkLlxuXG4gIFByb21pc2VzIHRoYXQgYXJlIGZ1bGZpbGxlZCBoYXZlIGEgZnVsZmlsbG1lbnQgdmFsdWUgYW5kIGFyZSBpbiB0aGUgZnVsZmlsbGVkXG4gIHN0YXRlLiAgUHJvbWlzZXMgdGhhdCBhcmUgcmVqZWN0ZWQgaGF2ZSBhIHJlamVjdGlvbiByZWFzb24gYW5kIGFyZSBpbiB0aGVcbiAgcmVqZWN0ZWQgc3RhdGUuICBBIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5ldmVyIGEgdGhlbmFibGUuXG5cbiAgUHJvbWlzZXMgY2FuIGFsc28gYmUgc2FpZCB0byAqcmVzb2x2ZSogYSB2YWx1ZS4gIElmIHRoaXMgdmFsdWUgaXMgYWxzbyBhXG4gIHByb21pc2UsIHRoZW4gdGhlIG9yaWdpbmFsIHByb21pc2UncyBzZXR0bGVkIHN0YXRlIHdpbGwgbWF0Y2ggdGhlIHZhbHVlJ3NcbiAgc2V0dGxlZCBzdGF0ZS4gIFNvIGEgcHJvbWlzZSB0aGF0ICpyZXNvbHZlcyogYSBwcm9taXNlIHRoYXQgcmVqZWN0cyB3aWxsXG4gIGl0c2VsZiByZWplY3QsIGFuZCBhIHByb21pc2UgdGhhdCAqcmVzb2x2ZXMqIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIHdpbGxcbiAgaXRzZWxmIGZ1bGZpbGwuXG5cblxuICBCYXNpYyBVc2FnZTpcbiAgLS0tLS0tLS0tLS0tXG5cbiAgYGBganNcbiAgbGV0IHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAvLyBvbiBzdWNjZXNzXG4gICAgcmVzb2x2ZSh2YWx1ZSk7XG5cbiAgICAvLyBvbiBmYWlsdXJlXG4gICAgcmVqZWN0KHJlYXNvbik7XG4gIH0pO1xuXG4gIHByb21pc2UudGhlbihmdW5jdGlvbih2YWx1ZSkge1xuICAgIC8vIG9uIGZ1bGZpbGxtZW50XG4gIH0sIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgIC8vIG9uIHJlamVjdGlvblxuICB9KTtcbiAgYGBgXG5cbiAgQWR2YW5jZWQgVXNhZ2U6XG4gIC0tLS0tLS0tLS0tLS0tLVxuXG4gIFByb21pc2VzIHNoaW5lIHdoZW4gYWJzdHJhY3RpbmcgYXdheSBhc3luY2hyb25vdXMgaW50ZXJhY3Rpb25zIHN1Y2ggYXNcbiAgYFhNTEh0dHBSZXF1ZXN0YHMuXG5cbiAgYGBganNcbiAgZnVuY3Rpb24gZ2V0SlNPTih1cmwpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICAgIGxldCB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblxuICAgICAgeGhyLm9wZW4oJ0dFVCcsIHVybCk7XG4gICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gaGFuZGxlcjtcbiAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnanNvbic7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgIHhoci5zZW5kKCk7XG5cbiAgICAgIGZ1bmN0aW9uIGhhbmRsZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLnJlYWR5U3RhdGUgPT09IHRoaXMuRE9ORSkge1xuICAgICAgICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgICByZXNvbHZlKHRoaXMucmVzcG9uc2UpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdnZXRKU09OOiBgJyArIHVybCArICdgIGZhaWxlZCB3aXRoIHN0YXR1czogWycgKyB0aGlzLnN0YXR1cyArICddJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldEpTT04oJy9wb3N0cy5qc29uJykudGhlbihmdW5jdGlvbihqc29uKSB7XG4gICAgLy8gb24gZnVsZmlsbG1lbnRcbiAgfSwgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgLy8gb24gcmVqZWN0aW9uXG4gIH0pO1xuICBgYGBcblxuICBVbmxpa2UgY2FsbGJhY2tzLCBwcm9taXNlcyBhcmUgZ3JlYXQgY29tcG9zYWJsZSBwcmltaXRpdmVzLlxuXG4gIGBgYGpzXG4gIFByb21pc2UuYWxsKFtcbiAgICBnZXRKU09OKCcvcG9zdHMnKSxcbiAgICBnZXRKU09OKCcvY29tbWVudHMnKVxuICBdKS50aGVuKGZ1bmN0aW9uKHZhbHVlcyl7XG4gICAgdmFsdWVzWzBdIC8vID0+IHBvc3RzSlNPTlxuICAgIHZhbHVlc1sxXSAvLyA9PiBjb21tZW50c0pTT05cblxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH0pO1xuICBgYGBcblxuICBAY2xhc3MgUHJvbWlzZVxuICBAcGFyYW0ge2Z1bmN0aW9ufSByZXNvbHZlclxuICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gIEBjb25zdHJ1Y3RvclxuKi9cbmZ1bmN0aW9uIFByb21pc2UocmVzb2x2ZXIpIHtcbiAgdGhpc1tQUk9NSVNFX0lEXSA9IG5leHRJZCgpO1xuICB0aGlzLl9yZXN1bHQgPSB0aGlzLl9zdGF0ZSA9IHVuZGVmaW5lZDtcbiAgdGhpcy5fc3Vic2NyaWJlcnMgPSBbXTtcblxuICBpZiAobm9vcCAhPT0gcmVzb2x2ZXIpIHtcbiAgICB0eXBlb2YgcmVzb2x2ZXIgIT09ICdmdW5jdGlvbicgJiYgbmVlZHNSZXNvbHZlcigpO1xuICAgIHRoaXMgaW5zdGFuY2VvZiBQcm9taXNlID8gaW5pdGlhbGl6ZVByb21pc2UodGhpcywgcmVzb2x2ZXIpIDogbmVlZHNOZXcoKTtcbiAgfVxufVxuXG5Qcm9taXNlLmFsbCA9IGFsbDtcblByb21pc2UucmFjZSA9IHJhY2U7XG5Qcm9taXNlLnJlc29sdmUgPSByZXNvbHZlO1xuUHJvbWlzZS5yZWplY3QgPSByZWplY3Q7XG5Qcm9taXNlLl9zZXRTY2hlZHVsZXIgPSBzZXRTY2hlZHVsZXI7XG5Qcm9taXNlLl9zZXRBc2FwID0gc2V0QXNhcDtcblByb21pc2UuX2FzYXAgPSBhc2FwO1xuXG5Qcm9taXNlLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFByb21pc2UsXG5cbiAgLyoqXG4gICAgVGhlIHByaW1hcnkgd2F5IG9mIGludGVyYWN0aW5nIHdpdGggYSBwcm9taXNlIGlzIHRocm91Z2ggaXRzIGB0aGVuYCBtZXRob2QsXG4gICAgd2hpY2ggcmVnaXN0ZXJzIGNhbGxiYWNrcyB0byByZWNlaXZlIGVpdGhlciBhIHByb21pc2UncyBldmVudHVhbCB2YWx1ZSBvciB0aGVcbiAgICByZWFzb24gd2h5IHRoZSBwcm9taXNlIGNhbm5vdCBiZSBmdWxmaWxsZWQuXG4gIFxuICAgIGBgYGpzXG4gICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uKHVzZXIpe1xuICAgICAgLy8gdXNlciBpcyBhdmFpbGFibGVcbiAgICB9LCBmdW5jdGlvbihyZWFzb24pe1xuICAgICAgLy8gdXNlciBpcyB1bmF2YWlsYWJsZSwgYW5kIHlvdSBhcmUgZ2l2ZW4gdGhlIHJlYXNvbiB3aHlcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgQ2hhaW5pbmdcbiAgICAtLS0tLS0tLVxuICBcbiAgICBUaGUgcmV0dXJuIHZhbHVlIG9mIGB0aGVuYCBpcyBpdHNlbGYgYSBwcm9taXNlLiAgVGhpcyBzZWNvbmQsICdkb3duc3RyZWFtJ1xuICAgIHByb21pc2UgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBmaXJzdCBwcm9taXNlJ3MgZnVsZmlsbG1lbnRcbiAgICBvciByZWplY3Rpb24gaGFuZGxlciwgb3IgcmVqZWN0ZWQgaWYgdGhlIGhhbmRsZXIgdGhyb3dzIGFuIGV4Y2VwdGlvbi5cbiAgXG4gICAgYGBganNcbiAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgIHJldHVybiB1c2VyLm5hbWU7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgcmV0dXJuICdkZWZhdWx0IG5hbWUnO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKHVzZXJOYW1lKSB7XG4gICAgICAvLyBJZiBgZmluZFVzZXJgIGZ1bGZpbGxlZCwgYHVzZXJOYW1lYCB3aWxsIGJlIHRoZSB1c2VyJ3MgbmFtZSwgb3RoZXJ3aXNlIGl0XG4gICAgICAvLyB3aWxsIGJlIGAnZGVmYXVsdCBuYW1lJ2BcbiAgICB9KTtcbiAgXG4gICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIHVzZXIsIGJ1dCBzdGlsbCB1bmhhcHB5Jyk7XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdgZmluZFVzZXJgIHJlamVjdGVkIGFuZCB3ZSdyZSB1bmhhcHB5Jyk7XG4gICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAvLyBpZiBgZmluZFVzZXJgIGZ1bGZpbGxlZCwgYHJlYXNvbmAgd2lsbCBiZSAnRm91bmQgdXNlciwgYnV0IHN0aWxsIHVuaGFwcHknLlxuICAgICAgLy8gSWYgYGZpbmRVc2VyYCByZWplY3RlZCwgYHJlYXNvbmAgd2lsbCBiZSAnYGZpbmRVc2VyYCByZWplY3RlZCBhbmQgd2UncmUgdW5oYXBweScuXG4gICAgfSk7XG4gICAgYGBgXG4gICAgSWYgdGhlIGRvd25zdHJlYW0gcHJvbWlzZSBkb2VzIG5vdCBzcGVjaWZ5IGEgcmVqZWN0aW9uIGhhbmRsZXIsIHJlamVjdGlvbiByZWFzb25zIHdpbGwgYmUgcHJvcGFnYXRlZCBmdXJ0aGVyIGRvd25zdHJlYW0uXG4gIFxuICAgIGBgYGpzXG4gICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgUGVkYWdvZ2ljYWxFeGNlcHRpb24oJ1Vwc3RyZWFtIGVycm9yJyk7XG4gICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICB9KS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgLy8gbmV2ZXIgcmVhY2hlZFxuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIC8vIFRoZSBgUGVkZ2Fnb2NpYWxFeGNlcHRpb25gIGlzIHByb3BhZ2F0ZWQgYWxsIHRoZSB3YXkgZG93biB0byBoZXJlXG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIEFzc2ltaWxhdGlvblxuICAgIC0tLS0tLS0tLS0tLVxuICBcbiAgICBTb21ldGltZXMgdGhlIHZhbHVlIHlvdSB3YW50IHRvIHByb3BhZ2F0ZSB0byBhIGRvd25zdHJlYW0gcHJvbWlzZSBjYW4gb25seSBiZVxuICAgIHJldHJpZXZlZCBhc3luY2hyb25vdXNseS4gVGhpcyBjYW4gYmUgYWNoaWV2ZWQgYnkgcmV0dXJuaW5nIGEgcHJvbWlzZSBpbiB0aGVcbiAgICBmdWxmaWxsbWVudCBvciByZWplY3Rpb24gaGFuZGxlci4gVGhlIGRvd25zdHJlYW0gcHJvbWlzZSB3aWxsIHRoZW4gYmUgcGVuZGluZ1xuICAgIHVudGlsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlzIHNldHRsZWQuIFRoaXMgaXMgY2FsbGVkICphc3NpbWlsYXRpb24qLlxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgcmV0dXJuIGZpbmRDb21tZW50c0J5QXV0aG9yKHVzZXIpO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKGNvbW1lbnRzKSB7XG4gICAgICAvLyBUaGUgdXNlcidzIGNvbW1lbnRzIGFyZSBub3cgYXZhaWxhYmxlXG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIElmIHRoZSBhc3NpbWxpYXRlZCBwcm9taXNlIHJlamVjdHMsIHRoZW4gdGhlIGRvd25zdHJlYW0gcHJvbWlzZSB3aWxsIGFsc28gcmVqZWN0LlxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgcmV0dXJuIGZpbmRDb21tZW50c0J5QXV0aG9yKHVzZXIpO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKGNvbW1lbnRzKSB7XG4gICAgICAvLyBJZiBgZmluZENvbW1lbnRzQnlBdXRob3JgIGZ1bGZpbGxzLCB3ZSdsbCBoYXZlIHRoZSB2YWx1ZSBoZXJlXG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgLy8gSWYgYGZpbmRDb21tZW50c0J5QXV0aG9yYCByZWplY3RzLCB3ZSdsbCBoYXZlIHRoZSByZWFzb24gaGVyZVxuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBTaW1wbGUgRXhhbXBsZVxuICAgIC0tLS0tLS0tLS0tLS0tXG4gIFxuICAgIFN5bmNocm9ub3VzIEV4YW1wbGVcbiAgXG4gICAgYGBgamF2YXNjcmlwdFxuICAgIGxldCByZXN1bHQ7XG4gIFxuICAgIHRyeSB7XG4gICAgICByZXN1bHQgPSBmaW5kUmVzdWx0KCk7XG4gICAgICAvLyBzdWNjZXNzXG4gICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgIC8vIGZhaWx1cmVcbiAgICB9XG4gICAgYGBgXG4gIFxuICAgIEVycmJhY2sgRXhhbXBsZVxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRSZXN1bHQoZnVuY3Rpb24ocmVzdWx0LCBlcnIpe1xuICAgICAgaWYgKGVycikge1xuICAgICAgICAvLyBmYWlsdXJlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBzdWNjZXNzXG4gICAgICB9XG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIFByb21pc2UgRXhhbXBsZTtcbiAgXG4gICAgYGBgamF2YXNjcmlwdFxuICAgIGZpbmRSZXN1bHQoKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCl7XG4gICAgICAvLyBzdWNjZXNzXG4gICAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAgIC8vIGZhaWx1cmVcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgQWR2YW5jZWQgRXhhbXBsZVxuICAgIC0tLS0tLS0tLS0tLS0tXG4gIFxuICAgIFN5bmNocm9ub3VzIEV4YW1wbGVcbiAgXG4gICAgYGBgamF2YXNjcmlwdFxuICAgIGxldCBhdXRob3IsIGJvb2tzO1xuICBcbiAgICB0cnkge1xuICAgICAgYXV0aG9yID0gZmluZEF1dGhvcigpO1xuICAgICAgYm9va3MgID0gZmluZEJvb2tzQnlBdXRob3IoYXV0aG9yKTtcbiAgICAgIC8vIHN1Y2Nlc3NcbiAgICB9IGNhdGNoKHJlYXNvbikge1xuICAgICAgLy8gZmFpbHVyZVxuICAgIH1cbiAgICBgYGBcbiAgXG4gICAgRXJyYmFjayBFeGFtcGxlXG4gIFxuICAgIGBgYGpzXG4gIFxuICAgIGZ1bmN0aW9uIGZvdW5kQm9va3MoYm9va3MpIHtcbiAgXG4gICAgfVxuICBcbiAgICBmdW5jdGlvbiBmYWlsdXJlKHJlYXNvbikge1xuICBcbiAgICB9XG4gIFxuICAgIGZpbmRBdXRob3IoZnVuY3Rpb24oYXV0aG9yLCBlcnIpe1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBmYWlsdXJlKGVycik7XG4gICAgICAgIC8vIGZhaWx1cmVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZmluZEJvb29rc0J5QXV0aG9yKGF1dGhvciwgZnVuY3Rpb24oYm9va3MsIGVycikge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICBmYWlsdXJlKGVycik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZvdW5kQm9va3MoYm9va3MpO1xuICAgICAgICAgICAgICB9IGNhdGNoKHJlYXNvbikge1xuICAgICAgICAgICAgICAgIGZhaWx1cmUocmVhc29uKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgICAgZmFpbHVyZShlcnIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHN1Y2Nlc3NcbiAgICAgIH1cbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgUHJvbWlzZSBFeGFtcGxlO1xuICBcbiAgICBgYGBqYXZhc2NyaXB0XG4gICAgZmluZEF1dGhvcigpLlxuICAgICAgdGhlbihmaW5kQm9va3NCeUF1dGhvcikuXG4gICAgICB0aGVuKGZ1bmN0aW9uKGJvb2tzKXtcbiAgICAgICAgLy8gZm91bmQgYm9va3NcbiAgICB9KS5jYXRjaChmdW5jdGlvbihyZWFzb24pe1xuICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgQG1ldGhvZCB0aGVuXG4gICAgQHBhcmFtIHtGdW5jdGlvbn0gb25GdWxmaWxsZWRcbiAgICBAcGFyYW0ge0Z1bmN0aW9ufSBvblJlamVjdGVkXG4gICAgVXNlZnVsIGZvciB0b29saW5nLlxuICAgIEByZXR1cm4ge1Byb21pc2V9XG4gICovXG4gIHRoZW46IHRoZW4sXG5cbiAgLyoqXG4gICAgYGNhdGNoYCBpcyBzaW1wbHkgc3VnYXIgZm9yIGB0aGVuKHVuZGVmaW5lZCwgb25SZWplY3Rpb24pYCB3aGljaCBtYWtlcyBpdCB0aGUgc2FtZVxuICAgIGFzIHRoZSBjYXRjaCBibG9jayBvZiBhIHRyeS9jYXRjaCBzdGF0ZW1lbnQuXG4gIFxuICAgIGBgYGpzXG4gICAgZnVuY3Rpb24gZmluZEF1dGhvcigpe1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZG4ndCBmaW5kIHRoYXQgYXV0aG9yJyk7XG4gICAgfVxuICBcbiAgICAvLyBzeW5jaHJvbm91c1xuICAgIHRyeSB7XG4gICAgICBmaW5kQXV0aG9yKCk7XG4gICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nXG4gICAgfVxuICBcbiAgICAvLyBhc3luYyB3aXRoIHByb21pc2VzXG4gICAgZmluZEF1dGhvcigpLmNhdGNoKGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZ1xuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBAbWV0aG9kIGNhdGNoXG4gICAgQHBhcmFtIHtGdW5jdGlvbn0gb25SZWplY3Rpb25cbiAgICBVc2VmdWwgZm9yIHRvb2xpbmcuXG4gICAgQHJldHVybiB7UHJvbWlzZX1cbiAgKi9cbiAgJ2NhdGNoJzogZnVuY3Rpb24gX2NhdGNoKG9uUmVqZWN0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihudWxsLCBvblJlamVjdGlvbik7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHBvbHlmaWxsKCkge1xuICAgIHZhciBsb2NhbCA9IHVuZGVmaW5lZDtcblxuICAgIGlmICh0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBsb2NhbCA9IGdsb2JhbDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBsb2NhbCA9IHNlbGY7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxvY2FsID0gRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwb2x5ZmlsbCBmYWlsZWQgYmVjYXVzZSBnbG9iYWwgb2JqZWN0IGlzIHVuYXZhaWxhYmxlIGluIHRoaXMgZW52aXJvbm1lbnQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBQID0gbG9jYWwuUHJvbWlzZTtcblxuICAgIGlmIChQKSB7XG4gICAgICAgIHZhciBwcm9taXNlVG9TdHJpbmcgPSBudWxsO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZVRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKFAucmVzb2x2ZSgpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gc2lsZW50bHkgaWdub3JlZFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb21pc2VUb1N0cmluZyA9PT0gJ1tvYmplY3QgUHJvbWlzZV0nICYmICFQLmNhc3QpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxvY2FsLlByb21pc2UgPSBQcm9taXNlO1xufVxuXG5wb2x5ZmlsbCgpO1xuLy8gU3RyYW5nZSBjb21wYXQuLlxuUHJvbWlzZS5wb2x5ZmlsbCA9IHBvbHlmaWxsO1xuUHJvbWlzZS5Qcm9taXNlID0gUHJvbWlzZTtcblxucmV0dXJuIFByb21pc2U7XG5cbn0pKSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lczYtcHJvbWlzZS5tYXBcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZXM2LXByb21pc2UvZGlzdC9lczYtcHJvbWlzZS5qc1xuLy8gbW9kdWxlIGlkID0gNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb2Nlc3MvYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY29yZS11dGlsLWlzL2xpYi91dGlsLmpzXG4vLyBtb2R1bGUgaWQgPSA3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vVHlwZXMgb2YgZWxlbWVudHMgZm91bmQgaW4gdGhlIERPTVxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdFRleHQ6IFwidGV4dFwiLCAvL1RleHRcblx0RGlyZWN0aXZlOiBcImRpcmVjdGl2ZVwiLCAvLzw/IC4uLiA/PlxuXHRDb21tZW50OiBcImNvbW1lbnRcIiwgLy88IS0tIC4uLiAtLT5cblx0U2NyaXB0OiBcInNjcmlwdFwiLCAvLzxzY3JpcHQ+IHRhZ3Ncblx0U3R5bGU6IFwic3R5bGVcIiwgLy88c3R5bGU+IHRhZ3Ncblx0VGFnOiBcInRhZ1wiLCAvL0FueSB0YWdcblx0Q0RBVEE6IFwiY2RhdGFcIiwgLy88IVtDREFUQVsgLi4uIF1dPlxuXHREb2N0eXBlOiBcImRvY3R5cGVcIixcblxuXHRpc1RhZzogZnVuY3Rpb24oZWxlbSl7XG5cdFx0cmV0dXJuIGVsZW0udHlwZSA9PT0gXCJ0YWdcIiB8fCBlbGVtLnR5cGUgPT09IFwic2NyaXB0XCIgfHwgZWxlbS50eXBlID09PSBcInN0eWxlXCI7XG5cdH1cbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZG9tZWxlbWVudHR5cGUvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICAgIGVyci5jb250ZXh0ID0gZXI7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIGhhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG07XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgaWYgKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcilcbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcikgP1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlXG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuXG4gIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pICYmICF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKSB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKSB7XG4gICAgICBtID0gdGhpcy5fbWF4TGlzdGVuZXJzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfVxuXG4gICAgaWYgKG0gJiYgbSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQgPSB0cnVlO1xuICAgICAgY29uc29sZS5lcnJvcignKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgJyArXG4gICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUudHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gbm90IHN1cHBvcnRlZCBpbiBJRSAxMFxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIHZhciBmaXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGcoKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcblxuICAgIGlmICghZmlyZWQpIHtcbiAgICAgIGZpcmVkID0gdHJ1ZTtcbiAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9XG5cbiAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB0aGlzLm9uKHR5cGUsIGcpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbGlzdCwgcG9zaXRpb24sIGxlbmd0aCwgaTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXR1cm4gdGhpcztcblxuICBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuICBsZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgcG9zaXRpb24gPSAtMTtcblxuICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHxcbiAgICAgIChpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpICYmIGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cbiAgfSBlbHNlIGlmIChpc09iamVjdChsaXN0KSkge1xuICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcbiAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgIChsaXN0W2ldLmxpc3RlbmVyICYmIGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgbGlzdC5sZW5ndGggPSAwO1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGtleSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgaWYgKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGVsc2UgaWYgKHRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzRnVuY3Rpb24obGlzdGVuZXJzKSkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAvLyBMSUZPIG9yZGVyXG4gICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0pO1xuICB9XG4gIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSBbXTtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IFt0aGlzLl9ldmVudHNbdHlwZV1dO1xuICBlbHNlXG4gICAgcmV0ID0gdGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGV2bGlzdGVuZXIpKVxuICAgICAgcmV0dXJuIDE7XG4gICAgZWxzZSBpZiAoZXZsaXN0ZW5lcilcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gMDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2V2ZW50cy9ldmVudHMuanNcbi8vIG1vZHVsZSBpZCA9IDlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIFBhcnNlciA9IHJlcXVpcmUoXCIuL1BhcnNlci5qc1wiKSxcbiAgICBEb21IYW5kbGVyID0gcmVxdWlyZShcImRvbWhhbmRsZXJcIik7XG5cbmZ1bmN0aW9uIGRlZmluZVByb3AobmFtZSwgdmFsdWUpe1xuXHRkZWxldGUgbW9kdWxlLmV4cG9ydHNbbmFtZV07XG5cdG1vZHVsZS5leHBvcnRzW25hbWVdID0gdmFsdWU7XG5cdHJldHVybiB2YWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdFBhcnNlcjogUGFyc2VyLFxuXHRUb2tlbml6ZXI6IHJlcXVpcmUoXCIuL1Rva2VuaXplci5qc1wiKSxcblx0RWxlbWVudFR5cGU6IHJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKSxcblx0RG9tSGFuZGxlcjogRG9tSGFuZGxlcixcblx0Z2V0IEZlZWRIYW5kbGVyKCl7XG5cdFx0cmV0dXJuIGRlZmluZVByb3AoXCJGZWVkSGFuZGxlclwiLCByZXF1aXJlKFwiLi9GZWVkSGFuZGxlci5qc1wiKSk7XG5cdH0sXG5cdGdldCBTdHJlYW0oKXtcblx0XHRyZXR1cm4gZGVmaW5lUHJvcChcIlN0cmVhbVwiLCByZXF1aXJlKFwiLi9TdHJlYW0uanNcIikpO1xuXHR9LFxuXHRnZXQgV3JpdGFibGVTdHJlYW0oKXtcblx0XHRyZXR1cm4gZGVmaW5lUHJvcChcIldyaXRhYmxlU3RyZWFtXCIsIHJlcXVpcmUoXCIuL1dyaXRhYmxlU3RyZWFtLmpzXCIpKTtcblx0fSxcblx0Z2V0IFByb3h5SGFuZGxlcigpe1xuXHRcdHJldHVybiBkZWZpbmVQcm9wKFwiUHJveHlIYW5kbGVyXCIsIHJlcXVpcmUoXCIuL1Byb3h5SGFuZGxlci5qc1wiKSk7XG5cdH0sXG5cdGdldCBEb21VdGlscygpe1xuXHRcdHJldHVybiBkZWZpbmVQcm9wKFwiRG9tVXRpbHNcIiwgcmVxdWlyZShcImRvbXV0aWxzXCIpKTtcblx0fSxcblx0Z2V0IENvbGxlY3RpbmdIYW5kbGVyKCl7XG5cdFx0cmV0dXJuIGRlZmluZVByb3AoXCJDb2xsZWN0aW5nSGFuZGxlclwiLCByZXF1aXJlKFwiLi9Db2xsZWN0aW5nSGFuZGxlci5qc1wiKSk7XG5cdH0sXG5cdC8vIEZvciBsZWdhY3kgc3VwcG9ydFxuXHREZWZhdWx0SGFuZGxlcjogRG9tSGFuZGxlcixcblx0Z2V0IFJzc0hhbmRsZXIoKXtcblx0XHRyZXR1cm4gZGVmaW5lUHJvcChcIlJzc0hhbmRsZXJcIiwgdGhpcy5GZWVkSGFuZGxlcik7XG5cdH0sXG5cdC8vaGVscGVyIG1ldGhvZHNcblx0cGFyc2VET006IGZ1bmN0aW9uKGRhdGEsIG9wdGlvbnMpe1xuXHRcdHZhciBoYW5kbGVyID0gbmV3IERvbUhhbmRsZXIob3B0aW9ucyk7XG5cdFx0bmV3IFBhcnNlcihoYW5kbGVyLCBvcHRpb25zKS5lbmQoZGF0YSk7XG5cdFx0cmV0dXJuIGhhbmRsZXIuZG9tO1xuXHR9LFxuXHRwYXJzZUZlZWQ6IGZ1bmN0aW9uKGZlZWQsIG9wdGlvbnMpe1xuXHRcdHZhciBoYW5kbGVyID0gbmV3IG1vZHVsZS5leHBvcnRzLkZlZWRIYW5kbGVyKG9wdGlvbnMpO1xuXHRcdG5ldyBQYXJzZXIoaGFuZGxlciwgb3B0aW9ucykuZW5kKGZlZWQpO1xuXHRcdHJldHVybiBoYW5kbGVyLmRvbTtcblx0fSxcblx0Y3JlYXRlRG9tU3RyZWFtOiBmdW5jdGlvbihjYiwgb3B0aW9ucywgZWxlbWVudENiKXtcblx0XHR2YXIgaGFuZGxlciA9IG5ldyBEb21IYW5kbGVyKGNiLCBvcHRpb25zLCBlbGVtZW50Q2IpO1xuXHRcdHJldHVybiBuZXcgUGFyc2VyKGhhbmRsZXIsIG9wdGlvbnMpO1xuXHR9LFxuXHQvLyBMaXN0IG9mIGFsbCBldmVudHMgdGhhdCB0aGUgcGFyc2VyIGVtaXRzXG5cdEVWRU5UUzogeyAvKiBGb3JtYXQ6IGV2ZW50bmFtZTogbnVtYmVyIG9mIGFyZ3VtZW50cyAqL1xuXHRcdGF0dHJpYnV0ZTogMixcblx0XHRjZGF0YXN0YXJ0OiAwLFxuXHRcdGNkYXRhZW5kOiAwLFxuXHRcdHRleHQ6IDEsXG5cdFx0cHJvY2Vzc2luZ2luc3RydWN0aW9uOiAyLFxuXHRcdGNvbW1lbnQ6IDEsXG5cdFx0Y29tbWVudGVuZDogMCxcblx0XHRjbG9zZXRhZzogMSxcblx0XHRvcGVudGFnOiAyLFxuXHRcdG9wZW50YWduYW1lOiAxLFxuXHRcdGVycm9yOiAxLFxuXHRcdGVuZDogMFxuXHR9XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2h0bWxwYXJzZXIyL2xpYi9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBqUXVlcnk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJqUXVlcnlcIlxuLy8gbW9kdWxlIGlkID0gMTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLypcclxuQGxpY2Vuc2VcclxuQ29weXJpZ2h0IDIwMTUgQ2xvdWRTaGFyZSBJbmMuXHJcblxyXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xyXG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXHJcbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG5cclxuICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxyXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXHJcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxyXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXHJcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4qL1xyXG52YXIgYm90dGxlID0gcmVxdWlyZSgnLi9ib3R0bGUnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYm90dGxlLmNvbnRhaW5lci5DbG91ZFNoYXJlQ2xpZW50O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NzLXNkay9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiOyhmdW5jdGlvbih1bmRlZmluZWQpIHtcbiAgICAndXNlIHN0cmljdCc7XG4gICAgLyoqXG4gICAgICogQm90dGxlSlMgdjEuNi4wIC0gMjAxNy0wMi0yMlxuICAgICAqIEEgcG93ZXJmdWwgZGVwZW5kZW5jeSBpbmplY3Rpb24gbWljcm8gY29udGFpbmVyXG4gICAgICpcbiAgICAgKiBDb3B5cmlnaHQgKGMpIDIwMTcgU3RlcGhlbiBZb3VuZ1xuICAgICAqIExpY2Vuc2VkIE1JVFxuICAgICAqL1xuICAgIFxuICAgIC8qKlxuICAgICAqIFVuaXF1ZSBpZCBjb3VudGVyO1xuICAgICAqXG4gICAgICogQHR5cGUgTnVtYmVyXG4gICAgICovXG4gICAgdmFyIGlkID0gMDtcbiAgICBcbiAgICAvKipcbiAgICAgKiBMb2NhbCBzbGljZSBhbGlhc1xuICAgICAqXG4gICAgICogQHR5cGUgRnVuY3Rpb25zXG4gICAgICovXG4gICAgdmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuICAgIFxuICAgIC8qKlxuICAgICAqIEl0ZXJhdG9yIHVzZWQgdG8gd2FsayBkb3duIGEgbmVzdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIElmIEJvdHRsZS5jb25maWcuc3RyaWN0IGlzIHRydWUsIHRoaXMgbWV0aG9kIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGl0IGVuY291bnRlcnMgYW5cbiAgICAgKiB1bmRlZmluZWQgcGF0aFxuICAgICAqXG4gICAgICogQHBhcmFtIE9iamVjdCBvYmpcbiAgICAgKiBAcGFyYW0gU3RyaW5nIHByb3BcbiAgICAgKiBAcmV0dXJuIG1peGVkXG4gICAgICogQHRocm93cyBFcnJvciBpZiBCb3R0bGUgaXMgdW5hYmxlIHRvIHJlc29sdmUgdGhlIHJlcXVlc3RlZCBzZXJ2aWNlLlxuICAgICAqL1xuICAgIHZhciBnZXROZXN0ZWQgPSBmdW5jdGlvbiBnZXROZXN0ZWQob2JqLCBwcm9wKSB7XG4gICAgICAgIHZhciBzZXJ2aWNlID0gb2JqW3Byb3BdO1xuICAgICAgICBpZiAoc2VydmljZSA9PT0gdW5kZWZpbmVkICYmIGdsb2JhbENvbmZpZy5zdHJpY3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQm90dGxlIHdhcyB1bmFibGUgdG8gcmVzb2x2ZSBhIHNlcnZpY2UuICBgJyArIHByb3AgKyAnYCBpcyB1bmRlZmluZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlcnZpY2U7XG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBHZXQgYSBuZXN0ZWQgYm90dGxlLiBXaWxsIHNldCBhbmQgcmV0dXJuIGlmIG5vdCBzZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gU3RyaW5nIG5hbWVcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciBnZXROZXN0ZWRCb3R0bGUgPSBmdW5jdGlvbiBnZXROZXN0ZWRCb3R0bGUobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5uZXN0ZWRbbmFtZV0gfHwgKHRoaXMubmVzdGVkW25hbWVdID0gQm90dGxlLnBvcCgpKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIEdldCBhIHNlcnZpY2Ugc3RvcmVkIHVuZGVyIGEgbmVzdGVkIGtleVxuICAgICAqXG4gICAgICogQHBhcmFtIFN0cmluZyBmdWxsbmFtZVxuICAgICAqIEByZXR1cm4gU2VydmljZVxuICAgICAqL1xuICAgIHZhciBnZXROZXN0ZWRTZXJ2aWNlID0gZnVuY3Rpb24gZ2V0TmVzdGVkU2VydmljZShmdWxsbmFtZSkge1xuICAgICAgICByZXR1cm4gZnVsbG5hbWUuc3BsaXQoJy4nKS5yZWR1Y2UoZ2V0TmVzdGVkLCB0aGlzKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGEgY29uc3RhbnRcbiAgICAgKlxuICAgICAqIEBwYXJhbSBTdHJpbmcgbmFtZVxuICAgICAqIEBwYXJhbSBtaXhlZCB2YWx1ZVxuICAgICAqIEByZXR1cm4gQm90dGxlXG4gICAgICovXG4gICAgdmFyIGNvbnN0YW50ID0gZnVuY3Rpb24gY29uc3RhbnQobmFtZSwgdmFsdWUpIHtcbiAgICAgICAgdmFyIHBhcnRzID0gbmFtZS5zcGxpdCgnLicpO1xuICAgICAgICBuYW1lID0gcGFydHMucG9wKCk7XG4gICAgICAgIGRlZmluZUNvbnN0YW50LmNhbGwocGFydHMucmVkdWNlKHNldFZhbHVlT2JqZWN0LCB0aGlzLmNvbnRhaW5lciksIG5hbWUsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBcbiAgICB2YXIgZGVmaW5lQ29uc3RhbnQgPSBmdW5jdGlvbiBkZWZpbmVDb25zdGFudChuYW1lLCB2YWx1ZSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgbmFtZSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlIDogZmFsc2UsXG4gICAgICAgICAgICBlbnVtZXJhYmxlIDogdHJ1ZSxcbiAgICAgICAgICAgIHZhbHVlIDogdmFsdWUsXG4gICAgICAgICAgICB3cml0YWJsZSA6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgXG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgZGVjb3JhdG9yLlxuICAgICAqXG4gICAgICogQHBhcmFtIFN0cmluZyBmdWxsbmFtZVxuICAgICAqIEBwYXJhbSBGdW5jdGlvbiBmdW5jXG4gICAgICogQHJldHVybiBCb3R0bGVcbiAgICAgKi9cbiAgICB2YXIgZGVjb3JhdG9yID0gZnVuY3Rpb24gZGVjb3JhdG9yKGZ1bGxuYW1lLCBmdW5jKSB7XG4gICAgICAgIHZhciBwYXJ0cywgbmFtZTtcbiAgICAgICAgaWYgKHR5cGVvZiBmdWxsbmFtZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgZnVuYyA9IGZ1bGxuYW1lO1xuICAgICAgICAgICAgZnVsbG5hbWUgPSAnX19nbG9iYWxfXyc7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgcGFydHMgPSBmdWxsbmFtZS5zcGxpdCgnLicpO1xuICAgICAgICBuYW1lID0gcGFydHMuc2hpZnQoKTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgZ2V0TmVzdGVkQm90dGxlLmNhbGwodGhpcywgbmFtZSkuZGVjb3JhdG9yKHBhcnRzLmpvaW4oJy4nKSwgZnVuYyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGVjb3JhdG9yc1tuYW1lXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVjb3JhdG9yc1tuYW1lXSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kZWNvcmF0b3JzW25hbWVdLnB1c2goZnVuYyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCB3aGVuIEJvdHRsZSNyZXNvbHZlIGlzIGNhbGxlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBGdW5jdGlvbiBmdW5jXG4gICAgICogQHJldHVybiBCb3R0bGVcbiAgICAgKi9cbiAgICB2YXIgZGVmZXIgPSBmdW5jdGlvbiBkZWZlcihmdW5jKSB7XG4gICAgICAgIHRoaXMuZGVmZXJyZWQucHVzaChmdW5jKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBcbiAgICBcbiAgICAvKipcbiAgICAgKiBJbW1lZGlhdGVseSBpbnN0YW50aWF0ZXMgdGhlIHByb3ZpZGVkIGxpc3Qgb2Ygc2VydmljZXMgYW5kIHJldHVybnMgdGhlbS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBBcnJheSBzZXJ2aWNlc1xuICAgICAqIEByZXR1cm4gQXJyYXkgQXJyYXkgb2YgaW5zdGFuY2VzIChpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIHByb3ZpZGVkKVxuICAgICAqL1xuICAgIHZhciBkaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3Qoc2VydmljZXMpIHtcbiAgICAgICAgcmV0dXJuIChzZXJ2aWNlcyB8fCBbXSkubWFwKGdldE5lc3RlZFNlcnZpY2UsIHRoaXMuY29udGFpbmVyKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGEgZmFjdG9yeSBpbnNpZGUgYSBnZW5lcmljIHByb3ZpZGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIFN0cmluZyBuYW1lXG4gICAgICogQHBhcmFtIEZ1bmN0aW9uIEZhY3RvcnlcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciBmYWN0b3J5ID0gZnVuY3Rpb24gZmFjdG9yeShuYW1lLCBGYWN0b3J5KSB7XG4gICAgICAgIHJldHVybiBwcm92aWRlci5jYWxsKHRoaXMsIG5hbWUsIGZ1bmN0aW9uIEdlbmVyaWNQcm92aWRlcigpIHtcbiAgICAgICAgICAgIHRoaXMuJGdldCA9IEZhY3Rvcnk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgXG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYW4gaW5zdGFuY2UgZmFjdG9yeSBpbnNpZGUgYSBnZW5lcmljIGZhY3RvcnkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gRmFjdG9yeSAtIFRoZSBmYWN0b3J5IGZ1bmN0aW9uLCBtYXRjaGVzIHRoZSBzaWduYXR1cmUgcmVxdWlyZWQgZm9yIHRoZVxuICAgICAqIGBmYWN0b3J5YCBtZXRob2RcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciBpbnN0YW5jZUZhY3RvcnkgPSBmdW5jdGlvbiBpbnN0YW5jZUZhY3RvcnkobmFtZSwgRmFjdG9yeSkge1xuICAgICAgICByZXR1cm4gZmFjdG9yeS5jYWxsKHRoaXMsIG5hbWUsIGZ1bmN0aW9uIEdlbmVyaWNJbnN0YW5jZUZhY3RvcnkoY29udGFpbmVyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlIDogRmFjdG9yeS5iaW5kKEZhY3RvcnksIGNvbnRhaW5lcilcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgXG4gICAgLyoqXG4gICAgICogQSBmaWx0ZXIgZnVuY3Rpb24gZm9yIHJlbW92aW5nIGJvdHRsZSBjb250YWluZXIgbWV0aG9kcyBhbmQgcHJvdmlkZXJzIGZyb20gYSBsaXN0IG9mIGtleXNcbiAgICAgKi9cbiAgICB2YXIgYnlNZXRob2QgPSBmdW5jdGlvbiBieU1ldGhvZChuYW1lKSB7XG4gICAgICAgIHJldHVybiAhL15cXCQoPzpkZWNvcmF0b3J8cmVnaXN0ZXJ8bGlzdCkkfFByb3ZpZGVyJC8udGVzdChuYW1lKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIExpc3QgdGhlIHNlcnZpY2VzIHJlZ2lzdGVyZWQgb24gdGhlIGNvbnRhaW5lci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBPYmplY3QgY29udGFpbmVyXG4gICAgICogQHJldHVybiBBcnJheVxuICAgICAqL1xuICAgIHZhciBsaXN0ID0gZnVuY3Rpb24gbGlzdChjb250YWluZXIpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNvbnRhaW5lciB8fCB0aGlzLmNvbnRhaW5lciB8fCB7fSkuZmlsdGVyKGJ5TWV0aG9kKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgYnkgcHJvdmlkZXIgdG8gc2V0IHVwIG1pZGRsZXdhcmUgZm9yIGVhY2ggcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBOdW1iZXIgaWRcbiAgICAgKiBAcGFyYW0gU3RyaW5nIG5hbWVcbiAgICAgKiBAcGFyYW0gT2JqZWN0IGluc3RhbmNlXG4gICAgICogQHBhcmFtIE9iamVjdCBjb250YWluZXJcbiAgICAgKiBAcmV0dXJuIHZvaWRcbiAgICAgKi9cbiAgICB2YXIgYXBwbHlNaWRkbGV3YXJlID0gZnVuY3Rpb24gYXBwbHlNaWRkbGV3YXJlKG1pZGRsZXdhcmUsIG5hbWUsIGluc3RhbmNlLCBjb250YWluZXIpIHtcbiAgICAgICAgdmFyIGRlc2NyaXB0b3IgPSB7XG4gICAgICAgICAgICBjb25maWd1cmFibGUgOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZSA6IHRydWVcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKG1pZGRsZXdhcmUubGVuZ3RoKSB7XG4gICAgICAgICAgICBkZXNjcmlwdG9yLmdldCA9IGZ1bmN0aW9uIGdldFdpdGhNaWRkbGV3ZWFyKCkge1xuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgdmFyIG5leHQgPSBmdW5jdGlvbiBuZXh0TWlkZGxld2FyZShlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChtaWRkbGV3YXJlW2luZGV4XSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWlkZGxld2FyZVtpbmRleCsrXShpbnN0YW5jZSwgbmV4dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5leHQoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVzY3JpcHRvci52YWx1ZSA9IGluc3RhbmNlO1xuICAgICAgICAgICAgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnRhaW5lciwgbmFtZSwgZGVzY3JpcHRvcik7XG4gICAgXG4gICAgICAgIHJldHVybiBjb250YWluZXJbbmFtZV07XG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBtaWRkbGV3YXJlLlxuICAgICAqXG4gICAgICogQHBhcmFtIFN0cmluZyBuYW1lXG4gICAgICogQHBhcmFtIEZ1bmN0aW9uIGZ1bmNcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciBtaWRkbGV3YXJlID0gZnVuY3Rpb24gbWlkZGxld2FyZShmdWxsbmFtZSwgZnVuYykge1xuICAgICAgICB2YXIgcGFydHMsIG5hbWU7XG4gICAgICAgIGlmICh0eXBlb2YgZnVsbG5hbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGZ1bmMgPSBmdWxsbmFtZTtcbiAgICAgICAgICAgIGZ1bGxuYW1lID0gJ19fZ2xvYmFsX18nO1xuICAgICAgICB9XG4gICAgXG4gICAgICAgIHBhcnRzID0gZnVsbG5hbWUuc3BsaXQoJy4nKTtcbiAgICAgICAgbmFtZSA9IHBhcnRzLnNoaWZ0KCk7XG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGdldE5lc3RlZEJvdHRsZS5jYWxsKHRoaXMsIG5hbWUpLm1pZGRsZXdhcmUocGFydHMuam9pbignLicpLCBmdW5jKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5taWRkbGV3YXJlc1tuYW1lXSkge1xuICAgICAgICAgICAgICAgIHRoaXMubWlkZGxld2FyZXNbbmFtZV0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubWlkZGxld2FyZXNbbmFtZV0ucHVzaChmdW5jKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIE5hbWVkIGJvdHRsZSBpbnN0YW5jZXNcbiAgICAgKlxuICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAqL1xuICAgIHZhciBib3R0bGVzID0ge307XG4gICAgXG4gICAgLyoqXG4gICAgICogR2V0IGFuIGluc3RhbmNlIG9mIGJvdHRsZS5cbiAgICAgKlxuICAgICAqIElmIGEgbmFtZSBpcyBwcm92aWRlZCB0aGUgaW5zdGFuY2Ugd2lsbCBiZSBzdG9yZWQgaW4gYSBsb2NhbCBoYXNoLiAgQ2FsbGluZyBCb3R0bGUucG9wIG11bHRpcGxlXG4gICAgICogdGltZXMgd2l0aCB0aGUgc2FtZSBuYW1lIHdpbGwgcmV0dXJuIHRoZSBzYW1lIGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHBhcmFtIFN0cmluZyBuYW1lXG4gICAgICogQHJldHVybiBCb3R0bGVcbiAgICAgKi9cbiAgICB2YXIgcG9wID0gZnVuY3Rpb24gcG9wKG5hbWUpIHtcbiAgICAgICAgdmFyIGluc3RhbmNlO1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpbnN0YW5jZSA9IGJvdHRsZXNbbmFtZV07XG4gICAgICAgICAgICBpZiAoIWluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgYm90dGxlc1tuYW1lXSA9IGluc3RhbmNlID0gbmV3IEJvdHRsZSgpO1xuICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbnN0YW50KCdCT1RUTEVfTkFNRScsIG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQm90dGxlKCk7XG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBDbGVhciBhbGwgbmFtZWQgYm90dGxlcy5cbiAgICAgKi9cbiAgICB2YXIgY2xlYXIgPSBmdW5jdGlvbiBjbGVhcihuYW1lKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBib3R0bGVzW25hbWVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYm90dGxlcyA9IHt9O1xuICAgICAgICB9XG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBVc2VkIHRvIHByb2Nlc3MgZGVjb3JhdG9ycyBpbiB0aGUgcHJvdmlkZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBPYmplY3QgaW5zdGFuY2VcbiAgICAgKiBAcGFyYW0gRnVuY3Rpb24gZnVuY1xuICAgICAqIEByZXR1cm4gTWl4ZWRcbiAgICAgKi9cbiAgICB2YXIgcmVkdWNlciA9IGZ1bmN0aW9uIHJlZHVjZXIoaW5zdGFuY2UsIGZ1bmMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMoaW5zdGFuY2UpO1xuICAgIH07XG4gICAgXG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBTdHJpbmcgZnVsbG5hbWVcbiAgICAgKiBAcGFyYW0gRnVuY3Rpb24gUHJvdmlkZXJcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciBwcm92aWRlciA9IGZ1bmN0aW9uIHByb3ZpZGVyKGZ1bGxuYW1lLCBQcm92aWRlcikge1xuICAgICAgICB2YXIgcGFydHMsIG5hbWU7XG4gICAgICAgIHBhcnRzID0gZnVsbG5hbWUuc3BsaXQoJy4nKTtcbiAgICAgICAgaWYgKHRoaXMucHJvdmlkZXJNYXBbZnVsbG5hbWVdICYmIHBhcnRzLmxlbmd0aCA9PT0gMSAmJiAhdGhpcy5jb250YWluZXJbZnVsbG5hbWUgKyAnUHJvdmlkZXInXSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoZnVsbG5hbWUgKyAnIHByb3ZpZGVyIGFscmVhZHkgaW5zdGFudGlhdGVkLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3JpZ2luYWxQcm92aWRlcnNbZnVsbG5hbWVdID0gUHJvdmlkZXI7XG4gICAgICAgIHRoaXMucHJvdmlkZXJNYXBbZnVsbG5hbWVdID0gdHJ1ZTtcbiAgICBcbiAgICAgICAgbmFtZSA9IHBhcnRzLnNoaWZ0KCk7XG4gICAgXG4gICAgICAgIGlmIChwYXJ0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNyZWF0ZVN1YlByb3ZpZGVyLmNhbGwodGhpcywgbmFtZSwgUHJvdmlkZXIsIHBhcnRzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjcmVhdGVQcm92aWRlci5jYWxsKHRoaXMsIG5hbWUsIFByb3ZpZGVyKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIEdldCBkZWNvcmF0b3JzIGFuZCBtaWRkbGV3YXJlIGluY2x1ZGluZyBnbG9iYWxzXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIGFycmF5XG4gICAgICovXG4gICAgdmFyIGdldFdpdGhHbG9iYWwgPSBmdW5jdGlvbiBnZXRXaXRoR2xvYmFsKGNvbGxlY3Rpb24sIG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIChjb2xsZWN0aW9uW25hbWVdIHx8IFtdKS5jb25jYXQoY29sbGVjdGlvbi5fX2dsb2JhbF9fIHx8IFtdKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB0aGUgcHJvdmlkZXIgcHJvcGVydGllcyBvbiB0aGUgY29udGFpbmVyXG4gICAgICpcbiAgICAgKiBAcGFyYW0gU3RyaW5nIG5hbWVcbiAgICAgKiBAcGFyYW0gRnVuY3Rpb24gUHJvdmlkZXJcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciBjcmVhdGVQcm92aWRlciA9IGZ1bmN0aW9uIGNyZWF0ZVByb3ZpZGVyKG5hbWUsIFByb3ZpZGVyKSB7XG4gICAgICAgIHZhciBwcm92aWRlck5hbWUsIHByb3BlcnRpZXMsIGNvbnRhaW5lciwgaWQsIGRlY29yYXRvcnMsIG1pZGRsZXdhcmVzO1xuICAgIFxuICAgICAgICBpZCA9IHRoaXMuaWQ7XG4gICAgICAgIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuICAgICAgICBkZWNvcmF0b3JzID0gdGhpcy5kZWNvcmF0b3JzO1xuICAgICAgICBtaWRkbGV3YXJlcyA9IHRoaXMubWlkZGxld2FyZXM7XG4gICAgICAgIHByb3ZpZGVyTmFtZSA9IG5hbWUgKyAnUHJvdmlkZXInO1xuICAgIFxuICAgICAgICBwcm9wZXJ0aWVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgcHJvcGVydGllc1twcm92aWRlck5hbWVdID0ge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlIDogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGUgOiB0cnVlLFxuICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24gZ2V0UHJvdmlkZXIoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gbmV3IFByb3ZpZGVyKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNvbnRhaW5lcltwcm92aWRlck5hbWVdO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lcltwcm92aWRlck5hbWVdID0gaW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIFxuICAgICAgICBwcm9wZXJ0aWVzW25hbWVdID0ge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlIDogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGUgOiB0cnVlLFxuICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24gZ2V0U2VydmljZSgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJvdmlkZXIgPSBjb250YWluZXJbcHJvdmlkZXJOYW1lXTtcbiAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgaWYgKHByb3ZpZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGZpbHRlciB0aHJvdWdoIGRlY29yYXRvcnNcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBnZXRXaXRoR2xvYmFsKGRlY29yYXRvcnMsIG5hbWUpLnJlZHVjZShyZWR1Y2VyLCBwcm92aWRlci4kZ2V0KGNvbnRhaW5lcikpO1xuICAgIFxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgY29udGFpbmVyW3Byb3ZpZGVyTmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb250YWluZXJbbmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZSA9PT0gdW5kZWZpbmVkID8gaW5zdGFuY2UgOiBhcHBseU1pZGRsZXdhcmUoZ2V0V2l0aEdsb2JhbChtaWRkbGV3YXJlcywgbmFtZSksXG4gICAgICAgICAgICAgICAgICAgIG5hbWUsIGluc3RhbmNlLCBjb250YWluZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIFxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb250YWluZXIsIHByb3BlcnRpZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBib3R0bGUgY29udGFpbmVyIG9uIHRoZSBjdXJyZW50IGJvdHRsZSBjb250YWluZXIsIGFuZCByZWdpc3RlcnNcbiAgICAgKiB0aGUgcHJvdmlkZXIgdW5kZXIgdGhlIHN1YiBjb250YWluZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gU3RyaW5nIG5hbWVcbiAgICAgKiBAcGFyYW0gRnVuY3Rpb24gUHJvdmlkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkgcGFydHNcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciBjcmVhdGVTdWJQcm92aWRlciA9IGZ1bmN0aW9uIGNyZWF0ZVN1YlByb3ZpZGVyKG5hbWUsIFByb3ZpZGVyLCBwYXJ0cykge1xuICAgICAgICB2YXIgYm90dGxlO1xuICAgICAgICBib3R0bGUgPSBnZXROZXN0ZWRCb3R0bGUuY2FsbCh0aGlzLCBuYW1lKTtcbiAgICAgICAgdGhpcy5mYWN0b3J5KG5hbWUsIGZ1bmN0aW9uIFN1YlByb3ZpZGVyRmFjdG9yeSgpIHtcbiAgICAgICAgICAgIHJldHVybiBib3R0bGUuY29udGFpbmVyO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGJvdHRsZS5wcm92aWRlcihwYXJ0cy5qb2luKCcuJyksIFByb3ZpZGVyKTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGEgc2VydmljZSwgZmFjdG9yeSwgcHJvdmlkZXIsIG9yIHZhbHVlIGJhc2VkIG9uIHByb3BlcnRpZXMgb24gdGhlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIHByb3BlcnRpZXM6XG4gICAgICogICogT2JqLiRuYW1lICAgU3RyaW5nIHJlcXVpcmVkIGV4OiBgJ1RoaW5nJ2BcbiAgICAgKiAgKiBPYmouJHR5cGUgICBTdHJpbmcgb3B0aW9uYWwgJ3NlcnZpY2UnLCAnZmFjdG9yeScsICdwcm92aWRlcicsICd2YWx1ZScuICBEZWZhdWx0OiAnc2VydmljZSdcbiAgICAgKiAgKiBPYmouJGluamVjdCBNaXhlZCAgb3B0aW9uYWwgb25seSB1c2VmdWwgd2l0aCAkdHlwZSAnc2VydmljZScgbmFtZSBvciBhcnJheSBvZiBuYW1lc1xuICAgICAqICAqIE9iai4kdmFsdWUgIE1peGVkICBvcHRpb25hbCBOb3JtYWxseSBPYmogaXMgcmVnaXN0ZXJlZCBvbiB0aGUgY29udGFpbmVyLiAgSG93ZXZlciwgaWYgdGhpc1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eSBpcyBpbmNsdWRlZCwgaXQncyB2YWx1ZSB3aWxsIGJlIHJlZ2lzdGVyZWQgb24gdGhlIGNvbnRhaW5lclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICBpbnN0ZWFkIG9mIHRoZSBvYmplY3QgaXRzc2VsZi4gIFVzZWZ1bCBmb3IgcmVnaXN0ZXJpbmcgb2JqZWN0cyBvbiB0aGVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgYm90dGxlIGNvbnRhaW5lciB3aXRob3V0IG1vZGlmeWluZyB0aG9zZSBvYmplY3RzIHdpdGggYm90dGxlIHNwZWNpZmljIGtleXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gRnVuY3Rpb24gT2JqXG4gICAgICogQHJldHVybiBCb3R0bGVcbiAgICAgKi9cbiAgICB2YXIgcmVnaXN0ZXIgPSBmdW5jdGlvbiByZWdpc3RlcihPYmopIHtcbiAgICAgICAgdmFyIHZhbHVlID0gT2JqLiR2YWx1ZSA9PT0gdW5kZWZpbmVkID8gT2JqIDogT2JqLiR2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXNbT2JqLiR0eXBlIHx8ICdzZXJ2aWNlJ10uYXBwbHkodGhpcywgW09iai4kbmFtZSwgdmFsdWVdLmNvbmNhdChPYmouJGluamVjdCB8fCBbXSkpO1xuICAgIH07XG4gICAgXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBwcm92aWRlcnMgZnJvbSB0aGUgbWFwIGFuZCBjb250YWluZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gU3RyaW5nIG5hbWVcbiAgICAgKiBAcmV0dXJuIHZvaWRcbiAgICAgKi9cbiAgICB2YXIgcmVtb3ZlUHJvdmlkZXJNYXAgPSBmdW5jdGlvbiByZXNldFByb3ZpZGVyKG5hbWUpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMucHJvdmlkZXJNYXBbbmFtZV07XG4gICAgICAgIGRlbGV0ZSB0aGlzLmNvbnRhaW5lcltuYW1lXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29udGFpbmVyW25hbWUgKyAnUHJvdmlkZXInXTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIFJlc2V0cyBhbGwgcHJvdmlkZXJzIG9uIGEgYm90dGxlIGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHJldHVybiB2b2lkXG4gICAgICovXG4gICAgdmFyIHJlc2V0UHJvdmlkZXJzID0gZnVuY3Rpb24gcmVzZXRQcm92aWRlcnMoKSB7XG4gICAgICAgIHZhciBwcm92aWRlcnMgPSB0aGlzLm9yaWdpbmFsUHJvdmlkZXJzO1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLm9yaWdpbmFsUHJvdmlkZXJzKS5mb3JFYWNoKGZ1bmN0aW9uIHJlc2V0UHJ2aWRlcihwcm92aWRlcikge1xuICAgICAgICAgICAgdmFyIHBhcnRzID0gcHJvdmlkZXIuc3BsaXQoJy4nKTtcbiAgICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlUHJvdmlkZXJNYXAuY2FsbCh0aGlzLCBwYXJ0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFydHMuZm9yRWFjaChyZW1vdmVQcm92aWRlck1hcCwgZ2V0TmVzdGVkQm90dGxlLmNhbGwodGhpcywgcGFydHNbMF0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbW92ZVByb3ZpZGVyTWFwLmNhbGwodGhpcywgcHJvdmlkZXIpO1xuICAgICAgICAgICAgdGhpcy5wcm92aWRlcihwcm92aWRlciwgcHJvdmlkZXJzW3Byb3ZpZGVyXSk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIH07XG4gICAgXG4gICAgXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZSBhbnkgZGVmZXJyZWQgZnVuY3Rpb25zXG4gICAgICpcbiAgICAgKiBAcGFyYW0gTWl4ZWQgZGF0YVxuICAgICAqIEByZXR1cm4gQm90dGxlXG4gICAgICovXG4gICAgdmFyIHJlc29sdmUgPSBmdW5jdGlvbiByZXNvbHZlKGRhdGEpIHtcbiAgICAgICAgdGhpcy5kZWZlcnJlZC5mb3JFYWNoKGZ1bmN0aW9uIGRlZmVycmVkSXRlcmF0b3IoZnVuYykge1xuICAgICAgICAgICAgZnVuYyhkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgXG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBzZXJ2aWNlIGluc2lkZSBhIGdlbmVyaWMgZmFjdG9yeS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBTdHJpbmcgbmFtZVxuICAgICAqIEBwYXJhbSBGdW5jdGlvbiBTZXJ2aWNlXG4gICAgICogQHJldHVybiBCb3R0bGVcbiAgICAgKi9cbiAgICB2YXIgc2VydmljZSA9IGZ1bmN0aW9uIHNlcnZpY2UobmFtZSwgU2VydmljZSkge1xuICAgICAgICB2YXIgZGVwcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpIDogbnVsbDtcbiAgICAgICAgdmFyIGJvdHRsZSA9IHRoaXM7XG4gICAgICAgIHJldHVybiBmYWN0b3J5LmNhbGwodGhpcywgbmFtZSwgZnVuY3Rpb24gR2VuZXJpY0ZhY3RvcnkoKSB7XG4gICAgICAgICAgICBpZiAoZGVwcykge1xuICAgICAgICAgICAgICAgIGRlcHMgPSBkZXBzLm1hcChnZXROZXN0ZWRTZXJ2aWNlLCBib3R0bGUuY29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICBkZXBzLnVuc2hpZnQoU2VydmljZSk7XG4gICAgICAgICAgICAgICAgU2VydmljZSA9IFNlcnZpY2UuYmluZC5hcHBseShTZXJ2aWNlLCBkZXBzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXcgU2VydmljZSgpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGEgdmFsdWVcbiAgICAgKlxuICAgICAqIEBwYXJhbSBTdHJpbmcgbmFtZVxuICAgICAqIEBwYXJhbSBtaXhlZCB2YWxcbiAgICAgKiBAcmV0dXJuIEJvdHRsZVxuICAgICAqL1xuICAgIHZhciB2YWx1ZSA9IGZ1bmN0aW9uIHZhbHVlKG5hbWUsIHZhbCkge1xuICAgICAgICB2YXIgcGFydHM7XG4gICAgICAgIHBhcnRzID0gbmFtZS5zcGxpdCgnLicpO1xuICAgICAgICBuYW1lID0gcGFydHMucG9wKCk7XG4gICAgICAgIGRlZmluZVZhbHVlLmNhbGwocGFydHMucmVkdWNlKHNldFZhbHVlT2JqZWN0LCB0aGlzLmNvbnRhaW5lciksIG5hbWUsIHZhbCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgXG4gICAgLyoqXG4gICAgICogSXRlcmF0b3IgZm9yIHNldHRpbmcgYSBwbGFpbiBvYmplY3QgbGl0ZXJhbCB2aWEgZGVmaW5lVmFsdWVcbiAgICAgKlxuICAgICAqIEBwYXJhbSBPYmplY3QgY29udGFpbmVyXG4gICAgICogQHBhcmFtIHN0cmluZyBuYW1lXG4gICAgICovXG4gICAgdmFyIHNldFZhbHVlT2JqZWN0ID0gZnVuY3Rpb24gc2V0VmFsdWVPYmplY3QoY29udGFpbmVyLCBuYW1lKSB7XG4gICAgICAgIHZhciBuZXN0ZWRDb250YWluZXIgPSBjb250YWluZXJbbmFtZV07XG4gICAgICAgIGlmICghbmVzdGVkQ29udGFpbmVyKSB7XG4gICAgICAgICAgICBuZXN0ZWRDb250YWluZXIgPSB7fTtcbiAgICAgICAgICAgIGRlZmluZVZhbHVlLmNhbGwoY29udGFpbmVyLCBuYW1lLCBuZXN0ZWRDb250YWluZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXN0ZWRDb250YWluZXI7XG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBEZWZpbmUgYSBtdXRhYmxlIHByb3BlcnR5IG9uIHRoZSBjb250YWluZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gU3RyaW5nIG5hbWVcbiAgICAgKiBAcGFyYW0gbWl4ZWQgdmFsXG4gICAgICogQHJldHVybiB2b2lkXG4gICAgICogQHNjb3BlIGNvbnRhaW5lclxuICAgICAqL1xuICAgIHZhciBkZWZpbmVWYWx1ZSA9IGZ1bmN0aW9uIGRlZmluZVZhbHVlKG5hbWUsIHZhbCkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgbmFtZSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlIDogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGUgOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWUgOiB2YWwsXG4gICAgICAgICAgICB3cml0YWJsZSA6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBcbiAgICBcbiAgICAvKipcbiAgICAgKiBCb3R0bGUgY29uc3RydWN0b3JcbiAgICAgKlxuICAgICAqIEBwYXJhbSBTdHJpbmcgbmFtZSBPcHRpb25hbCBuYW1lIGZvciBmdW5jdGlvbmFsIGNvbnN0cnVjdGlvblxuICAgICAqL1xuICAgIHZhciBCb3R0bGUgPSBmdW5jdGlvbiBCb3R0bGUobmFtZSkge1xuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQm90dGxlKSkge1xuICAgICAgICAgICAgcmV0dXJuIEJvdHRsZS5wb3AobmFtZSk7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgdGhpcy5pZCA9IGlkKys7XG4gICAgXG4gICAgICAgIHRoaXMuZGVjb3JhdG9ycyA9IHt9O1xuICAgICAgICB0aGlzLm1pZGRsZXdhcmVzID0ge307XG4gICAgICAgIHRoaXMubmVzdGVkID0ge307XG4gICAgICAgIHRoaXMucHJvdmlkZXJNYXAgPSB7fTtcbiAgICAgICAgdGhpcy5vcmlnaW5hbFByb3ZpZGVycyA9IHt9O1xuICAgICAgICB0aGlzLmRlZmVycmVkID0gW107XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0ge1xuICAgICAgICAgICAgJGRlY29yYXRvciA6IGRlY29yYXRvci5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgJHJlZ2lzdGVyIDogcmVnaXN0ZXIuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICRsaXN0IDogbGlzdC5iaW5kKHRoaXMpXG4gICAgICAgIH07XG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBCb3R0bGUgcHJvdG90eXBlXG4gICAgICovXG4gICAgQm90dGxlLnByb3RvdHlwZSA9IHtcbiAgICAgICAgY29uc3RhbnQgOiBjb25zdGFudCxcbiAgICAgICAgZGVjb3JhdG9yIDogZGVjb3JhdG9yLFxuICAgICAgICBkZWZlciA6IGRlZmVyLFxuICAgICAgICBkaWdlc3QgOiBkaWdlc3QsXG4gICAgICAgIGZhY3RvcnkgOiBmYWN0b3J5LFxuICAgICAgICBpbnN0YW5jZUZhY3Rvcnk6IGluc3RhbmNlRmFjdG9yeSxcbiAgICAgICAgbGlzdCA6IGxpc3QsXG4gICAgICAgIG1pZGRsZXdhcmUgOiBtaWRkbGV3YXJlLFxuICAgICAgICBwcm92aWRlciA6IHByb3ZpZGVyLFxuICAgICAgICByZXNldFByb3ZpZGVycyA6IHJlc2V0UHJvdmlkZXJzLFxuICAgICAgICByZWdpc3RlciA6IHJlZ2lzdGVyLFxuICAgICAgICByZXNvbHZlIDogcmVzb2x2ZSxcbiAgICAgICAgc2VydmljZSA6IHNlcnZpY2UsXG4gICAgICAgIHZhbHVlIDogdmFsdWVcbiAgICB9O1xuICAgIFxuICAgIC8qKlxuICAgICAqIEJvdHRsZSBzdGF0aWNcbiAgICAgKi9cbiAgICBCb3R0bGUucG9wID0gcG9wO1xuICAgIEJvdHRsZS5jbGVhciA9IGNsZWFyO1xuICAgIEJvdHRsZS5saXN0ID0gbGlzdDtcbiAgICBcbiAgICAvKipcbiAgICAgKiBHbG9iYWwgY29uZmlnXG4gICAgICovXG4gICAgdmFyIGdsb2JhbENvbmZpZyA9IEJvdHRsZS5jb25maWcgPSB7XG4gICAgICAgIHN0cmljdCA6IGZhbHNlXG4gICAgfTtcbiAgICBcbiAgICAvKipcbiAgICAgKiBFeHBvcnRzIHNjcmlwdCBhZGFwdGVkIGZyb20gbG9kYXNoIHYyLjQuMSBNb2Rlcm4gQnVpbGRcbiAgICAgKlxuICAgICAqIEBzZWUgaHR0cDovL2xvZGFzaC5jb20vXG4gICAgICovXG4gICAgXG4gICAgLyoqXG4gICAgICogVmFsaWQgb2JqZWN0IHR5cGUgbWFwXG4gICAgICpcbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICB2YXIgb2JqZWN0VHlwZXMgPSB7XG4gICAgICAgICdmdW5jdGlvbicgOiB0cnVlLFxuICAgICAgICAnb2JqZWN0JyA6IHRydWVcbiAgICB9O1xuICAgIFxuICAgIChmdW5jdGlvbiBleHBvcnRCb3R0bGUocm9vdCkge1xuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogRnJlZSB2YXJpYWJsZSBleHBvcnRzXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0eXBlIEZ1bmN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgZnJlZUV4cG9ydHMgPSBvYmplY3RUeXBlc1t0eXBlb2YgZXhwb3J0c10gJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuICAgIFxuICAgICAgICAvKipcbiAgICAgICAgICogRnJlZSB2YXJpYWJsZSBtb2R1bGVcbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICB2YXIgZnJlZU1vZHVsZSA9IG9iamVjdFR5cGVzW3R5cGVvZiBtb2R1bGVdICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTtcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbW1vbkpTIG1vZHVsZS5leHBvcnRzXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0eXBlIEZ1bmN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICB2YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cyAmJiBmcmVlRXhwb3J0cztcbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZyZWUgdmFyaWFibGUgYGdsb2JhbGBcbiAgICAgICAgICpcbiAgICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICB2YXIgZnJlZUdsb2JhbCA9IG9iamVjdFR5cGVzW3R5cGVvZiBnbG9iYWxdICYmIGdsb2JhbDtcbiAgICAgICAgaWYgKGZyZWVHbG9iYWwgJiYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSkge1xuICAgICAgICAgICAgcm9vdCA9IGZyZWVHbG9iYWw7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV4cG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT09ICdvYmplY3QnICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgICAgIHJvb3QuQm90dGxlID0gQm90dGxlO1xuICAgICAgICAgICAgZGVmaW5lKGZ1bmN0aW9uKCkgeyByZXR1cm4gQm90dGxlOyB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlKSB7XG4gICAgICAgICAgICBpZiAobW9kdWxlRXhwb3J0cykge1xuICAgICAgICAgICAgICAgIChmcmVlTW9kdWxlLmV4cG9ydHMgPSBCb3R0bGUpLkJvdHRsZSA9IEJvdHRsZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZnJlZUV4cG9ydHMuQm90dGxlID0gQm90dGxlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcm9vdC5Cb3R0bGUgPSBCb3R0bGU7XG4gICAgICAgIH1cbiAgICB9KChvYmplY3RUeXBlc1t0eXBlb2Ygd2luZG93XSAmJiB3aW5kb3cpIHx8IHRoaXMpKTtcbiAgICBcbn0uY2FsbCh0aGlzKSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2JvdHRsZWpzL2Rpc3QvYm90dGxlLmpzXG4vLyBtb2R1bGUgaWQgPSAxM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBsaXN0ID0gW107XHJcblx0bGlzdC50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xyXG5cdFx0dmFyIHJlc3VsdCA9IFtdO1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGl0ZW0gPSB0aGlzW2ldO1xyXG5cdFx0XHRpZihpdGVtWzJdKSB7XHJcblx0XHRcdFx0cmVzdWx0LnB1c2goXCJAbWVkaWEgXCIgKyBpdGVtWzJdICsgXCJ7XCIgKyBpdGVtWzFdICsgXCJ9XCIpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHJlc3VsdC5wdXNoKGl0ZW1bMV0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gcmVzdWx0LmpvaW4oXCJcIik7XHJcblx0fTtcclxuXHRyZXR1cm4gbGlzdDtcclxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyL2Nzc1RvU3RyaW5nLmpzXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmluaGVyaXRzKFN0cmVhbSwgRUUpO1xuU3RyZWFtLlJlYWRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzJyk7XG5TdHJlYW0uV3JpdGFibGUgPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanMnKTtcblN0cmVhbS5EdXBsZXggPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzJyk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qcycpO1xuU3RyZWFtLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzJyk7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuNC54XG5TdHJlYW0uU3RyZWFtID0gU3RyZWFtO1xuXG5cblxuLy8gb2xkLXN0eWxlIHN0cmVhbXMuICBOb3RlIHRoYXQgdGhlIHBpcGUgbWV0aG9kICh0aGUgb25seSByZWxldmFudFxuLy8gcGFydCBvZiB0aGlzIGNsYXNzKSBpcyBvdmVycmlkZGVuIGluIHRoZSBSZWFkYWJsZSBjbGFzcy5cblxuZnVuY3Rpb24gU3RyZWFtKCkge1xuICBFRS5jYWxsKHRoaXMpO1xufVxuXG5TdHJlYW0ucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBvcHRpb25zKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzO1xuXG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGlmIChkZXN0LndyaXRhYmxlKSB7XG4gICAgICBpZiAoZmFsc2UgPT09IGRlc3Qud3JpdGUoY2h1bmspICYmIHNvdXJjZS5wYXVzZSkge1xuICAgICAgICBzb3VyY2UucGF1c2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2RhdGEnLCBvbmRhdGEpO1xuXG4gIGZ1bmN0aW9uIG9uZHJhaW4oKSB7XG4gICAgaWYgKHNvdXJjZS5yZWFkYWJsZSAmJiBzb3VyY2UucmVzdW1lKSB7XG4gICAgICBzb3VyY2UucmVzdW1lKCk7XG4gICAgfVxuICB9XG5cbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICAvLyBJZiB0aGUgJ2VuZCcgb3B0aW9uIGlzIG5vdCBzdXBwbGllZCwgZGVzdC5lbmQoKSB3aWxsIGJlIGNhbGxlZCB3aGVuXG4gIC8vIHNvdXJjZSBnZXRzIHRoZSAnZW5kJyBvciAnY2xvc2UnIGV2ZW50cy4gIE9ubHkgZGVzdC5lbmQoKSBvbmNlLlxuICBpZiAoIWRlc3QuX2lzU3RkaW8gJiYgKCFvcHRpb25zIHx8IG9wdGlvbnMuZW5kICE9PSBmYWxzZSkpIHtcbiAgICBzb3VyY2Uub24oJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2Uub24oJ2Nsb3NlJywgb25jbG9zZSk7XG4gIH1cblxuICB2YXIgZGlkT25FbmQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIGRlc3QuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgZGVzdC5kZXN0cm95KCk7XG4gIH1cblxuICAvLyBkb24ndCBsZWF2ZSBkYW5nbGluZyBwaXBlcyB3aGVuIHRoZXJlIGFyZSBlcnJvcnMuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBjbGVhbnVwKCk7XG4gICAgaWYgKEVFLmxpc3RlbmVyQ291bnQodGhpcywgJ2Vycm9yJykgPT09IDApIHtcbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgc3RyZWFtIGVycm9yIGluIHBpcGUuXG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuICBkZXN0Lm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIHJlbW92ZSBhbGwgdGhlIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlcmUgYWRkZWQuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG4gIH1cblxuICBzb3VyY2Uub24oJ2VuZCcsIGNsZWFudXApO1xuICBzb3VyY2Uub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0LmVtaXQoJ3BpcGUnLCBzb3VyY2UpO1xuXG4gIC8vIEFsbG93IGZvciB1bml4LWxpa2UgdXNhZ2U6IEEucGlwZShCKS5waXBlKEMpXG4gIHJldHVybiBkZXN0O1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLypcclxuXHRNSVQgTGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxyXG5cdEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcclxuKi9cclxudmFyIHN0eWxlc0luRG9tID0ge30sXHJcblx0bWVtb2l6ZSA9IGZ1bmN0aW9uKGZuKSB7XHJcblx0XHR2YXIgbWVtbztcclxuXHRcdHJldHVybiBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdGlmICh0eXBlb2YgbWVtbyA9PT0gXCJ1bmRlZmluZWRcIikgbWVtbyA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcblx0XHRcdHJldHVybiBtZW1vO1xyXG5cdFx0fTtcclxuXHR9LFxyXG5cdGlzT2xkSUUgPSBtZW1vaXplKGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIC9tc2llIFs2LTldXFxiLy50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpO1xyXG5cdH0pLFxyXG5cdGdldEhlYWRFbGVtZW50ID0gbWVtb2l6ZShmdW5jdGlvbiAoKSB7XHJcblx0XHRyZXR1cm4gZG9jdW1lbnQuaGVhZCB8fCBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF07XHJcblx0fSksXHJcblx0c2luZ2xldG9uRWxlbWVudCA9IG51bGwsXHJcblx0c2luZ2xldG9uQ291bnRlciA9IDA7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGxpc3QsIG9wdGlvbnMpIHtcclxuXHRpZih0eXBlb2YgREVCVUcgIT09IFwidW5kZWZpbmVkXCIgJiYgREVCVUcpIHtcclxuXHRcdGlmKHR5cGVvZiBkb2N1bWVudCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHN0eWxlLWxvYWRlciBjYW5ub3QgYmUgdXNlZCBpbiBhIG5vbi1icm93c2VyIGVudmlyb25tZW50XCIpO1xyXG5cdH1cclxuXHJcblx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblx0Ly8gRm9yY2Ugc2luZ2xlLXRhZyBzb2x1dGlvbiBvbiBJRTYtOSwgd2hpY2ggaGFzIGEgaGFyZCBsaW1pdCBvbiB0aGUgIyBvZiA8c3R5bGU+XHJcblx0Ly8gdGFncyBpdCB3aWxsIGFsbG93IG9uIGEgcGFnZVxyXG5cdGlmICh0eXBlb2Ygb3B0aW9ucy5zaW5nbGV0b24gPT09IFwidW5kZWZpbmVkXCIpIG9wdGlvbnMuc2luZ2xldG9uID0gaXNPbGRJRSgpO1xyXG5cclxuXHR2YXIgc3R5bGVzID0gbGlzdFRvU3R5bGVzKGxpc3QpO1xyXG5cdGFkZFN0eWxlc1RvRG9tKHN0eWxlcywgb3B0aW9ucyk7XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbiB1cGRhdGUobmV3TGlzdCkge1xyXG5cdFx0dmFyIG1heVJlbW92ZSA9IFtdO1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgaXRlbSA9IHN0eWxlc1tpXTtcclxuXHRcdFx0dmFyIGRvbVN0eWxlID0gc3R5bGVzSW5Eb21baXRlbS5pZF07XHJcblx0XHRcdGRvbVN0eWxlLnJlZnMtLTtcclxuXHRcdFx0bWF5UmVtb3ZlLnB1c2goZG9tU3R5bGUpO1xyXG5cdFx0fVxyXG5cdFx0aWYobmV3TGlzdCkge1xyXG5cdFx0XHR2YXIgbmV3U3R5bGVzID0gbGlzdFRvU3R5bGVzKG5ld0xpc3QpO1xyXG5cdFx0XHRhZGRTdHlsZXNUb0RvbShuZXdTdHlsZXMsIG9wdGlvbnMpO1xyXG5cdFx0fVxyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IG1heVJlbW92ZS5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgZG9tU3R5bGUgPSBtYXlSZW1vdmVbaV07XHJcblx0XHRcdGlmKGRvbVN0eWxlLnJlZnMgPT09IDApIHtcclxuXHRcdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspXHJcblx0XHRcdFx0XHRkb21TdHlsZS5wYXJ0c1tqXSgpO1xyXG5cdFx0XHRcdGRlbGV0ZSBzdHlsZXNJbkRvbVtkb21TdHlsZS5pZF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRTdHlsZXNUb0RvbShzdHlsZXMsIG9wdGlvbnMpIHtcclxuXHRmb3IodmFyIGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHR2YXIgaXRlbSA9IHN0eWxlc1tpXTtcclxuXHRcdHZhciBkb21TdHlsZSA9IHN0eWxlc0luRG9tW2l0ZW0uaWRdO1xyXG5cdFx0aWYoZG9tU3R5bGUpIHtcclxuXHRcdFx0ZG9tU3R5bGUucmVmcysrO1xyXG5cdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspIHtcclxuXHRcdFx0XHRkb21TdHlsZS5wYXJ0c1tqXShpdGVtLnBhcnRzW2pdKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRmb3IoOyBqIDwgaXRlbS5wYXJ0cy5sZW5ndGg7IGorKykge1xyXG5cdFx0XHRcdGRvbVN0eWxlLnBhcnRzLnB1c2goYWRkU3R5bGUoaXRlbS5wYXJ0c1tqXSwgb3B0aW9ucykpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR2YXIgcGFydHMgPSBbXTtcclxuXHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IGl0ZW0ucGFydHMubGVuZ3RoOyBqKyspIHtcclxuXHRcdFx0XHRwYXJ0cy5wdXNoKGFkZFN0eWxlKGl0ZW0ucGFydHNbal0sIG9wdGlvbnMpKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRzdHlsZXNJbkRvbVtpdGVtLmlkXSA9IHtpZDogaXRlbS5pZCwgcmVmczogMSwgcGFydHM6IHBhcnRzfTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxpc3RUb1N0eWxlcyhsaXN0KSB7XHJcblx0dmFyIHN0eWxlcyA9IFtdO1xyXG5cdHZhciBuZXdTdHlsZXMgPSB7fTtcclxuXHRmb3IodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xyXG5cdFx0dmFyIGl0ZW0gPSBsaXN0W2ldO1xyXG5cdFx0dmFyIGlkID0gaXRlbVswXTtcclxuXHRcdHZhciBjc3MgPSBpdGVtWzFdO1xyXG5cdFx0dmFyIG1lZGlhID0gaXRlbVsyXTtcclxuXHRcdHZhciBzb3VyY2VNYXAgPSBpdGVtWzNdO1xyXG5cdFx0dmFyIHBhcnQgPSB7Y3NzOiBjc3MsIG1lZGlhOiBtZWRpYSwgc291cmNlTWFwOiBzb3VyY2VNYXB9O1xyXG5cdFx0aWYoIW5ld1N0eWxlc1tpZF0pXHJcblx0XHRcdHN0eWxlcy5wdXNoKG5ld1N0eWxlc1tpZF0gPSB7aWQ6IGlkLCBwYXJ0czogW3BhcnRdfSk7XHJcblx0XHRlbHNlXHJcblx0XHRcdG5ld1N0eWxlc1tpZF0ucGFydHMucHVzaChwYXJ0KTtcclxuXHR9XHJcblx0cmV0dXJuIHN0eWxlcztcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlU3R5bGVFbGVtZW50KCkge1xyXG5cdHZhciBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7XHJcblx0dmFyIGhlYWQgPSBnZXRIZWFkRWxlbWVudCgpO1xyXG5cdHN0eWxlRWxlbWVudC50eXBlID0gXCJ0ZXh0L2Nzc1wiO1xyXG5cdGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuXHRyZXR1cm4gc3R5bGVFbGVtZW50O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVMaW5rRWxlbWVudCgpIHtcclxuXHR2YXIgbGlua0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibGlua1wiKTtcclxuXHR2YXIgaGVhZCA9IGdldEhlYWRFbGVtZW50KCk7XHJcblx0bGlua0VsZW1lbnQucmVsID0gXCJzdHlsZXNoZWV0XCI7XHJcblx0aGVhZC5hcHBlbmRDaGlsZChsaW5rRWxlbWVudCk7XHJcblx0cmV0dXJuIGxpbmtFbGVtZW50O1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRTdHlsZShvYmosIG9wdGlvbnMpIHtcclxuXHR2YXIgc3R5bGVFbGVtZW50LCB1cGRhdGUsIHJlbW92ZTtcclxuXHJcblx0aWYgKG9wdGlvbnMuc2luZ2xldG9uKSB7XHJcblx0XHR2YXIgc3R5bGVJbmRleCA9IHNpbmdsZXRvbkNvdW50ZXIrKztcclxuXHRcdHN0eWxlRWxlbWVudCA9IHNpbmdsZXRvbkVsZW1lbnQgfHwgKHNpbmdsZXRvbkVsZW1lbnQgPSBjcmVhdGVTdHlsZUVsZW1lbnQoKSk7XHJcblx0XHR1cGRhdGUgPSBhcHBseVRvU2luZ2xldG9uVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50LCBzdHlsZUluZGV4LCBmYWxzZSk7XHJcblx0XHRyZW1vdmUgPSBhcHBseVRvU2luZ2xldG9uVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50LCBzdHlsZUluZGV4LCB0cnVlKTtcclxuXHR9IGVsc2UgaWYob2JqLnNvdXJjZU1hcCAmJlxyXG5cdFx0dHlwZW9mIFVSTCA9PT0gXCJmdW5jdGlvblwiICYmXHJcblx0XHR0eXBlb2YgVVJMLmNyZWF0ZU9iamVjdFVSTCA9PT0gXCJmdW5jdGlvblwiICYmXHJcblx0XHR0eXBlb2YgVVJMLnJldm9rZU9iamVjdFVSTCA9PT0gXCJmdW5jdGlvblwiICYmXHJcblx0XHR0eXBlb2YgQmxvYiA9PT0gXCJmdW5jdGlvblwiICYmXHJcblx0XHR0eXBlb2YgYnRvYSA9PT0gXCJmdW5jdGlvblwiKSB7XHJcblx0XHRzdHlsZUVsZW1lbnQgPSBjcmVhdGVMaW5rRWxlbWVudCgpO1xyXG5cdFx0dXBkYXRlID0gdXBkYXRlTGluay5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCk7XHJcblx0XHRyZW1vdmUgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0c3R5bGVFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuXHRcdFx0aWYoc3R5bGVFbGVtZW50LmhyZWYpXHJcblx0XHRcdFx0VVJMLnJldm9rZU9iamVjdFVSTChzdHlsZUVsZW1lbnQuaHJlZik7XHJcblx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHRzdHlsZUVsZW1lbnQgPSBjcmVhdGVTdHlsZUVsZW1lbnQoKTtcclxuXHRcdHVwZGF0ZSA9IGFwcGx5VG9UYWcuYmluZChudWxsLCBzdHlsZUVsZW1lbnQpO1xyXG5cdFx0cmVtb3ZlID0gZnVuY3Rpb24oKSB7XHJcblx0XHRcdHN0eWxlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudCk7XHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0dXBkYXRlKG9iaik7XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbiB1cGRhdGVTdHlsZShuZXdPYmopIHtcclxuXHRcdGlmKG5ld09iaikge1xyXG5cdFx0XHRpZihuZXdPYmouY3NzID09PSBvYmouY3NzICYmIG5ld09iai5tZWRpYSA9PT0gb2JqLm1lZGlhICYmIG5ld09iai5zb3VyY2VNYXAgPT09IG9iai5zb3VyY2VNYXApXHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR1cGRhdGUob2JqID0gbmV3T2JqKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHJlbW92ZSgpO1xyXG5cdFx0fVxyXG5cdH07XHJcbn1cclxuXHJcbnZhciByZXBsYWNlVGV4dCA9IChmdW5jdGlvbiAoKSB7XHJcblx0dmFyIHRleHRTdG9yZSA9IFtdO1xyXG5cclxuXHRyZXR1cm4gZnVuY3Rpb24gKGluZGV4LCByZXBsYWNlbWVudCkge1xyXG5cdFx0dGV4dFN0b3JlW2luZGV4XSA9IHJlcGxhY2VtZW50O1xyXG5cdFx0cmV0dXJuIHRleHRTdG9yZS5maWx0ZXIoQm9vbGVhbikuam9pbignXFxuJyk7XHJcblx0fTtcclxufSkoKTtcclxuXHJcbmZ1bmN0aW9uIGFwcGx5VG9TaW5nbGV0b25UYWcoc3R5bGVFbGVtZW50LCBpbmRleCwgcmVtb3ZlLCBvYmopIHtcclxuXHR2YXIgY3NzID0gcmVtb3ZlID8gXCJcIiA6IG9iai5jc3M7XHJcblxyXG5cdGlmIChzdHlsZUVsZW1lbnQuc3R5bGVTaGVldCkge1xyXG5cdFx0c3R5bGVFbGVtZW50LnN0eWxlU2hlZXQuY3NzVGV4dCA9IHJlcGxhY2VUZXh0KGluZGV4LCBjc3MpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHR2YXIgY3NzTm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcyk7XHJcblx0XHR2YXIgY2hpbGROb2RlcyA9IHN0eWxlRWxlbWVudC5jaGlsZE5vZGVzO1xyXG5cdFx0aWYgKGNoaWxkTm9kZXNbaW5kZXhdKSBzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoY2hpbGROb2Rlc1tpbmRleF0pO1xyXG5cdFx0aWYgKGNoaWxkTm9kZXMubGVuZ3RoKSB7XHJcblx0XHRcdHN0eWxlRWxlbWVudC5pbnNlcnRCZWZvcmUoY3NzTm9kZSwgY2hpbGROb2Rlc1tpbmRleF0pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGNzc05vZGUpO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gYXBwbHlUb1RhZyhzdHlsZUVsZW1lbnQsIG9iaikge1xyXG5cdHZhciBjc3MgPSBvYmouY3NzO1xyXG5cdHZhciBtZWRpYSA9IG9iai5tZWRpYTtcclxuXHR2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcclxuXHJcblx0aWYobWVkaWEpIHtcclxuXHRcdHN0eWxlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJtZWRpYVwiLCBtZWRpYSlcclxuXHR9XHJcblxyXG5cdGlmKHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0KSB7XHJcblx0XHRzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xyXG5cdH0gZWxzZSB7XHJcblx0XHR3aGlsZShzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCkge1xyXG5cdFx0XHRzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50LmZpcnN0Q2hpbGQpO1xyXG5cdFx0fVxyXG5cdFx0c3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gdXBkYXRlTGluayhsaW5rRWxlbWVudCwgb2JqKSB7XHJcblx0dmFyIGNzcyA9IG9iai5jc3M7XHJcblx0dmFyIG1lZGlhID0gb2JqLm1lZGlhO1xyXG5cdHZhciBzb3VyY2VNYXAgPSBvYmouc291cmNlTWFwO1xyXG5cclxuXHRpZihzb3VyY2VNYXApIHtcclxuXHRcdC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzI2NjAzODc1XHJcblx0XHRjc3MgKz0gXCJcXG4vKiMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247YmFzZTY0LFwiICsgYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkoc291cmNlTWFwKSkpKSArIFwiICovXCI7XHJcblx0fVxyXG5cclxuXHR2YXIgYmxvYiA9IG5ldyBCbG9iKFtjc3NdLCB7IHR5cGU6IFwidGV4dC9jc3NcIiB9KTtcclxuXHJcblx0dmFyIG9sZFNyYyA9IGxpbmtFbGVtZW50LmhyZWY7XHJcblxyXG5cdGxpbmtFbGVtZW50LmhyZWYgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xyXG5cclxuXHRpZihvbGRTcmMpXHJcblx0XHRVUkwucmV2b2tlT2JqZWN0VVJMKG9sZFNyYyk7XHJcbn1cclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcbi8vIG1vZHVsZSBpZCA9IDE2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0JztcblxudmFyIGJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpO1xudmFyIEJ1ZmZlciA9IGJ1ZmZlci5CdWZmZXI7XG52YXIgU2xvd0J1ZmZlciA9IGJ1ZmZlci5TbG93QnVmZmVyO1xudmFyIE1BWF9MRU4gPSBidWZmZXIua01heExlbmd0aCB8fCAyMTQ3NDgzNjQ3O1xuZXhwb3J0cy5hbGxvYyA9IGZ1bmN0aW9uIGFsbG9jKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgQnVmZmVyLmFsbG9jID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYyhzaXplLCBmaWxsLCBlbmNvZGluZyk7XG4gIH1cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IG5vdCBiZSBudW1iZXInKTtcbiAgfVxuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc2l6ZSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKHNpemUgPiBNQVhfTEVOKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NpemUgaXMgdG9vIGxhcmdlJyk7XG4gIH1cbiAgdmFyIGVuYyA9IGVuY29kaW5nO1xuICB2YXIgX2ZpbGwgPSBmaWxsO1xuICBpZiAoX2ZpbGwgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuYyA9IHVuZGVmaW5lZDtcbiAgICBfZmlsbCA9IDA7XG4gIH1cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gIGlmICh0eXBlb2YgX2ZpbGwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIGZpbGxCdWYgPSBuZXcgQnVmZmVyKF9maWxsLCBlbmMpO1xuICAgIHZhciBmbGVuID0gZmlsbEJ1Zi5sZW5ndGg7XG4gICAgdmFyIGkgPSAtMTtcbiAgICB3aGlsZSAoKytpIDwgc2l6ZSkge1xuICAgICAgYnVmW2ldID0gZmlsbEJ1ZltpICUgZmxlbl07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGJ1Zi5maWxsKF9maWxsKTtcbiAgfVxuICByZXR1cm4gYnVmO1xufVxuZXhwb3J0cy5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIGFsbG9jVW5zYWZlKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBCdWZmZXIuYWxsb2NVbnNhZmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlKHNpemUpO1xuICB9XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdzaXplIG11c3QgYmUgYSBudW1iZXInKTtcbiAgfVxuICBpZiAoc2l6ZSA+IE1BWF9MRU4pIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc2l6ZSBpcyB0b28gbGFyZ2UnKTtcbiAgfVxuICByZXR1cm4gbmV3IEJ1ZmZlcihzaXplKTtcbn1cbmV4cG9ydHMuZnJvbSA9IGZ1bmN0aW9uIGZyb20odmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIEJ1ZmZlci5mcm9tID09PSAnZnVuY3Rpb24nICYmICghZ2xvYmFsLlVpbnQ4QXJyYXkgfHwgVWludDhBcnJheS5mcm9tICE9PSBCdWZmZXIuZnJvbSkpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20odmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCk7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKTtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KTtcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgdmFyIG9mZnNldCA9IGVuY29kaW5nT3JPZmZzZXQ7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgIH1cbiAgICB2YXIgbGVuID0gbGVuZ3RoO1xuICAgIGlmICh0eXBlb2YgbGVuID09PSAndW5kZWZpbmVkJykge1xuICAgICAgbGVuID0gdmFsdWUuYnl0ZUxlbmd0aCAtIG9mZnNldDtcbiAgICB9XG4gICAgaWYgKG9mZnNldCA+PSB2YWx1ZS5ieXRlTGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKGxlbiA+IHZhbHVlLmJ5dGVMZW5ndGggLSBvZmZzZXQpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZS5zbGljZShvZmZzZXQsIG9mZnNldCArIGxlbikpO1xuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgdmFyIG91dCA9IG5ldyBCdWZmZXIodmFsdWUubGVuZ3RoKTtcbiAgICB2YWx1ZS5jb3B5KG91dCwgMCwgMCwgdmFsdWUubGVuZ3RoKTtcbiAgICByZXR1cm4gb3V0O1xuICB9XG4gIGlmICh2YWx1ZSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSB8fCAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gdmFsdWUpIHtcbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlLnR5cGUgPT09ICdCdWZmZXInICYmIEFycmF5LmlzQXJyYXkodmFsdWUuZGF0YSkpIHtcbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlLmRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgJyArICdBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpO1xufVxuZXhwb3J0cy5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiBhbGxvY1Vuc2FmZVNsb3coc2l6ZSkge1xuICBpZiAodHlwZW9mIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyhzaXplKTtcbiAgfVxuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc2l6ZSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKHNpemUgPj0gTUFYX0xFTikge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdzaXplIGlzIHRvbyBsYXJnZScpO1xuICB9XG4gIHJldHVybiBuZXcgU2xvd0J1ZmZlcihzaXplKTtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9idWZmZXItc2hpbXMvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDE3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0ge1xuXHRcIkFhY3V0ZVwiOiBcIsOBXCIsXG5cdFwiYWFjdXRlXCI6IFwiw6FcIixcblx0XCJBYnJldmVcIjogXCLEglwiLFxuXHRcImFicmV2ZVwiOiBcIsSDXCIsXG5cdFwiYWNcIjogXCLiiL5cIixcblx0XCJhY2RcIjogXCLiiL9cIixcblx0XCJhY0VcIjogXCLiiL7Ms1wiLFxuXHRcIkFjaXJjXCI6IFwiw4JcIixcblx0XCJhY2lyY1wiOiBcIsOiXCIsXG5cdFwiYWN1dGVcIjogXCLCtFwiLFxuXHRcIkFjeVwiOiBcItCQXCIsXG5cdFwiYWN5XCI6IFwi0LBcIixcblx0XCJBRWxpZ1wiOiBcIsOGXCIsXG5cdFwiYWVsaWdcIjogXCLDplwiLFxuXHRcImFmXCI6IFwi4oGhXCIsXG5cdFwiQWZyXCI6IFwi8J2UhFwiLFxuXHRcImFmclwiOiBcIvCdlJ5cIixcblx0XCJBZ3JhdmVcIjogXCLDgFwiLFxuXHRcImFncmF2ZVwiOiBcIsOgXCIsXG5cdFwiYWxlZnN5bVwiOiBcIuKEtVwiLFxuXHRcImFsZXBoXCI6IFwi4oS1XCIsXG5cdFwiQWxwaGFcIjogXCLOkVwiLFxuXHRcImFscGhhXCI6IFwizrFcIixcblx0XCJBbWFjclwiOiBcIsSAXCIsXG5cdFwiYW1hY3JcIjogXCLEgVwiLFxuXHRcImFtYWxnXCI6IFwi4qi/XCIsXG5cdFwiYW1wXCI6IFwiJlwiLFxuXHRcIkFNUFwiOiBcIiZcIixcblx0XCJhbmRhbmRcIjogXCLiqZVcIixcblx0XCJBbmRcIjogXCLiqZNcIixcblx0XCJhbmRcIjogXCLiiKdcIixcblx0XCJhbmRkXCI6IFwi4qmcXCIsXG5cdFwiYW5kc2xvcGVcIjogXCLiqZhcIixcblx0XCJhbmR2XCI6IFwi4qmaXCIsXG5cdFwiYW5nXCI6IFwi4oigXCIsXG5cdFwiYW5nZVwiOiBcIuKmpFwiLFxuXHRcImFuZ2xlXCI6IFwi4oigXCIsXG5cdFwiYW5nbXNkYWFcIjogXCLipqhcIixcblx0XCJhbmdtc2RhYlwiOiBcIuKmqVwiLFxuXHRcImFuZ21zZGFjXCI6IFwi4qaqXCIsXG5cdFwiYW5nbXNkYWRcIjogXCLipqtcIixcblx0XCJhbmdtc2RhZVwiOiBcIuKmrFwiLFxuXHRcImFuZ21zZGFmXCI6IFwi4qatXCIsXG5cdFwiYW5nbXNkYWdcIjogXCLipq5cIixcblx0XCJhbmdtc2RhaFwiOiBcIuKmr1wiLFxuXHRcImFuZ21zZFwiOiBcIuKIoVwiLFxuXHRcImFuZ3J0XCI6IFwi4oifXCIsXG5cdFwiYW5ncnR2YlwiOiBcIuKKvlwiLFxuXHRcImFuZ3J0dmJkXCI6IFwi4qadXCIsXG5cdFwiYW5nc3BoXCI6IFwi4oiiXCIsXG5cdFwiYW5nc3RcIjogXCLDhVwiLFxuXHRcImFuZ3phcnJcIjogXCLijbxcIixcblx0XCJBb2dvblwiOiBcIsSEXCIsXG5cdFwiYW9nb25cIjogXCLEhVwiLFxuXHRcIkFvcGZcIjogXCLwnZS4XCIsXG5cdFwiYW9wZlwiOiBcIvCdlZJcIixcblx0XCJhcGFjaXJcIjogXCLiqa9cIixcblx0XCJhcFwiOiBcIuKJiFwiLFxuXHRcImFwRVwiOiBcIuKpsFwiLFxuXHRcImFwZVwiOiBcIuKJilwiLFxuXHRcImFwaWRcIjogXCLiiYtcIixcblx0XCJhcG9zXCI6IFwiJ1wiLFxuXHRcIkFwcGx5RnVuY3Rpb25cIjogXCLigaFcIixcblx0XCJhcHByb3hcIjogXCLiiYhcIixcblx0XCJhcHByb3hlcVwiOiBcIuKJilwiLFxuXHRcIkFyaW5nXCI6IFwiw4VcIixcblx0XCJhcmluZ1wiOiBcIsOlXCIsXG5cdFwiQXNjclwiOiBcIvCdkpxcIixcblx0XCJhc2NyXCI6IFwi8J2StlwiLFxuXHRcIkFzc2lnblwiOiBcIuKJlFwiLFxuXHRcImFzdFwiOiBcIipcIixcblx0XCJhc3ltcFwiOiBcIuKJiFwiLFxuXHRcImFzeW1wZXFcIjogXCLiiY1cIixcblx0XCJBdGlsZGVcIjogXCLDg1wiLFxuXHRcImF0aWxkZVwiOiBcIsOjXCIsXG5cdFwiQXVtbFwiOiBcIsOEXCIsXG5cdFwiYXVtbFwiOiBcIsOkXCIsXG5cdFwiYXdjb25pbnRcIjogXCLiiLNcIixcblx0XCJhd2ludFwiOiBcIuKokVwiLFxuXHRcImJhY2tjb25nXCI6IFwi4omMXCIsXG5cdFwiYmFja2Vwc2lsb25cIjogXCLPtlwiLFxuXHRcImJhY2twcmltZVwiOiBcIuKAtVwiLFxuXHRcImJhY2tzaW1cIjogXCLiiL1cIixcblx0XCJiYWNrc2ltZXFcIjogXCLii41cIixcblx0XCJCYWNrc2xhc2hcIjogXCLiiJZcIixcblx0XCJCYXJ2XCI6IFwi4qunXCIsXG5cdFwiYmFydmVlXCI6IFwi4oq9XCIsXG5cdFwiYmFyd2VkXCI6IFwi4oyFXCIsXG5cdFwiQmFyd2VkXCI6IFwi4oyGXCIsXG5cdFwiYmFyd2VkZ2VcIjogXCLijIVcIixcblx0XCJiYnJrXCI6IFwi4o61XCIsXG5cdFwiYmJya3RicmtcIjogXCLijrZcIixcblx0XCJiY29uZ1wiOiBcIuKJjFwiLFxuXHRcIkJjeVwiOiBcItCRXCIsXG5cdFwiYmN5XCI6IFwi0LFcIixcblx0XCJiZHF1b1wiOiBcIuKAnlwiLFxuXHRcImJlY2F1c1wiOiBcIuKItVwiLFxuXHRcImJlY2F1c2VcIjogXCLiiLVcIixcblx0XCJCZWNhdXNlXCI6IFwi4oi1XCIsXG5cdFwiYmVtcHR5dlwiOiBcIuKmsFwiLFxuXHRcImJlcHNpXCI6IFwiz7ZcIixcblx0XCJiZXJub3VcIjogXCLihKxcIixcblx0XCJCZXJub3VsbGlzXCI6IFwi4oSsXCIsXG5cdFwiQmV0YVwiOiBcIs6SXCIsXG5cdFwiYmV0YVwiOiBcIs6yXCIsXG5cdFwiYmV0aFwiOiBcIuKEtlwiLFxuXHRcImJldHdlZW5cIjogXCLiiaxcIixcblx0XCJCZnJcIjogXCLwnZSFXCIsXG5cdFwiYmZyXCI6IFwi8J2Un1wiLFxuXHRcImJpZ2NhcFwiOiBcIuKLglwiLFxuXHRcImJpZ2NpcmNcIjogXCLil69cIixcblx0XCJiaWdjdXBcIjogXCLii4NcIixcblx0XCJiaWdvZG90XCI6IFwi4qiAXCIsXG5cdFwiYmlnb3BsdXNcIjogXCLiqIFcIixcblx0XCJiaWdvdGltZXNcIjogXCLiqIJcIixcblx0XCJiaWdzcWN1cFwiOiBcIuKohlwiLFxuXHRcImJpZ3N0YXJcIjogXCLimIVcIixcblx0XCJiaWd0cmlhbmdsZWRvd25cIjogXCLilr1cIixcblx0XCJiaWd0cmlhbmdsZXVwXCI6IFwi4pazXCIsXG5cdFwiYmlndXBsdXNcIjogXCLiqIRcIixcblx0XCJiaWd2ZWVcIjogXCLii4FcIixcblx0XCJiaWd3ZWRnZVwiOiBcIuKLgFwiLFxuXHRcImJrYXJvd1wiOiBcIuKkjVwiLFxuXHRcImJsYWNrbG96ZW5nZVwiOiBcIuKnq1wiLFxuXHRcImJsYWNrc3F1YXJlXCI6IFwi4paqXCIsXG5cdFwiYmxhY2t0cmlhbmdsZVwiOiBcIuKWtFwiLFxuXHRcImJsYWNrdHJpYW5nbGVkb3duXCI6IFwi4pa+XCIsXG5cdFwiYmxhY2t0cmlhbmdsZWxlZnRcIjogXCLil4JcIixcblx0XCJibGFja3RyaWFuZ2xlcmlnaHRcIjogXCLilrhcIixcblx0XCJibGFua1wiOiBcIuKQo1wiLFxuXHRcImJsazEyXCI6IFwi4paSXCIsXG5cdFwiYmxrMTRcIjogXCLilpFcIixcblx0XCJibGszNFwiOiBcIuKWk1wiLFxuXHRcImJsb2NrXCI6IFwi4paIXCIsXG5cdFwiYm5lXCI6IFwiPeKDpVwiLFxuXHRcImJuZXF1aXZcIjogXCLiiaHig6VcIixcblx0XCJiTm90XCI6IFwi4qutXCIsXG5cdFwiYm5vdFwiOiBcIuKMkFwiLFxuXHRcIkJvcGZcIjogXCLwnZS5XCIsXG5cdFwiYm9wZlwiOiBcIvCdlZNcIixcblx0XCJib3RcIjogXCLiiqVcIixcblx0XCJib3R0b21cIjogXCLiiqVcIixcblx0XCJib3d0aWVcIjogXCLii4hcIixcblx0XCJib3hib3hcIjogXCLip4lcIixcblx0XCJib3hkbFwiOiBcIuKUkFwiLFxuXHRcImJveGRMXCI6IFwi4pWVXCIsXG5cdFwiYm94RGxcIjogXCLilZZcIixcblx0XCJib3hETFwiOiBcIuKVl1wiLFxuXHRcImJveGRyXCI6IFwi4pSMXCIsXG5cdFwiYm94ZFJcIjogXCLilZJcIixcblx0XCJib3hEclwiOiBcIuKVk1wiLFxuXHRcImJveERSXCI6IFwi4pWUXCIsXG5cdFwiYm94aFwiOiBcIuKUgFwiLFxuXHRcImJveEhcIjogXCLilZBcIixcblx0XCJib3hoZFwiOiBcIuKUrFwiLFxuXHRcImJveEhkXCI6IFwi4pWkXCIsXG5cdFwiYm94aERcIjogXCLilaVcIixcblx0XCJib3hIRFwiOiBcIuKVplwiLFxuXHRcImJveGh1XCI6IFwi4pS0XCIsXG5cdFwiYm94SHVcIjogXCLiladcIixcblx0XCJib3hoVVwiOiBcIuKVqFwiLFxuXHRcImJveEhVXCI6IFwi4pWpXCIsXG5cdFwiYm94bWludXNcIjogXCLiip9cIixcblx0XCJib3hwbHVzXCI6IFwi4oqeXCIsXG5cdFwiYm94dGltZXNcIjogXCLiiqBcIixcblx0XCJib3h1bFwiOiBcIuKUmFwiLFxuXHRcImJveHVMXCI6IFwi4pWbXCIsXG5cdFwiYm94VWxcIjogXCLilZxcIixcblx0XCJib3hVTFwiOiBcIuKVnVwiLFxuXHRcImJveHVyXCI6IFwi4pSUXCIsXG5cdFwiYm94dVJcIjogXCLilZhcIixcblx0XCJib3hVclwiOiBcIuKVmVwiLFxuXHRcImJveFVSXCI6IFwi4pWaXCIsXG5cdFwiYm94dlwiOiBcIuKUglwiLFxuXHRcImJveFZcIjogXCLilZFcIixcblx0XCJib3h2aFwiOiBcIuKUvFwiLFxuXHRcImJveHZIXCI6IFwi4pWqXCIsXG5cdFwiYm94VmhcIjogXCLilatcIixcblx0XCJib3hWSFwiOiBcIuKVrFwiLFxuXHRcImJveHZsXCI6IFwi4pSkXCIsXG5cdFwiYm94dkxcIjogXCLilaFcIixcblx0XCJib3hWbFwiOiBcIuKVolwiLFxuXHRcImJveFZMXCI6IFwi4pWjXCIsXG5cdFwiYm94dnJcIjogXCLilJxcIixcblx0XCJib3h2UlwiOiBcIuKVnlwiLFxuXHRcImJveFZyXCI6IFwi4pWfXCIsXG5cdFwiYm94VlJcIjogXCLilaBcIixcblx0XCJicHJpbWVcIjogXCLigLVcIixcblx0XCJicmV2ZVwiOiBcIsuYXCIsXG5cdFwiQnJldmVcIjogXCLLmFwiLFxuXHRcImJydmJhclwiOiBcIsKmXCIsXG5cdFwiYnNjclwiOiBcIvCdkrdcIixcblx0XCJCc2NyXCI6IFwi4oSsXCIsXG5cdFwiYnNlbWlcIjogXCLigY9cIixcblx0XCJic2ltXCI6IFwi4oi9XCIsXG5cdFwiYnNpbWVcIjogXCLii41cIixcblx0XCJic29sYlwiOiBcIuKnhVwiLFxuXHRcImJzb2xcIjogXCJcXFxcXCIsXG5cdFwiYnNvbGhzdWJcIjogXCLin4hcIixcblx0XCJidWxsXCI6IFwi4oCiXCIsXG5cdFwiYnVsbGV0XCI6IFwi4oCiXCIsXG5cdFwiYnVtcFwiOiBcIuKJjlwiLFxuXHRcImJ1bXBFXCI6IFwi4qquXCIsXG5cdFwiYnVtcGVcIjogXCLiiY9cIixcblx0XCJCdW1wZXFcIjogXCLiiY5cIixcblx0XCJidW1wZXFcIjogXCLiiY9cIixcblx0XCJDYWN1dGVcIjogXCLEhlwiLFxuXHRcImNhY3V0ZVwiOiBcIsSHXCIsXG5cdFwiY2FwYW5kXCI6IFwi4qmEXCIsXG5cdFwiY2FwYnJjdXBcIjogXCLiqYlcIixcblx0XCJjYXBjYXBcIjogXCLiqYtcIixcblx0XCJjYXBcIjogXCLiiKlcIixcblx0XCJDYXBcIjogXCLii5JcIixcblx0XCJjYXBjdXBcIjogXCLiqYdcIixcblx0XCJjYXBkb3RcIjogXCLiqYBcIixcblx0XCJDYXBpdGFsRGlmZmVyZW50aWFsRFwiOiBcIuKFhVwiLFxuXHRcImNhcHNcIjogXCLiiKnvuIBcIixcblx0XCJjYXJldFwiOiBcIuKBgVwiLFxuXHRcImNhcm9uXCI6IFwiy4dcIixcblx0XCJDYXlsZXlzXCI6IFwi4oStXCIsXG5cdFwiY2NhcHNcIjogXCLiqY1cIixcblx0XCJDY2Fyb25cIjogXCLEjFwiLFxuXHRcImNjYXJvblwiOiBcIsSNXCIsXG5cdFwiQ2NlZGlsXCI6IFwiw4dcIixcblx0XCJjY2VkaWxcIjogXCLDp1wiLFxuXHRcIkNjaXJjXCI6IFwixIhcIixcblx0XCJjY2lyY1wiOiBcIsSJXCIsXG5cdFwiQ2NvbmludFwiOiBcIuKIsFwiLFxuXHRcImNjdXBzXCI6IFwi4qmMXCIsXG5cdFwiY2N1cHNzbVwiOiBcIuKpkFwiLFxuXHRcIkNkb3RcIjogXCLEilwiLFxuXHRcImNkb3RcIjogXCLEi1wiLFxuXHRcImNlZGlsXCI6IFwiwrhcIixcblx0XCJDZWRpbGxhXCI6IFwiwrhcIixcblx0XCJjZW1wdHl2XCI6IFwi4qayXCIsXG5cdFwiY2VudFwiOiBcIsKiXCIsXG5cdFwiY2VudGVyZG90XCI6IFwiwrdcIixcblx0XCJDZW50ZXJEb3RcIjogXCLCt1wiLFxuXHRcImNmclwiOiBcIvCdlKBcIixcblx0XCJDZnJcIjogXCLihK1cIixcblx0XCJDSGN5XCI6IFwi0KdcIixcblx0XCJjaGN5XCI6IFwi0YdcIixcblx0XCJjaGVja1wiOiBcIuKck1wiLFxuXHRcImNoZWNrbWFya1wiOiBcIuKck1wiLFxuXHRcIkNoaVwiOiBcIs6nXCIsXG5cdFwiY2hpXCI6IFwiz4dcIixcblx0XCJjaXJjXCI6IFwiy4ZcIixcblx0XCJjaXJjZXFcIjogXCLiiZdcIixcblx0XCJjaXJjbGVhcnJvd2xlZnRcIjogXCLihrpcIixcblx0XCJjaXJjbGVhcnJvd3JpZ2h0XCI6IFwi4oa7XCIsXG5cdFwiY2lyY2xlZGFzdFwiOiBcIuKKm1wiLFxuXHRcImNpcmNsZWRjaXJjXCI6IFwi4oqaXCIsXG5cdFwiY2lyY2xlZGRhc2hcIjogXCLiip1cIixcblx0XCJDaXJjbGVEb3RcIjogXCLiiplcIixcblx0XCJjaXJjbGVkUlwiOiBcIsKuXCIsXG5cdFwiY2lyY2xlZFNcIjogXCLik4hcIixcblx0XCJDaXJjbGVNaW51c1wiOiBcIuKKllwiLFxuXHRcIkNpcmNsZVBsdXNcIjogXCLiipVcIixcblx0XCJDaXJjbGVUaW1lc1wiOiBcIuKKl1wiLFxuXHRcImNpclwiOiBcIuKXi1wiLFxuXHRcImNpckVcIjogXCLip4NcIixcblx0XCJjaXJlXCI6IFwi4omXXCIsXG5cdFwiY2lyZm5pbnRcIjogXCLiqJBcIixcblx0XCJjaXJtaWRcIjogXCLiq69cIixcblx0XCJjaXJzY2lyXCI6IFwi4qeCXCIsXG5cdFwiQ2xvY2t3aXNlQ29udG91ckludGVncmFsXCI6IFwi4oiyXCIsXG5cdFwiQ2xvc2VDdXJseURvdWJsZVF1b3RlXCI6IFwi4oCdXCIsXG5cdFwiQ2xvc2VDdXJseVF1b3RlXCI6IFwi4oCZXCIsXG5cdFwiY2x1YnNcIjogXCLimaNcIixcblx0XCJjbHVic3VpdFwiOiBcIuKZo1wiLFxuXHRcImNvbG9uXCI6IFwiOlwiLFxuXHRcIkNvbG9uXCI6IFwi4oi3XCIsXG5cdFwiQ29sb25lXCI6IFwi4qm0XCIsXG5cdFwiY29sb25lXCI6IFwi4omUXCIsXG5cdFwiY29sb25lcVwiOiBcIuKJlFwiLFxuXHRcImNvbW1hXCI6IFwiLFwiLFxuXHRcImNvbW1hdFwiOiBcIkBcIixcblx0XCJjb21wXCI6IFwi4oiBXCIsXG5cdFwiY29tcGZuXCI6IFwi4oiYXCIsXG5cdFwiY29tcGxlbWVudFwiOiBcIuKIgVwiLFxuXHRcImNvbXBsZXhlc1wiOiBcIuKEglwiLFxuXHRcImNvbmdcIjogXCLiiYVcIixcblx0XCJjb25nZG90XCI6IFwi4qmtXCIsXG5cdFwiQ29uZ3J1ZW50XCI6IFwi4omhXCIsXG5cdFwiY29uaW50XCI6IFwi4oiuXCIsXG5cdFwiQ29uaW50XCI6IFwi4oivXCIsXG5cdFwiQ29udG91ckludGVncmFsXCI6IFwi4oiuXCIsXG5cdFwiY29wZlwiOiBcIvCdlZRcIixcblx0XCJDb3BmXCI6IFwi4oSCXCIsXG5cdFwiY29wcm9kXCI6IFwi4oiQXCIsXG5cdFwiQ29wcm9kdWN0XCI6IFwi4oiQXCIsXG5cdFwiY29weVwiOiBcIsKpXCIsXG5cdFwiQ09QWVwiOiBcIsKpXCIsXG5cdFwiY29weXNyXCI6IFwi4oSXXCIsXG5cdFwiQ291bnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbFwiOiBcIuKIs1wiLFxuXHRcImNyYXJyXCI6IFwi4oa1XCIsXG5cdFwiY3Jvc3NcIjogXCLinJdcIixcblx0XCJDcm9zc1wiOiBcIuKor1wiLFxuXHRcIkNzY3JcIjogXCLwnZKeXCIsXG5cdFwiY3NjclwiOiBcIvCdkrhcIixcblx0XCJjc3ViXCI6IFwi4quPXCIsXG5cdFwiY3N1YmVcIjogXCLiq5FcIixcblx0XCJjc3VwXCI6IFwi4quQXCIsXG5cdFwiY3N1cGVcIjogXCLiq5JcIixcblx0XCJjdGRvdFwiOiBcIuKLr1wiLFxuXHRcImN1ZGFycmxcIjogXCLipLhcIixcblx0XCJjdWRhcnJyXCI6IFwi4qS1XCIsXG5cdFwiY3VlcHJcIjogXCLii55cIixcblx0XCJjdWVzY1wiOiBcIuKLn1wiLFxuXHRcImN1bGFyclwiOiBcIuKGtlwiLFxuXHRcImN1bGFycnBcIjogXCLipL1cIixcblx0XCJjdXBicmNhcFwiOiBcIuKpiFwiLFxuXHRcImN1cGNhcFwiOiBcIuKphlwiLFxuXHRcIkN1cENhcFwiOiBcIuKJjVwiLFxuXHRcImN1cFwiOiBcIuKIqlwiLFxuXHRcIkN1cFwiOiBcIuKLk1wiLFxuXHRcImN1cGN1cFwiOiBcIuKpilwiLFxuXHRcImN1cGRvdFwiOiBcIuKKjVwiLFxuXHRcImN1cG9yXCI6IFwi4qmFXCIsXG5cdFwiY3Vwc1wiOiBcIuKIqu+4gFwiLFxuXHRcImN1cmFyclwiOiBcIuKGt1wiLFxuXHRcImN1cmFycm1cIjogXCLipLxcIixcblx0XCJjdXJseWVxcHJlY1wiOiBcIuKLnlwiLFxuXHRcImN1cmx5ZXFzdWNjXCI6IFwi4oufXCIsXG5cdFwiY3VybHl2ZWVcIjogXCLii45cIixcblx0XCJjdXJseXdlZGdlXCI6IFwi4ouPXCIsXG5cdFwiY3VycmVuXCI6IFwiwqRcIixcblx0XCJjdXJ2ZWFycm93bGVmdFwiOiBcIuKGtlwiLFxuXHRcImN1cnZlYXJyb3dyaWdodFwiOiBcIuKGt1wiLFxuXHRcImN1dmVlXCI6IFwi4ouOXCIsXG5cdFwiY3V3ZWRcIjogXCLii49cIixcblx0XCJjd2NvbmludFwiOiBcIuKIslwiLFxuXHRcImN3aW50XCI6IFwi4oixXCIsXG5cdFwiY3lsY3R5XCI6IFwi4oytXCIsXG5cdFwiZGFnZ2VyXCI6IFwi4oCgXCIsXG5cdFwiRGFnZ2VyXCI6IFwi4oChXCIsXG5cdFwiZGFsZXRoXCI6IFwi4oS4XCIsXG5cdFwiZGFyclwiOiBcIuKGk1wiLFxuXHRcIkRhcnJcIjogXCLihqFcIixcblx0XCJkQXJyXCI6IFwi4oeTXCIsXG5cdFwiZGFzaFwiOiBcIuKAkFwiLFxuXHRcIkRhc2h2XCI6IFwi4qukXCIsXG5cdFwiZGFzaHZcIjogXCLiiqNcIixcblx0XCJkYmthcm93XCI6IFwi4qSPXCIsXG5cdFwiZGJsYWNcIjogXCLLnVwiLFxuXHRcIkRjYXJvblwiOiBcIsSOXCIsXG5cdFwiZGNhcm9uXCI6IFwixI9cIixcblx0XCJEY3lcIjogXCLQlFwiLFxuXHRcImRjeVwiOiBcItC0XCIsXG5cdFwiZGRhZ2dlclwiOiBcIuKAoVwiLFxuXHRcImRkYXJyXCI6IFwi4oeKXCIsXG5cdFwiRERcIjogXCLihYVcIixcblx0XCJkZFwiOiBcIuKFhlwiLFxuXHRcIkREb3RyYWhkXCI6IFwi4qSRXCIsXG5cdFwiZGRvdHNlcVwiOiBcIuKpt1wiLFxuXHRcImRlZ1wiOiBcIsKwXCIsXG5cdFwiRGVsXCI6IFwi4oiHXCIsXG5cdFwiRGVsdGFcIjogXCLOlFwiLFxuXHRcImRlbHRhXCI6IFwizrRcIixcblx0XCJkZW1wdHl2XCI6IFwi4qaxXCIsXG5cdFwiZGZpc2h0XCI6IFwi4qW/XCIsXG5cdFwiRGZyXCI6IFwi8J2Uh1wiLFxuXHRcImRmclwiOiBcIvCdlKFcIixcblx0XCJkSGFyXCI6IFwi4qWlXCIsXG5cdFwiZGhhcmxcIjogXCLih4NcIixcblx0XCJkaGFyclwiOiBcIuKHglwiLFxuXHRcIkRpYWNyaXRpY2FsQWN1dGVcIjogXCLCtFwiLFxuXHRcIkRpYWNyaXRpY2FsRG90XCI6IFwiy5lcIixcblx0XCJEaWFjcml0aWNhbERvdWJsZUFjdXRlXCI6IFwiy51cIixcblx0XCJEaWFjcml0aWNhbEdyYXZlXCI6IFwiYFwiLFxuXHRcIkRpYWNyaXRpY2FsVGlsZGVcIjogXCLLnFwiLFxuXHRcImRpYW1cIjogXCLii4RcIixcblx0XCJkaWFtb25kXCI6IFwi4ouEXCIsXG5cdFwiRGlhbW9uZFwiOiBcIuKLhFwiLFxuXHRcImRpYW1vbmRzdWl0XCI6IFwi4pmmXCIsXG5cdFwiZGlhbXNcIjogXCLimaZcIixcblx0XCJkaWVcIjogXCLCqFwiLFxuXHRcIkRpZmZlcmVudGlhbERcIjogXCLihYZcIixcblx0XCJkaWdhbW1hXCI6IFwiz51cIixcblx0XCJkaXNpblwiOiBcIuKLslwiLFxuXHRcImRpdlwiOiBcIsO3XCIsXG5cdFwiZGl2aWRlXCI6IFwiw7dcIixcblx0XCJkaXZpZGVvbnRpbWVzXCI6IFwi4ouHXCIsXG5cdFwiZGl2b254XCI6IFwi4ouHXCIsXG5cdFwiREpjeVwiOiBcItCCXCIsXG5cdFwiZGpjeVwiOiBcItGSXCIsXG5cdFwiZGxjb3JuXCI6IFwi4oyeXCIsXG5cdFwiZGxjcm9wXCI6IFwi4oyNXCIsXG5cdFwiZG9sbGFyXCI6IFwiJFwiLFxuXHRcIkRvcGZcIjogXCLwnZS7XCIsXG5cdFwiZG9wZlwiOiBcIvCdlZVcIixcblx0XCJEb3RcIjogXCLCqFwiLFxuXHRcImRvdFwiOiBcIsuZXCIsXG5cdFwiRG90RG90XCI6IFwi4oOcXCIsXG5cdFwiZG90ZXFcIjogXCLiiZBcIixcblx0XCJkb3RlcWRvdFwiOiBcIuKJkVwiLFxuXHRcIkRvdEVxdWFsXCI6IFwi4omQXCIsXG5cdFwiZG90bWludXNcIjogXCLiiLhcIixcblx0XCJkb3RwbHVzXCI6IFwi4oiUXCIsXG5cdFwiZG90c3F1YXJlXCI6IFwi4oqhXCIsXG5cdFwiZG91YmxlYmFyd2VkZ2VcIjogXCLijIZcIixcblx0XCJEb3VibGVDb250b3VySW50ZWdyYWxcIjogXCLiiK9cIixcblx0XCJEb3VibGVEb3RcIjogXCLCqFwiLFxuXHRcIkRvdWJsZURvd25BcnJvd1wiOiBcIuKHk1wiLFxuXHRcIkRvdWJsZUxlZnRBcnJvd1wiOiBcIuKHkFwiLFxuXHRcIkRvdWJsZUxlZnRSaWdodEFycm93XCI6IFwi4oeUXCIsXG5cdFwiRG91YmxlTGVmdFRlZVwiOiBcIuKrpFwiLFxuXHRcIkRvdWJsZUxvbmdMZWZ0QXJyb3dcIjogXCLin7hcIixcblx0XCJEb3VibGVMb25nTGVmdFJpZ2h0QXJyb3dcIjogXCLin7pcIixcblx0XCJEb3VibGVMb25nUmlnaHRBcnJvd1wiOiBcIuKfuVwiLFxuXHRcIkRvdWJsZVJpZ2h0QXJyb3dcIjogXCLih5JcIixcblx0XCJEb3VibGVSaWdodFRlZVwiOiBcIuKKqFwiLFxuXHRcIkRvdWJsZVVwQXJyb3dcIjogXCLih5FcIixcblx0XCJEb3VibGVVcERvd25BcnJvd1wiOiBcIuKHlVwiLFxuXHRcIkRvdWJsZVZlcnRpY2FsQmFyXCI6IFwi4oilXCIsXG5cdFwiRG93bkFycm93QmFyXCI6IFwi4qSTXCIsXG5cdFwiZG93bmFycm93XCI6IFwi4oaTXCIsXG5cdFwiRG93bkFycm93XCI6IFwi4oaTXCIsXG5cdFwiRG93bmFycm93XCI6IFwi4oeTXCIsXG5cdFwiRG93bkFycm93VXBBcnJvd1wiOiBcIuKHtVwiLFxuXHRcIkRvd25CcmV2ZVwiOiBcIsyRXCIsXG5cdFwiZG93bmRvd25hcnJvd3NcIjogXCLih4pcIixcblx0XCJkb3duaGFycG9vbmxlZnRcIjogXCLih4NcIixcblx0XCJkb3duaGFycG9vbnJpZ2h0XCI6IFwi4oeCXCIsXG5cdFwiRG93bkxlZnRSaWdodFZlY3RvclwiOiBcIuKlkFwiLFxuXHRcIkRvd25MZWZ0VGVlVmVjdG9yXCI6IFwi4qWeXCIsXG5cdFwiRG93bkxlZnRWZWN0b3JCYXJcIjogXCLipZZcIixcblx0XCJEb3duTGVmdFZlY3RvclwiOiBcIuKGvVwiLFxuXHRcIkRvd25SaWdodFRlZVZlY3RvclwiOiBcIuKln1wiLFxuXHRcIkRvd25SaWdodFZlY3RvckJhclwiOiBcIuKll1wiLFxuXHRcIkRvd25SaWdodFZlY3RvclwiOiBcIuKHgVwiLFxuXHRcIkRvd25UZWVBcnJvd1wiOiBcIuKGp1wiLFxuXHRcIkRvd25UZWVcIjogXCLiiqRcIixcblx0XCJkcmJrYXJvd1wiOiBcIuKkkFwiLFxuXHRcImRyY29yblwiOiBcIuKMn1wiLFxuXHRcImRyY3JvcFwiOiBcIuKMjFwiLFxuXHRcIkRzY3JcIjogXCLwnZKfXCIsXG5cdFwiZHNjclwiOiBcIvCdkrlcIixcblx0XCJEU2N5XCI6IFwi0IVcIixcblx0XCJkc2N5XCI6IFwi0ZVcIixcblx0XCJkc29sXCI6IFwi4qe2XCIsXG5cdFwiRHN0cm9rXCI6IFwixJBcIixcblx0XCJkc3Ryb2tcIjogXCLEkVwiLFxuXHRcImR0ZG90XCI6IFwi4ouxXCIsXG5cdFwiZHRyaVwiOiBcIuKWv1wiLFxuXHRcImR0cmlmXCI6IFwi4pa+XCIsXG5cdFwiZHVhcnJcIjogXCLih7VcIixcblx0XCJkdWhhclwiOiBcIuKlr1wiLFxuXHRcImR3YW5nbGVcIjogXCLipqZcIixcblx0XCJEWmN5XCI6IFwi0I9cIixcblx0XCJkemN5XCI6IFwi0Z9cIixcblx0XCJkemlncmFyclwiOiBcIuKfv1wiLFxuXHRcIkVhY3V0ZVwiOiBcIsOJXCIsXG5cdFwiZWFjdXRlXCI6IFwiw6lcIixcblx0XCJlYXN0ZXJcIjogXCLiqa5cIixcblx0XCJFY2Fyb25cIjogXCLEmlwiLFxuXHRcImVjYXJvblwiOiBcIsSbXCIsXG5cdFwiRWNpcmNcIjogXCLDilwiLFxuXHRcImVjaXJjXCI6IFwiw6pcIixcblx0XCJlY2lyXCI6IFwi4omWXCIsXG5cdFwiZWNvbG9uXCI6IFwi4omVXCIsXG5cdFwiRWN5XCI6IFwi0K1cIixcblx0XCJlY3lcIjogXCLRjVwiLFxuXHRcImVERG90XCI6IFwi4qm3XCIsXG5cdFwiRWRvdFwiOiBcIsSWXCIsXG5cdFwiZWRvdFwiOiBcIsSXXCIsXG5cdFwiZURvdFwiOiBcIuKJkVwiLFxuXHRcImVlXCI6IFwi4oWHXCIsXG5cdFwiZWZEb3RcIjogXCLiiZJcIixcblx0XCJFZnJcIjogXCLwnZSIXCIsXG5cdFwiZWZyXCI6IFwi8J2UolwiLFxuXHRcImVnXCI6IFwi4qqaXCIsXG5cdFwiRWdyYXZlXCI6IFwiw4hcIixcblx0XCJlZ3JhdmVcIjogXCLDqFwiLFxuXHRcImVnc1wiOiBcIuKqllwiLFxuXHRcImVnc2RvdFwiOiBcIuKqmFwiLFxuXHRcImVsXCI6IFwi4qqZXCIsXG5cdFwiRWxlbWVudFwiOiBcIuKIiFwiLFxuXHRcImVsaW50ZXJzXCI6IFwi4o+nXCIsXG5cdFwiZWxsXCI6IFwi4oSTXCIsXG5cdFwiZWxzXCI6IFwi4qqVXCIsXG5cdFwiZWxzZG90XCI6IFwi4qqXXCIsXG5cdFwiRW1hY3JcIjogXCLEklwiLFxuXHRcImVtYWNyXCI6IFwixJNcIixcblx0XCJlbXB0eVwiOiBcIuKIhVwiLFxuXHRcImVtcHR5c2V0XCI6IFwi4oiFXCIsXG5cdFwiRW1wdHlTbWFsbFNxdWFyZVwiOiBcIuKXu1wiLFxuXHRcImVtcHR5dlwiOiBcIuKIhVwiLFxuXHRcIkVtcHR5VmVyeVNtYWxsU3F1YXJlXCI6IFwi4parXCIsXG5cdFwiZW1zcDEzXCI6IFwi4oCEXCIsXG5cdFwiZW1zcDE0XCI6IFwi4oCFXCIsXG5cdFwiZW1zcFwiOiBcIuKAg1wiLFxuXHRcIkVOR1wiOiBcIsWKXCIsXG5cdFwiZW5nXCI6IFwixYtcIixcblx0XCJlbnNwXCI6IFwi4oCCXCIsXG5cdFwiRW9nb25cIjogXCLEmFwiLFxuXHRcImVvZ29uXCI6IFwixJlcIixcblx0XCJFb3BmXCI6IFwi8J2UvFwiLFxuXHRcImVvcGZcIjogXCLwnZWWXCIsXG5cdFwiZXBhclwiOiBcIuKLlVwiLFxuXHRcImVwYXJzbFwiOiBcIuKno1wiLFxuXHRcImVwbHVzXCI6IFwi4qmxXCIsXG5cdFwiZXBzaVwiOiBcIs61XCIsXG5cdFwiRXBzaWxvblwiOiBcIs6VXCIsXG5cdFwiZXBzaWxvblwiOiBcIs61XCIsXG5cdFwiZXBzaXZcIjogXCLPtVwiLFxuXHRcImVxY2lyY1wiOiBcIuKJllwiLFxuXHRcImVxY29sb25cIjogXCLiiZVcIixcblx0XCJlcXNpbVwiOiBcIuKJglwiLFxuXHRcImVxc2xhbnRndHJcIjogXCLiqpZcIixcblx0XCJlcXNsYW50bGVzc1wiOiBcIuKqlVwiLFxuXHRcIkVxdWFsXCI6IFwi4qm1XCIsXG5cdFwiZXF1YWxzXCI6IFwiPVwiLFxuXHRcIkVxdWFsVGlsZGVcIjogXCLiiYJcIixcblx0XCJlcXVlc3RcIjogXCLiiZ9cIixcblx0XCJFcXVpbGlicml1bVwiOiBcIuKHjFwiLFxuXHRcImVxdWl2XCI6IFwi4omhXCIsXG5cdFwiZXF1aXZERFwiOiBcIuKpuFwiLFxuXHRcImVxdnBhcnNsXCI6IFwi4qelXCIsXG5cdFwiZXJhcnJcIjogXCLipbFcIixcblx0XCJlckRvdFwiOiBcIuKJk1wiLFxuXHRcImVzY3JcIjogXCLihK9cIixcblx0XCJFc2NyXCI6IFwi4oSwXCIsXG5cdFwiZXNkb3RcIjogXCLiiZBcIixcblx0XCJFc2ltXCI6IFwi4qmzXCIsXG5cdFwiZXNpbVwiOiBcIuKJglwiLFxuXHRcIkV0YVwiOiBcIs6XXCIsXG5cdFwiZXRhXCI6IFwizrdcIixcblx0XCJFVEhcIjogXCLDkFwiLFxuXHRcImV0aFwiOiBcIsOwXCIsXG5cdFwiRXVtbFwiOiBcIsOLXCIsXG5cdFwiZXVtbFwiOiBcIsOrXCIsXG5cdFwiZXVyb1wiOiBcIuKCrFwiLFxuXHRcImV4Y2xcIjogXCIhXCIsXG5cdFwiZXhpc3RcIjogXCLiiINcIixcblx0XCJFeGlzdHNcIjogXCLiiINcIixcblx0XCJleHBlY3RhdGlvblwiOiBcIuKEsFwiLFxuXHRcImV4cG9uZW50aWFsZVwiOiBcIuKFh1wiLFxuXHRcIkV4cG9uZW50aWFsRVwiOiBcIuKFh1wiLFxuXHRcImZhbGxpbmdkb3RzZXFcIjogXCLiiZJcIixcblx0XCJGY3lcIjogXCLQpFwiLFxuXHRcImZjeVwiOiBcItGEXCIsXG5cdFwiZmVtYWxlXCI6IFwi4pmAXCIsXG5cdFwiZmZpbGlnXCI6IFwi76yDXCIsXG5cdFwiZmZsaWdcIjogXCLvrIBcIixcblx0XCJmZmxsaWdcIjogXCLvrIRcIixcblx0XCJGZnJcIjogXCLwnZSJXCIsXG5cdFwiZmZyXCI6IFwi8J2Uo1wiLFxuXHRcImZpbGlnXCI6IFwi76yBXCIsXG5cdFwiRmlsbGVkU21hbGxTcXVhcmVcIjogXCLil7xcIixcblx0XCJGaWxsZWRWZXJ5U21hbGxTcXVhcmVcIjogXCLilqpcIixcblx0XCJmamxpZ1wiOiBcImZqXCIsXG5cdFwiZmxhdFwiOiBcIuKZrVwiLFxuXHRcImZsbGlnXCI6IFwi76yCXCIsXG5cdFwiZmx0bnNcIjogXCLilrFcIixcblx0XCJmbm9mXCI6IFwixpJcIixcblx0XCJGb3BmXCI6IFwi8J2UvVwiLFxuXHRcImZvcGZcIjogXCLwnZWXXCIsXG5cdFwiZm9yYWxsXCI6IFwi4oiAXCIsXG5cdFwiRm9yQWxsXCI6IFwi4oiAXCIsXG5cdFwiZm9ya1wiOiBcIuKLlFwiLFxuXHRcImZvcmt2XCI6IFwi4quZXCIsXG5cdFwiRm91cmllcnRyZlwiOiBcIuKEsVwiLFxuXHRcImZwYXJ0aW50XCI6IFwi4qiNXCIsXG5cdFwiZnJhYzEyXCI6IFwiwr1cIixcblx0XCJmcmFjMTNcIjogXCLihZNcIixcblx0XCJmcmFjMTRcIjogXCLCvFwiLFxuXHRcImZyYWMxNVwiOiBcIuKFlVwiLFxuXHRcImZyYWMxNlwiOiBcIuKFmVwiLFxuXHRcImZyYWMxOFwiOiBcIuKFm1wiLFxuXHRcImZyYWMyM1wiOiBcIuKFlFwiLFxuXHRcImZyYWMyNVwiOiBcIuKFllwiLFxuXHRcImZyYWMzNFwiOiBcIsK+XCIsXG5cdFwiZnJhYzM1XCI6IFwi4oWXXCIsXG5cdFwiZnJhYzM4XCI6IFwi4oWcXCIsXG5cdFwiZnJhYzQ1XCI6IFwi4oWYXCIsXG5cdFwiZnJhYzU2XCI6IFwi4oWaXCIsXG5cdFwiZnJhYzU4XCI6IFwi4oWdXCIsXG5cdFwiZnJhYzc4XCI6IFwi4oWeXCIsXG5cdFwiZnJhc2xcIjogXCLigYRcIixcblx0XCJmcm93blwiOiBcIuKMolwiLFxuXHRcImZzY3JcIjogXCLwnZK7XCIsXG5cdFwiRnNjclwiOiBcIuKEsVwiLFxuXHRcImdhY3V0ZVwiOiBcIse1XCIsXG5cdFwiR2FtbWFcIjogXCLOk1wiLFxuXHRcImdhbW1hXCI6IFwizrNcIixcblx0XCJHYW1tYWRcIjogXCLPnFwiLFxuXHRcImdhbW1hZFwiOiBcIs+dXCIsXG5cdFwiZ2FwXCI6IFwi4qqGXCIsXG5cdFwiR2JyZXZlXCI6IFwixJ5cIixcblx0XCJnYnJldmVcIjogXCLEn1wiLFxuXHRcIkdjZWRpbFwiOiBcIsSiXCIsXG5cdFwiR2NpcmNcIjogXCLEnFwiLFxuXHRcImdjaXJjXCI6IFwixJ1cIixcblx0XCJHY3lcIjogXCLQk1wiLFxuXHRcImdjeVwiOiBcItCzXCIsXG5cdFwiR2RvdFwiOiBcIsSgXCIsXG5cdFwiZ2RvdFwiOiBcIsShXCIsXG5cdFwiZ2VcIjogXCLiiaVcIixcblx0XCJnRVwiOiBcIuKJp1wiLFxuXHRcImdFbFwiOiBcIuKqjFwiLFxuXHRcImdlbFwiOiBcIuKLm1wiLFxuXHRcImdlcVwiOiBcIuKJpVwiLFxuXHRcImdlcXFcIjogXCLiiadcIixcblx0XCJnZXFzbGFudFwiOiBcIuKpvlwiLFxuXHRcImdlc2NjXCI6IFwi4qqpXCIsXG5cdFwiZ2VzXCI6IFwi4qm+XCIsXG5cdFwiZ2VzZG90XCI6IFwi4qqAXCIsXG5cdFwiZ2VzZG90b1wiOiBcIuKqglwiLFxuXHRcImdlc2RvdG9sXCI6IFwi4qqEXCIsXG5cdFwiZ2VzbFwiOiBcIuKLm++4gFwiLFxuXHRcImdlc2xlc1wiOiBcIuKqlFwiLFxuXHRcIkdmclwiOiBcIvCdlIpcIixcblx0XCJnZnJcIjogXCLwnZSkXCIsXG5cdFwiZ2dcIjogXCLiiatcIixcblx0XCJHZ1wiOiBcIuKLmVwiLFxuXHRcImdnZ1wiOiBcIuKLmVwiLFxuXHRcImdpbWVsXCI6IFwi4oS3XCIsXG5cdFwiR0pjeVwiOiBcItCDXCIsXG5cdFwiZ2pjeVwiOiBcItGTXCIsXG5cdFwiZ2xhXCI6IFwi4qqlXCIsXG5cdFwiZ2xcIjogXCLiibdcIixcblx0XCJnbEVcIjogXCLiqpJcIixcblx0XCJnbGpcIjogXCLiqqRcIixcblx0XCJnbmFwXCI6IFwi4qqKXCIsXG5cdFwiZ25hcHByb3hcIjogXCLiqopcIixcblx0XCJnbmVcIjogXCLiqohcIixcblx0XCJnbkVcIjogXCLiialcIixcblx0XCJnbmVxXCI6IFwi4qqIXCIsXG5cdFwiZ25lcXFcIjogXCLiialcIixcblx0XCJnbnNpbVwiOiBcIuKLp1wiLFxuXHRcIkdvcGZcIjogXCLwnZS+XCIsXG5cdFwiZ29wZlwiOiBcIvCdlZhcIixcblx0XCJncmF2ZVwiOiBcImBcIixcblx0XCJHcmVhdGVyRXF1YWxcIjogXCLiiaVcIixcblx0XCJHcmVhdGVyRXF1YWxMZXNzXCI6IFwi4oubXCIsXG5cdFwiR3JlYXRlckZ1bGxFcXVhbFwiOiBcIuKJp1wiLFxuXHRcIkdyZWF0ZXJHcmVhdGVyXCI6IFwi4qqiXCIsXG5cdFwiR3JlYXRlckxlc3NcIjogXCLiibdcIixcblx0XCJHcmVhdGVyU2xhbnRFcXVhbFwiOiBcIuKpvlwiLFxuXHRcIkdyZWF0ZXJUaWxkZVwiOiBcIuKJs1wiLFxuXHRcIkdzY3JcIjogXCLwnZKiXCIsXG5cdFwiZ3NjclwiOiBcIuKEilwiLFxuXHRcImdzaW1cIjogXCLiibNcIixcblx0XCJnc2ltZVwiOiBcIuKqjlwiLFxuXHRcImdzaW1sXCI6IFwi4qqQXCIsXG5cdFwiZ3RjY1wiOiBcIuKqp1wiLFxuXHRcImd0Y2lyXCI6IFwi4qm6XCIsXG5cdFwiZ3RcIjogXCI+XCIsXG5cdFwiR1RcIjogXCI+XCIsXG5cdFwiR3RcIjogXCLiiatcIixcblx0XCJndGRvdFwiOiBcIuKLl1wiLFxuXHRcImd0bFBhclwiOiBcIuKmlVwiLFxuXHRcImd0cXVlc3RcIjogXCLiqbxcIixcblx0XCJndHJhcHByb3hcIjogXCLiqoZcIixcblx0XCJndHJhcnJcIjogXCLipbhcIixcblx0XCJndHJkb3RcIjogXCLii5dcIixcblx0XCJndHJlcWxlc3NcIjogXCLii5tcIixcblx0XCJndHJlcXFsZXNzXCI6IFwi4qqMXCIsXG5cdFwiZ3RybGVzc1wiOiBcIuKJt1wiLFxuXHRcImd0cnNpbVwiOiBcIuKJs1wiLFxuXHRcImd2ZXJ0bmVxcVwiOiBcIuKJqe+4gFwiLFxuXHRcImd2bkVcIjogXCLiianvuIBcIixcblx0XCJIYWNla1wiOiBcIsuHXCIsXG5cdFwiaGFpcnNwXCI6IFwi4oCKXCIsXG5cdFwiaGFsZlwiOiBcIsK9XCIsXG5cdFwiaGFtaWx0XCI6IFwi4oSLXCIsXG5cdFwiSEFSRGN5XCI6IFwi0KpcIixcblx0XCJoYXJkY3lcIjogXCLRilwiLFxuXHRcImhhcnJjaXJcIjogXCLipYhcIixcblx0XCJoYXJyXCI6IFwi4oaUXCIsXG5cdFwiaEFyclwiOiBcIuKHlFwiLFxuXHRcImhhcnJ3XCI6IFwi4oatXCIsXG5cdFwiSGF0XCI6IFwiXlwiLFxuXHRcImhiYXJcIjogXCLihI9cIixcblx0XCJIY2lyY1wiOiBcIsSkXCIsXG5cdFwiaGNpcmNcIjogXCLEpVwiLFxuXHRcImhlYXJ0c1wiOiBcIuKZpVwiLFxuXHRcImhlYXJ0c3VpdFwiOiBcIuKZpVwiLFxuXHRcImhlbGxpcFwiOiBcIuKAplwiLFxuXHRcImhlcmNvblwiOiBcIuKKuVwiLFxuXHRcImhmclwiOiBcIvCdlKVcIixcblx0XCJIZnJcIjogXCLihIxcIixcblx0XCJIaWxiZXJ0U3BhY2VcIjogXCLihItcIixcblx0XCJoa3NlYXJvd1wiOiBcIuKkpVwiLFxuXHRcImhrc3dhcm93XCI6IFwi4qSmXCIsXG5cdFwiaG9hcnJcIjogXCLih79cIixcblx0XCJob210aHRcIjogXCLiiLtcIixcblx0XCJob29rbGVmdGFycm93XCI6IFwi4oapXCIsXG5cdFwiaG9va3JpZ2h0YXJyb3dcIjogXCLihqpcIixcblx0XCJob3BmXCI6IFwi8J2VmVwiLFxuXHRcIkhvcGZcIjogXCLihI1cIixcblx0XCJob3JiYXJcIjogXCLigJVcIixcblx0XCJIb3Jpem9udGFsTGluZVwiOiBcIuKUgFwiLFxuXHRcImhzY3JcIjogXCLwnZK9XCIsXG5cdFwiSHNjclwiOiBcIuKEi1wiLFxuXHRcImhzbGFzaFwiOiBcIuKEj1wiLFxuXHRcIkhzdHJva1wiOiBcIsSmXCIsXG5cdFwiaHN0cm9rXCI6IFwixKdcIixcblx0XCJIdW1wRG93bkh1bXBcIjogXCLiiY5cIixcblx0XCJIdW1wRXF1YWxcIjogXCLiiY9cIixcblx0XCJoeWJ1bGxcIjogXCLigYNcIixcblx0XCJoeXBoZW5cIjogXCLigJBcIixcblx0XCJJYWN1dGVcIjogXCLDjVwiLFxuXHRcImlhY3V0ZVwiOiBcIsOtXCIsXG5cdFwiaWNcIjogXCLigaNcIixcblx0XCJJY2lyY1wiOiBcIsOOXCIsXG5cdFwiaWNpcmNcIjogXCLDrlwiLFxuXHRcIkljeVwiOiBcItCYXCIsXG5cdFwiaWN5XCI6IFwi0LhcIixcblx0XCJJZG90XCI6IFwixLBcIixcblx0XCJJRWN5XCI6IFwi0JVcIixcblx0XCJpZWN5XCI6IFwi0LVcIixcblx0XCJpZXhjbFwiOiBcIsKhXCIsXG5cdFwiaWZmXCI6IFwi4oeUXCIsXG5cdFwiaWZyXCI6IFwi8J2UplwiLFxuXHRcIklmclwiOiBcIuKEkVwiLFxuXHRcIklncmF2ZVwiOiBcIsOMXCIsXG5cdFwiaWdyYXZlXCI6IFwiw6xcIixcblx0XCJpaVwiOiBcIuKFiFwiLFxuXHRcImlpaWludFwiOiBcIuKojFwiLFxuXHRcImlpaW50XCI6IFwi4oitXCIsXG5cdFwiaWluZmluXCI6IFwi4qecXCIsXG5cdFwiaWlvdGFcIjogXCLihKlcIixcblx0XCJJSmxpZ1wiOiBcIsSyXCIsXG5cdFwiaWpsaWdcIjogXCLEs1wiLFxuXHRcIkltYWNyXCI6IFwixKpcIixcblx0XCJpbWFjclwiOiBcIsSrXCIsXG5cdFwiaW1hZ2VcIjogXCLihJFcIixcblx0XCJJbWFnaW5hcnlJXCI6IFwi4oWIXCIsXG5cdFwiaW1hZ2xpbmVcIjogXCLihJBcIixcblx0XCJpbWFncGFydFwiOiBcIuKEkVwiLFxuXHRcImltYXRoXCI6IFwixLFcIixcblx0XCJJbVwiOiBcIuKEkVwiLFxuXHRcImltb2ZcIjogXCLiirdcIixcblx0XCJpbXBlZFwiOiBcIsa1XCIsXG5cdFwiSW1wbGllc1wiOiBcIuKHklwiLFxuXHRcImluY2FyZVwiOiBcIuKEhVwiLFxuXHRcImluXCI6IFwi4oiIXCIsXG5cdFwiaW5maW5cIjogXCLiiJ5cIixcblx0XCJpbmZpbnRpZVwiOiBcIuKnnVwiLFxuXHRcImlub2RvdFwiOiBcIsSxXCIsXG5cdFwiaW50Y2FsXCI6IFwi4oq6XCIsXG5cdFwiaW50XCI6IFwi4oirXCIsXG5cdFwiSW50XCI6IFwi4oisXCIsXG5cdFwiaW50ZWdlcnNcIjogXCLihKRcIixcblx0XCJJbnRlZ3JhbFwiOiBcIuKIq1wiLFxuXHRcImludGVyY2FsXCI6IFwi4oq6XCIsXG5cdFwiSW50ZXJzZWN0aW9uXCI6IFwi4ouCXCIsXG5cdFwiaW50bGFyaGtcIjogXCLiqJdcIixcblx0XCJpbnRwcm9kXCI6IFwi4qi8XCIsXG5cdFwiSW52aXNpYmxlQ29tbWFcIjogXCLigaNcIixcblx0XCJJbnZpc2libGVUaW1lc1wiOiBcIuKBolwiLFxuXHRcIklPY3lcIjogXCLQgVwiLFxuXHRcImlvY3lcIjogXCLRkVwiLFxuXHRcIklvZ29uXCI6IFwixK5cIixcblx0XCJpb2dvblwiOiBcIsSvXCIsXG5cdFwiSW9wZlwiOiBcIvCdlYBcIixcblx0XCJpb3BmXCI6IFwi8J2VmlwiLFxuXHRcIklvdGFcIjogXCLOmVwiLFxuXHRcImlvdGFcIjogXCLOuVwiLFxuXHRcImlwcm9kXCI6IFwi4qi8XCIsXG5cdFwiaXF1ZXN0XCI6IFwiwr9cIixcblx0XCJpc2NyXCI6IFwi8J2SvlwiLFxuXHRcIklzY3JcIjogXCLihJBcIixcblx0XCJpc2luXCI6IFwi4oiIXCIsXG5cdFwiaXNpbmRvdFwiOiBcIuKLtVwiLFxuXHRcImlzaW5FXCI6IFwi4ou5XCIsXG5cdFwiaXNpbnNcIjogXCLii7RcIixcblx0XCJpc2luc3ZcIjogXCLii7NcIixcblx0XCJpc2ludlwiOiBcIuKIiFwiLFxuXHRcIml0XCI6IFwi4oGiXCIsXG5cdFwiSXRpbGRlXCI6IFwixKhcIixcblx0XCJpdGlsZGVcIjogXCLEqVwiLFxuXHRcIkl1a2N5XCI6IFwi0IZcIixcblx0XCJpdWtjeVwiOiBcItGWXCIsXG5cdFwiSXVtbFwiOiBcIsOPXCIsXG5cdFwiaXVtbFwiOiBcIsOvXCIsXG5cdFwiSmNpcmNcIjogXCLEtFwiLFxuXHRcImpjaXJjXCI6IFwixLVcIixcblx0XCJKY3lcIjogXCLQmVwiLFxuXHRcImpjeVwiOiBcItC5XCIsXG5cdFwiSmZyXCI6IFwi8J2UjVwiLFxuXHRcImpmclwiOiBcIvCdlKdcIixcblx0XCJqbWF0aFwiOiBcIsi3XCIsXG5cdFwiSm9wZlwiOiBcIvCdlYFcIixcblx0XCJqb3BmXCI6IFwi8J2Vm1wiLFxuXHRcIkpzY3JcIjogXCLwnZKlXCIsXG5cdFwianNjclwiOiBcIvCdkr9cIixcblx0XCJKc2VyY3lcIjogXCLQiFwiLFxuXHRcImpzZXJjeVwiOiBcItGYXCIsXG5cdFwiSnVrY3lcIjogXCLQhFwiLFxuXHRcImp1a2N5XCI6IFwi0ZRcIixcblx0XCJLYXBwYVwiOiBcIs6aXCIsXG5cdFwia2FwcGFcIjogXCLOulwiLFxuXHRcImthcHBhdlwiOiBcIs+wXCIsXG5cdFwiS2NlZGlsXCI6IFwixLZcIixcblx0XCJrY2VkaWxcIjogXCLEt1wiLFxuXHRcIktjeVwiOiBcItCaXCIsXG5cdFwia2N5XCI6IFwi0LpcIixcblx0XCJLZnJcIjogXCLwnZSOXCIsXG5cdFwia2ZyXCI6IFwi8J2UqFwiLFxuXHRcImtncmVlblwiOiBcIsS4XCIsXG5cdFwiS0hjeVwiOiBcItClXCIsXG5cdFwia2hjeVwiOiBcItGFXCIsXG5cdFwiS0pjeVwiOiBcItCMXCIsXG5cdFwia2pjeVwiOiBcItGcXCIsXG5cdFwiS29wZlwiOiBcIvCdlYJcIixcblx0XCJrb3BmXCI6IFwi8J2VnFwiLFxuXHRcIktzY3JcIjogXCLwnZKmXCIsXG5cdFwia3NjclwiOiBcIvCdk4BcIixcblx0XCJsQWFyclwiOiBcIuKHmlwiLFxuXHRcIkxhY3V0ZVwiOiBcIsS5XCIsXG5cdFwibGFjdXRlXCI6IFwixLpcIixcblx0XCJsYWVtcHR5dlwiOiBcIuKmtFwiLFxuXHRcImxhZ3JhblwiOiBcIuKEklwiLFxuXHRcIkxhbWJkYVwiOiBcIs6bXCIsXG5cdFwibGFtYmRhXCI6IFwizrtcIixcblx0XCJsYW5nXCI6IFwi4p+oXCIsXG5cdFwiTGFuZ1wiOiBcIuKfqlwiLFxuXHRcImxhbmdkXCI6IFwi4qaRXCIsXG5cdFwibGFuZ2xlXCI6IFwi4p+oXCIsXG5cdFwibGFwXCI6IFwi4qqFXCIsXG5cdFwiTGFwbGFjZXRyZlwiOiBcIuKEklwiLFxuXHRcImxhcXVvXCI6IFwiwqtcIixcblx0XCJsYXJyYlwiOiBcIuKHpFwiLFxuXHRcImxhcnJiZnNcIjogXCLipJ9cIixcblx0XCJsYXJyXCI6IFwi4oaQXCIsXG5cdFwiTGFyclwiOiBcIuKGnlwiLFxuXHRcImxBcnJcIjogXCLih5BcIixcblx0XCJsYXJyZnNcIjogXCLipJ1cIixcblx0XCJsYXJyaGtcIjogXCLihqlcIixcblx0XCJsYXJybHBcIjogXCLihqtcIixcblx0XCJsYXJycGxcIjogXCLipLlcIixcblx0XCJsYXJyc2ltXCI6IFwi4qWzXCIsXG5cdFwibGFycnRsXCI6IFwi4oaiXCIsXG5cdFwibGF0YWlsXCI6IFwi4qSZXCIsXG5cdFwibEF0YWlsXCI6IFwi4qSbXCIsXG5cdFwibGF0XCI6IFwi4qqrXCIsXG5cdFwibGF0ZVwiOiBcIuKqrVwiLFxuXHRcImxhdGVzXCI6IFwi4qqt77iAXCIsXG5cdFwibGJhcnJcIjogXCLipIxcIixcblx0XCJsQmFyclwiOiBcIuKkjlwiLFxuXHRcImxiYnJrXCI6IFwi4p2yXCIsXG5cdFwibGJyYWNlXCI6IFwie1wiLFxuXHRcImxicmFja1wiOiBcIltcIixcblx0XCJsYnJrZVwiOiBcIuKmi1wiLFxuXHRcImxicmtzbGRcIjogXCLipo9cIixcblx0XCJsYnJrc2x1XCI6IFwi4qaNXCIsXG5cdFwiTGNhcm9uXCI6IFwixL1cIixcblx0XCJsY2Fyb25cIjogXCLEvlwiLFxuXHRcIkxjZWRpbFwiOiBcIsS7XCIsXG5cdFwibGNlZGlsXCI6IFwixLxcIixcblx0XCJsY2VpbFwiOiBcIuKMiFwiLFxuXHRcImxjdWJcIjogXCJ7XCIsXG5cdFwiTGN5XCI6IFwi0JtcIixcblx0XCJsY3lcIjogXCLQu1wiLFxuXHRcImxkY2FcIjogXCLipLZcIixcblx0XCJsZHF1b1wiOiBcIuKAnFwiLFxuXHRcImxkcXVvclwiOiBcIuKAnlwiLFxuXHRcImxkcmRoYXJcIjogXCLipadcIixcblx0XCJsZHJ1c2hhclwiOiBcIuKli1wiLFxuXHRcImxkc2hcIjogXCLihrJcIixcblx0XCJsZVwiOiBcIuKJpFwiLFxuXHRcImxFXCI6IFwi4ommXCIsXG5cdFwiTGVmdEFuZ2xlQnJhY2tldFwiOiBcIuKfqFwiLFxuXHRcIkxlZnRBcnJvd0JhclwiOiBcIuKHpFwiLFxuXHRcImxlZnRhcnJvd1wiOiBcIuKGkFwiLFxuXHRcIkxlZnRBcnJvd1wiOiBcIuKGkFwiLFxuXHRcIkxlZnRhcnJvd1wiOiBcIuKHkFwiLFxuXHRcIkxlZnRBcnJvd1JpZ2h0QXJyb3dcIjogXCLih4ZcIixcblx0XCJsZWZ0YXJyb3d0YWlsXCI6IFwi4oaiXCIsXG5cdFwiTGVmdENlaWxpbmdcIjogXCLijIhcIixcblx0XCJMZWZ0RG91YmxlQnJhY2tldFwiOiBcIuKfplwiLFxuXHRcIkxlZnREb3duVGVlVmVjdG9yXCI6IFwi4qWhXCIsXG5cdFwiTGVmdERvd25WZWN0b3JCYXJcIjogXCLipZlcIixcblx0XCJMZWZ0RG93blZlY3RvclwiOiBcIuKHg1wiLFxuXHRcIkxlZnRGbG9vclwiOiBcIuKMilwiLFxuXHRcImxlZnRoYXJwb29uZG93blwiOiBcIuKGvVwiLFxuXHRcImxlZnRoYXJwb29udXBcIjogXCLihrxcIixcblx0XCJsZWZ0bGVmdGFycm93c1wiOiBcIuKHh1wiLFxuXHRcImxlZnRyaWdodGFycm93XCI6IFwi4oaUXCIsXG5cdFwiTGVmdFJpZ2h0QXJyb3dcIjogXCLihpRcIixcblx0XCJMZWZ0cmlnaHRhcnJvd1wiOiBcIuKHlFwiLFxuXHRcImxlZnRyaWdodGFycm93c1wiOiBcIuKHhlwiLFxuXHRcImxlZnRyaWdodGhhcnBvb25zXCI6IFwi4oeLXCIsXG5cdFwibGVmdHJpZ2h0c3F1aWdhcnJvd1wiOiBcIuKGrVwiLFxuXHRcIkxlZnRSaWdodFZlY3RvclwiOiBcIuKljlwiLFxuXHRcIkxlZnRUZWVBcnJvd1wiOiBcIuKGpFwiLFxuXHRcIkxlZnRUZWVcIjogXCLiiqNcIixcblx0XCJMZWZ0VGVlVmVjdG9yXCI6IFwi4qWaXCIsXG5cdFwibGVmdHRocmVldGltZXNcIjogXCLii4tcIixcblx0XCJMZWZ0VHJpYW5nbGVCYXJcIjogXCLip49cIixcblx0XCJMZWZ0VHJpYW5nbGVcIjogXCLiirJcIixcblx0XCJMZWZ0VHJpYW5nbGVFcXVhbFwiOiBcIuKKtFwiLFxuXHRcIkxlZnRVcERvd25WZWN0b3JcIjogXCLipZFcIixcblx0XCJMZWZ0VXBUZWVWZWN0b3JcIjogXCLipaBcIixcblx0XCJMZWZ0VXBWZWN0b3JCYXJcIjogXCLipZhcIixcblx0XCJMZWZ0VXBWZWN0b3JcIjogXCLihr9cIixcblx0XCJMZWZ0VmVjdG9yQmFyXCI6IFwi4qWSXCIsXG5cdFwiTGVmdFZlY3RvclwiOiBcIuKGvFwiLFxuXHRcImxFZ1wiOiBcIuKqi1wiLFxuXHRcImxlZ1wiOiBcIuKLmlwiLFxuXHRcImxlcVwiOiBcIuKJpFwiLFxuXHRcImxlcXFcIjogXCLiiaZcIixcblx0XCJsZXFzbGFudFwiOiBcIuKpvVwiLFxuXHRcImxlc2NjXCI6IFwi4qqoXCIsXG5cdFwibGVzXCI6IFwi4qm9XCIsXG5cdFwibGVzZG90XCI6IFwi4qm/XCIsXG5cdFwibGVzZG90b1wiOiBcIuKqgVwiLFxuXHRcImxlc2RvdG9yXCI6IFwi4qqDXCIsXG5cdFwibGVzZ1wiOiBcIuKLmu+4gFwiLFxuXHRcImxlc2dlc1wiOiBcIuKqk1wiLFxuXHRcImxlc3NhcHByb3hcIjogXCLiqoVcIixcblx0XCJsZXNzZG90XCI6IFwi4ouWXCIsXG5cdFwibGVzc2VxZ3RyXCI6IFwi4ouaXCIsXG5cdFwibGVzc2VxcWd0clwiOiBcIuKqi1wiLFxuXHRcIkxlc3NFcXVhbEdyZWF0ZXJcIjogXCLii5pcIixcblx0XCJMZXNzRnVsbEVxdWFsXCI6IFwi4ommXCIsXG5cdFwiTGVzc0dyZWF0ZXJcIjogXCLiibZcIixcblx0XCJsZXNzZ3RyXCI6IFwi4om2XCIsXG5cdFwiTGVzc0xlc3NcIjogXCLiqqFcIixcblx0XCJsZXNzc2ltXCI6IFwi4omyXCIsXG5cdFwiTGVzc1NsYW50RXF1YWxcIjogXCLiqb1cIixcblx0XCJMZXNzVGlsZGVcIjogXCLiibJcIixcblx0XCJsZmlzaHRcIjogXCLipbxcIixcblx0XCJsZmxvb3JcIjogXCLijIpcIixcblx0XCJMZnJcIjogXCLwnZSPXCIsXG5cdFwibGZyXCI6IFwi8J2UqVwiLFxuXHRcImxnXCI6IFwi4om2XCIsXG5cdFwibGdFXCI6IFwi4qqRXCIsXG5cdFwibEhhclwiOiBcIuKlolwiLFxuXHRcImxoYXJkXCI6IFwi4oa9XCIsXG5cdFwibGhhcnVcIjogXCLihrxcIixcblx0XCJsaGFydWxcIjogXCLipapcIixcblx0XCJsaGJsa1wiOiBcIuKWhFwiLFxuXHRcIkxKY3lcIjogXCLQiVwiLFxuXHRcImxqY3lcIjogXCLRmVwiLFxuXHRcImxsYXJyXCI6IFwi4oeHXCIsXG5cdFwibGxcIjogXCLiiapcIixcblx0XCJMbFwiOiBcIuKLmFwiLFxuXHRcImxsY29ybmVyXCI6IFwi4oyeXCIsXG5cdFwiTGxlZnRhcnJvd1wiOiBcIuKHmlwiLFxuXHRcImxsaGFyZFwiOiBcIuKlq1wiLFxuXHRcImxsdHJpXCI6IFwi4pe6XCIsXG5cdFwiTG1pZG90XCI6IFwixL9cIixcblx0XCJsbWlkb3RcIjogXCLFgFwiLFxuXHRcImxtb3VzdGFjaGVcIjogXCLijrBcIixcblx0XCJsbW91c3RcIjogXCLijrBcIixcblx0XCJsbmFwXCI6IFwi4qqJXCIsXG5cdFwibG5hcHByb3hcIjogXCLiqolcIixcblx0XCJsbmVcIjogXCLiqodcIixcblx0XCJsbkVcIjogXCLiiahcIixcblx0XCJsbmVxXCI6IFwi4qqHXCIsXG5cdFwibG5lcXFcIjogXCLiiahcIixcblx0XCJsbnNpbVwiOiBcIuKLplwiLFxuXHRcImxvYW5nXCI6IFwi4p+sXCIsXG5cdFwibG9hcnJcIjogXCLih71cIixcblx0XCJsb2Jya1wiOiBcIuKfplwiLFxuXHRcImxvbmdsZWZ0YXJyb3dcIjogXCLin7VcIixcblx0XCJMb25nTGVmdEFycm93XCI6IFwi4p+1XCIsXG5cdFwiTG9uZ2xlZnRhcnJvd1wiOiBcIuKfuFwiLFxuXHRcImxvbmdsZWZ0cmlnaHRhcnJvd1wiOiBcIuKft1wiLFxuXHRcIkxvbmdMZWZ0UmlnaHRBcnJvd1wiOiBcIuKft1wiLFxuXHRcIkxvbmdsZWZ0cmlnaHRhcnJvd1wiOiBcIuKfulwiLFxuXHRcImxvbmdtYXBzdG9cIjogXCLin7xcIixcblx0XCJsb25ncmlnaHRhcnJvd1wiOiBcIuKftlwiLFxuXHRcIkxvbmdSaWdodEFycm93XCI6IFwi4p+2XCIsXG5cdFwiTG9uZ3JpZ2h0YXJyb3dcIjogXCLin7lcIixcblx0XCJsb29wYXJyb3dsZWZ0XCI6IFwi4oarXCIsXG5cdFwibG9vcGFycm93cmlnaHRcIjogXCLihqxcIixcblx0XCJsb3BhclwiOiBcIuKmhVwiLFxuXHRcIkxvcGZcIjogXCLwnZWDXCIsXG5cdFwibG9wZlwiOiBcIvCdlZ1cIixcblx0XCJsb3BsdXNcIjogXCLiqK1cIixcblx0XCJsb3RpbWVzXCI6IFwi4qi0XCIsXG5cdFwibG93YXN0XCI6IFwi4oiXXCIsXG5cdFwibG93YmFyXCI6IFwiX1wiLFxuXHRcIkxvd2VyTGVmdEFycm93XCI6IFwi4oaZXCIsXG5cdFwiTG93ZXJSaWdodEFycm93XCI6IFwi4oaYXCIsXG5cdFwibG96XCI6IFwi4peKXCIsXG5cdFwibG96ZW5nZVwiOiBcIuKXilwiLFxuXHRcImxvemZcIjogXCLip6tcIixcblx0XCJscGFyXCI6IFwiKFwiLFxuXHRcImxwYXJsdFwiOiBcIuKmk1wiLFxuXHRcImxyYXJyXCI6IFwi4oeGXCIsXG5cdFwibHJjb3JuZXJcIjogXCLijJ9cIixcblx0XCJscmhhclwiOiBcIuKHi1wiLFxuXHRcImxyaGFyZFwiOiBcIuKlrVwiLFxuXHRcImxybVwiOiBcIuKAjlwiLFxuXHRcImxydHJpXCI6IFwi4oq/XCIsXG5cdFwibHNhcXVvXCI6IFwi4oC5XCIsXG5cdFwibHNjclwiOiBcIvCdk4FcIixcblx0XCJMc2NyXCI6IFwi4oSSXCIsXG5cdFwibHNoXCI6IFwi4oawXCIsXG5cdFwiTHNoXCI6IFwi4oawXCIsXG5cdFwibHNpbVwiOiBcIuKJslwiLFxuXHRcImxzaW1lXCI6IFwi4qqNXCIsXG5cdFwibHNpbWdcIjogXCLiqo9cIixcblx0XCJsc3FiXCI6IFwiW1wiLFxuXHRcImxzcXVvXCI6IFwi4oCYXCIsXG5cdFwibHNxdW9yXCI6IFwi4oCaXCIsXG5cdFwiTHN0cm9rXCI6IFwixYFcIixcblx0XCJsc3Ryb2tcIjogXCLFglwiLFxuXHRcImx0Y2NcIjogXCLiqqZcIixcblx0XCJsdGNpclwiOiBcIuKpuVwiLFxuXHRcImx0XCI6IFwiPFwiLFxuXHRcIkxUXCI6IFwiPFwiLFxuXHRcIkx0XCI6IFwi4omqXCIsXG5cdFwibHRkb3RcIjogXCLii5ZcIixcblx0XCJsdGhyZWVcIjogXCLii4tcIixcblx0XCJsdGltZXNcIjogXCLii4lcIixcblx0XCJsdGxhcnJcIjogXCLipbZcIixcblx0XCJsdHF1ZXN0XCI6IFwi4qm7XCIsXG5cdFwibHRyaVwiOiBcIuKXg1wiLFxuXHRcImx0cmllXCI6IFwi4oq0XCIsXG5cdFwibHRyaWZcIjogXCLil4JcIixcblx0XCJsdHJQYXJcIjogXCLippZcIixcblx0XCJsdXJkc2hhclwiOiBcIuKlilwiLFxuXHRcImx1cnVoYXJcIjogXCLipaZcIixcblx0XCJsdmVydG5lcXFcIjogXCLiiajvuIBcIixcblx0XCJsdm5FXCI6IFwi4omo77iAXCIsXG5cdFwibWFjclwiOiBcIsKvXCIsXG5cdFwibWFsZVwiOiBcIuKZglwiLFxuXHRcIm1hbHRcIjogXCLinKBcIixcblx0XCJtYWx0ZXNlXCI6IFwi4pygXCIsXG5cdFwiTWFwXCI6IFwi4qSFXCIsXG5cdFwibWFwXCI6IFwi4oamXCIsXG5cdFwibWFwc3RvXCI6IFwi4oamXCIsXG5cdFwibWFwc3RvZG93blwiOiBcIuKGp1wiLFxuXHRcIm1hcHN0b2xlZnRcIjogXCLihqRcIixcblx0XCJtYXBzdG91cFwiOiBcIuKGpVwiLFxuXHRcIm1hcmtlclwiOiBcIuKWrlwiLFxuXHRcIm1jb21tYVwiOiBcIuKoqVwiLFxuXHRcIk1jeVwiOiBcItCcXCIsXG5cdFwibWN5XCI6IFwi0LxcIixcblx0XCJtZGFzaFwiOiBcIuKAlFwiLFxuXHRcIm1ERG90XCI6IFwi4oi6XCIsXG5cdFwibWVhc3VyZWRhbmdsZVwiOiBcIuKIoVwiLFxuXHRcIk1lZGl1bVNwYWNlXCI6IFwi4oGfXCIsXG5cdFwiTWVsbGludHJmXCI6IFwi4oSzXCIsXG5cdFwiTWZyXCI6IFwi8J2UkFwiLFxuXHRcIm1mclwiOiBcIvCdlKpcIixcblx0XCJtaG9cIjogXCLihKdcIixcblx0XCJtaWNyb1wiOiBcIsK1XCIsXG5cdFwibWlkYXN0XCI6IFwiKlwiLFxuXHRcIm1pZGNpclwiOiBcIuKrsFwiLFxuXHRcIm1pZFwiOiBcIuKIo1wiLFxuXHRcIm1pZGRvdFwiOiBcIsK3XCIsXG5cdFwibWludXNiXCI6IFwi4oqfXCIsXG5cdFwibWludXNcIjogXCLiiJJcIixcblx0XCJtaW51c2RcIjogXCLiiLhcIixcblx0XCJtaW51c2R1XCI6IFwi4qiqXCIsXG5cdFwiTWludXNQbHVzXCI6IFwi4oiTXCIsXG5cdFwibWxjcFwiOiBcIuKrm1wiLFxuXHRcIm1sZHJcIjogXCLigKZcIixcblx0XCJtbnBsdXNcIjogXCLiiJNcIixcblx0XCJtb2RlbHNcIjogXCLiiqdcIixcblx0XCJNb3BmXCI6IFwi8J2VhFwiLFxuXHRcIm1vcGZcIjogXCLwnZWeXCIsXG5cdFwibXBcIjogXCLiiJNcIixcblx0XCJtc2NyXCI6IFwi8J2TglwiLFxuXHRcIk1zY3JcIjogXCLihLNcIixcblx0XCJtc3Rwb3NcIjogXCLiiL5cIixcblx0XCJNdVwiOiBcIs6cXCIsXG5cdFwibXVcIjogXCLOvFwiLFxuXHRcIm11bHRpbWFwXCI6IFwi4oq4XCIsXG5cdFwibXVtYXBcIjogXCLiirhcIixcblx0XCJuYWJsYVwiOiBcIuKIh1wiLFxuXHRcIk5hY3V0ZVwiOiBcIsWDXCIsXG5cdFwibmFjdXRlXCI6IFwixYRcIixcblx0XCJuYW5nXCI6IFwi4oig4oOSXCIsXG5cdFwibmFwXCI6IFwi4omJXCIsXG5cdFwibmFwRVwiOiBcIuKpsMy4XCIsXG5cdFwibmFwaWRcIjogXCLiiYvMuFwiLFxuXHRcIm5hcG9zXCI6IFwixYlcIixcblx0XCJuYXBwcm94XCI6IFwi4omJXCIsXG5cdFwibmF0dXJhbFwiOiBcIuKZrlwiLFxuXHRcIm5hdHVyYWxzXCI6IFwi4oSVXCIsXG5cdFwibmF0dXJcIjogXCLima5cIixcblx0XCJuYnNwXCI6IFwiwqBcIixcblx0XCJuYnVtcFwiOiBcIuKJjsy4XCIsXG5cdFwibmJ1bXBlXCI6IFwi4omPzLhcIixcblx0XCJuY2FwXCI6IFwi4qmDXCIsXG5cdFwiTmNhcm9uXCI6IFwixYdcIixcblx0XCJuY2Fyb25cIjogXCLFiFwiLFxuXHRcIk5jZWRpbFwiOiBcIsWFXCIsXG5cdFwibmNlZGlsXCI6IFwixYZcIixcblx0XCJuY29uZ1wiOiBcIuKJh1wiLFxuXHRcIm5jb25nZG90XCI6IFwi4qmtzLhcIixcblx0XCJuY3VwXCI6IFwi4qmCXCIsXG5cdFwiTmN5XCI6IFwi0J1cIixcblx0XCJuY3lcIjogXCLQvVwiLFxuXHRcIm5kYXNoXCI6IFwi4oCTXCIsXG5cdFwibmVhcmhrXCI6IFwi4qSkXCIsXG5cdFwibmVhcnJcIjogXCLihpdcIixcblx0XCJuZUFyclwiOiBcIuKHl1wiLFxuXHRcIm5lYXJyb3dcIjogXCLihpdcIixcblx0XCJuZVwiOiBcIuKJoFwiLFxuXHRcIm5lZG90XCI6IFwi4omQzLhcIixcblx0XCJOZWdhdGl2ZU1lZGl1bVNwYWNlXCI6IFwi4oCLXCIsXG5cdFwiTmVnYXRpdmVUaGlja1NwYWNlXCI6IFwi4oCLXCIsXG5cdFwiTmVnYXRpdmVUaGluU3BhY2VcIjogXCLigItcIixcblx0XCJOZWdhdGl2ZVZlcnlUaGluU3BhY2VcIjogXCLigItcIixcblx0XCJuZXF1aXZcIjogXCLiiaJcIixcblx0XCJuZXNlYXJcIjogXCLipKhcIixcblx0XCJuZXNpbVwiOiBcIuKJgsy4XCIsXG5cdFwiTmVzdGVkR3JlYXRlckdyZWF0ZXJcIjogXCLiiatcIixcblx0XCJOZXN0ZWRMZXNzTGVzc1wiOiBcIuKJqlwiLFxuXHRcIk5ld0xpbmVcIjogXCJcXG5cIixcblx0XCJuZXhpc3RcIjogXCLiiIRcIixcblx0XCJuZXhpc3RzXCI6IFwi4oiEXCIsXG5cdFwiTmZyXCI6IFwi8J2UkVwiLFxuXHRcIm5mclwiOiBcIvCdlKtcIixcblx0XCJuZ0VcIjogXCLiiafMuFwiLFxuXHRcIm5nZVwiOiBcIuKJsVwiLFxuXHRcIm5nZXFcIjogXCLiibFcIixcblx0XCJuZ2VxcVwiOiBcIuKJp8y4XCIsXG5cdFwibmdlcXNsYW50XCI6IFwi4qm+zLhcIixcblx0XCJuZ2VzXCI6IFwi4qm+zLhcIixcblx0XCJuR2dcIjogXCLii5nMuFwiLFxuXHRcIm5nc2ltXCI6IFwi4om1XCIsXG5cdFwibkd0XCI6IFwi4omr4oOSXCIsXG5cdFwibmd0XCI6IFwi4omvXCIsXG5cdFwibmd0clwiOiBcIuKJr1wiLFxuXHRcIm5HdHZcIjogXCLiiavMuFwiLFxuXHRcIm5oYXJyXCI6IFwi4oauXCIsXG5cdFwibmhBcnJcIjogXCLih45cIixcblx0XCJuaHBhclwiOiBcIuKrslwiLFxuXHRcIm5pXCI6IFwi4oiLXCIsXG5cdFwibmlzXCI6IFwi4ou8XCIsXG5cdFwibmlzZFwiOiBcIuKLulwiLFxuXHRcIm5pdlwiOiBcIuKIi1wiLFxuXHRcIk5KY3lcIjogXCLQilwiLFxuXHRcIm5qY3lcIjogXCLRmlwiLFxuXHRcIm5sYXJyXCI6IFwi4oaaXCIsXG5cdFwibmxBcnJcIjogXCLih41cIixcblx0XCJubGRyXCI6IFwi4oClXCIsXG5cdFwibmxFXCI6IFwi4ommzLhcIixcblx0XCJubGVcIjogXCLiibBcIixcblx0XCJubGVmdGFycm93XCI6IFwi4oaaXCIsXG5cdFwibkxlZnRhcnJvd1wiOiBcIuKHjVwiLFxuXHRcIm5sZWZ0cmlnaHRhcnJvd1wiOiBcIuKGrlwiLFxuXHRcIm5MZWZ0cmlnaHRhcnJvd1wiOiBcIuKHjlwiLFxuXHRcIm5sZXFcIjogXCLiibBcIixcblx0XCJubGVxcVwiOiBcIuKJpsy4XCIsXG5cdFwibmxlcXNsYW50XCI6IFwi4qm9zLhcIixcblx0XCJubGVzXCI6IFwi4qm9zLhcIixcblx0XCJubGVzc1wiOiBcIuKJrlwiLFxuXHRcIm5MbFwiOiBcIuKLmMy4XCIsXG5cdFwibmxzaW1cIjogXCLiibRcIixcblx0XCJuTHRcIjogXCLiiarig5JcIixcblx0XCJubHRcIjogXCLiia5cIixcblx0XCJubHRyaVwiOiBcIuKLqlwiLFxuXHRcIm5sdHJpZVwiOiBcIuKLrFwiLFxuXHRcIm5MdHZcIjogXCLiiarMuFwiLFxuXHRcIm5taWRcIjogXCLiiKRcIixcblx0XCJOb0JyZWFrXCI6IFwi4oGgXCIsXG5cdFwiTm9uQnJlYWtpbmdTcGFjZVwiOiBcIsKgXCIsXG5cdFwibm9wZlwiOiBcIvCdlZ9cIixcblx0XCJOb3BmXCI6IFwi4oSVXCIsXG5cdFwiTm90XCI6IFwi4qusXCIsXG5cdFwibm90XCI6IFwiwqxcIixcblx0XCJOb3RDb25ncnVlbnRcIjogXCLiiaJcIixcblx0XCJOb3RDdXBDYXBcIjogXCLiia1cIixcblx0XCJOb3REb3VibGVWZXJ0aWNhbEJhclwiOiBcIuKIplwiLFxuXHRcIk5vdEVsZW1lbnRcIjogXCLiiIlcIixcblx0XCJOb3RFcXVhbFwiOiBcIuKJoFwiLFxuXHRcIk5vdEVxdWFsVGlsZGVcIjogXCLiiYLMuFwiLFxuXHRcIk5vdEV4aXN0c1wiOiBcIuKIhFwiLFxuXHRcIk5vdEdyZWF0ZXJcIjogXCLiia9cIixcblx0XCJOb3RHcmVhdGVyRXF1YWxcIjogXCLiibFcIixcblx0XCJOb3RHcmVhdGVyRnVsbEVxdWFsXCI6IFwi4omnzLhcIixcblx0XCJOb3RHcmVhdGVyR3JlYXRlclwiOiBcIuKJq8y4XCIsXG5cdFwiTm90R3JlYXRlckxlc3NcIjogXCLiiblcIixcblx0XCJOb3RHcmVhdGVyU2xhbnRFcXVhbFwiOiBcIuKpvsy4XCIsXG5cdFwiTm90R3JlYXRlclRpbGRlXCI6IFwi4om1XCIsXG5cdFwiTm90SHVtcERvd25IdW1wXCI6IFwi4omOzLhcIixcblx0XCJOb3RIdW1wRXF1YWxcIjogXCLiiY/MuFwiLFxuXHRcIm5vdGluXCI6IFwi4oiJXCIsXG5cdFwibm90aW5kb3RcIjogXCLii7XMuFwiLFxuXHRcIm5vdGluRVwiOiBcIuKLucy4XCIsXG5cdFwibm90aW52YVwiOiBcIuKIiVwiLFxuXHRcIm5vdGludmJcIjogXCLii7dcIixcblx0XCJub3RpbnZjXCI6IFwi4ou2XCIsXG5cdFwiTm90TGVmdFRyaWFuZ2xlQmFyXCI6IFwi4qePzLhcIixcblx0XCJOb3RMZWZ0VHJpYW5nbGVcIjogXCLii6pcIixcblx0XCJOb3RMZWZ0VHJpYW5nbGVFcXVhbFwiOiBcIuKLrFwiLFxuXHRcIk5vdExlc3NcIjogXCLiia5cIixcblx0XCJOb3RMZXNzRXF1YWxcIjogXCLiibBcIixcblx0XCJOb3RMZXNzR3JlYXRlclwiOiBcIuKJuFwiLFxuXHRcIk5vdExlc3NMZXNzXCI6IFwi4omqzLhcIixcblx0XCJOb3RMZXNzU2xhbnRFcXVhbFwiOiBcIuKpvcy4XCIsXG5cdFwiTm90TGVzc1RpbGRlXCI6IFwi4om0XCIsXG5cdFwiTm90TmVzdGVkR3JlYXRlckdyZWF0ZXJcIjogXCLiqqLMuFwiLFxuXHRcIk5vdE5lc3RlZExlc3NMZXNzXCI6IFwi4qqhzLhcIixcblx0XCJub3RuaVwiOiBcIuKIjFwiLFxuXHRcIm5vdG5pdmFcIjogXCLiiIxcIixcblx0XCJub3RuaXZiXCI6IFwi4ou+XCIsXG5cdFwibm90bml2Y1wiOiBcIuKLvVwiLFxuXHRcIk5vdFByZWNlZGVzXCI6IFwi4oqAXCIsXG5cdFwiTm90UHJlY2VkZXNFcXVhbFwiOiBcIuKqr8y4XCIsXG5cdFwiTm90UHJlY2VkZXNTbGFudEVxdWFsXCI6IFwi4ougXCIsXG5cdFwiTm90UmV2ZXJzZUVsZW1lbnRcIjogXCLiiIxcIixcblx0XCJOb3RSaWdodFRyaWFuZ2xlQmFyXCI6IFwi4qeQzLhcIixcblx0XCJOb3RSaWdodFRyaWFuZ2xlXCI6IFwi4ourXCIsXG5cdFwiTm90UmlnaHRUcmlhbmdsZUVxdWFsXCI6IFwi4outXCIsXG5cdFwiTm90U3F1YXJlU3Vic2V0XCI6IFwi4oqPzLhcIixcblx0XCJOb3RTcXVhcmVTdWJzZXRFcXVhbFwiOiBcIuKLolwiLFxuXHRcIk5vdFNxdWFyZVN1cGVyc2V0XCI6IFwi4oqQzLhcIixcblx0XCJOb3RTcXVhcmVTdXBlcnNldEVxdWFsXCI6IFwi4oujXCIsXG5cdFwiTm90U3Vic2V0XCI6IFwi4oqC4oOSXCIsXG5cdFwiTm90U3Vic2V0RXF1YWxcIjogXCLiiohcIixcblx0XCJOb3RTdWNjZWVkc1wiOiBcIuKKgVwiLFxuXHRcIk5vdFN1Y2NlZWRzRXF1YWxcIjogXCLiqrDMuFwiLFxuXHRcIk5vdFN1Y2NlZWRzU2xhbnRFcXVhbFwiOiBcIuKLoVwiLFxuXHRcIk5vdFN1Y2NlZWRzVGlsZGVcIjogXCLiib/MuFwiLFxuXHRcIk5vdFN1cGVyc2V0XCI6IFwi4oqD4oOSXCIsXG5cdFwiTm90U3VwZXJzZXRFcXVhbFwiOiBcIuKKiVwiLFxuXHRcIk5vdFRpbGRlXCI6IFwi4omBXCIsXG5cdFwiTm90VGlsZGVFcXVhbFwiOiBcIuKJhFwiLFxuXHRcIk5vdFRpbGRlRnVsbEVxdWFsXCI6IFwi4omHXCIsXG5cdFwiTm90VGlsZGVUaWxkZVwiOiBcIuKJiVwiLFxuXHRcIk5vdFZlcnRpY2FsQmFyXCI6IFwi4oikXCIsXG5cdFwibnBhcmFsbGVsXCI6IFwi4oimXCIsXG5cdFwibnBhclwiOiBcIuKIplwiLFxuXHRcIm5wYXJzbFwiOiBcIuKrveKDpVwiLFxuXHRcIm5wYXJ0XCI6IFwi4oiCzLhcIixcblx0XCJucG9saW50XCI6IFwi4qiUXCIsXG5cdFwibnByXCI6IFwi4oqAXCIsXG5cdFwibnByY3VlXCI6IFwi4ougXCIsXG5cdFwibnByZWNcIjogXCLiioBcIixcblx0XCJucHJlY2VxXCI6IFwi4qqvzLhcIixcblx0XCJucHJlXCI6IFwi4qqvzLhcIixcblx0XCJucmFycmNcIjogXCLipLPMuFwiLFxuXHRcIm5yYXJyXCI6IFwi4oabXCIsXG5cdFwibnJBcnJcIjogXCLih49cIixcblx0XCJucmFycndcIjogXCLihp3MuFwiLFxuXHRcIm5yaWdodGFycm93XCI6IFwi4oabXCIsXG5cdFwiblJpZ2h0YXJyb3dcIjogXCLih49cIixcblx0XCJucnRyaVwiOiBcIuKLq1wiLFxuXHRcIm5ydHJpZVwiOiBcIuKLrVwiLFxuXHRcIm5zY1wiOiBcIuKKgVwiLFxuXHRcIm5zY2N1ZVwiOiBcIuKLoVwiLFxuXHRcIm5zY2VcIjogXCLiqrDMuFwiLFxuXHRcIk5zY3JcIjogXCLwnZKpXCIsXG5cdFwibnNjclwiOiBcIvCdk4NcIixcblx0XCJuc2hvcnRtaWRcIjogXCLiiKRcIixcblx0XCJuc2hvcnRwYXJhbGxlbFwiOiBcIuKIplwiLFxuXHRcIm5zaW1cIjogXCLiiYFcIixcblx0XCJuc2ltZVwiOiBcIuKJhFwiLFxuXHRcIm5zaW1lcVwiOiBcIuKJhFwiLFxuXHRcIm5zbWlkXCI6IFwi4oikXCIsXG5cdFwibnNwYXJcIjogXCLiiKZcIixcblx0XCJuc3FzdWJlXCI6IFwi4ouiXCIsXG5cdFwibnNxc3VwZVwiOiBcIuKLo1wiLFxuXHRcIm5zdWJcIjogXCLiioRcIixcblx0XCJuc3ViRVwiOiBcIuKrhcy4XCIsXG5cdFwibnN1YmVcIjogXCLiiohcIixcblx0XCJuc3Vic2V0XCI6IFwi4oqC4oOSXCIsXG5cdFwibnN1YnNldGVxXCI6IFwi4oqIXCIsXG5cdFwibnN1YnNldGVxcVwiOiBcIuKrhcy4XCIsXG5cdFwibnN1Y2NcIjogXCLiioFcIixcblx0XCJuc3VjY2VxXCI6IFwi4qqwzLhcIixcblx0XCJuc3VwXCI6IFwi4oqFXCIsXG5cdFwibnN1cEVcIjogXCLiq4bMuFwiLFxuXHRcIm5zdXBlXCI6IFwi4oqJXCIsXG5cdFwibnN1cHNldFwiOiBcIuKKg+KDklwiLFxuXHRcIm5zdXBzZXRlcVwiOiBcIuKKiVwiLFxuXHRcIm5zdXBzZXRlcXFcIjogXCLiq4bMuFwiLFxuXHRcIm50Z2xcIjogXCLiiblcIixcblx0XCJOdGlsZGVcIjogXCLDkVwiLFxuXHRcIm50aWxkZVwiOiBcIsOxXCIsXG5cdFwibnRsZ1wiOiBcIuKJuFwiLFxuXHRcIm50cmlhbmdsZWxlZnRcIjogXCLii6pcIixcblx0XCJudHJpYW5nbGVsZWZ0ZXFcIjogXCLii6xcIixcblx0XCJudHJpYW5nbGVyaWdodFwiOiBcIuKLq1wiLFxuXHRcIm50cmlhbmdsZXJpZ2h0ZXFcIjogXCLii61cIixcblx0XCJOdVwiOiBcIs6dXCIsXG5cdFwibnVcIjogXCLOvVwiLFxuXHRcIm51bVwiOiBcIiNcIixcblx0XCJudW1lcm9cIjogXCLihJZcIixcblx0XCJudW1zcFwiOiBcIuKAh1wiLFxuXHRcIm52YXBcIjogXCLiiY3ig5JcIixcblx0XCJudmRhc2hcIjogXCLiiqxcIixcblx0XCJudkRhc2hcIjogXCLiiq1cIixcblx0XCJuVmRhc2hcIjogXCLiiq5cIixcblx0XCJuVkRhc2hcIjogXCLiiq9cIixcblx0XCJudmdlXCI6IFwi4oml4oOSXCIsXG5cdFwibnZndFwiOiBcIj7ig5JcIixcblx0XCJudkhhcnJcIjogXCLipIRcIixcblx0XCJudmluZmluXCI6IFwi4qeeXCIsXG5cdFwibnZsQXJyXCI6IFwi4qSCXCIsXG5cdFwibnZsZVwiOiBcIuKJpOKDklwiLFxuXHRcIm52bHRcIjogXCI84oOSXCIsXG5cdFwibnZsdHJpZVwiOiBcIuKKtOKDklwiLFxuXHRcIm52ckFyclwiOiBcIuKkg1wiLFxuXHRcIm52cnRyaWVcIjogXCLiirXig5JcIixcblx0XCJudnNpbVwiOiBcIuKIvOKDklwiLFxuXHRcIm53YXJoa1wiOiBcIuKko1wiLFxuXHRcIm53YXJyXCI6IFwi4oaWXCIsXG5cdFwibndBcnJcIjogXCLih5ZcIixcblx0XCJud2Fycm93XCI6IFwi4oaWXCIsXG5cdFwibnduZWFyXCI6IFwi4qSnXCIsXG5cdFwiT2FjdXRlXCI6IFwiw5NcIixcblx0XCJvYWN1dGVcIjogXCLDs1wiLFxuXHRcIm9hc3RcIjogXCLiiptcIixcblx0XCJPY2lyY1wiOiBcIsOUXCIsXG5cdFwib2NpcmNcIjogXCLDtFwiLFxuXHRcIm9jaXJcIjogXCLiippcIixcblx0XCJPY3lcIjogXCLQnlwiLFxuXHRcIm9jeVwiOiBcItC+XCIsXG5cdFwib2Rhc2hcIjogXCLiip1cIixcblx0XCJPZGJsYWNcIjogXCLFkFwiLFxuXHRcIm9kYmxhY1wiOiBcIsWRXCIsXG5cdFwib2RpdlwiOiBcIuKouFwiLFxuXHRcIm9kb3RcIjogXCLiiplcIixcblx0XCJvZHNvbGRcIjogXCLiprxcIixcblx0XCJPRWxpZ1wiOiBcIsWSXCIsXG5cdFwib2VsaWdcIjogXCLFk1wiLFxuXHRcIm9mY2lyXCI6IFwi4qa/XCIsXG5cdFwiT2ZyXCI6IFwi8J2UklwiLFxuXHRcIm9mclwiOiBcIvCdlKxcIixcblx0XCJvZ29uXCI6IFwiy5tcIixcblx0XCJPZ3JhdmVcIjogXCLDklwiLFxuXHRcIm9ncmF2ZVwiOiBcIsOyXCIsXG5cdFwib2d0XCI6IFwi4qeBXCIsXG5cdFwib2hiYXJcIjogXCLiprVcIixcblx0XCJvaG1cIjogXCLOqVwiLFxuXHRcIm9pbnRcIjogXCLiiK5cIixcblx0XCJvbGFyclwiOiBcIuKGulwiLFxuXHRcIm9sY2lyXCI6IFwi4qa+XCIsXG5cdFwib2xjcm9zc1wiOiBcIuKmu1wiLFxuXHRcIm9saW5lXCI6IFwi4oC+XCIsXG5cdFwib2x0XCI6IFwi4qeAXCIsXG5cdFwiT21hY3JcIjogXCLFjFwiLFxuXHRcIm9tYWNyXCI6IFwixY1cIixcblx0XCJPbWVnYVwiOiBcIs6pXCIsXG5cdFwib21lZ2FcIjogXCLPiVwiLFxuXHRcIk9taWNyb25cIjogXCLOn1wiLFxuXHRcIm9taWNyb25cIjogXCLOv1wiLFxuXHRcIm9taWRcIjogXCLiprZcIixcblx0XCJvbWludXNcIjogXCLiipZcIixcblx0XCJPb3BmXCI6IFwi8J2VhlwiLFxuXHRcIm9vcGZcIjogXCLwnZWgXCIsXG5cdFwib3BhclwiOiBcIuKmt1wiLFxuXHRcIk9wZW5DdXJseURvdWJsZVF1b3RlXCI6IFwi4oCcXCIsXG5cdFwiT3BlbkN1cmx5UXVvdGVcIjogXCLigJhcIixcblx0XCJvcGVycFwiOiBcIuKmuVwiLFxuXHRcIm9wbHVzXCI6IFwi4oqVXCIsXG5cdFwib3JhcnJcIjogXCLihrtcIixcblx0XCJPclwiOiBcIuKplFwiLFxuXHRcIm9yXCI6IFwi4oioXCIsXG5cdFwib3JkXCI6IFwi4qmdXCIsXG5cdFwib3JkZXJcIjogXCLihLRcIixcblx0XCJvcmRlcm9mXCI6IFwi4oS0XCIsXG5cdFwib3JkZlwiOiBcIsKqXCIsXG5cdFwib3JkbVwiOiBcIsK6XCIsXG5cdFwib3JpZ29mXCI6IFwi4oq2XCIsXG5cdFwib3JvclwiOiBcIuKpllwiLFxuXHRcIm9yc2xvcGVcIjogXCLiqZdcIixcblx0XCJvcnZcIjogXCLiqZtcIixcblx0XCJvU1wiOiBcIuKTiFwiLFxuXHRcIk9zY3JcIjogXCLwnZKqXCIsXG5cdFwib3NjclwiOiBcIuKEtFwiLFxuXHRcIk9zbGFzaFwiOiBcIsOYXCIsXG5cdFwib3NsYXNoXCI6IFwiw7hcIixcblx0XCJvc29sXCI6IFwi4oqYXCIsXG5cdFwiT3RpbGRlXCI6IFwiw5VcIixcblx0XCJvdGlsZGVcIjogXCLDtVwiLFxuXHRcIm90aW1lc2FzXCI6IFwi4qi2XCIsXG5cdFwiT3RpbWVzXCI6IFwi4qi3XCIsXG5cdFwib3RpbWVzXCI6IFwi4oqXXCIsXG5cdFwiT3VtbFwiOiBcIsOWXCIsXG5cdFwib3VtbFwiOiBcIsO2XCIsXG5cdFwib3ZiYXJcIjogXCLijL1cIixcblx0XCJPdmVyQmFyXCI6IFwi4oC+XCIsXG5cdFwiT3ZlckJyYWNlXCI6IFwi4o+eXCIsXG5cdFwiT3ZlckJyYWNrZXRcIjogXCLijrRcIixcblx0XCJPdmVyUGFyZW50aGVzaXNcIjogXCLij5xcIixcblx0XCJwYXJhXCI6IFwiwrZcIixcblx0XCJwYXJhbGxlbFwiOiBcIuKIpVwiLFxuXHRcInBhclwiOiBcIuKIpVwiLFxuXHRcInBhcnNpbVwiOiBcIuKrs1wiLFxuXHRcInBhcnNsXCI6IFwi4qu9XCIsXG5cdFwicGFydFwiOiBcIuKIglwiLFxuXHRcIlBhcnRpYWxEXCI6IFwi4oiCXCIsXG5cdFwiUGN5XCI6IFwi0J9cIixcblx0XCJwY3lcIjogXCLQv1wiLFxuXHRcInBlcmNudFwiOiBcIiVcIixcblx0XCJwZXJpb2RcIjogXCIuXCIsXG5cdFwicGVybWlsXCI6IFwi4oCwXCIsXG5cdFwicGVycFwiOiBcIuKKpVwiLFxuXHRcInBlcnRlbmtcIjogXCLigLFcIixcblx0XCJQZnJcIjogXCLwnZSTXCIsXG5cdFwicGZyXCI6IFwi8J2UrVwiLFxuXHRcIlBoaVwiOiBcIs6mXCIsXG5cdFwicGhpXCI6IFwiz4ZcIixcblx0XCJwaGl2XCI6IFwiz5VcIixcblx0XCJwaG1tYXRcIjogXCLihLNcIixcblx0XCJwaG9uZVwiOiBcIuKYjlwiLFxuXHRcIlBpXCI6IFwizqBcIixcblx0XCJwaVwiOiBcIs+AXCIsXG5cdFwicGl0Y2hmb3JrXCI6IFwi4ouUXCIsXG5cdFwicGl2XCI6IFwiz5ZcIixcblx0XCJwbGFuY2tcIjogXCLihI9cIixcblx0XCJwbGFuY2toXCI6IFwi4oSOXCIsXG5cdFwicGxhbmt2XCI6IFwi4oSPXCIsXG5cdFwicGx1c2FjaXJcIjogXCLiqKNcIixcblx0XCJwbHVzYlwiOiBcIuKKnlwiLFxuXHRcInBsdXNjaXJcIjogXCLiqKJcIixcblx0XCJwbHVzXCI6IFwiK1wiLFxuXHRcInBsdXNkb1wiOiBcIuKIlFwiLFxuXHRcInBsdXNkdVwiOiBcIuKopVwiLFxuXHRcInBsdXNlXCI6IFwi4qmyXCIsXG5cdFwiUGx1c01pbnVzXCI6IFwiwrFcIixcblx0XCJwbHVzbW5cIjogXCLCsVwiLFxuXHRcInBsdXNzaW1cIjogXCLiqKZcIixcblx0XCJwbHVzdHdvXCI6IFwi4qinXCIsXG5cdFwicG1cIjogXCLCsVwiLFxuXHRcIlBvaW5jYXJlcGxhbmVcIjogXCLihIxcIixcblx0XCJwb2ludGludFwiOiBcIuKolVwiLFxuXHRcInBvcGZcIjogXCLwnZWhXCIsXG5cdFwiUG9wZlwiOiBcIuKEmVwiLFxuXHRcInBvdW5kXCI6IFwiwqNcIixcblx0XCJwcmFwXCI6IFwi4qq3XCIsXG5cdFwiUHJcIjogXCLiqrtcIixcblx0XCJwclwiOiBcIuKJulwiLFxuXHRcInByY3VlXCI6IFwi4om8XCIsXG5cdFwicHJlY2FwcHJveFwiOiBcIuKqt1wiLFxuXHRcInByZWNcIjogXCLiibpcIixcblx0XCJwcmVjY3VybHllcVwiOiBcIuKJvFwiLFxuXHRcIlByZWNlZGVzXCI6IFwi4om6XCIsXG5cdFwiUHJlY2VkZXNFcXVhbFwiOiBcIuKqr1wiLFxuXHRcIlByZWNlZGVzU2xhbnRFcXVhbFwiOiBcIuKJvFwiLFxuXHRcIlByZWNlZGVzVGlsZGVcIjogXCLiib5cIixcblx0XCJwcmVjZXFcIjogXCLiqq9cIixcblx0XCJwcmVjbmFwcHJveFwiOiBcIuKquVwiLFxuXHRcInByZWNuZXFxXCI6IFwi4qq1XCIsXG5cdFwicHJlY25zaW1cIjogXCLii6hcIixcblx0XCJwcmVcIjogXCLiqq9cIixcblx0XCJwckVcIjogXCLiqrNcIixcblx0XCJwcmVjc2ltXCI6IFwi4om+XCIsXG5cdFwicHJpbWVcIjogXCLigLJcIixcblx0XCJQcmltZVwiOiBcIuKAs1wiLFxuXHRcInByaW1lc1wiOiBcIuKEmVwiLFxuXHRcInBybmFwXCI6IFwi4qq5XCIsXG5cdFwicHJuRVwiOiBcIuKqtVwiLFxuXHRcInBybnNpbVwiOiBcIuKLqFwiLFxuXHRcInByb2RcIjogXCLiiI9cIixcblx0XCJQcm9kdWN0XCI6IFwi4oiPXCIsXG5cdFwicHJvZmFsYXJcIjogXCLijK5cIixcblx0XCJwcm9mbGluZVwiOiBcIuKMklwiLFxuXHRcInByb2ZzdXJmXCI6IFwi4oyTXCIsXG5cdFwicHJvcFwiOiBcIuKInVwiLFxuXHRcIlByb3BvcnRpb25hbFwiOiBcIuKInVwiLFxuXHRcIlByb3BvcnRpb25cIjogXCLiiLdcIixcblx0XCJwcm9wdG9cIjogXCLiiJ1cIixcblx0XCJwcnNpbVwiOiBcIuKJvlwiLFxuXHRcInBydXJlbFwiOiBcIuKKsFwiLFxuXHRcIlBzY3JcIjogXCLwnZKrXCIsXG5cdFwicHNjclwiOiBcIvCdk4VcIixcblx0XCJQc2lcIjogXCLOqFwiLFxuXHRcInBzaVwiOiBcIs+IXCIsXG5cdFwicHVuY3NwXCI6IFwi4oCIXCIsXG5cdFwiUWZyXCI6IFwi8J2UlFwiLFxuXHRcInFmclwiOiBcIvCdlK5cIixcblx0XCJxaW50XCI6IFwi4qiMXCIsXG5cdFwicW9wZlwiOiBcIvCdlaJcIixcblx0XCJRb3BmXCI6IFwi4oSaXCIsXG5cdFwicXByaW1lXCI6IFwi4oGXXCIsXG5cdFwiUXNjclwiOiBcIvCdkqxcIixcblx0XCJxc2NyXCI6IFwi8J2ThlwiLFxuXHRcInF1YXRlcm5pb25zXCI6IFwi4oSNXCIsXG5cdFwicXVhdGludFwiOiBcIuKollwiLFxuXHRcInF1ZXN0XCI6IFwiP1wiLFxuXHRcInF1ZXN0ZXFcIjogXCLiiZ9cIixcblx0XCJxdW90XCI6IFwiXFxcIlwiLFxuXHRcIlFVT1RcIjogXCJcXFwiXCIsXG5cdFwickFhcnJcIjogXCLih5tcIixcblx0XCJyYWNlXCI6IFwi4oi9zLFcIixcblx0XCJSYWN1dGVcIjogXCLFlFwiLFxuXHRcInJhY3V0ZVwiOiBcIsWVXCIsXG5cdFwicmFkaWNcIjogXCLiiJpcIixcblx0XCJyYWVtcHR5dlwiOiBcIuKms1wiLFxuXHRcInJhbmdcIjogXCLin6lcIixcblx0XCJSYW5nXCI6IFwi4p+rXCIsXG5cdFwicmFuZ2RcIjogXCLippJcIixcblx0XCJyYW5nZVwiOiBcIuKmpVwiLFxuXHRcInJhbmdsZVwiOiBcIuKfqVwiLFxuXHRcInJhcXVvXCI6IFwiwrtcIixcblx0XCJyYXJyYXBcIjogXCLipbVcIixcblx0XCJyYXJyYlwiOiBcIuKHpVwiLFxuXHRcInJhcnJiZnNcIjogXCLipKBcIixcblx0XCJyYXJyY1wiOiBcIuKks1wiLFxuXHRcInJhcnJcIjogXCLihpJcIixcblx0XCJSYXJyXCI6IFwi4oagXCIsXG5cdFwickFyclwiOiBcIuKHklwiLFxuXHRcInJhcnJmc1wiOiBcIuKknlwiLFxuXHRcInJhcnJoa1wiOiBcIuKGqlwiLFxuXHRcInJhcnJscFwiOiBcIuKGrFwiLFxuXHRcInJhcnJwbFwiOiBcIuKlhVwiLFxuXHRcInJhcnJzaW1cIjogXCLipbRcIixcblx0XCJSYXJydGxcIjogXCLipJZcIixcblx0XCJyYXJydGxcIjogXCLihqNcIixcblx0XCJyYXJyd1wiOiBcIuKGnVwiLFxuXHRcInJhdGFpbFwiOiBcIuKkmlwiLFxuXHRcInJBdGFpbFwiOiBcIuKknFwiLFxuXHRcInJhdGlvXCI6IFwi4oi2XCIsXG5cdFwicmF0aW9uYWxzXCI6IFwi4oSaXCIsXG5cdFwicmJhcnJcIjogXCLipI1cIixcblx0XCJyQmFyclwiOiBcIuKkj1wiLFxuXHRcIlJCYXJyXCI6IFwi4qSQXCIsXG5cdFwicmJicmtcIjogXCLinbNcIixcblx0XCJyYnJhY2VcIjogXCJ9XCIsXG5cdFwicmJyYWNrXCI6IFwiXVwiLFxuXHRcInJicmtlXCI6IFwi4qaMXCIsXG5cdFwicmJya3NsZFwiOiBcIuKmjlwiLFxuXHRcInJicmtzbHVcIjogXCLippBcIixcblx0XCJSY2Fyb25cIjogXCLFmFwiLFxuXHRcInJjYXJvblwiOiBcIsWZXCIsXG5cdFwiUmNlZGlsXCI6IFwixZZcIixcblx0XCJyY2VkaWxcIjogXCLFl1wiLFxuXHRcInJjZWlsXCI6IFwi4oyJXCIsXG5cdFwicmN1YlwiOiBcIn1cIixcblx0XCJSY3lcIjogXCLQoFwiLFxuXHRcInJjeVwiOiBcItGAXCIsXG5cdFwicmRjYVwiOiBcIuKkt1wiLFxuXHRcInJkbGRoYXJcIjogXCLipalcIixcblx0XCJyZHF1b1wiOiBcIuKAnVwiLFxuXHRcInJkcXVvclwiOiBcIuKAnVwiLFxuXHRcInJkc2hcIjogXCLihrNcIixcblx0XCJyZWFsXCI6IFwi4oScXCIsXG5cdFwicmVhbGluZVwiOiBcIuKEm1wiLFxuXHRcInJlYWxwYXJ0XCI6IFwi4oScXCIsXG5cdFwicmVhbHNcIjogXCLihJ1cIixcblx0XCJSZVwiOiBcIuKEnFwiLFxuXHRcInJlY3RcIjogXCLilq1cIixcblx0XCJyZWdcIjogXCLCrlwiLFxuXHRcIlJFR1wiOiBcIsKuXCIsXG5cdFwiUmV2ZXJzZUVsZW1lbnRcIjogXCLiiItcIixcblx0XCJSZXZlcnNlRXF1aWxpYnJpdW1cIjogXCLih4tcIixcblx0XCJSZXZlcnNlVXBFcXVpbGlicml1bVwiOiBcIuKlr1wiLFxuXHRcInJmaXNodFwiOiBcIuKlvVwiLFxuXHRcInJmbG9vclwiOiBcIuKMi1wiLFxuXHRcInJmclwiOiBcIvCdlK9cIixcblx0XCJSZnJcIjogXCLihJxcIixcblx0XCJySGFyXCI6IFwi4qWkXCIsXG5cdFwicmhhcmRcIjogXCLih4FcIixcblx0XCJyaGFydVwiOiBcIuKHgFwiLFxuXHRcInJoYXJ1bFwiOiBcIuKlrFwiLFxuXHRcIlJob1wiOiBcIs6hXCIsXG5cdFwicmhvXCI6IFwiz4FcIixcblx0XCJyaG92XCI6IFwiz7FcIixcblx0XCJSaWdodEFuZ2xlQnJhY2tldFwiOiBcIuKfqVwiLFxuXHRcIlJpZ2h0QXJyb3dCYXJcIjogXCLih6VcIixcblx0XCJyaWdodGFycm93XCI6IFwi4oaSXCIsXG5cdFwiUmlnaHRBcnJvd1wiOiBcIuKGklwiLFxuXHRcIlJpZ2h0YXJyb3dcIjogXCLih5JcIixcblx0XCJSaWdodEFycm93TGVmdEFycm93XCI6IFwi4oeEXCIsXG5cdFwicmlnaHRhcnJvd3RhaWxcIjogXCLihqNcIixcblx0XCJSaWdodENlaWxpbmdcIjogXCLijIlcIixcblx0XCJSaWdodERvdWJsZUJyYWNrZXRcIjogXCLin6dcIixcblx0XCJSaWdodERvd25UZWVWZWN0b3JcIjogXCLipZ1cIixcblx0XCJSaWdodERvd25WZWN0b3JCYXJcIjogXCLipZVcIixcblx0XCJSaWdodERvd25WZWN0b3JcIjogXCLih4JcIixcblx0XCJSaWdodEZsb29yXCI6IFwi4oyLXCIsXG5cdFwicmlnaHRoYXJwb29uZG93blwiOiBcIuKHgVwiLFxuXHRcInJpZ2h0aGFycG9vbnVwXCI6IFwi4oeAXCIsXG5cdFwicmlnaHRsZWZ0YXJyb3dzXCI6IFwi4oeEXCIsXG5cdFwicmlnaHRsZWZ0aGFycG9vbnNcIjogXCLih4xcIixcblx0XCJyaWdodHJpZ2h0YXJyb3dzXCI6IFwi4oeJXCIsXG5cdFwicmlnaHRzcXVpZ2Fycm93XCI6IFwi4oadXCIsXG5cdFwiUmlnaHRUZWVBcnJvd1wiOiBcIuKGplwiLFxuXHRcIlJpZ2h0VGVlXCI6IFwi4oqiXCIsXG5cdFwiUmlnaHRUZWVWZWN0b3JcIjogXCLipZtcIixcblx0XCJyaWdodHRocmVldGltZXNcIjogXCLii4xcIixcblx0XCJSaWdodFRyaWFuZ2xlQmFyXCI6IFwi4qeQXCIsXG5cdFwiUmlnaHRUcmlhbmdsZVwiOiBcIuKKs1wiLFxuXHRcIlJpZ2h0VHJpYW5nbGVFcXVhbFwiOiBcIuKKtVwiLFxuXHRcIlJpZ2h0VXBEb3duVmVjdG9yXCI6IFwi4qWPXCIsXG5cdFwiUmlnaHRVcFRlZVZlY3RvclwiOiBcIuKlnFwiLFxuXHRcIlJpZ2h0VXBWZWN0b3JCYXJcIjogXCLipZRcIixcblx0XCJSaWdodFVwVmVjdG9yXCI6IFwi4oa+XCIsXG5cdFwiUmlnaHRWZWN0b3JCYXJcIjogXCLipZNcIixcblx0XCJSaWdodFZlY3RvclwiOiBcIuKHgFwiLFxuXHRcInJpbmdcIjogXCLLmlwiLFxuXHRcInJpc2luZ2RvdHNlcVwiOiBcIuKJk1wiLFxuXHRcInJsYXJyXCI6IFwi4oeEXCIsXG5cdFwicmxoYXJcIjogXCLih4xcIixcblx0XCJybG1cIjogXCLigI9cIixcblx0XCJybW91c3RhY2hlXCI6IFwi4o6xXCIsXG5cdFwicm1vdXN0XCI6IFwi4o6xXCIsXG5cdFwicm5taWRcIjogXCLiq65cIixcblx0XCJyb2FuZ1wiOiBcIuKfrVwiLFxuXHRcInJvYXJyXCI6IFwi4oe+XCIsXG5cdFwicm9icmtcIjogXCLin6dcIixcblx0XCJyb3BhclwiOiBcIuKmhlwiLFxuXHRcInJvcGZcIjogXCLwnZWjXCIsXG5cdFwiUm9wZlwiOiBcIuKEnVwiLFxuXHRcInJvcGx1c1wiOiBcIuKorlwiLFxuXHRcInJvdGltZXNcIjogXCLiqLVcIixcblx0XCJSb3VuZEltcGxpZXNcIjogXCLipbBcIixcblx0XCJycGFyXCI6IFwiKVwiLFxuXHRcInJwYXJndFwiOiBcIuKmlFwiLFxuXHRcInJwcG9saW50XCI6IFwi4qiSXCIsXG5cdFwicnJhcnJcIjogXCLih4lcIixcblx0XCJScmlnaHRhcnJvd1wiOiBcIuKHm1wiLFxuXHRcInJzYXF1b1wiOiBcIuKAulwiLFxuXHRcInJzY3JcIjogXCLwnZOHXCIsXG5cdFwiUnNjclwiOiBcIuKEm1wiLFxuXHRcInJzaFwiOiBcIuKGsVwiLFxuXHRcIlJzaFwiOiBcIuKGsVwiLFxuXHRcInJzcWJcIjogXCJdXCIsXG5cdFwicnNxdW9cIjogXCLigJlcIixcblx0XCJyc3F1b3JcIjogXCLigJlcIixcblx0XCJydGhyZWVcIjogXCLii4xcIixcblx0XCJydGltZXNcIjogXCLii4pcIixcblx0XCJydHJpXCI6IFwi4pa5XCIsXG5cdFwicnRyaWVcIjogXCLiirVcIixcblx0XCJydHJpZlwiOiBcIuKWuFwiLFxuXHRcInJ0cmlsdHJpXCI6IFwi4qeOXCIsXG5cdFwiUnVsZURlbGF5ZWRcIjogXCLip7RcIixcblx0XCJydWx1aGFyXCI6IFwi4qWoXCIsXG5cdFwicnhcIjogXCLihJ5cIixcblx0XCJTYWN1dGVcIjogXCLFmlwiLFxuXHRcInNhY3V0ZVwiOiBcIsWbXCIsXG5cdFwic2JxdW9cIjogXCLigJpcIixcblx0XCJzY2FwXCI6IFwi4qq4XCIsXG5cdFwiU2Nhcm9uXCI6IFwixaBcIixcblx0XCJzY2Fyb25cIjogXCLFoVwiLFxuXHRcIlNjXCI6IFwi4qq8XCIsXG5cdFwic2NcIjogXCLiibtcIixcblx0XCJzY2N1ZVwiOiBcIuKJvVwiLFxuXHRcInNjZVwiOiBcIuKqsFwiLFxuXHRcInNjRVwiOiBcIuKqtFwiLFxuXHRcIlNjZWRpbFwiOiBcIsWeXCIsXG5cdFwic2NlZGlsXCI6IFwixZ9cIixcblx0XCJTY2lyY1wiOiBcIsWcXCIsXG5cdFwic2NpcmNcIjogXCLFnVwiLFxuXHRcInNjbmFwXCI6IFwi4qq6XCIsXG5cdFwic2NuRVwiOiBcIuKqtlwiLFxuXHRcInNjbnNpbVwiOiBcIuKLqVwiLFxuXHRcInNjcG9saW50XCI6IFwi4qiTXCIsXG5cdFwic2NzaW1cIjogXCLiib9cIixcblx0XCJTY3lcIjogXCLQoVwiLFxuXHRcInNjeVwiOiBcItGBXCIsXG5cdFwic2RvdGJcIjogXCLiiqFcIixcblx0XCJzZG90XCI6IFwi4ouFXCIsXG5cdFwic2RvdGVcIjogXCLiqaZcIixcblx0XCJzZWFyaGtcIjogXCLipKVcIixcblx0XCJzZWFyclwiOiBcIuKGmFwiLFxuXHRcInNlQXJyXCI6IFwi4oeYXCIsXG5cdFwic2VhcnJvd1wiOiBcIuKGmFwiLFxuXHRcInNlY3RcIjogXCLCp1wiLFxuXHRcInNlbWlcIjogXCI7XCIsXG5cdFwic2Vzd2FyXCI6IFwi4qSpXCIsXG5cdFwic2V0bWludXNcIjogXCLiiJZcIixcblx0XCJzZXRtblwiOiBcIuKIllwiLFxuXHRcInNleHRcIjogXCLinLZcIixcblx0XCJTZnJcIjogXCLwnZSWXCIsXG5cdFwic2ZyXCI6IFwi8J2UsFwiLFxuXHRcInNmcm93blwiOiBcIuKMolwiLFxuXHRcInNoYXJwXCI6IFwi4pmvXCIsXG5cdFwiU0hDSGN5XCI6IFwi0KlcIixcblx0XCJzaGNoY3lcIjogXCLRiVwiLFxuXHRcIlNIY3lcIjogXCLQqFwiLFxuXHRcInNoY3lcIjogXCLRiFwiLFxuXHRcIlNob3J0RG93bkFycm93XCI6IFwi4oaTXCIsXG5cdFwiU2hvcnRMZWZ0QXJyb3dcIjogXCLihpBcIixcblx0XCJzaG9ydG1pZFwiOiBcIuKIo1wiLFxuXHRcInNob3J0cGFyYWxsZWxcIjogXCLiiKVcIixcblx0XCJTaG9ydFJpZ2h0QXJyb3dcIjogXCLihpJcIixcblx0XCJTaG9ydFVwQXJyb3dcIjogXCLihpFcIixcblx0XCJzaHlcIjogXCLCrVwiLFxuXHRcIlNpZ21hXCI6IFwizqNcIixcblx0XCJzaWdtYVwiOiBcIs+DXCIsXG5cdFwic2lnbWFmXCI6IFwiz4JcIixcblx0XCJzaWdtYXZcIjogXCLPglwiLFxuXHRcInNpbVwiOiBcIuKIvFwiLFxuXHRcInNpbWRvdFwiOiBcIuKpqlwiLFxuXHRcInNpbWVcIjogXCLiiYNcIixcblx0XCJzaW1lcVwiOiBcIuKJg1wiLFxuXHRcInNpbWdcIjogXCLiqp5cIixcblx0XCJzaW1nRVwiOiBcIuKqoFwiLFxuXHRcInNpbWxcIjogXCLiqp1cIixcblx0XCJzaW1sRVwiOiBcIuKqn1wiLFxuXHRcInNpbW5lXCI6IFwi4omGXCIsXG5cdFwic2ltcGx1c1wiOiBcIuKopFwiLFxuXHRcInNpbXJhcnJcIjogXCLipbJcIixcblx0XCJzbGFyclwiOiBcIuKGkFwiLFxuXHRcIlNtYWxsQ2lyY2xlXCI6IFwi4oiYXCIsXG5cdFwic21hbGxzZXRtaW51c1wiOiBcIuKIllwiLFxuXHRcInNtYXNocFwiOiBcIuKos1wiLFxuXHRcInNtZXBhcnNsXCI6IFwi4qekXCIsXG5cdFwic21pZFwiOiBcIuKIo1wiLFxuXHRcInNtaWxlXCI6IFwi4oyjXCIsXG5cdFwic210XCI6IFwi4qqqXCIsXG5cdFwic210ZVwiOiBcIuKqrFwiLFxuXHRcInNtdGVzXCI6IFwi4qqs77iAXCIsXG5cdFwiU09GVGN5XCI6IFwi0KxcIixcblx0XCJzb2Z0Y3lcIjogXCLRjFwiLFxuXHRcInNvbGJhclwiOiBcIuKMv1wiLFxuXHRcInNvbGJcIjogXCLip4RcIixcblx0XCJzb2xcIjogXCIvXCIsXG5cdFwiU29wZlwiOiBcIvCdlYpcIixcblx0XCJzb3BmXCI6IFwi8J2VpFwiLFxuXHRcInNwYWRlc1wiOiBcIuKZoFwiLFxuXHRcInNwYWRlc3VpdFwiOiBcIuKZoFwiLFxuXHRcInNwYXJcIjogXCLiiKVcIixcblx0XCJzcWNhcFwiOiBcIuKKk1wiLFxuXHRcInNxY2Fwc1wiOiBcIuKKk++4gFwiLFxuXHRcInNxY3VwXCI6IFwi4oqUXCIsXG5cdFwic3FjdXBzXCI6IFwi4oqU77iAXCIsXG5cdFwiU3FydFwiOiBcIuKImlwiLFxuXHRcInNxc3ViXCI6IFwi4oqPXCIsXG5cdFwic3FzdWJlXCI6IFwi4oqRXCIsXG5cdFwic3FzdWJzZXRcIjogXCLiio9cIixcblx0XCJzcXN1YnNldGVxXCI6IFwi4oqRXCIsXG5cdFwic3FzdXBcIjogXCLiipBcIixcblx0XCJzcXN1cGVcIjogXCLiipJcIixcblx0XCJzcXN1cHNldFwiOiBcIuKKkFwiLFxuXHRcInNxc3Vwc2V0ZXFcIjogXCLiipJcIixcblx0XCJzcXVhcmVcIjogXCLilqFcIixcblx0XCJTcXVhcmVcIjogXCLilqFcIixcblx0XCJTcXVhcmVJbnRlcnNlY3Rpb25cIjogXCLiipNcIixcblx0XCJTcXVhcmVTdWJzZXRcIjogXCLiio9cIixcblx0XCJTcXVhcmVTdWJzZXRFcXVhbFwiOiBcIuKKkVwiLFxuXHRcIlNxdWFyZVN1cGVyc2V0XCI6IFwi4oqQXCIsXG5cdFwiU3F1YXJlU3VwZXJzZXRFcXVhbFwiOiBcIuKKklwiLFxuXHRcIlNxdWFyZVVuaW9uXCI6IFwi4oqUXCIsXG5cdFwic3F1YXJmXCI6IFwi4paqXCIsXG5cdFwic3F1XCI6IFwi4pahXCIsXG5cdFwic3F1ZlwiOiBcIuKWqlwiLFxuXHRcInNyYXJyXCI6IFwi4oaSXCIsXG5cdFwiU3NjclwiOiBcIvCdkq5cIixcblx0XCJzc2NyXCI6IFwi8J2TiFwiLFxuXHRcInNzZXRtblwiOiBcIuKIllwiLFxuXHRcInNzbWlsZVwiOiBcIuKMo1wiLFxuXHRcInNzdGFyZlwiOiBcIuKLhlwiLFxuXHRcIlN0YXJcIjogXCLii4ZcIixcblx0XCJzdGFyXCI6IFwi4piGXCIsXG5cdFwic3RhcmZcIjogXCLimIVcIixcblx0XCJzdHJhaWdodGVwc2lsb25cIjogXCLPtVwiLFxuXHRcInN0cmFpZ2h0cGhpXCI6IFwiz5VcIixcblx0XCJzdHJuc1wiOiBcIsKvXCIsXG5cdFwic3ViXCI6IFwi4oqCXCIsXG5cdFwiU3ViXCI6IFwi4ouQXCIsXG5cdFwic3ViZG90XCI6IFwi4qq9XCIsXG5cdFwic3ViRVwiOiBcIuKrhVwiLFxuXHRcInN1YmVcIjogXCLiioZcIixcblx0XCJzdWJlZG90XCI6IFwi4quDXCIsXG5cdFwic3VibXVsdFwiOiBcIuKrgVwiLFxuXHRcInN1Ym5FXCI6IFwi4quLXCIsXG5cdFwic3VibmVcIjogXCLiiopcIixcblx0XCJzdWJwbHVzXCI6IFwi4qq/XCIsXG5cdFwic3VicmFyclwiOiBcIuKluVwiLFxuXHRcInN1YnNldFwiOiBcIuKKglwiLFxuXHRcIlN1YnNldFwiOiBcIuKLkFwiLFxuXHRcInN1YnNldGVxXCI6IFwi4oqGXCIsXG5cdFwic3Vic2V0ZXFxXCI6IFwi4quFXCIsXG5cdFwiU3Vic2V0RXF1YWxcIjogXCLiioZcIixcblx0XCJzdWJzZXRuZXFcIjogXCLiiopcIixcblx0XCJzdWJzZXRuZXFxXCI6IFwi4quLXCIsXG5cdFwic3Vic2ltXCI6IFwi4quHXCIsXG5cdFwic3Vic3ViXCI6IFwi4quVXCIsXG5cdFwic3Vic3VwXCI6IFwi4quTXCIsXG5cdFwic3VjY2FwcHJveFwiOiBcIuKquFwiLFxuXHRcInN1Y2NcIjogXCLiibtcIixcblx0XCJzdWNjY3VybHllcVwiOiBcIuKJvVwiLFxuXHRcIlN1Y2NlZWRzXCI6IFwi4om7XCIsXG5cdFwiU3VjY2VlZHNFcXVhbFwiOiBcIuKqsFwiLFxuXHRcIlN1Y2NlZWRzU2xhbnRFcXVhbFwiOiBcIuKJvVwiLFxuXHRcIlN1Y2NlZWRzVGlsZGVcIjogXCLiib9cIixcblx0XCJzdWNjZXFcIjogXCLiqrBcIixcblx0XCJzdWNjbmFwcHJveFwiOiBcIuKqulwiLFxuXHRcInN1Y2NuZXFxXCI6IFwi4qq2XCIsXG5cdFwic3VjY25zaW1cIjogXCLii6lcIixcblx0XCJzdWNjc2ltXCI6IFwi4om/XCIsXG5cdFwiU3VjaFRoYXRcIjogXCLiiItcIixcblx0XCJzdW1cIjogXCLiiJFcIixcblx0XCJTdW1cIjogXCLiiJFcIixcblx0XCJzdW5nXCI6IFwi4pmqXCIsXG5cdFwic3VwMVwiOiBcIsK5XCIsXG5cdFwic3VwMlwiOiBcIsKyXCIsXG5cdFwic3VwM1wiOiBcIsKzXCIsXG5cdFwic3VwXCI6IFwi4oqDXCIsXG5cdFwiU3VwXCI6IFwi4ouRXCIsXG5cdFwic3VwZG90XCI6IFwi4qq+XCIsXG5cdFwic3VwZHN1YlwiOiBcIuKrmFwiLFxuXHRcInN1cEVcIjogXCLiq4ZcIixcblx0XCJzdXBlXCI6IFwi4oqHXCIsXG5cdFwic3VwZWRvdFwiOiBcIuKrhFwiLFxuXHRcIlN1cGVyc2V0XCI6IFwi4oqDXCIsXG5cdFwiU3VwZXJzZXRFcXVhbFwiOiBcIuKKh1wiLFxuXHRcInN1cGhzb2xcIjogXCLin4lcIixcblx0XCJzdXBoc3ViXCI6IFwi4quXXCIsXG5cdFwic3VwbGFyclwiOiBcIuKlu1wiLFxuXHRcInN1cG11bHRcIjogXCLiq4JcIixcblx0XCJzdXBuRVwiOiBcIuKrjFwiLFxuXHRcInN1cG5lXCI6IFwi4oqLXCIsXG5cdFwic3VwcGx1c1wiOiBcIuKrgFwiLFxuXHRcInN1cHNldFwiOiBcIuKKg1wiLFxuXHRcIlN1cHNldFwiOiBcIuKLkVwiLFxuXHRcInN1cHNldGVxXCI6IFwi4oqHXCIsXG5cdFwic3Vwc2V0ZXFxXCI6IFwi4quGXCIsXG5cdFwic3Vwc2V0bmVxXCI6IFwi4oqLXCIsXG5cdFwic3Vwc2V0bmVxcVwiOiBcIuKrjFwiLFxuXHRcInN1cHNpbVwiOiBcIuKriFwiLFxuXHRcInN1cHN1YlwiOiBcIuKrlFwiLFxuXHRcInN1cHN1cFwiOiBcIuKrllwiLFxuXHRcInN3YXJoa1wiOiBcIuKkplwiLFxuXHRcInN3YXJyXCI6IFwi4oaZXCIsXG5cdFwic3dBcnJcIjogXCLih5lcIixcblx0XCJzd2Fycm93XCI6IFwi4oaZXCIsXG5cdFwic3dud2FyXCI6IFwi4qSqXCIsXG5cdFwic3psaWdcIjogXCLDn1wiLFxuXHRcIlRhYlwiOiBcIlxcdFwiLFxuXHRcInRhcmdldFwiOiBcIuKMllwiLFxuXHRcIlRhdVwiOiBcIs6kXCIsXG5cdFwidGF1XCI6IFwiz4RcIixcblx0XCJ0YnJrXCI6IFwi4o60XCIsXG5cdFwiVGNhcm9uXCI6IFwixaRcIixcblx0XCJ0Y2Fyb25cIjogXCLFpVwiLFxuXHRcIlRjZWRpbFwiOiBcIsWiXCIsXG5cdFwidGNlZGlsXCI6IFwixaNcIixcblx0XCJUY3lcIjogXCLQolwiLFxuXHRcInRjeVwiOiBcItGCXCIsXG5cdFwidGRvdFwiOiBcIuKDm1wiLFxuXHRcInRlbHJlY1wiOiBcIuKMlVwiLFxuXHRcIlRmclwiOiBcIvCdlJdcIixcblx0XCJ0ZnJcIjogXCLwnZSxXCIsXG5cdFwidGhlcmU0XCI6IFwi4oi0XCIsXG5cdFwidGhlcmVmb3JlXCI6IFwi4oi0XCIsXG5cdFwiVGhlcmVmb3JlXCI6IFwi4oi0XCIsXG5cdFwiVGhldGFcIjogXCLOmFwiLFxuXHRcInRoZXRhXCI6IFwizrhcIixcblx0XCJ0aGV0YXN5bVwiOiBcIs+RXCIsXG5cdFwidGhldGF2XCI6IFwiz5FcIixcblx0XCJ0aGlja2FwcHJveFwiOiBcIuKJiFwiLFxuXHRcInRoaWNrc2ltXCI6IFwi4oi8XCIsXG5cdFwiVGhpY2tTcGFjZVwiOiBcIuKBn+KAilwiLFxuXHRcIlRoaW5TcGFjZVwiOiBcIuKAiVwiLFxuXHRcInRoaW5zcFwiOiBcIuKAiVwiLFxuXHRcInRoa2FwXCI6IFwi4omIXCIsXG5cdFwidGhrc2ltXCI6IFwi4oi8XCIsXG5cdFwiVEhPUk5cIjogXCLDnlwiLFxuXHRcInRob3JuXCI6IFwiw75cIixcblx0XCJ0aWxkZVwiOiBcIsucXCIsXG5cdFwiVGlsZGVcIjogXCLiiLxcIixcblx0XCJUaWxkZUVxdWFsXCI6IFwi4omDXCIsXG5cdFwiVGlsZGVGdWxsRXF1YWxcIjogXCLiiYVcIixcblx0XCJUaWxkZVRpbGRlXCI6IFwi4omIXCIsXG5cdFwidGltZXNiYXJcIjogXCLiqLFcIixcblx0XCJ0aW1lc2JcIjogXCLiiqBcIixcblx0XCJ0aW1lc1wiOiBcIsOXXCIsXG5cdFwidGltZXNkXCI6IFwi4qiwXCIsXG5cdFwidGludFwiOiBcIuKIrVwiLFxuXHRcInRvZWFcIjogXCLipKhcIixcblx0XCJ0b3Bib3RcIjogXCLijLZcIixcblx0XCJ0b3BjaXJcIjogXCLiq7FcIixcblx0XCJ0b3BcIjogXCLiiqRcIixcblx0XCJUb3BmXCI6IFwi8J2Vi1wiLFxuXHRcInRvcGZcIjogXCLwnZWlXCIsXG5cdFwidG9wZm9ya1wiOiBcIuKrmlwiLFxuXHRcInRvc2FcIjogXCLipKlcIixcblx0XCJ0cHJpbWVcIjogXCLigLRcIixcblx0XCJ0cmFkZVwiOiBcIuKEolwiLFxuXHRcIlRSQURFXCI6IFwi4oSiXCIsXG5cdFwidHJpYW5nbGVcIjogXCLilrVcIixcblx0XCJ0cmlhbmdsZWRvd25cIjogXCLilr9cIixcblx0XCJ0cmlhbmdsZWxlZnRcIjogXCLil4NcIixcblx0XCJ0cmlhbmdsZWxlZnRlcVwiOiBcIuKKtFwiLFxuXHRcInRyaWFuZ2xlcVwiOiBcIuKJnFwiLFxuXHRcInRyaWFuZ2xlcmlnaHRcIjogXCLilrlcIixcblx0XCJ0cmlhbmdsZXJpZ2h0ZXFcIjogXCLiirVcIixcblx0XCJ0cmlkb3RcIjogXCLil6xcIixcblx0XCJ0cmllXCI6IFwi4omcXCIsXG5cdFwidHJpbWludXNcIjogXCLiqLpcIixcblx0XCJUcmlwbGVEb3RcIjogXCLig5tcIixcblx0XCJ0cmlwbHVzXCI6IFwi4qi5XCIsXG5cdFwidHJpc2JcIjogXCLip41cIixcblx0XCJ0cml0aW1lXCI6IFwi4qi7XCIsXG5cdFwidHJwZXppdW1cIjogXCLij6JcIixcblx0XCJUc2NyXCI6IFwi8J2Sr1wiLFxuXHRcInRzY3JcIjogXCLwnZOJXCIsXG5cdFwiVFNjeVwiOiBcItCmXCIsXG5cdFwidHNjeVwiOiBcItGGXCIsXG5cdFwiVFNIY3lcIjogXCLQi1wiLFxuXHRcInRzaGN5XCI6IFwi0ZtcIixcblx0XCJUc3Ryb2tcIjogXCLFplwiLFxuXHRcInRzdHJva1wiOiBcIsWnXCIsXG5cdFwidHdpeHRcIjogXCLiiaxcIixcblx0XCJ0d29oZWFkbGVmdGFycm93XCI6IFwi4oaeXCIsXG5cdFwidHdvaGVhZHJpZ2h0YXJyb3dcIjogXCLihqBcIixcblx0XCJVYWN1dGVcIjogXCLDmlwiLFxuXHRcInVhY3V0ZVwiOiBcIsO6XCIsXG5cdFwidWFyclwiOiBcIuKGkVwiLFxuXHRcIlVhcnJcIjogXCLihp9cIixcblx0XCJ1QXJyXCI6IFwi4oeRXCIsXG5cdFwiVWFycm9jaXJcIjogXCLipYlcIixcblx0XCJVYnJjeVwiOiBcItCOXCIsXG5cdFwidWJyY3lcIjogXCLRnlwiLFxuXHRcIlVicmV2ZVwiOiBcIsWsXCIsXG5cdFwidWJyZXZlXCI6IFwixa1cIixcblx0XCJVY2lyY1wiOiBcIsObXCIsXG5cdFwidWNpcmNcIjogXCLDu1wiLFxuXHRcIlVjeVwiOiBcItCjXCIsXG5cdFwidWN5XCI6IFwi0YNcIixcblx0XCJ1ZGFyclwiOiBcIuKHhVwiLFxuXHRcIlVkYmxhY1wiOiBcIsWwXCIsXG5cdFwidWRibGFjXCI6IFwixbFcIixcblx0XCJ1ZGhhclwiOiBcIuKlrlwiLFxuXHRcInVmaXNodFwiOiBcIuKlvlwiLFxuXHRcIlVmclwiOiBcIvCdlJhcIixcblx0XCJ1ZnJcIjogXCLwnZSyXCIsXG5cdFwiVWdyYXZlXCI6IFwiw5lcIixcblx0XCJ1Z3JhdmVcIjogXCLDuVwiLFxuXHRcInVIYXJcIjogXCLipaNcIixcblx0XCJ1aGFybFwiOiBcIuKGv1wiLFxuXHRcInVoYXJyXCI6IFwi4oa+XCIsXG5cdFwidWhibGtcIjogXCLiloBcIixcblx0XCJ1bGNvcm5cIjogXCLijJxcIixcblx0XCJ1bGNvcm5lclwiOiBcIuKMnFwiLFxuXHRcInVsY3JvcFwiOiBcIuKMj1wiLFxuXHRcInVsdHJpXCI6IFwi4pe4XCIsXG5cdFwiVW1hY3JcIjogXCLFqlwiLFxuXHRcInVtYWNyXCI6IFwixatcIixcblx0XCJ1bWxcIjogXCLCqFwiLFxuXHRcIlVuZGVyQmFyXCI6IFwiX1wiLFxuXHRcIlVuZGVyQnJhY2VcIjogXCLij59cIixcblx0XCJVbmRlckJyYWNrZXRcIjogXCLijrVcIixcblx0XCJVbmRlclBhcmVudGhlc2lzXCI6IFwi4o+dXCIsXG5cdFwiVW5pb25cIjogXCLii4NcIixcblx0XCJVbmlvblBsdXNcIjogXCLiio5cIixcblx0XCJVb2dvblwiOiBcIsWyXCIsXG5cdFwidW9nb25cIjogXCLFs1wiLFxuXHRcIlVvcGZcIjogXCLwnZWMXCIsXG5cdFwidW9wZlwiOiBcIvCdlaZcIixcblx0XCJVcEFycm93QmFyXCI6IFwi4qSSXCIsXG5cdFwidXBhcnJvd1wiOiBcIuKGkVwiLFxuXHRcIlVwQXJyb3dcIjogXCLihpFcIixcblx0XCJVcGFycm93XCI6IFwi4oeRXCIsXG5cdFwiVXBBcnJvd0Rvd25BcnJvd1wiOiBcIuKHhVwiLFxuXHRcInVwZG93bmFycm93XCI6IFwi4oaVXCIsXG5cdFwiVXBEb3duQXJyb3dcIjogXCLihpVcIixcblx0XCJVcGRvd25hcnJvd1wiOiBcIuKHlVwiLFxuXHRcIlVwRXF1aWxpYnJpdW1cIjogXCLipa5cIixcblx0XCJ1cGhhcnBvb25sZWZ0XCI6IFwi4oa/XCIsXG5cdFwidXBoYXJwb29ucmlnaHRcIjogXCLihr5cIixcblx0XCJ1cGx1c1wiOiBcIuKKjlwiLFxuXHRcIlVwcGVyTGVmdEFycm93XCI6IFwi4oaWXCIsXG5cdFwiVXBwZXJSaWdodEFycm93XCI6IFwi4oaXXCIsXG5cdFwidXBzaVwiOiBcIs+FXCIsXG5cdFwiVXBzaVwiOiBcIs+SXCIsXG5cdFwidXBzaWhcIjogXCLPklwiLFxuXHRcIlVwc2lsb25cIjogXCLOpVwiLFxuXHRcInVwc2lsb25cIjogXCLPhVwiLFxuXHRcIlVwVGVlQXJyb3dcIjogXCLihqVcIixcblx0XCJVcFRlZVwiOiBcIuKKpVwiLFxuXHRcInVwdXBhcnJvd3NcIjogXCLih4hcIixcblx0XCJ1cmNvcm5cIjogXCLijJ1cIixcblx0XCJ1cmNvcm5lclwiOiBcIuKMnVwiLFxuXHRcInVyY3JvcFwiOiBcIuKMjlwiLFxuXHRcIlVyaW5nXCI6IFwixa5cIixcblx0XCJ1cmluZ1wiOiBcIsWvXCIsXG5cdFwidXJ0cmlcIjogXCLil7lcIixcblx0XCJVc2NyXCI6IFwi8J2SsFwiLFxuXHRcInVzY3JcIjogXCLwnZOKXCIsXG5cdFwidXRkb3RcIjogXCLii7BcIixcblx0XCJVdGlsZGVcIjogXCLFqFwiLFxuXHRcInV0aWxkZVwiOiBcIsWpXCIsXG5cdFwidXRyaVwiOiBcIuKWtVwiLFxuXHRcInV0cmlmXCI6IFwi4pa0XCIsXG5cdFwidXVhcnJcIjogXCLih4hcIixcblx0XCJVdW1sXCI6IFwiw5xcIixcblx0XCJ1dW1sXCI6IFwiw7xcIixcblx0XCJ1d2FuZ2xlXCI6IFwi4qanXCIsXG5cdFwidmFuZ3J0XCI6IFwi4qacXCIsXG5cdFwidmFyZXBzaWxvblwiOiBcIs+1XCIsXG5cdFwidmFya2FwcGFcIjogXCLPsFwiLFxuXHRcInZhcm5vdGhpbmdcIjogXCLiiIVcIixcblx0XCJ2YXJwaGlcIjogXCLPlVwiLFxuXHRcInZhcnBpXCI6IFwiz5ZcIixcblx0XCJ2YXJwcm9wdG9cIjogXCLiiJ1cIixcblx0XCJ2YXJyXCI6IFwi4oaVXCIsXG5cdFwidkFyclwiOiBcIuKHlVwiLFxuXHRcInZhcnJob1wiOiBcIs+xXCIsXG5cdFwidmFyc2lnbWFcIjogXCLPglwiLFxuXHRcInZhcnN1YnNldG5lcVwiOiBcIuKKiu+4gFwiLFxuXHRcInZhcnN1YnNldG5lcXFcIjogXCLiq4vvuIBcIixcblx0XCJ2YXJzdXBzZXRuZXFcIjogXCLiiovvuIBcIixcblx0XCJ2YXJzdXBzZXRuZXFxXCI6IFwi4quM77iAXCIsXG5cdFwidmFydGhldGFcIjogXCLPkVwiLFxuXHRcInZhcnRyaWFuZ2xlbGVmdFwiOiBcIuKKslwiLFxuXHRcInZhcnRyaWFuZ2xlcmlnaHRcIjogXCLiirNcIixcblx0XCJ2QmFyXCI6IFwi4quoXCIsXG5cdFwiVmJhclwiOiBcIuKrq1wiLFxuXHRcInZCYXJ2XCI6IFwi4qupXCIsXG5cdFwiVmN5XCI6IFwi0JJcIixcblx0XCJ2Y3lcIjogXCLQslwiLFxuXHRcInZkYXNoXCI6IFwi4oqiXCIsXG5cdFwidkRhc2hcIjogXCLiiqhcIixcblx0XCJWZGFzaFwiOiBcIuKKqVwiLFxuXHRcIlZEYXNoXCI6IFwi4oqrXCIsXG5cdFwiVmRhc2hsXCI6IFwi4qumXCIsXG5cdFwidmVlYmFyXCI6IFwi4oq7XCIsXG5cdFwidmVlXCI6IFwi4oioXCIsXG5cdFwiVmVlXCI6IFwi4ouBXCIsXG5cdFwidmVlZXFcIjogXCLiiZpcIixcblx0XCJ2ZWxsaXBcIjogXCLii65cIixcblx0XCJ2ZXJiYXJcIjogXCJ8XCIsXG5cdFwiVmVyYmFyXCI6IFwi4oCWXCIsXG5cdFwidmVydFwiOiBcInxcIixcblx0XCJWZXJ0XCI6IFwi4oCWXCIsXG5cdFwiVmVydGljYWxCYXJcIjogXCLiiKNcIixcblx0XCJWZXJ0aWNhbExpbmVcIjogXCJ8XCIsXG5cdFwiVmVydGljYWxTZXBhcmF0b3JcIjogXCLinZhcIixcblx0XCJWZXJ0aWNhbFRpbGRlXCI6IFwi4omAXCIsXG5cdFwiVmVyeVRoaW5TcGFjZVwiOiBcIuKAilwiLFxuXHRcIlZmclwiOiBcIvCdlJlcIixcblx0XCJ2ZnJcIjogXCLwnZSzXCIsXG5cdFwidmx0cmlcIjogXCLiirJcIixcblx0XCJ2bnN1YlwiOiBcIuKKguKDklwiLFxuXHRcInZuc3VwXCI6IFwi4oqD4oOSXCIsXG5cdFwiVm9wZlwiOiBcIvCdlY1cIixcblx0XCJ2b3BmXCI6IFwi8J2Vp1wiLFxuXHRcInZwcm9wXCI6IFwi4oidXCIsXG5cdFwidnJ0cmlcIjogXCLiirNcIixcblx0XCJWc2NyXCI6IFwi8J2SsVwiLFxuXHRcInZzY3JcIjogXCLwnZOLXCIsXG5cdFwidnN1Ym5FXCI6IFwi4quL77iAXCIsXG5cdFwidnN1Ym5lXCI6IFwi4oqK77iAXCIsXG5cdFwidnN1cG5FXCI6IFwi4quM77iAXCIsXG5cdFwidnN1cG5lXCI6IFwi4oqL77iAXCIsXG5cdFwiVnZkYXNoXCI6IFwi4oqqXCIsXG5cdFwidnppZ3phZ1wiOiBcIuKmmlwiLFxuXHRcIldjaXJjXCI6IFwixbRcIixcblx0XCJ3Y2lyY1wiOiBcIsW1XCIsXG5cdFwid2VkYmFyXCI6IFwi4qmfXCIsXG5cdFwid2VkZ2VcIjogXCLiiKdcIixcblx0XCJXZWRnZVwiOiBcIuKLgFwiLFxuXHRcIndlZGdlcVwiOiBcIuKJmVwiLFxuXHRcIndlaWVycFwiOiBcIuKEmFwiLFxuXHRcIldmclwiOiBcIvCdlJpcIixcblx0XCJ3ZnJcIjogXCLwnZS0XCIsXG5cdFwiV29wZlwiOiBcIvCdlY5cIixcblx0XCJ3b3BmXCI6IFwi8J2VqFwiLFxuXHRcIndwXCI6IFwi4oSYXCIsXG5cdFwid3JcIjogXCLiiYBcIixcblx0XCJ3cmVhdGhcIjogXCLiiYBcIixcblx0XCJXc2NyXCI6IFwi8J2SslwiLFxuXHRcIndzY3JcIjogXCLwnZOMXCIsXG5cdFwieGNhcFwiOiBcIuKLglwiLFxuXHRcInhjaXJjXCI6IFwi4pevXCIsXG5cdFwieGN1cFwiOiBcIuKLg1wiLFxuXHRcInhkdHJpXCI6IFwi4pa9XCIsXG5cdFwiWGZyXCI6IFwi8J2Um1wiLFxuXHRcInhmclwiOiBcIvCdlLVcIixcblx0XCJ4aGFyclwiOiBcIuKft1wiLFxuXHRcInhoQXJyXCI6IFwi4p+6XCIsXG5cdFwiWGlcIjogXCLOnlwiLFxuXHRcInhpXCI6IFwizr5cIixcblx0XCJ4bGFyclwiOiBcIuKftVwiLFxuXHRcInhsQXJyXCI6IFwi4p+4XCIsXG5cdFwieG1hcFwiOiBcIuKfvFwiLFxuXHRcInhuaXNcIjogXCLii7tcIixcblx0XCJ4b2RvdFwiOiBcIuKogFwiLFxuXHRcIlhvcGZcIjogXCLwnZWPXCIsXG5cdFwieG9wZlwiOiBcIvCdlalcIixcblx0XCJ4b3BsdXNcIjogXCLiqIFcIixcblx0XCJ4b3RpbWVcIjogXCLiqIJcIixcblx0XCJ4cmFyclwiOiBcIuKftlwiLFxuXHRcInhyQXJyXCI6IFwi4p+5XCIsXG5cdFwiWHNjclwiOiBcIvCdkrNcIixcblx0XCJ4c2NyXCI6IFwi8J2TjVwiLFxuXHRcInhzcWN1cFwiOiBcIuKohlwiLFxuXHRcInh1cGx1c1wiOiBcIuKohFwiLFxuXHRcInh1dHJpXCI6IFwi4pazXCIsXG5cdFwieHZlZVwiOiBcIuKLgVwiLFxuXHRcInh3ZWRnZVwiOiBcIuKLgFwiLFxuXHRcIllhY3V0ZVwiOiBcIsOdXCIsXG5cdFwieWFjdXRlXCI6IFwiw71cIixcblx0XCJZQWN5XCI6IFwi0K9cIixcblx0XCJ5YWN5XCI6IFwi0Y9cIixcblx0XCJZY2lyY1wiOiBcIsW2XCIsXG5cdFwieWNpcmNcIjogXCLFt1wiLFxuXHRcIlljeVwiOiBcItCrXCIsXG5cdFwieWN5XCI6IFwi0YtcIixcblx0XCJ5ZW5cIjogXCLCpVwiLFxuXHRcIllmclwiOiBcIvCdlJxcIixcblx0XCJ5ZnJcIjogXCLwnZS2XCIsXG5cdFwiWUljeVwiOiBcItCHXCIsXG5cdFwieWljeVwiOiBcItGXXCIsXG5cdFwiWW9wZlwiOiBcIvCdlZBcIixcblx0XCJ5b3BmXCI6IFwi8J2VqlwiLFxuXHRcIllzY3JcIjogXCLwnZK0XCIsXG5cdFwieXNjclwiOiBcIvCdk45cIixcblx0XCJZVWN5XCI6IFwi0K5cIixcblx0XCJ5dWN5XCI6IFwi0Y5cIixcblx0XCJ5dW1sXCI6IFwiw79cIixcblx0XCJZdW1sXCI6IFwixbhcIixcblx0XCJaYWN1dGVcIjogXCLFuVwiLFxuXHRcInphY3V0ZVwiOiBcIsW6XCIsXG5cdFwiWmNhcm9uXCI6IFwixb1cIixcblx0XCJ6Y2Fyb25cIjogXCLFvlwiLFxuXHRcIlpjeVwiOiBcItCXXCIsXG5cdFwiemN5XCI6IFwi0LdcIixcblx0XCJaZG90XCI6IFwixbtcIixcblx0XCJ6ZG90XCI6IFwixbxcIixcblx0XCJ6ZWV0cmZcIjogXCLihKhcIixcblx0XCJaZXJvV2lkdGhTcGFjZVwiOiBcIuKAi1wiLFxuXHRcIlpldGFcIjogXCLOllwiLFxuXHRcInpldGFcIjogXCLOtlwiLFxuXHRcInpmclwiOiBcIvCdlLdcIixcblx0XCJaZnJcIjogXCLihKhcIixcblx0XCJaSGN5XCI6IFwi0JZcIixcblx0XCJ6aGN5XCI6IFwi0LZcIixcblx0XCJ6aWdyYXJyXCI6IFwi4oedXCIsXG5cdFwiem9wZlwiOiBcIvCdlatcIixcblx0XCJab3BmXCI6IFwi4oSkXCIsXG5cdFwiWnNjclwiOiBcIvCdkrVcIixcblx0XCJ6c2NyXCI6IFwi8J2Tj1wiLFxuXHRcInp3alwiOiBcIuKAjVwiLFxuXHRcInp3bmpcIjogXCLigIxcIlxufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZW50aXRpZXMvbWFwcy9lbnRpdGllcy5qc29uXG4vLyBtb2R1bGUgaWQgPSAxOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHtcblx0XCJhbXBcIjogXCImXCIsXG5cdFwiYXBvc1wiOiBcIidcIixcblx0XCJndFwiOiBcIj5cIixcblx0XCJsdFwiOiBcIjxcIixcblx0XCJxdW90XCI6IFwiXFxcIlwiXG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9lbnRpdGllcy9tYXBzL3htbC5qc29uXG4vLyBtb2R1bGUgaWQgPSAxOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmlmICghcHJvY2Vzcy52ZXJzaW9uIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YwLicpID09PSAwIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLicpID09PSAwICYmIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS44LicpICE9PSAwKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gbmV4dFRpY2s7XG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IHByb2Nlc3MubmV4dFRpY2s7XG59XG5cbmZ1bmN0aW9uIG5leHRUaWNrKGZuLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImNhbGxiYWNrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cbiAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBhcmdzLCBpO1xuICBzd2l0Y2ggKGxlbikge1xuICBjYXNlIDA6XG4gIGNhc2UgMTpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbik7XG4gIGNhc2UgMjpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tPbmUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEpO1xuICAgIH0pO1xuICBjYXNlIDM6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVHdvKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyKTtcbiAgICB9KTtcbiAgY2FzZSA0OlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICB9KTtcbiAgZGVmYXVsdDpcbiAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgIGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYXJncy5sZW5ndGgpIHtcbiAgICAgIGFyZ3NbaSsrXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrKCkge1xuICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgfSk7XG4gIH1cbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9wcm9jZXNzLW5leHRpY2stYXJncy9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLCBEdXBsZXgpO1xuXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdGF0ZShzdHJlYW0pIHtcbiAgdGhpcy5hZnRlclRyYW5zZm9ybSA9IGZ1bmN0aW9uIChlciwgZGF0YSkge1xuICAgIHJldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKTtcbiAgfTtcblxuICB0aGlzLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgdGhpcy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcbiAgdGhpcy53cml0ZWNodW5rID0gbnVsbDtcbiAgdGhpcy53cml0ZWVuY29kaW5nID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSkge1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuICB0cy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcblxuICB2YXIgY2IgPSB0cy53cml0ZWNiO1xuXG4gIGlmICghY2IpIHJldHVybiBzdHJlYW0uZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ25vIHdyaXRlY2IgaW4gVHJhbnNmb3JtIGNsYXNzJykpO1xuXG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcblxuICBpZiAoZGF0YSAhPT0gbnVsbCAmJiBkYXRhICE9PSB1bmRlZmluZWQpIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIGNiKGVyKTtcblxuICB2YXIgcnMgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHJzLnJlYWRpbmcgPSBmYWxzZTtcbiAgaWYgKHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgc3RyZWFtLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59XG5cbmZ1bmN0aW9uIFRyYW5zZm9ybShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFuc2Zvcm0pKSByZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtcblxuICBEdXBsZXguY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZSA9IG5ldyBUcmFuc2Zvcm1TdGF0ZSh0aGlzKTtcblxuICB2YXIgc3RyZWFtID0gdGhpcztcblxuICAvLyBzdGFydCBvdXQgYXNraW5nIGZvciBhIHJlYWRhYmxlIGV2ZW50IG9uY2UgZGF0YSBpcyB0cmFuc2Zvcm1lZC5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIHdlIGhhdmUgaW1wbGVtZW50ZWQgdGhlIF9yZWFkIG1ldGhvZCwgYW5kIGRvbmUgdGhlIG90aGVyIHRoaW5nc1xuICAvLyB0aGF0IFJlYWRhYmxlIHdhbnRzIGJlZm9yZSB0aGUgZmlyc3QgX3JlYWQgY2FsbCwgc28gdW5zZXQgdGhlXG4gIC8vIHN5bmMgZ3VhcmQgZmxhZy5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtID09PSAnZnVuY3Rpb24nKSB0aGlzLl90cmFuc2Zvcm0gPSBvcHRpb25zLnRyYW5zZm9ybTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5mbHVzaCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmx1c2ggPSBvcHRpb25zLmZsdXNoO1xuICB9XG5cbiAgLy8gV2hlbiB0aGUgd3JpdGFibGUgc2lkZSBmaW5pc2hlcywgdGhlbiBmbHVzaCBvdXQgYW55dGhpbmcgcmVtYWluaW5nLlxuICB0aGlzLm9uY2UoJ3ByZWZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuX2ZsdXNoID09PSAnZnVuY3Rpb24nKSB0aGlzLl9mbHVzaChmdW5jdGlvbiAoZXIsIGRhdGEpIHtcbiAgICAgIGRvbmUoc3RyZWFtLCBlciwgZGF0YSk7XG4gICAgfSk7ZWxzZSBkb25lKHN0cmVhbSk7XG4gIH0pO1xufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgcmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIGNodW5rLCBlbmNvZGluZyk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBwYXJ0IHdoZXJlIHlvdSBkbyBzdHVmZiFcbi8vIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vICdjaHVuaycgaXMgYW4gaW5wdXQgY2h1bmsuXG4vL1xuLy8gQ2FsbCBgcHVzaChuZXdDaHVuaylgIHRvIHBhc3MgYWxvbmcgdHJhbnNmb3JtZWQgb3V0cHV0XG4vLyB0byB0aGUgcmVhZGFibGUgc2lkZS4gIFlvdSBtYXkgY2FsbCAncHVzaCcgemVybyBvciBtb3JlIHRpbWVzLlxuLy9cbi8vIENhbGwgYGNiKGVycilgIHdoZW4geW91IGFyZSBkb25lIHdpdGggdGhpcyBjaHVuay4gIElmIHlvdSBwYXNzXG4vLyBhbiBlcnJvciwgdGhlbiB0aGF0J2xsIHB1dCB0aGUgaHVydCBvbiB0aGUgd2hvbGUgb3BlcmF0aW9uLiAgSWYgeW91XG4vLyBuZXZlciBjYWxsIGNiKCksIHRoZW4geW91J2xsIG5ldmVyIGdldCBhbm90aGVyIGNodW5rLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdHJhbnNmb3JtKCkgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHwgcnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IHVuZGVmaW5lZCkgc3RyZWFtLnB1c2goZGF0YSk7XG5cbiAgLy8gaWYgdGhlcmUncyBub3RoaW5nIGluIHRoZSB3cml0ZSBidWZmZXIsIHRoZW4gdGhhdCBtZWFuc1xuICAvLyB0aGF0IG5vdGhpbmcgbW9yZSB3aWxsIGV2ZXIgYmUgcHJvdmlkZWRcbiAgdmFyIHdzID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuXG4gIGlmICh3cy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignQ2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHdzLmxlbmd0aCAhPSAwJyk7XG5cbiAgaWYgKHRzLnRyYW5zZm9ybWluZykgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gc3RpbGwgdHJhbnNmb3JtaW5nJyk7XG5cbiAgcmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXG4vLyBtb2R1bGUgaWQgPSAyMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBlbmNvZGluZywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBXcml0YWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgYXN5bmNXcml0ZSA9ICFwcm9jZXNzLmJyb3dzZXIgJiYgWyd2MC4xMCcsICd2MC45LiddLmluZGV4T2YocHJvY2Vzcy52ZXJzaW9uLnNsaWNlKDAsIDUpKSA+IC0xID8gc2V0SW1tZWRpYXRlIDogcHJvY2Vzc05leHRUaWNrO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbldyaXRhYmxlLldyaXRhYmxlU3RhdGUgPSBXcml0YWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgaW50ZXJuYWxVdGlsID0ge1xuICBkZXByZWNhdGU6IHJlcXVpcmUoJ3V0aWwtZGVwcmVjYXRlJylcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW07XG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIFN0cmVhbSA9IHJlcXVpcmUoJ3N0JyArICdyZWFtJyk7XG4gIH0gY2F0Y2ggKF8pIHt9IGZpbmFsbHkge1xuICAgIGlmICghU3RyZWFtKSBTdHJlYW0gPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG4gIH1cbn0pKCk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPHJlcGxhY2VtZW50PiovXG52YXIgYnVmZmVyU2hpbSA9IHJlcXVpcmUoJ2J1ZmZlci1zaGltcycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoV3JpdGFibGUsIFN0cmVhbSk7XG5cbmZ1bmN0aW9uIG5vcCgpIHt9XG5cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gV3JpdGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciBvciBub3QgdGhpcyBzdHJlYW1cbiAgLy8gY29udGFpbnMgYnVmZmVycyBvciBvYmplY3RzLlxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLndyaXRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggd3JpdGUoKSBzdGFydHMgcmV0dXJuaW5nIGZhbHNlXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgdGhhdCB3ZSBhbHdheXMgcmV0dXJuIGZhbHNlIGlmXG4gIC8vIHRoZSBlbnRpcmUgYnVmZmVyIGlzIG5vdCBmbHVzaGVkIGltbWVkaWF0ZWx5IG9uIHdyaXRlKClcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdmFyIGRlZmF1bHRId20gPSB0aGlzLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gaHdtIHx8IGh3bSA9PT0gMCA/IGh3bSA6IGRlZmF1bHRId207XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+fnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICAvLyBkcmFpbiBldmVudCBmbGFnLlxuICB0aGlzLm5lZWREcmFpbiA9IGZhbHNlO1xuICAvLyBhdCB0aGUgc3RhcnQgb2YgY2FsbGluZyBlbmQoKVxuICB0aGlzLmVuZGluZyA9IGZhbHNlO1xuICAvLyB3aGVuIGVuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIHJldHVybmVkXG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgLy8gd2hlbiAnZmluaXNoJyBpcyBlbWl0dGVkXG4gIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBzaG91bGQgd2UgZGVjb2RlIHN0cmluZ3MgaW50byBidWZmZXJzIGJlZm9yZSBwYXNzaW5nIHRvIF93cml0ZT9cbiAgLy8gdGhpcyBpcyBoZXJlIHNvIHRoYXQgc29tZSBub2RlLWNvcmUgc3RyZWFtcyBjYW4gb3B0aW1pemUgc3RyaW5nXG4gIC8vIGhhbmRsaW5nIGF0IGEgbG93ZXIgbGV2ZWwuXG4gIHZhciBub0RlY29kZSA9IG9wdGlvbnMuZGVjb2RlU3RyaW5ncyA9PT0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlU3RyaW5ncyA9ICFub0RlY29kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyBub3QgYW4gYWN0dWFsIGJ1ZmZlciB3ZSBrZWVwIHRyYWNrIG9mLCBidXQgYSBtZWFzdXJlbWVudFxuICAvLyBvZiBob3cgbXVjaCB3ZSdyZSB3YWl0aW5nIHRvIGdldCBwdXNoZWQgdG8gc29tZSB1bmRlcmx5aW5nXG4gIC8vIHNvY2tldCBvciBmaWxlLlxuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIHNlZSB3aGVuIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSB3cml0ZS5cbiAgdGhpcy53cml0aW5nID0gZmFsc2U7XG5cbiAgLy8gd2hlbiB0cnVlIGFsbCB3cml0ZXMgd2lsbCBiZSBidWZmZXJlZCB1bnRpbCAudW5jb3JrKCkgY2FsbFxuICB0aGlzLmNvcmtlZCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gYSBmbGFnIHRvIGtub3cgaWYgd2UncmUgcHJvY2Vzc2luZyBwcmV2aW91c2x5IGJ1ZmZlcmVkIGl0ZW1zLCB3aGljaFxuICAvLyBtYXkgY2FsbCB0aGUgX3dyaXRlKCkgY2FsbGJhY2sgaW4gdGhlIHNhbWUgdGljaywgc28gdGhhdCB3ZSBkb24ndFxuICAvLyBlbmQgdXAgaW4gYW4gb3ZlcmxhcHBlZCBvbndyaXRlIHNpdHVhdGlvbi5cbiAgdGhpcy5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQncyBwYXNzZWQgdG8gX3dyaXRlKGNodW5rLGNiKVxuICB0aGlzLm9ud3JpdGUgPSBmdW5jdGlvbiAoZXIpIHtcbiAgICBvbndyaXRlKHN0cmVhbSwgZXIpO1xuICB9O1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0IHRoZSB1c2VyIHN1cHBsaWVzIHRvIHdyaXRlKGNodW5rLGVuY29kaW5nLGNiKVxuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuXG4gIC8vIHRoZSBhbW91bnQgdGhhdCBpcyBiZWluZyB3cml0dGVuIHdoZW4gX3dyaXRlIGlzIGNhbGxlZC5cbiAgdGhpcy53cml0ZWxlbiA9IDA7XG5cbiAgdGhpcy5idWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB0aGlzLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuXG4gIC8vIG51bWJlciBvZiBwZW5kaW5nIHVzZXItc3VwcGxpZWQgd3JpdGUgY2FsbGJhY2tzXG4gIC8vIHRoaXMgbXVzdCBiZSAwIGJlZm9yZSAnZmluaXNoJyBjYW4gYmUgZW1pdHRlZFxuICB0aGlzLnBlbmRpbmdjYiA9IDA7XG5cbiAgLy8gZW1pdCBwcmVmaW5pc2ggaWYgdGhlIG9ubHkgdGhpbmcgd2UncmUgd2FpdGluZyBmb3IgaXMgX3dyaXRlIGNic1xuICAvLyBUaGlzIGlzIHJlbGV2YW50IGZvciBzeW5jaHJvbm91cyBUcmFuc2Zvcm0gc3RyZWFtc1xuICB0aGlzLnByZWZpbmlzaGVkID0gZmFsc2U7XG5cbiAgLy8gVHJ1ZSBpZiB0aGUgZXJyb3Igd2FzIGFscmVhZHkgZW1pdHRlZCBhbmQgc2hvdWxkIG5vdCBiZSB0aHJvd24gYWdhaW5cbiAgdGhpcy5lcnJvckVtaXR0ZWQgPSBmYWxzZTtcblxuICAvLyBjb3VudCBidWZmZXJlZCByZXF1ZXN0c1xuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcblxuICAvLyBhbGxvY2F0ZSB0aGUgZmlyc3QgQ29ya2VkUmVxdWVzdCwgdGhlcmUgaXMgYWx3YXlzXG4gIC8vIG9uZSBhbGxvY2F0ZWQgYW5kIGZyZWUgdG8gdXNlLCBhbmQgd2UgbWFpbnRhaW4gYXQgbW9zdCB0d29cbiAgdGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdCh0aGlzKTtcbn1cblxuV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24gZ2V0QnVmZmVyKCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyZWRSZXF1ZXN0O1xuICB2YXIgb3V0ID0gW107XG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgb3V0LnB1c2goY3VycmVudCk7XG4gICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsICdidWZmZXInLCB7XG4gICAgICBnZXQ6IGludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRCdWZmZXIoKTtcbiAgICAgIH0sICdfd3JpdGFibGVTdGF0ZS5idWZmZXIgaXMgZGVwcmVjYXRlZC4gVXNlIF93cml0YWJsZVN0YXRlLmdldEJ1ZmZlciAnICsgJ2luc3RlYWQuJylcbiAgICB9KTtcbiAgfSBjYXRjaCAoXykge31cbn0pKCk7XG5cbi8vIFRlc3QgX3dyaXRhYmxlU3RhdGUgZm9yIGluaGVyaXRhbmNlIHRvIGFjY291bnQgZm9yIER1cGxleCBzdHJlYW1zLFxuLy8gd2hvc2UgcHJvdG90eXBlIGNoYWluIG9ubHkgcG9pbnRzIHRvIFJlYWRhYmxlLlxudmFyIHJlYWxIYXNJbnN0YW5jZTtcbmlmICh0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIFN5bWJvbC5oYXNJbnN0YW5jZSAmJiB0eXBlb2YgRnVuY3Rpb24ucHJvdG90eXBlW1N5bWJvbC5oYXNJbnN0YW5jZV0gPT09ICdmdW5jdGlvbicpIHtcbiAgcmVhbEhhc0luc3RhbmNlID0gRnVuY3Rpb24ucHJvdG90eXBlW1N5bWJvbC5oYXNJbnN0YW5jZV07XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZSwgU3ltYm9sLmhhc0luc3RhbmNlLCB7XG4gICAgdmFsdWU6IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgIGlmIChyZWFsSGFzSW5zdGFuY2UuY2FsbCh0aGlzLCBvYmplY3QpKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgcmV0dXJuIG9iamVjdCAmJiBvYmplY3QuX3dyaXRhYmxlU3RhdGUgaW5zdGFuY2VvZiBXcml0YWJsZVN0YXRlO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICByZWFsSGFzSW5zdGFuY2UgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIHRoaXM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRvby5cbiAgLy8gYHJlYWxIYXNJbnN0YW5jZWAgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdXNpbmcgcGxhaW4gYGluc3RhbmNlb2ZgXG4gIC8vIHdvdWxkIHJldHVybiBmYWxzZSwgYXMgbm8gYF93cml0YWJsZVN0YXRlYCBwcm9wZXJ0eSBpcyBhdHRhY2hlZC5cblxuICAvLyBUcnlpbmcgdG8gdXNlIHRoZSBjdXN0b20gYGluc3RhbmNlb2ZgIGZvciBXcml0YWJsZSBoZXJlIHdpbGwgYWxzbyBicmVhayB0aGVcbiAgLy8gTm9kZS5qcyBMYXp5VHJhbnNmb3JtIGltcGxlbWVudGF0aW9uLCB3aGljaCBoYXMgYSBub24tdHJpdmlhbCBnZXR0ZXIgZm9yXG4gIC8vIGBfd3JpdGFibGVTdGF0ZWAgdGhhdCB3b3VsZCBsZWFkIHRvIGluZmluaXRlIHJlY3Vyc2lvbi5cbiAgaWYgKCFyZWFsSGFzSW5zdGFuY2UuY2FsbChXcml0YWJsZSwgdGhpcykgJiYgISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSkge1xuICAgIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG4gIH1cblxuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGUgPSBvcHRpb25zLndyaXRlO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gT3RoZXJ3aXNlIHBlb3BsZSBjYW4gcGlwZSBXcml0YWJsZSBzdHJlYW1zLCB3aGljaCBpcyBqdXN0IHdyb25nLlxuV3JpdGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0Nhbm5vdCBwaXBlLCBub3QgcmVhZGFibGUnKSk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUFmdGVyRW5kKHN0cmVhbSwgY2IpIHtcbiAgdmFyIGVyID0gbmV3IEVycm9yKCd3cml0ZSBhZnRlciBlbmQnKTtcbiAgLy8gVE9ETzogZGVmZXIgZXJyb3IgZXZlbnRzIGNvbnNpc3RlbnRseSBldmVyeXdoZXJlLCBub3QganVzdCB0aGUgY2JcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtcbn1cblxuLy8gQ2hlY2tzIHRoYXQgYSB1c2VyLXN1cHBsaWVkIGNodW5rIGlzIHZhbGlkLCBlc3BlY2lhbGx5IGZvciB0aGUgcGFydGljdWxhclxuLy8gbW9kZSB0aGUgc3RyZWFtIGlzIGluLiBDdXJyZW50bHkgdGhpcyBtZWFucyB0aGF0IGBudWxsYCBpcyBuZXZlciBhY2NlcHRlZFxuLy8gYW5kIHVuZGVmaW5lZC9ub24tc3RyaW5nIHZhbHVlcyBhcmUgb25seSBhbGxvd2VkIGluIG9iamVjdCBtb2RlLlxuZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgY2IpIHtcbiAgdmFyIHZhbGlkID0gdHJ1ZTtcbiAgdmFyIGVyID0gZmFsc2U7XG5cbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdNYXkgbm90IHdyaXRlIG51bGwgdmFsdWVzIHRvIHN0cmVhbScpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICB9XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgICBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtcbiAgICB2YWxpZCA9IGZhbHNlO1xuICB9XG4gIHJldHVybiB2YWxpZDtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHJldCA9IGZhbHNlO1xuICB2YXIgaXNCdWYgPSBCdWZmZXIuaXNCdWZmZXIoY2h1bmspO1xuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChpc0J1ZikgZW5jb2RpbmcgPSAnYnVmZmVyJztlbHNlIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIGNiID0gbm9wO1xuXG4gIGlmIChzdGF0ZS5lbmRlZCkgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7ZWxzZSBpZiAoaXNCdWYgfHwgdmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGlzQnVmLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBzdGF0ZS5jb3JrZWQrKztcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS51bmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZC0tO1xuXG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCkgY2xlYXJCdWZmZXIodGhpcywgc3RhdGUpO1xuICB9XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuc2V0RGVmYXVsdEVuY29kaW5nID0gZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIC8vIG5vZGU6OlBhcnNlRW5jb2RpbmcoKSByZXF1aXJlcyBsb3dlciBjYXNlLlxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIShbJ2hleCcsICd1dGY4JywgJ3V0Zi04JywgJ2FzY2lpJywgJ2JpbmFyeScsICdiYXNlNjQnLCAndWNzMicsICd1Y3MtMicsICd1dGYxNmxlJywgJ3V0Zi0xNmxlJywgJ3JhdyddLmluZGV4T2YoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpID4gLTEpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmRlZmF1bHRFbmNvZGluZyA9IGVuY29kaW5nO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHN0YXRlLmRlY29kZVN0cmluZ3MgIT09IGZhbHNlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IGJ1ZmZlclNoaW0uZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICB9XG4gIHJldHVybiBjaHVuaztcbn1cblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgaWYgKCFpc0J1Zikge1xuICAgIGNodW5rID0gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZyk7XG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gIH1cbiAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gIHN0YXRlLmxlbmd0aCArPSBsZW47XG5cbiAgdmFyIHJldCA9IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIC8vIHdlIG11c3QgZW5zdXJlIHRoYXQgcHJldmlvdXMgbmVlZERyYWluIHdpbGwgbm90IGJlIHJlc2V0IHRvIGZhbHNlLlxuICBpZiAoIXJldCkgc3RhdGUubmVlZERyYWluID0gdHJ1ZTtcblxuICBpZiAoc3RhdGUud3JpdGluZyB8fCBzdGF0ZS5jb3JrZWQpIHtcbiAgICB2YXIgbGFzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG5ldyBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICBpZiAobGFzdCkge1xuICAgICAgbGFzdC5uZXh0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgKz0gMTtcbiAgfSBlbHNlIHtcbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB3cml0ZXYsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBzdGF0ZS53cml0ZWxlbiA9IGxlbjtcbiAgc3RhdGUud3JpdGVjYiA9IGNiO1xuICBzdGF0ZS53cml0aW5nID0gdHJ1ZTtcbiAgc3RhdGUuc3luYyA9IHRydWU7XG4gIGlmICh3cml0ZXYpIHN0cmVhbS5fd3JpdGV2KGNodW5rLCBzdGF0ZS5vbndyaXRlKTtlbHNlIHN0cmVhbS5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBzdGF0ZS5vbndyaXRlKTtcbiAgc3RhdGUuc3luYyA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKSB7XG4gIC0tc3RhdGUucGVuZGluZ2NiO1xuICBpZiAoc3luYykgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7ZWxzZSBjYihlcik7XG5cbiAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbn1cblxuZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKSB7XG4gIHN0YXRlLndyaXRpbmcgPSBmYWxzZTtcbiAgc3RhdGUud3JpdGVjYiA9IG51bGw7XG4gIHN0YXRlLmxlbmd0aCAtPSBzdGF0ZS53cml0ZWxlbjtcbiAgc3RhdGUud3JpdGVsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlKHN0cmVhbSwgZXIpIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgc3luYyA9IHN0YXRlLnN5bmM7XG4gIHZhciBjYiA9IHN0YXRlLndyaXRlY2I7XG5cbiAgb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKTtcblxuICBpZiAoZXIpIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO2Vsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG5cbiAgICBpZiAoIWZpbmlzaGVkICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSB7XG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG5cbiAgICBpZiAoc3luYykge1xuICAgICAgLyo8cmVwbGFjZW1lbnQ+Ki9cbiAgICAgIGFzeW5jV3JpdGUoYWZ0ZXJXcml0ZSwgc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICAgIC8qPC9yZXBsYWNlbWVudD4qL1xuICAgIH0gZWxzZSB7XG4gICAgICBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKSB7XG4gIGlmICghZmluaXNoZWQpIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKTtcbiAgc3RhdGUucGVuZGluZ2NiLS07XG4gIGNiKCk7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xufVxuXG4vLyBNdXN0IGZvcmNlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBvbiBuZXh0VGljaywgc28gdGhhdCB3ZSBkb24ndFxuLy8gZW1pdCAnZHJhaW4nIGJlZm9yZSB0aGUgd3JpdGUoKSBjb25zdW1lciBnZXRzIHRoZSAnZmFsc2UnIHJldHVyblxuLy8gdmFsdWUsIGFuZCBoYXMgYSBjaGFuY2UgdG8gYXR0YWNoIGEgJ2RyYWluJyBsaXN0ZW5lci5cbmZ1bmN0aW9uIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUubmVlZERyYWluKSB7XG4gICAgc3RhdGUubmVlZERyYWluID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2RyYWluJyk7XG4gIH1cbn1cblxuLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGJ1ZmZlciB3YWl0aW5nLCB0aGVuIHByb2Nlc3MgaXRcbmZ1bmN0aW9uIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IHRydWU7XG4gIHZhciBlbnRyeSA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdDtcblxuICBpZiAoc3RyZWFtLl93cml0ZXYgJiYgZW50cnkgJiYgZW50cnkubmV4dCkge1xuICAgIC8vIEZhc3QgY2FzZSwgd3JpdGUgZXZlcnl0aGluZyB1c2luZyBfd3JpdGV2KClcbiAgICB2YXIgbCA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50O1xuICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXkobCk7XG4gICAgdmFyIGhvbGRlciA9IHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZTtcbiAgICBob2xkZXIuZW50cnkgPSBlbnRyeTtcblxuICAgIHZhciBjb3VudCA9IDA7XG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICBidWZmZXJbY291bnRdID0gZW50cnk7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICBjb3VudCArPSAxO1xuICAgIH1cblxuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgdHJ1ZSwgc3RhdGUubGVuZ3RoLCBidWZmZXIsICcnLCBob2xkZXIuZmluaXNoKTtcblxuICAgIC8vIGRvV3JpdGUgaXMgYWxtb3N0IGFsd2F5cyBhc3luYywgZGVmZXIgdGhlc2UgdG8gc2F2ZSBhIGJpdCBvZiB0aW1lXG4gICAgLy8gYXMgdGhlIGhvdCBwYXRoIGVuZHMgd2l0aCBkb1dyaXRlXG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gICAgaWYgKGhvbGRlci5uZXh0KSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBob2xkZXIubmV4dDtcbiAgICAgIGhvbGRlci5uZXh0ID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gbmV3IENvcmtlZFJlcXVlc3Qoc3RhdGUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBTbG93IGNhc2UsIHdyaXRlIGNodW5rcyBvbmUtYnktb25lXG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICB2YXIgY2h1bmsgPSBlbnRyeS5jaHVuaztcbiAgICAgIHZhciBlbmNvZGluZyA9IGVudHJ5LmVuY29kaW5nO1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5ID09PSBudWxsKSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcbiAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gZW50cnk7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG5ldyBFcnJvcignX3dyaXRlKCkgaXMgbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZXYgPSBudWxsO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQpIHRoaXMud3JpdGUoY2h1bmssIGVuY29kaW5nKTtcblxuICAvLyAuZW5kKCkgZnVsbHkgdW5jb3Jrc1xuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkID0gMTtcbiAgICB0aGlzLnVuY29yaygpO1xuICB9XG5cbiAgLy8gaWdub3JlIHVubmVjZXNzYXJ5IGVuZCgpIGNhbGxzLlxuICBpZiAoIXN0YXRlLmVuZGluZyAmJiAhc3RhdGUuZmluaXNoZWQpIGVuZFdyaXRhYmxlKHRoaXMsIHN0YXRlLCBjYik7XG59O1xuXG5mdW5jdGlvbiBuZWVkRmluaXNoKHN0YXRlKSB7XG4gIHJldHVybiBzdGF0ZS5lbmRpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9PT0gbnVsbCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLndyaXRpbmc7XG59XG5cbmZ1bmN0aW9uIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucHJlZmluaXNoZWQpIHtcbiAgICBzdGF0ZS5wcmVmaW5pc2hlZCA9IHRydWU7XG4gICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIG5lZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcbiAgaWYgKG5lZWQpIHtcbiAgICBpZiAoc3RhdGUucGVuZGluZ2NiID09PSAwKSB7XG4gICAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgICBzdGF0ZS5maW5pc2hlZCA9IHRydWU7XG4gICAgICBzdHJlYW0uZW1pdCgnZmluaXNoJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpIHByb2Nlc3NOZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgc3RyZWFtLndyaXRhYmxlID0gZmFsc2U7XG59XG5cbi8vIEl0IHNlZW1zIGEgbGlua2VkIGxpc3QgYnV0IGl0IGlzIG5vdFxuLy8gdGhlcmUgd2lsbCBiZSBvbmx5IDIgb2YgdGhlc2UgZm9yIGVhY2ggc3RyZWFtXG5mdW5jdGlvbiBDb3JrZWRSZXF1ZXN0KHN0YXRlKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdGhpcy5uZXh0ID0gbnVsbDtcbiAgdGhpcy5lbnRyeSA9IG51bGw7XG4gIHRoaXMuZmluaXNoID0gZnVuY3Rpb24gKGVycikge1xuICAgIHZhciBlbnRyeSA9IF90aGlzLmVudHJ5O1xuICAgIF90aGlzLmVudHJ5ID0gbnVsbDtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgICBjYihlcnIpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgIH1cbiAgICBpZiAoc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlKSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IF90aGlzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBfdGhpcztcbiAgICB9XG4gIH07XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qc1xuLy8gbW9kdWxlIGlkID0gMjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnZhciBpc0J1ZmZlckVuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmdcbiAgfHwgZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgICAgICBzd2l0Y2ggKGVuY29kaW5nICYmIGVuY29kaW5nLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgIGNhc2UgJ2hleCc6IGNhc2UgJ3V0ZjgnOiBjYXNlICd1dGYtOCc6IGNhc2UgJ2FzY2lpJzogY2FzZSAnYmluYXJ5JzogY2FzZSAnYmFzZTY0JzogY2FzZSAndWNzMic6IGNhc2UgJ3Vjcy0yJzogY2FzZSAndXRmMTZsZSc6IGNhc2UgJ3V0Zi0xNmxlJzogY2FzZSAncmF3JzogcmV0dXJuIHRydWU7XG4gICAgICAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2U7XG4gICAgICAgfVxuICAgICB9XG5cblxuZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgaWYgKGVuY29kaW5nICYmICFpc0J1ZmZlckVuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKTtcbiAgfVxufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuIENFU1UtOCBpcyBoYW5kbGVkIGFzIHBhcnQgb2YgdGhlIFVURi04IGVuY29kaW5nLlxuLy9cbi8vIEBUT0RPIEhhbmRsaW5nIGFsbCBlbmNvZGluZ3MgaW5zaWRlIGEgc2luZ2xlIG9iamVjdCBtYWtlcyBpdCB2ZXJ5IGRpZmZpY3VsdFxuLy8gdG8gcmVhc29uIGFib3V0IHRoaXMgY29kZSwgc28gaXQgc2hvdWxkIGJlIHNwbGl0IHVwIGluIHRoZSBmdXR1cmUuXG4vLyBAVE9ETyBUaGVyZSBzaG91bGQgYmUgYSB1dGY4LXN0cmljdCBlbmNvZGluZyB0aGF0IHJlamVjdHMgaW52YWxpZCBVVEYtOCBjb2RlXG4vLyBwb2ludHMgYXMgdXNlZCBieSBDRVNVLTguXG52YXIgU3RyaW5nRGVjb2RlciA9IGV4cG9ydHMuU3RyaW5nRGVjb2RlciA9IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gIHRoaXMuZW5jb2RpbmcgPSAoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1stX10vLCAnJyk7XG4gIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKTtcbiAgc3dpdGNoICh0aGlzLmVuY29kaW5nKSB7XG4gICAgY2FzZSAndXRmOCc6XG4gICAgICAvLyBDRVNVLTggcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDMtYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDM7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIC8vIFVURi0xNiByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMi1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMjtcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIC8vIEJhc2UtNjQgc3RvcmVzIDMgYnl0ZXMgaW4gNCBjaGFycywgYW5kIHBhZHMgdGhlIHJlbWFpbmRlci5cbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDM7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHBhc3NUaHJvdWdoV3JpdGU7XG4gICAgICByZXR1cm47XG4gIH1cblxuICAvLyBFbm91Z2ggc3BhY2UgdG8gc3RvcmUgYWxsIGJ5dGVzIG9mIGEgc2luZ2xlIGNoYXJhY3Rlci4gVVRGLTggbmVlZHMgNFxuICAvLyBieXRlcywgYnV0IENFU1UtOCBtYXkgcmVxdWlyZSB1cCB0byA2ICgzIGJ5dGVzIHBlciBzdXJyb2dhdGUpLlxuICB0aGlzLmNoYXJCdWZmZXIgPSBuZXcgQnVmZmVyKDYpO1xuICAvLyBOdW1iZXIgb2YgYnl0ZXMgcmVjZWl2ZWQgZm9yIHRoZSBjdXJyZW50IGluY29tcGxldGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuXG4gIHRoaXMuY2hhclJlY2VpdmVkID0gMDtcbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIGV4cGVjdGVkIGZvciB0aGUgY3VycmVudCBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgY2hhcmFjdGVyLlxuICB0aGlzLmNoYXJMZW5ndGggPSAwO1xufTtcblxuXG4vLyB3cml0ZSBkZWNvZGVzIHRoZSBnaXZlbiBidWZmZXIgYW5kIHJldHVybnMgaXQgYXMgSlMgc3RyaW5nIHRoYXQgaXNcbi8vIGd1YXJhbnRlZWQgdG8gbm90IGNvbnRhaW4gYW55IHBhcnRpYWwgbXVsdGktYnl0ZSBjaGFyYWN0ZXJzLiBBbnkgcGFydGlhbFxuLy8gY2hhcmFjdGVyIGZvdW5kIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciBpcyBidWZmZXJlZCB1cCwgYW5kIHdpbGwgYmVcbi8vIHJldHVybmVkIHdoZW4gY2FsbGluZyB3cml0ZSBhZ2FpbiB3aXRoIHRoZSByZW1haW5pbmcgYnl0ZXMuXG4vL1xuLy8gTm90ZTogQ29udmVydGluZyBhIEJ1ZmZlciBjb250YWluaW5nIGFuIG9ycGhhbiBzdXJyb2dhdGUgdG8gYSBTdHJpbmdcbi8vIGN1cnJlbnRseSB3b3JrcywgYnV0IGNvbnZlcnRpbmcgYSBTdHJpbmcgdG8gYSBCdWZmZXIgKHZpYSBgbmV3IEJ1ZmZlcmAsIG9yXG4vLyBCdWZmZXIjd3JpdGUpIHdpbGwgcmVwbGFjZSBpbmNvbXBsZXRlIHN1cnJvZ2F0ZXMgd2l0aCB0aGUgdW5pY29kZVxuLy8gcmVwbGFjZW1lbnQgY2hhcmFjdGVyLiBTZWUgaHR0cHM6Ly9jb2RlcmV2aWV3LmNocm9taXVtLm9yZy8xMjExNzMwMDkvIC5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIHZhciBjaGFyU3RyID0gJyc7XG4gIC8vIGlmIG91ciBsYXN0IHdyaXRlIGVuZGVkIHdpdGggYW4gaW5jb21wbGV0ZSBtdWx0aWJ5dGUgY2hhcmFjdGVyXG4gIHdoaWxlICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgcmVtYWluaW5nIGJ5dGVzIHRoaXMgYnVmZmVyIGhhcyB0byBvZmZlciBmb3IgdGhpcyBjaGFyXG4gICAgdmFyIGF2YWlsYWJsZSA9IChidWZmZXIubGVuZ3RoID49IHRoaXMuY2hhckxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkKSA/XG4gICAgICAgIHRoaXMuY2hhckxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkIDpcbiAgICAgICAgYnVmZmVyLmxlbmd0aDtcblxuICAgIC8vIGFkZCB0aGUgbmV3IGJ5dGVzIHRvIHRoZSBjaGFyIGJ1ZmZlclxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgdGhpcy5jaGFyUmVjZWl2ZWQsIDAsIGF2YWlsYWJsZSk7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gYXZhaWxhYmxlO1xuXG4gICAgaWYgKHRoaXMuY2hhclJlY2VpdmVkIDwgdGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgICAvLyBzdGlsbCBub3QgZW5vdWdoIGNoYXJzIGluIHRoaXMgYnVmZmVyPyB3YWl0IGZvciBtb3JlIC4uLlxuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSBieXRlcyBiZWxvbmdpbmcgdG8gdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGZyb20gdGhlIGJ1ZmZlclxuICAgIGJ1ZmZlciA9IGJ1ZmZlci5zbGljZShhdmFpbGFibGUsIGJ1ZmZlci5sZW5ndGgpO1xuXG4gICAgLy8gZ2V0IHRoZSBjaGFyYWN0ZXIgdGhhdCB3YXMgc3BsaXRcbiAgICBjaGFyU3RyID0gdGhpcy5jaGFyQnVmZmVyLnNsaWNlKDAsIHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG5cbiAgICAvLyBDRVNVLTg6IGxlYWQgc3Vycm9nYXRlIChEODAwLURCRkYpIGlzIGFsc28gdGhlIGluY29tcGxldGUgY2hhcmFjdGVyXG4gICAgdmFyIGNoYXJDb2RlID0gY2hhclN0ci5jaGFyQ29kZUF0KGNoYXJTdHIubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCArPSB0aGlzLnN1cnJvZ2F0ZVNpemU7XG4gICAgICBjaGFyU3RyID0gJyc7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgPSB0aGlzLmNoYXJMZW5ndGggPSAwO1xuXG4gICAgLy8gaWYgdGhlcmUgYXJlIG5vIG1vcmUgYnl0ZXMgaW4gdGhpcyBidWZmZXIsIGp1c3QgZW1pdCBvdXIgY2hhclxuICAgIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY2hhclN0cjtcbiAgICB9XG4gICAgYnJlYWs7XG4gIH1cblxuICAvLyBkZXRlcm1pbmUgYW5kIHNldCBjaGFyTGVuZ3RoIC8gY2hhclJlY2VpdmVkXG4gIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKTtcblxuICB2YXIgZW5kID0gYnVmZmVyLmxlbmd0aDtcbiAgaWYgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGJ1ZmZlciB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgYnl0ZXMgd2UgZ290XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQsIGVuZCk7XG4gICAgZW5kIC09IHRoaXMuY2hhclJlY2VpdmVkO1xuICB9XG5cbiAgY2hhclN0ciArPSBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgZW5kKTtcblxuICB2YXIgZW5kID0gY2hhclN0ci5sZW5ndGggLSAxO1xuICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoZW5kKTtcbiAgLy8gQ0VTVS04OiBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgIHZhciBzaXplID0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgIHRoaXMuY2hhckxlbmd0aCArPSBzaXplO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IHNpemU7XG4gICAgdGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCBzaXplLCAwLCBzaXplKTtcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIDAsIDAsIHNpemUpO1xuICAgIHJldHVybiBjaGFyU3RyLnN1YnN0cmluZygwLCBlbmQpO1xuICB9XG5cbiAgLy8gb3IganVzdCBlbWl0IHRoZSBjaGFyU3RyXG4gIHJldHVybiBjaGFyU3RyO1xufTtcblxuLy8gZGV0ZWN0SW5jb21wbGV0ZUNoYXIgZGV0ZXJtaW5lcyBpZiB0aGVyZSBpcyBhbiBpbmNvbXBsZXRlIFVURi04IGNoYXJhY3RlciBhdFxuLy8gdGhlIGVuZCBvZiB0aGUgZ2l2ZW4gYnVmZmVyLiBJZiBzbywgaXQgc2V0cyB0aGlzLmNoYXJMZW5ndGggdG8gdGhlIGJ5dGVcbi8vIGxlbmd0aCB0aGF0IGNoYXJhY3RlciwgYW5kIHNldHMgdGhpcy5jaGFyUmVjZWl2ZWQgdG8gdGhlIG51bWJlciBvZiBieXRlc1xuLy8gdGhhdCBhcmUgYXZhaWxhYmxlIGZvciB0aGlzIGNoYXJhY3Rlci5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmRldGVjdEluY29tcGxldGVDaGFyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIC8vIGRldGVybWluZSBob3cgbWFueSBieXRlcyB3ZSBoYXZlIHRvIGNoZWNrIGF0IHRoZSBlbmQgb2YgdGhpcyBidWZmZXJcbiAgdmFyIGkgPSAoYnVmZmVyLmxlbmd0aCA+PSAzKSA/IDMgOiBidWZmZXIubGVuZ3RoO1xuXG4gIC8vIEZpZ3VyZSBvdXQgaWYgb25lIG9mIHRoZSBsYXN0IGkgYnl0ZXMgb2Ygb3VyIGJ1ZmZlciBhbm5vdW5jZXMgYW5cbiAgLy8gaW5jb21wbGV0ZSBjaGFyLlxuICBmb3IgKDsgaSA+IDA7IGktLSkge1xuICAgIHZhciBjID0gYnVmZmVyW2J1ZmZlci5sZW5ndGggLSBpXTtcblxuICAgIC8vIFNlZSBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VURi04I0Rlc2NyaXB0aW9uXG5cbiAgICAvLyAxMTBYWFhYWFxuICAgIGlmIChpID09IDEgJiYgYyA+PiA1ID09IDB4MDYpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDI7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyAxMTEwWFhYWFxuICAgIGlmIChpIDw9IDIgJiYgYyA+PiA0ID09IDB4MEUpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDM7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyAxMTExMFhYWFxuICAgIGlmIChpIDw9IDMgJiYgYyA+PiAzID09IDB4MUUpIHtcbiAgICAgIHRoaXMuY2hhckxlbmd0aCA9IDQ7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBpO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIHZhciByZXMgPSAnJztcbiAgaWYgKGJ1ZmZlciAmJiBidWZmZXIubGVuZ3RoKVxuICAgIHJlcyA9IHRoaXMud3JpdGUoYnVmZmVyKTtcblxuICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQpIHtcbiAgICB2YXIgY3IgPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgICB2YXIgYnVmID0gdGhpcy5jaGFyQnVmZmVyO1xuICAgIHZhciBlbmMgPSB0aGlzLmVuY29kaW5nO1xuICAgIHJlcyArPSBidWYuc2xpY2UoMCwgY3IpLnRvU3RyaW5nKGVuYyk7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gcGFzc1Rocm91Z2hXcml0ZShidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBidWZmZXIubGVuZ3RoICUgMjtcbiAgdGhpcy5jaGFyTGVuZ3RoID0gdGhpcy5jaGFyUmVjZWl2ZWQgPyAyIDogMDtcbn1cblxuZnVuY3Rpb24gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKSB7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDM7XG4gIHRoaXMuY2hhckxlbmd0aCA9IHRoaXMuY2hhclJlY2VpdmVkID8gMyA6IDA7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vc3RyaW5nX2RlY29kZXIvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDIzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcIl9cIlxuLy8gbW9kdWxlIGlkID0gMjRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPVxyXG4vKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXHJcbi8qKioqKiovIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxyXG4vKioqKioqLyBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cclxuLyoqKioqKi8gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcclxuLyoqKioqKi8gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XHJcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xyXG4vKioqKioqLyBcdFx0fVxyXG4vKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcclxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcclxuLyoqKioqKi8gXHRcdFx0aTogbW9kdWxlSWQsXHJcbi8qKioqKiovIFx0XHRcdGw6IGZhbHNlLFxyXG4vKioqKioqLyBcdFx0XHRleHBvcnRzOiB7fVxyXG4vKioqKioqLyBcdFx0fTtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxyXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXHJcbi8qKioqKiovIFx0XHRtb2R1bGUubCA9IHRydWU7XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxyXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xyXG4vKioqKioqLyBcdH1cclxuLyoqKioqKi9cclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxyXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcclxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xyXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xyXG4vKioqKioqLyBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xyXG4vKioqKioqLyBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGdldHRlciB9KTtcclxuLyoqKioqKi8gXHRcdH1cclxuLyoqKioqKi8gXHR9O1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcclxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XHJcbi8qKioqKiovIFx0XHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcclxuLyoqKioqKi8gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XHJcbi8qKioqKiovIFx0XHR9XHJcbi8qKioqKiovIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vKioqKioqLyBcdH07XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0Ly8gY3JlYXRlIGEgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0XHJcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XHJcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXHJcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDQ6IHJldHVybiB2YWx1ZSB3aGVuIGFscmVhZHkgbnMgb2JqZWN0XHJcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxyXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XHJcbi8qKioqKiovIFx0XHRpZihtb2RlICYgMSkgdmFsdWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKHZhbHVlKTtcclxuLyoqKioqKi8gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XHJcbi8qKioqKiovIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xyXG4vKioqKioqLyBcdFx0dmFyIG5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcclxuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XHJcbi8qKioqKiovIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XHJcbi8qKioqKiovIFx0XHRpZihtb2RlICYgMiAmJiB0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIGZvcih2YXIga2V5IGluIHZhbHVlKSBfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGtleSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiB2YWx1ZVtrZXldOyB9LmJpbmQobnVsbCwga2V5KSk7XHJcbi8qKioqKiovIFx0XHRyZXR1cm4gbnM7XHJcbi8qKioqKiovIFx0fTtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xyXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xyXG4vKioqKioqLyBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XHJcbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XHJcbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XHJcbi8qKioqKiovIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XHJcbi8qKioqKiovIFx0XHRyZXR1cm4gZ2V0dGVyO1xyXG4vKioqKioqLyBcdH07XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXHJcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXHJcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCIvcmVzb3VyY2VzL2pzL1wiO1xyXG4vKioqKioqL1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xyXG4vKioqKioqLyBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IFwiLi9zcmMvQ29tbW9uL0xpYnJhcmllcy9XZWJzb2NrZXRzL0Nsb3VkU2hhcmVXZWJTb2NrZXRzL2luZGV4LmpzXCIpO1xyXG4vKioqKioqLyB9KVxyXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKioqKioqLyAoe1xyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcclxuICBpZih0eXBlb2YgaXQgIT0gJ2Z1bmN0aW9uJyl0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhIGZ1bmN0aW9uIScpO1xyXG4gIHJldHVybiBpdDtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtbnVtYmVyLXZhbHVlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1udW1iZXItdmFsdWUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGNvZiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBtc2cpe1xyXG4gIGlmKHR5cGVvZiBpdCAhPSAnbnVtYmVyJyAmJiBjb2YoaXQpICE9ICdOdW1iZXInKXRocm93IFR5cGVFcnJvcihtc2cpO1xyXG4gIHJldHVybiAraXQ7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYWRkLXRvLXVuc2NvcGFibGVzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMi4xLjMuMzEgQXJyYXkucHJvdG90eXBlW0BAdW5zY29wYWJsZXNdXHJcbnZhciBVTlNDT1BBQkxFUyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCd1bnNjb3BhYmxlcycpXHJcbiAgLCBBcnJheVByb3RvICA9IEFycmF5LnByb3RvdHlwZTtcclxuaWYoQXJyYXlQcm90b1tVTlNDT1BBQkxFU10gPT0gdW5kZWZpbmVkKV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hpZGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hpZGUuanNcIikoQXJyYXlQcm90bywgVU5TQ09QQUJMRVMsIHt9KTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xyXG4gIEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdW2tleV0gPSB0cnVlO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpe1xyXG4gIGlmKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKXtcclxuICAgIHRocm93IFR5cGVFcnJvcihuYW1lICsgJzogaW5jb3JyZWN0IGludm9jYXRpb24hJyk7XHJcbiAgfSByZXR1cm4gaXQ7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XHJcbiAgaWYoIWlzT2JqZWN0KGl0KSl0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhbiBvYmplY3QhJyk7XHJcbiAgcmV0dXJuIGl0O1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktY29weS13aXRoaW4uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1jb3B5LXdpdGhpbi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuLy8gMjIuMS4zLjMgQXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCwgZW5kID0gdGhpcy5sZW5ndGgpXHJcblxyXG52YXIgdG9PYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLW9iamVjdC5qc1wiKVxyXG4gICwgdG9JbmRleCAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pbmRleCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW5kZXguanNcIilcclxuICAsIHRvTGVuZ3RoID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIik7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFtdLmNvcHlXaXRoaW4gfHwgZnVuY3Rpb24gY29weVdpdGhpbih0YXJnZXQvKj0gMCovLCBzdGFydC8qPSAwLCBlbmQgPSBAbGVuZ3RoKi8pe1xyXG4gIHZhciBPICAgICA9IHRvT2JqZWN0KHRoaXMpXHJcbiAgICAsIGxlbiAgID0gdG9MZW5ndGgoTy5sZW5ndGgpXHJcbiAgICAsIHRvICAgID0gdG9JbmRleCh0YXJnZXQsIGxlbilcclxuICAgICwgZnJvbSAgPSB0b0luZGV4KHN0YXJ0LCBsZW4pXHJcbiAgICAsIGVuZCAgID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWRcclxuICAgICwgY291bnQgPSBNYXRoLm1pbigoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB0b0luZGV4KGVuZCwgbGVuKSkgLSBmcm9tLCBsZW4gLSB0bylcclxuICAgICwgaW5jICAgPSAxO1xyXG4gIGlmKGZyb20gPCB0byAmJiB0byA8IGZyb20gKyBjb3VudCl7XHJcbiAgICBpbmMgID0gLTE7XHJcbiAgICBmcm9tICs9IGNvdW50IC0gMTtcclxuICAgIHRvICAgKz0gY291bnQgLSAxO1xyXG4gIH1cclxuICB3aGlsZShjb3VudC0tID4gMCl7XHJcbiAgICBpZihmcm9tIGluIE8pT1t0b10gPSBPW2Zyb21dO1xyXG4gICAgZWxzZSBkZWxldGUgT1t0b107XHJcbiAgICB0byAgICs9IGluYztcclxuICAgIGZyb20gKz0gaW5jO1xyXG4gIH0gcmV0dXJuIE87XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1maWxsLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1maWxsLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vIDIyLjEuMy42IEFycmF5LnByb3RvdHlwZS5maWxsKHZhbHVlLCBzdGFydCA9IDAsIGVuZCA9IHRoaXMubGVuZ3RoKVxyXG5cclxudmFyIHRvT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAsIHRvSW5kZXggID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW5kZXggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWluZGV4LmpzXCIpXHJcbiAgLCB0b0xlbmd0aCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWxlbmd0aCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZpbGwodmFsdWUgLyosIHN0YXJ0ID0gMCwgZW5kID0gQGxlbmd0aCAqLyl7XHJcbiAgdmFyIE8gICAgICA9IHRvT2JqZWN0KHRoaXMpXHJcbiAgICAsIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKVxyXG4gICAgLCBhTGVuICAgPSBhcmd1bWVudHMubGVuZ3RoXHJcbiAgICAsIGluZGV4ICA9IHRvSW5kZXgoYUxlbiA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIGxlbmd0aClcclxuICAgICwgZW5kICAgID0gYUxlbiA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWRcclxuICAgICwgZW5kUG9zID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0luZGV4KGVuZCwgbGVuZ3RoKTtcclxuICB3aGlsZShlbmRQb3MgPiBpbmRleClPW2luZGV4KytdID0gdmFsdWU7XHJcbiAgcmV0dXJuIE87XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1mcm9tLWl0ZXJhYmxlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1mcm9tLWl0ZXJhYmxlLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGZvck9mID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZm9yLW9mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mb3Itb2YuanNcIik7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0ZXIsIElURVJBVE9SKXtcclxuICB2YXIgcmVzdWx0ID0gW107XHJcbiAgZm9yT2YoaXRlciwgZmFsc2UsIHJlc3VsdC5wdXNoLCByZXN1bHQsIElURVJBVE9SKTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59O1xyXG5cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktaW5jbHVkZXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gZmFsc2UgLT4gQXJyYXkjaW5kZXhPZlxyXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xyXG52YXIgdG9JT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qc1wiKVxyXG4gICwgdG9MZW5ndGggID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIilcclxuICAsIHRvSW5kZXggICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWluZGV4ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qc1wiKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihJU19JTkNMVURFUyl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uKCR0aGlzLCBlbCwgZnJvbUluZGV4KXtcclxuICAgIHZhciBPICAgICAgPSB0b0lPYmplY3QoJHRoaXMpXHJcbiAgICAgICwgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpXHJcbiAgICAgICwgaW5kZXggID0gdG9JbmRleChmcm9tSW5kZXgsIGxlbmd0aClcclxuICAgICAgLCB2YWx1ZTtcclxuICAgIC8vIEFycmF5I2luY2x1ZGVzIHVzZXMgU2FtZVZhbHVlWmVybyBlcXVhbGl0eSBhbGdvcml0aG1cclxuICAgIGlmKElTX0lOQ0xVREVTICYmIGVsICE9IGVsKXdoaWxlKGxlbmd0aCA+IGluZGV4KXtcclxuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xyXG4gICAgICBpZih2YWx1ZSAhPSB2YWx1ZSlyZXR1cm4gdHJ1ZTtcclxuICAgIC8vIEFycmF5I3RvSW5kZXggaWdub3JlcyBob2xlcywgQXJyYXkjaW5jbHVkZXMgLSBub3RcclxuICAgIH0gZWxzZSBmb3IoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKWlmKElTX0lOQ0xVREVTIHx8IGluZGV4IGluIE8pe1xyXG4gICAgICBpZihPW2luZGV4XSA9PT0gZWwpcmV0dXJuIElTX0lOQ0xVREVTIHx8IGluZGV4IHx8IDA7XHJcbiAgICB9IHJldHVybiAhSVNfSU5DTFVERVMgJiYgLTE7XHJcbiAgfTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LW1ldGhvZHMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LW1ldGhvZHMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAwIC0+IEFycmF5I2ZvckVhY2hcclxuLy8gMSAtPiBBcnJheSNtYXBcclxuLy8gMiAtPiBBcnJheSNmaWx0ZXJcclxuLy8gMyAtPiBBcnJheSNzb21lXHJcbi8vIDQgLT4gQXJyYXkjZXZlcnlcclxuLy8gNSAtPiBBcnJheSNmaW5kXHJcbi8vIDYgLT4gQXJyYXkjZmluZEluZGV4XHJcbnZhciBjdHggICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2N0eCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzXCIpXHJcbiAgLCBJT2JqZWN0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lvYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanNcIilcclxuICAsIHRvT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAsIHRvTGVuZ3RoID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIilcclxuICAsIGFzYyAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktc3BlY2llcy1jcmVhdGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LXNwZWNpZXMtY3JlYXRlLmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFRZUEUsICRjcmVhdGUpe1xyXG4gIHZhciBJU19NQVAgICAgICAgID0gVFlQRSA9PSAxXHJcbiAgICAsIElTX0ZJTFRFUiAgICAgPSBUWVBFID09IDJcclxuICAgICwgSVNfU09NRSAgICAgICA9IFRZUEUgPT0gM1xyXG4gICAgLCBJU19FVkVSWSAgICAgID0gVFlQRSA9PSA0XHJcbiAgICAsIElTX0ZJTkRfSU5ERVggPSBUWVBFID09IDZcclxuICAgICwgTk9fSE9MRVMgICAgICA9IFRZUEUgPT0gNSB8fCBJU19GSU5EX0lOREVYXHJcbiAgICAsIGNyZWF0ZSAgICAgICAgPSAkY3JlYXRlIHx8IGFzYztcclxuICByZXR1cm4gZnVuY3Rpb24oJHRoaXMsIGNhbGxiYWNrZm4sIHRoYXQpe1xyXG4gICAgdmFyIE8gICAgICA9IHRvT2JqZWN0KCR0aGlzKVxyXG4gICAgICAsIHNlbGYgICA9IElPYmplY3QoTylcclxuICAgICAgLCBmICAgICAgPSBjdHgoY2FsbGJhY2tmbiwgdGhhdCwgMylcclxuICAgICAgLCBsZW5ndGggPSB0b0xlbmd0aChzZWxmLmxlbmd0aClcclxuICAgICAgLCBpbmRleCAgPSAwXHJcbiAgICAgICwgcmVzdWx0ID0gSVNfTUFQID8gY3JlYXRlKCR0aGlzLCBsZW5ndGgpIDogSVNfRklMVEVSID8gY3JlYXRlKCR0aGlzLCAwKSA6IHVuZGVmaW5lZFxyXG4gICAgICAsIHZhbCwgcmVzO1xyXG4gICAgZm9yKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKylpZihOT19IT0xFUyB8fCBpbmRleCBpbiBzZWxmKXtcclxuICAgICAgdmFsID0gc2VsZltpbmRleF07XHJcbiAgICAgIHJlcyA9IGYodmFsLCBpbmRleCwgTyk7XHJcbiAgICAgIGlmKFRZUEUpe1xyXG4gICAgICAgIGlmKElTX01BUClyZXN1bHRbaW5kZXhdID0gcmVzOyAgICAgICAgICAgIC8vIG1hcFxyXG4gICAgICAgIGVsc2UgaWYocmVzKXN3aXRjaChUWVBFKXtcclxuICAgICAgICAgIGNhc2UgMzogcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAvLyBzb21lXHJcbiAgICAgICAgICBjYXNlIDU6IHJldHVybiB2YWw7ICAgICAgICAgICAgICAgICAgICAgLy8gZmluZFxyXG4gICAgICAgICAgY2FzZSA2OiByZXR1cm4gaW5kZXg7ICAgICAgICAgICAgICAgICAgIC8vIGZpbmRJbmRleFxyXG4gICAgICAgICAgY2FzZSAyOiByZXN1bHQucHVzaCh2YWwpOyAgICAgICAgICAgICAgIC8vIGZpbHRlclxyXG4gICAgICAgIH0gZWxzZSBpZihJU19FVkVSWSlyZXR1cm4gZmFsc2U7ICAgICAgICAgIC8vIGV2ZXJ5XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBJU19GSU5EX0lOREVYID8gLTEgOiBJU19TT01FIHx8IElTX0VWRVJZID8gSVNfRVZFUlkgOiByZXN1bHQ7XHJcbiAgfTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LXJlZHVjZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1yZWR1Y2UuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBhRnVuY3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCB0b09iamVjdCAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLW9iamVjdC5qc1wiKVxyXG4gICwgSU9iamVjdCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qc1wiKVxyXG4gICwgdG9MZW5ndGggID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIik7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHRoYXQsIGNhbGxiYWNrZm4sIGFMZW4sIG1lbW8sIGlzUmlnaHQpe1xyXG4gIGFGdW5jdGlvbihjYWxsYmFja2ZuKTtcclxuICB2YXIgTyAgICAgID0gdG9PYmplY3QodGhhdClcclxuICAgICwgc2VsZiAgID0gSU9iamVjdChPKVxyXG4gICAgLCBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aClcclxuICAgICwgaW5kZXggID0gaXNSaWdodCA/IGxlbmd0aCAtIDEgOiAwXHJcbiAgICAsIGkgICAgICA9IGlzUmlnaHQgPyAtMSA6IDE7XHJcbiAgaWYoYUxlbiA8IDIpZm9yKDs7KXtcclxuICAgIGlmKGluZGV4IGluIHNlbGYpe1xyXG4gICAgICBtZW1vID0gc2VsZltpbmRleF07XHJcbiAgICAgIGluZGV4ICs9IGk7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgaW5kZXggKz0gaTtcclxuICAgIGlmKGlzUmlnaHQgPyBpbmRleCA8IDAgOiBsZW5ndGggPD0gaW5kZXgpe1xyXG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ1JlZHVjZSBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcclxuICAgIH1cclxuICB9XHJcbiAgZm9yKDtpc1JpZ2h0ID8gaW5kZXggPj0gMCA6IGxlbmd0aCA+IGluZGV4OyBpbmRleCArPSBpKWlmKGluZGV4IGluIHNlbGYpe1xyXG4gICAgbWVtbyA9IGNhbGxiYWNrZm4obWVtbywgc2VsZltpbmRleF0sIGluZGV4LCBPKTtcclxuICB9XHJcbiAgcmV0dXJuIG1lbW87XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGlzT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIilcclxuICAsIGlzQXJyYXkgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWFycmF5LmpzXCIpXHJcbiAgLCBTUEVDSUVTICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCdzcGVjaWVzJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9yaWdpbmFsKXtcclxuICB2YXIgQztcclxuICBpZihpc0FycmF5KG9yaWdpbmFsKSl7XHJcbiAgICBDID0gb3JpZ2luYWwuY29uc3RydWN0b3I7XHJcbiAgICAvLyBjcm9zcy1yZWFsbSBmYWxsYmFja1xyXG4gICAgaWYodHlwZW9mIEMgPT0gJ2Z1bmN0aW9uJyAmJiAoQyA9PT0gQXJyYXkgfHwgaXNBcnJheShDLnByb3RvdHlwZSkpKUMgPSB1bmRlZmluZWQ7XHJcbiAgICBpZihpc09iamVjdChDKSl7XHJcbiAgICAgIEMgPSBDW1NQRUNJRVNdO1xyXG4gICAgICBpZihDID09PSBudWxsKUMgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgfSByZXR1cm4gQyA9PT0gdW5kZWZpbmVkID8gQXJyYXkgOiBDO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktc3BlY2llcy1jcmVhdGUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNyZWF0ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyA5LjQuMi4zIEFycmF5U3BlY2llc0NyZWF0ZShvcmlnaW5hbEFycmF5LCBsZW5ndGgpXHJcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzXCIpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcmlnaW5hbCwgbGVuZ3RoKXtcclxuICByZXR1cm4gbmV3IChzcGVjaWVzQ29uc3RydWN0b3Iob3JpZ2luYWwpKShsZW5ndGgpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYmluZC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYmluZC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIGFGdW5jdGlvbiAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCBpc09iamVjdCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIilcclxuICAsIGludm9rZSAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pbnZva2UgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qc1wiKVxyXG4gICwgYXJyYXlTbGljZSA9IFtdLnNsaWNlXHJcbiAgLCBmYWN0b3JpZXMgID0ge307XHJcblxyXG52YXIgY29uc3RydWN0ID0gZnVuY3Rpb24oRiwgbGVuLCBhcmdzKXtcclxuICBpZighKGxlbiBpbiBmYWN0b3JpZXMpKXtcclxuICAgIGZvcih2YXIgbiA9IFtdLCBpID0gMDsgaSA8IGxlbjsgaSsrKW5baV0gPSAnYVsnICsgaSArICddJztcclxuICAgIGZhY3Rvcmllc1tsZW5dID0gRnVuY3Rpb24oJ0YsYScsICdyZXR1cm4gbmV3IEYoJyArIG4uam9pbignLCcpICsgJyknKTtcclxuICB9IHJldHVybiBmYWN0b3JpZXNbbGVuXShGLCBhcmdzKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24uYmluZCB8fCBmdW5jdGlvbiBiaW5kKHRoYXQgLyosIGFyZ3MuLi4gKi8pe1xyXG4gIHZhciBmbiAgICAgICA9IGFGdW5jdGlvbih0aGlzKVxyXG4gICAgLCBwYXJ0QXJncyA9IGFycmF5U2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xyXG4gIHZhciBib3VuZCA9IGZ1bmN0aW9uKC8qIGFyZ3MuLi4gKi8pe1xyXG4gICAgdmFyIGFyZ3MgPSBwYXJ0QXJncy5jb25jYXQoYXJyYXlTbGljZS5jYWxsKGFyZ3VtZW50cykpO1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBib3VuZCA/IGNvbnN0cnVjdChmbiwgYXJncy5sZW5ndGgsIGFyZ3MpIDogaW52b2tlKGZuLCBhcmdzLCB0aGF0KTtcclxuICB9O1xyXG4gIGlmKGlzT2JqZWN0KGZuLnByb3RvdHlwZSkpYm91bmQucHJvdG90eXBlID0gZm4ucHJvdG90eXBlO1xyXG4gIHJldHVybiBib3VuZDtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBnZXR0aW5nIHRhZyBmcm9tIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxyXG52YXIgY29mID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2YuanNcIilcclxuICAsIFRBRyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCd0b1N0cmluZ1RhZycpXHJcbiAgLy8gRVMzIHdyb25nIGhlcmVcclxuICAsIEFSRyA9IGNvZihmdW5jdGlvbigpeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpID09ICdBcmd1bWVudHMnO1xyXG5cclxuLy8gZmFsbGJhY2sgZm9yIElFMTEgU2NyaXB0IEFjY2VzcyBEZW5pZWQgZXJyb3JcclxudmFyIHRyeUdldCA9IGZ1bmN0aW9uKGl0LCBrZXkpe1xyXG4gIHRyeSB7XHJcbiAgICByZXR1cm4gaXRba2V5XTtcclxuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcclxuICB2YXIgTywgVCwgQjtcclxuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCA/ICdVbmRlZmluZWQnIDogaXQgPT09IG51bGwgPyAnTnVsbCdcclxuICAgIC8vIEBAdG9TdHJpbmdUYWcgY2FzZVxyXG4gICAgOiB0eXBlb2YgKFQgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRBRykpID09ICdzdHJpbmcnID8gVFxyXG4gICAgLy8gYnVpbHRpblRhZyBjYXNlXHJcbiAgICA6IEFSRyA/IGNvZihPKVxyXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xyXG4gICAgOiAoQiA9IGNvZihPKSkgPT0gJ09iamVjdCcgJiYgdHlwZW9mIE8uY2FsbGVlID09ICdmdW5jdGlvbicgPyAnQXJndW1lbnRzJyA6IEI7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2YuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xyXG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGl0KS5zbGljZSg4LCAtMSk7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24tc3Ryb25nLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIGRQICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWRwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcIikuZlxyXG4gICwgY3JlYXRlICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtY3JlYXRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzXCIpXHJcbiAgLCByZWRlZmluZUFsbCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3JlZGVmaW5lLWFsbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzXCIpXHJcbiAgLCBjdHggICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2N0eCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzXCIpXHJcbiAgLCBhbkluc3RhbmNlICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLWluc3RhbmNlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qc1wiKVxyXG4gICwgZGVmaW5lZCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZWZpbmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzXCIpXHJcbiAgLCBmb3JPZiAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Zvci1vZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzXCIpXHJcbiAgLCAkaXRlckRlZmluZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2l0ZXItZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qc1wiKVxyXG4gICwgc3RlcCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyLXN0ZXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qc1wiKVxyXG4gICwgc2V0U3BlY2llcyAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zZXQtc3BlY2llcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanNcIilcclxuICAsIERFU0NSSVBUT1JTID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpXHJcbiAgLCBmYXN0S2V5ICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21ldGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGEuanNcIikuZmFzdEtleVxyXG4gICwgU0laRSAgICAgICAgPSBERVNDUklQVE9SUyA/ICdfcycgOiAnc2l6ZSc7XHJcblxyXG52YXIgZ2V0RW50cnkgPSBmdW5jdGlvbih0aGF0LCBrZXkpe1xyXG4gIC8vIGZhc3QgY2FzZVxyXG4gIHZhciBpbmRleCA9IGZhc3RLZXkoa2V5KSwgZW50cnk7XHJcbiAgaWYoaW5kZXggIT09ICdGJylyZXR1cm4gdGhhdC5faVtpbmRleF07XHJcbiAgLy8gZnJvemVuIG9iamVjdCBjYXNlXHJcbiAgZm9yKGVudHJ5ID0gdGhhdC5fZjsgZW50cnk7IGVudHJ5ID0gZW50cnkubil7XHJcbiAgICBpZihlbnRyeS5rID09IGtleSlyZXR1cm4gZW50cnk7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgZ2V0Q29uc3RydWN0b3I6IGZ1bmN0aW9uKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpe1xyXG4gICAgdmFyIEMgPSB3cmFwcGVyKGZ1bmN0aW9uKHRoYXQsIGl0ZXJhYmxlKXtcclxuICAgICAgYW5JbnN0YW5jZSh0aGF0LCBDLCBOQU1FLCAnX2knKTtcclxuICAgICAgdGhhdC5faSA9IGNyZWF0ZShudWxsKTsgLy8gaW5kZXhcclxuICAgICAgdGhhdC5fZiA9IHVuZGVmaW5lZDsgICAgLy8gZmlyc3QgZW50cnlcclxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgICAgLy8gbGFzdCBlbnRyeVxyXG4gICAgICB0aGF0W1NJWkVdID0gMDsgICAgICAgICAvLyBzaXplXHJcbiAgICAgIGlmKGl0ZXJhYmxlICE9IHVuZGVmaW5lZClmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XHJcbiAgICB9KTtcclxuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XHJcbiAgICAgIC8vIDIzLjEuMy4xIE1hcC5wcm90b3R5cGUuY2xlYXIoKVxyXG4gICAgICAvLyAyMy4yLjMuMiBTZXQucHJvdG90eXBlLmNsZWFyKClcclxuICAgICAgY2xlYXI6IGZ1bmN0aW9uIGNsZWFyKCl7XHJcbiAgICAgICAgZm9yKHZhciB0aGF0ID0gdGhpcywgZGF0YSA9IHRoYXQuX2ksIGVudHJ5ID0gdGhhdC5fZjsgZW50cnk7IGVudHJ5ID0gZW50cnkubil7XHJcbiAgICAgICAgICBlbnRyeS5yID0gdHJ1ZTtcclxuICAgICAgICAgIGlmKGVudHJ5LnApZW50cnkucCA9IGVudHJ5LnAubiA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgIGRlbGV0ZSBkYXRhW2VudHJ5LmldO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGF0Ll9mID0gdGhhdC5fbCA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGF0W1NJWkVdID0gMDtcclxuICAgICAgfSxcclxuICAgICAgLy8gMjMuMS4zLjMgTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxyXG4gICAgICAvLyAyMy4yLjMuNCBTZXQucHJvdG90eXBlLmRlbGV0ZSh2YWx1ZSlcclxuICAgICAgJ2RlbGV0ZSc6IGZ1bmN0aW9uKGtleSl7XHJcbiAgICAgICAgdmFyIHRoYXQgID0gdGhpc1xyXG4gICAgICAgICAgLCBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSk7XHJcbiAgICAgICAgaWYoZW50cnkpe1xyXG4gICAgICAgICAgdmFyIG5leHQgPSBlbnRyeS5uXHJcbiAgICAgICAgICAgICwgcHJldiA9IGVudHJ5LnA7XHJcbiAgICAgICAgICBkZWxldGUgdGhhdC5faVtlbnRyeS5pXTtcclxuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xyXG4gICAgICAgICAgaWYocHJldilwcmV2Lm4gPSBuZXh0O1xyXG4gICAgICAgICAgaWYobmV4dCluZXh0LnAgPSBwcmV2O1xyXG4gICAgICAgICAgaWYodGhhdC5fZiA9PSBlbnRyeSl0aGF0Ll9mID0gbmV4dDtcclxuICAgICAgICAgIGlmKHRoYXQuX2wgPT0gZW50cnkpdGhhdC5fbCA9IHByZXY7XHJcbiAgICAgICAgICB0aGF0W1NJWkVdLS07XHJcbiAgICAgICAgfSByZXR1cm4gISFlbnRyeTtcclxuICAgICAgfSxcclxuICAgICAgLy8gMjMuMi4zLjYgU2V0LnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4sIHRoaXNBcmcgPSB1bmRlZmluZWQpXHJcbiAgICAgIC8vIDIzLjEuMy41IE1hcC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxyXG4gICAgICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyosIHRoYXQgPSB1bmRlZmluZWQgKi8pe1xyXG4gICAgICAgIGFuSW5zdGFuY2UodGhpcywgQywgJ2ZvckVhY2gnKTtcclxuICAgICAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgMylcclxuICAgICAgICAgICwgZW50cnk7XHJcbiAgICAgICAgd2hpbGUoZW50cnkgPSBlbnRyeSA/IGVudHJ5Lm4gOiB0aGlzLl9mKXtcclxuICAgICAgICAgIGYoZW50cnkudiwgZW50cnkuaywgdGhpcyk7XHJcbiAgICAgICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcclxuICAgICAgICAgIHdoaWxlKGVudHJ5ICYmIGVudHJ5LnIpZW50cnkgPSBlbnRyeS5wO1xyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICAgLy8gMjMuMS4zLjcgTWFwLnByb3RvdHlwZS5oYXMoa2V5KVxyXG4gICAgICAvLyAyMy4yLjMuNyBTZXQucHJvdG90eXBlLmhhcyh2YWx1ZSlcclxuICAgICAgaGFzOiBmdW5jdGlvbiBoYXMoa2V5KXtcclxuICAgICAgICByZXR1cm4gISFnZXRFbnRyeSh0aGlzLCBrZXkpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIGlmKERFU0NSSVBUT1JTKWRQKEMucHJvdG90eXBlLCAnc2l6ZScsIHtcclxuICAgICAgZ2V0OiBmdW5jdGlvbigpe1xyXG4gICAgICAgIHJldHVybiBkZWZpbmVkKHRoaXNbU0laRV0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBDO1xyXG4gIH0sXHJcbiAgZGVmOiBmdW5jdGlvbih0aGF0LCBrZXksIHZhbHVlKXtcclxuICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSlcclxuICAgICAgLCBwcmV2LCBpbmRleDtcclxuICAgIC8vIGNoYW5nZSBleGlzdGluZyBlbnRyeVxyXG4gICAgaWYoZW50cnkpe1xyXG4gICAgICBlbnRyeS52ID0gdmFsdWU7XHJcbiAgICAvLyBjcmVhdGUgbmV3IGVudHJ5XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGF0Ll9sID0gZW50cnkgPSB7XHJcbiAgICAgICAgaTogaW5kZXggPSBmYXN0S2V5KGtleSwgdHJ1ZSksIC8vIDwtIGluZGV4XHJcbiAgICAgICAgazoga2V5LCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIGtleVxyXG4gICAgICAgIHY6IHZhbHVlLCAgICAgICAgICAgICAgICAgICAgICAvLyA8LSB2YWx1ZVxyXG4gICAgICAgIHA6IHByZXYgPSB0aGF0Ll9sLCAgICAgICAgICAgICAvLyA8LSBwcmV2aW91cyBlbnRyeVxyXG4gICAgICAgIG46IHVuZGVmaW5lZCwgICAgICAgICAgICAgICAgICAvLyA8LSBuZXh0IGVudHJ5XHJcbiAgICAgICAgcjogZmFsc2UgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIHJlbW92ZWRcclxuICAgICAgfTtcclxuICAgICAgaWYoIXRoYXQuX2YpdGhhdC5fZiA9IGVudHJ5O1xyXG4gICAgICBpZihwcmV2KXByZXYubiA9IGVudHJ5O1xyXG4gICAgICB0aGF0W1NJWkVdKys7XHJcbiAgICAgIC8vIGFkZCB0byBpbmRleFxyXG4gICAgICBpZihpbmRleCAhPT0gJ0YnKXRoYXQuX2lbaW5kZXhdID0gZW50cnk7XHJcbiAgICB9IHJldHVybiB0aGF0O1xyXG4gIH0sXHJcbiAgZ2V0RW50cnk6IGdldEVudHJ5LFxyXG4gIHNldFN0cm9uZzogZnVuY3Rpb24oQywgTkFNRSwgSVNfTUFQKXtcclxuICAgIC8vIGFkZCAua2V5cywgLnZhbHVlcywgLmVudHJpZXMsIFtAQGl0ZXJhdG9yXVxyXG4gICAgLy8gMjMuMS4zLjQsIDIzLjEuMy44LCAyMy4xLjMuMTEsIDIzLjEuMy4xMiwgMjMuMi4zLjUsIDIzLjIuMy44LCAyMy4yLjMuMTAsIDIzLjIuMy4xMVxyXG4gICAgJGl0ZXJEZWZpbmUoQywgTkFNRSwgZnVuY3Rpb24oaXRlcmF0ZWQsIGtpbmQpe1xyXG4gICAgICB0aGlzLl90ID0gaXRlcmF0ZWQ7ICAvLyB0YXJnZXRcclxuICAgICAgdGhpcy5fayA9IGtpbmQ7ICAgICAgLy8ga2luZFxyXG4gICAgICB0aGlzLl9sID0gdW5kZWZpbmVkOyAvLyBwcmV2aW91c1xyXG4gICAgfSwgZnVuY3Rpb24oKXtcclxuICAgICAgdmFyIHRoYXQgID0gdGhpc1xyXG4gICAgICAgICwga2luZCAgPSB0aGF0Ll9rXHJcbiAgICAgICAgLCBlbnRyeSA9IHRoYXQuX2w7XHJcbiAgICAgIC8vIHJldmVydCB0byB0aGUgbGFzdCBleGlzdGluZyBlbnRyeVxyXG4gICAgICB3aGlsZShlbnRyeSAmJiBlbnRyeS5yKWVudHJ5ID0gZW50cnkucDtcclxuICAgICAgLy8gZ2V0IG5leHQgZW50cnlcclxuICAgICAgaWYoIXRoYXQuX3QgfHwgISh0aGF0Ll9sID0gZW50cnkgPSBlbnRyeSA/IGVudHJ5Lm4gOiB0aGF0Ll90Ll9mKSl7XHJcbiAgICAgICAgLy8gb3IgZmluaXNoIHRoZSBpdGVyYXRpb25cclxuICAgICAgICB0aGF0Ll90ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHJldHVybiBzdGVwKDEpO1xyXG4gICAgICB9XHJcbiAgICAgIC8vIHJldHVybiBzdGVwIGJ5IGtpbmRcclxuICAgICAgaWYoa2luZCA9PSAna2V5cycgIClyZXR1cm4gc3RlcCgwLCBlbnRyeS5rKTtcclxuICAgICAgaWYoa2luZCA9PSAndmFsdWVzJylyZXR1cm4gc3RlcCgwLCBlbnRyeS52KTtcclxuICAgICAgcmV0dXJuIHN0ZXAoMCwgW2VudHJ5LmssIGVudHJ5LnZdKTtcclxuICAgIH0sIElTX01BUCA/ICdlbnRyaWVzJyA6ICd2YWx1ZXMnICwgIUlTX01BUCwgdHJ1ZSk7XHJcblxyXG4gICAgLy8gYWRkIFtAQHNwZWNpZXNdLCAyMy4xLjIuMiwgMjMuMi4yLjJcclxuICAgIHNldFNwZWNpZXMoTkFNRSk7XHJcbiAgfVxyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi10by1qc29uLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24tdG8tanNvbi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gaHR0cHM6Ly9naXRodWIuY29tL0RhdmlkQnJ1YW50L01hcC1TZXQucHJvdG90eXBlLnRvSlNPTlxyXG52YXIgY2xhc3NvZiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NsYXNzb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanNcIilcclxuICAsIGZyb20gICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1mcm9tLWl0ZXJhYmxlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1mcm9tLWl0ZXJhYmxlLmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE5BTUUpe1xyXG4gIHJldHVybiBmdW5jdGlvbiB0b0pTT04oKXtcclxuICAgIGlmKGNsYXNzb2YodGhpcykgIT0gTkFNRSl0aHJvdyBUeXBlRXJyb3IoTkFNRSArIFwiI3RvSlNPTiBpc24ndCBnZW5lcmljXCIpO1xyXG4gICAgcmV0dXJuIGZyb20odGhpcyk7XHJcbiAgfTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24td2Vhay5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXdlYWsuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIHJlZGVmaW5lQWxsICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUtYWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanNcIilcclxuICAsIGdldFdlYWsgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fbWV0YSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWV0YS5qc1wiKS5nZXRXZWFrXHJcbiAgLCBhbk9iamVjdCAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCBpc09iamVjdCAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzXCIpXHJcbiAgLCBhbkluc3RhbmNlICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLWluc3RhbmNlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qc1wiKVxyXG4gICwgZm9yT2YgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mb3Itb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qc1wiKVxyXG4gICwgY3JlYXRlQXJyYXlNZXRob2QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1tZXRob2RzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1tZXRob2RzLmpzXCIpXHJcbiAgLCAkaGFzICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgLCBhcnJheUZpbmQgICAgICAgICA9IGNyZWF0ZUFycmF5TWV0aG9kKDUpXHJcbiAgLCBhcnJheUZpbmRJbmRleCAgICA9IGNyZWF0ZUFycmF5TWV0aG9kKDYpXHJcbiAgLCBpZCAgICAgICAgICAgICAgICA9IDA7XHJcblxyXG4vLyBmYWxsYmFjayBmb3IgdW5jYXVnaHQgZnJvemVuIGtleXNcclxudmFyIHVuY2F1Z2h0RnJvemVuU3RvcmUgPSBmdW5jdGlvbih0aGF0KXtcclxuICByZXR1cm4gdGhhdC5fbCB8fCAodGhhdC5fbCA9IG5ldyBVbmNhdWdodEZyb3plblN0b3JlKTtcclxufTtcclxudmFyIFVuY2F1Z2h0RnJvemVuU3RvcmUgPSBmdW5jdGlvbigpe1xyXG4gIHRoaXMuYSA9IFtdO1xyXG59O1xyXG52YXIgZmluZFVuY2F1Z2h0RnJvemVuID0gZnVuY3Rpb24oc3RvcmUsIGtleSl7XHJcbiAgcmV0dXJuIGFycmF5RmluZChzdG9yZS5hLCBmdW5jdGlvbihpdCl7XHJcbiAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcclxuICB9KTtcclxufTtcclxuVW5jYXVnaHRGcm96ZW5TdG9yZS5wcm90b3R5cGUgPSB7XHJcbiAgZ2V0OiBmdW5jdGlvbihrZXkpe1xyXG4gICAgdmFyIGVudHJ5ID0gZmluZFVuY2F1Z2h0RnJvemVuKHRoaXMsIGtleSk7XHJcbiAgICBpZihlbnRyeSlyZXR1cm4gZW50cnlbMV07XHJcbiAgfSxcclxuICBoYXM6IGZ1bmN0aW9uKGtleSl7XHJcbiAgICByZXR1cm4gISFmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcclxuICB9LFxyXG4gIHNldDogZnVuY3Rpb24oa2V5LCB2YWx1ZSl7XHJcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcclxuICAgIGlmKGVudHJ5KWVudHJ5WzFdID0gdmFsdWU7XHJcbiAgICBlbHNlIHRoaXMuYS5wdXNoKFtrZXksIHZhbHVlXSk7XHJcbiAgfSxcclxuICAnZGVsZXRlJzogZnVuY3Rpb24oa2V5KXtcclxuICAgIHZhciBpbmRleCA9IGFycmF5RmluZEluZGV4KHRoaXMuYSwgZnVuY3Rpb24oaXQpe1xyXG4gICAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcclxuICAgIH0pO1xyXG4gICAgaWYofmluZGV4KXRoaXMuYS5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgcmV0dXJuICEhfmluZGV4O1xyXG4gIH1cclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0ge1xyXG4gIGdldENvbnN0cnVjdG9yOiBmdW5jdGlvbih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKXtcclxuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbih0aGF0LCBpdGVyYWJsZSl7XHJcbiAgICAgIGFuSW5zdGFuY2UodGhhdCwgQywgTkFNRSwgJ19pJyk7XHJcbiAgICAgIHRoYXQuX2kgPSBpZCsrOyAgICAgIC8vIGNvbGxlY3Rpb24gaWRcclxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgLy8gbGVhayBzdG9yZSBmb3IgdW5jYXVnaHQgZnJvemVuIG9iamVjdHNcclxuICAgICAgaWYoaXRlcmFibGUgIT0gdW5kZWZpbmVkKWZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcclxuICAgIH0pO1xyXG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIHtcclxuICAgICAgLy8gMjMuMy4zLjIgV2Vha01hcC5wcm90b3R5cGUuZGVsZXRlKGtleSlcclxuICAgICAgLy8gMjMuNC4zLjMgV2Vha1NldC5wcm90b3R5cGUuZGVsZXRlKHZhbHVlKVxyXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24oa2V5KXtcclxuICAgICAgICBpZighaXNPYmplY3Qoa2V5KSlyZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgdmFyIGRhdGEgPSBnZXRXZWFrKGtleSk7XHJcbiAgICAgICAgaWYoZGF0YSA9PT0gdHJ1ZSlyZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh0aGlzKVsnZGVsZXRlJ10oa2V5KTtcclxuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpICYmIGRlbGV0ZSBkYXRhW3RoaXMuX2ldO1xyXG4gICAgICB9LFxyXG4gICAgICAvLyAyMy4zLjMuNCBXZWFrTWFwLnByb3RvdHlwZS5oYXMoa2V5KVxyXG4gICAgICAvLyAyMy40LjMuNCBXZWFrU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXHJcbiAgICAgIGhhczogZnVuY3Rpb24gaGFzKGtleSl7XHJcbiAgICAgICAgaWYoIWlzT2JqZWN0KGtleSkpcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xyXG4gICAgICAgIGlmKGRhdGEgPT09IHRydWUpcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodGhpcykuaGFzKGtleSk7XHJcbiAgICAgICAgcmV0dXJuIGRhdGEgJiYgJGhhcyhkYXRhLCB0aGlzLl9pKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gQztcclxuICB9LFxyXG4gIGRlZjogZnVuY3Rpb24odGhhdCwga2V5LCB2YWx1ZSl7XHJcbiAgICB2YXIgZGF0YSA9IGdldFdlYWsoYW5PYmplY3Qoa2V5KSwgdHJ1ZSk7XHJcbiAgICBpZihkYXRhID09PSB0cnVlKXVuY2F1Z2h0RnJvemVuU3RvcmUodGhhdCkuc2V0KGtleSwgdmFsdWUpO1xyXG4gICAgZWxzZSBkYXRhW3RoYXQuX2ldID0gdmFsdWU7XHJcbiAgICByZXR1cm4gdGhhdDtcclxuICB9LFxyXG4gIHVmc3RvcmU6IHVuY2F1Z2h0RnJvemVuU3RvcmVcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciBnbG9iYWwgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgLCAkZXhwb3J0ICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCByZWRlZmluZSAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3JlZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qc1wiKVxyXG4gICwgcmVkZWZpbmVBbGwgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19yZWRlZmluZS1hbGwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLWFsbC5qc1wiKVxyXG4gICwgbWV0YSAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tZXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzXCIpXHJcbiAgLCBmb3JPZiAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Zvci1vZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzXCIpXHJcbiAgLCBhbkluc3RhbmNlICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLWluc3RhbmNlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qc1wiKVxyXG4gICwgaXNPYmplY3QgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgZmFpbHMgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIilcclxuICAsICRpdGVyRGV0ZWN0ICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXRlci1kZXRlY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGV0ZWN0LmpzXCIpXHJcbiAgLCBzZXRUb1N0cmluZ1RhZyAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NldC10by1zdHJpbmctdGFnICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtdG8tc3RyaW5nLXRhZy5qc1wiKVxyXG4gICwgaW5oZXJpdElmUmVxdWlyZWQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pbmhlcml0LWlmLXJlcXVpcmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pbmhlcml0LWlmLXJlcXVpcmVkLmpzXCIpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihOQU1FLCB3cmFwcGVyLCBtZXRob2RzLCBjb21tb24sIElTX01BUCwgSVNfV0VBSyl7XHJcbiAgdmFyIEJhc2UgID0gZ2xvYmFsW05BTUVdXHJcbiAgICAsIEMgICAgID0gQmFzZVxyXG4gICAgLCBBRERFUiA9IElTX01BUCA/ICdzZXQnIDogJ2FkZCdcclxuICAgICwgcHJvdG8gPSBDICYmIEMucHJvdG90eXBlXHJcbiAgICAsIE8gICAgID0ge307XHJcbiAgdmFyIGZpeE1ldGhvZCA9IGZ1bmN0aW9uKEtFWSl7XHJcbiAgICB2YXIgZm4gPSBwcm90b1tLRVldO1xyXG4gICAgcmVkZWZpbmUocHJvdG8sIEtFWSxcclxuICAgICAgS0VZID09ICdkZWxldGUnID8gZnVuY3Rpb24oYSl7XHJcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XHJcbiAgICAgIH0gOiBLRVkgPT0gJ2hhcycgPyBmdW5jdGlvbiBoYXMoYSl7XHJcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XHJcbiAgICAgIH0gOiBLRVkgPT0gJ2dldCcgPyBmdW5jdGlvbiBnZXQoYSl7XHJcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gdW5kZWZpbmVkIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xyXG4gICAgICB9IDogS0VZID09ICdhZGQnID8gZnVuY3Rpb24gYWRkKGEpeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7IHJldHVybiB0aGlzOyB9XHJcbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYil7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhLCBiKTsgcmV0dXJuIHRoaXM7IH1cclxuICAgICk7XHJcbiAgfTtcclxuICBpZih0eXBlb2YgQyAhPSAnZnVuY3Rpb24nIHx8ICEoSVNfV0VBSyB8fCBwcm90by5mb3JFYWNoICYmICFmYWlscyhmdW5jdGlvbigpe1xyXG4gICAgbmV3IEMoKS5lbnRyaWVzKCkubmV4dCgpO1xyXG4gIH0pKSl7XHJcbiAgICAvLyBjcmVhdGUgY29sbGVjdGlvbiBjb25zdHJ1Y3RvclxyXG4gICAgQyA9IGNvbW1vbi5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKTtcclxuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCBtZXRob2RzKTtcclxuICAgIG1ldGEuTkVFRCA9IHRydWU7XHJcbiAgfSBlbHNlIHtcclxuICAgIHZhciBpbnN0YW5jZSAgICAgICAgICAgICA9IG5ldyBDXHJcbiAgICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcclxuICAgICAgLCBIQVNOVF9DSEFJTklORyAgICAgICA9IGluc3RhbmNlW0FEREVSXShJU19XRUFLID8ge30gOiAtMCwgMSkgIT0gaW5zdGFuY2VcclxuICAgICAgLy8gVjggfiAgQ2hyb21pdW0gNDAtIHdlYWstY29sbGVjdGlvbnMgdGhyb3dzIG9uIHByaW1pdGl2ZXMsIGJ1dCBzaG91bGQgcmV0dXJuIGZhbHNlXHJcbiAgICAgICwgVEhST1dTX09OX1BSSU1JVElWRVMgPSBmYWlscyhmdW5jdGlvbigpeyBpbnN0YW5jZS5oYXMoMSk7IH0pXHJcbiAgICAgIC8vIG1vc3QgZWFybHkgaW1wbGVtZW50YXRpb25zIGRvZXNuJ3Qgc3VwcG9ydHMgaXRlcmFibGVzLCBtb3N0IG1vZGVybiAtIG5vdCBjbG9zZSBpdCBjb3JyZWN0bHlcclxuICAgICAgLCBBQ0NFUFRfSVRFUkFCTEVTICAgICA9ICRpdGVyRGV0ZWN0KGZ1bmN0aW9uKGl0ZXIpeyBuZXcgQyhpdGVyKTsgfSkgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcclxuICAgICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXHJcbiAgICAgICwgQlVHR1lfWkVSTyA9ICFJU19XRUFLICYmIGZhaWxzKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgLy8gVjggfiBDaHJvbWl1bSA0Mi0gZmFpbHMgb25seSB3aXRoIDUrIGVsZW1lbnRzXHJcbiAgICAgICAgdmFyICRpbnN0YW5jZSA9IG5ldyBDKClcclxuICAgICAgICAgICwgaW5kZXggICAgID0gNTtcclxuICAgICAgICB3aGlsZShpbmRleC0tKSRpbnN0YW5jZVtBRERFUl0oaW5kZXgsIGluZGV4KTtcclxuICAgICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xyXG4gICAgICB9KTtcclxuICAgIGlmKCFBQ0NFUFRfSVRFUkFCTEVTKXsgXHJcbiAgICAgIEMgPSB3cmFwcGVyKGZ1bmN0aW9uKHRhcmdldCwgaXRlcmFibGUpe1xyXG4gICAgICAgIGFuSW5zdGFuY2UodGFyZ2V0LCBDLCBOQU1FKTtcclxuICAgICAgICB2YXIgdGhhdCA9IGluaGVyaXRJZlJlcXVpcmVkKG5ldyBCYXNlLCB0YXJnZXQsIEMpO1xyXG4gICAgICAgIGlmKGl0ZXJhYmxlICE9IHVuZGVmaW5lZClmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XHJcbiAgICAgICAgcmV0dXJuIHRoYXQ7XHJcbiAgICAgIH0pO1xyXG4gICAgICBDLnByb3RvdHlwZSA9IHByb3RvO1xyXG4gICAgICBwcm90by5jb25zdHJ1Y3RvciA9IEM7XHJcbiAgICB9XHJcbiAgICBpZihUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKXtcclxuICAgICAgZml4TWV0aG9kKCdkZWxldGUnKTtcclxuICAgICAgZml4TWV0aG9kKCdoYXMnKTtcclxuICAgICAgSVNfTUFQICYmIGZpeE1ldGhvZCgnZ2V0Jyk7XHJcbiAgICB9XHJcbiAgICBpZihCVUdHWV9aRVJPIHx8IEhBU05UX0NIQUlOSU5HKWZpeE1ldGhvZChBRERFUik7XHJcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxyXG4gICAgaWYoSVNfV0VBSyAmJiBwcm90by5jbGVhcilkZWxldGUgcHJvdG8uY2xlYXI7XHJcbiAgfVxyXG5cclxuICBzZXRUb1N0cmluZ1RhZyhDLCBOQU1FKTtcclxuXHJcbiAgT1tOQU1FXSA9IEM7XHJcbiAgJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAoQyAhPSBCYXNlKSwgTyk7XHJcblxyXG4gIGlmKCFJU19XRUFLKWNvbW1vbi5zZXRTdHJvbmcoQywgTkFNRSwgSVNfTUFQKTtcclxuXHJcbiAgcmV0dXJuIEM7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xyXG5cclxudmFyIGNvcmUgPSBtb2R1bGUuZXhwb3J0cyA9IHt2ZXJzaW9uOiAnMi40LjAnfTtcclxuaWYodHlwZW9mIF9fZSA9PSAnbnVtYmVyJylfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jcmVhdGUtcHJvcGVydHkuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3JlYXRlLXByb3BlcnR5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciAkZGVmaW5lUHJvcGVydHkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKVxyXG4gICwgY3JlYXRlRGVzYyAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcHJvcGVydHktZGVzYyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qc1wiKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob2JqZWN0LCBpbmRleCwgdmFsdWUpe1xyXG4gIGlmKGluZGV4IGluIG9iamVjdCkkZGVmaW5lUHJvcGVydHkuZihvYmplY3QsIGluZGV4LCBjcmVhdGVEZXNjKDAsIHZhbHVlKSk7XHJcbiAgZWxzZSBvYmplY3RbaW5kZXhdID0gdmFsdWU7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jdHguanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcclxudmFyIGFGdW5jdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2EtZnVuY3Rpb24gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanNcIik7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm4sIHRoYXQsIGxlbmd0aCl7XHJcbiAgYUZ1bmN0aW9uKGZuKTtcclxuICBpZih0aGF0ID09PSB1bmRlZmluZWQpcmV0dXJuIGZuO1xyXG4gIHN3aXRjaChsZW5ndGgpe1xyXG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24oYSl7XHJcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEpO1xyXG4gICAgfTtcclxuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEsIGIpe1xyXG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcclxuICAgIH07XHJcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhLCBiLCBjKXtcclxuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XHJcbiAgICB9O1xyXG4gIH1cclxuICByZXR1cm4gZnVuY3Rpb24oLyogLi4uYXJncyAqLyl7XHJcbiAgICByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcclxuICB9O1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGF0ZS10by1wcmltaXRpdmUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kYXRlLXRvLXByaW1pdGl2ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciBhbk9iamVjdCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b1ByaW1pdGl2ZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLXByaW1pdGl2ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzXCIpXHJcbiAgLCBOVU1CRVIgICAgICA9ICdudW1iZXInO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihoaW50KXtcclxuICBpZihoaW50ICE9PSAnc3RyaW5nJyAmJiBoaW50ICE9PSBOVU1CRVIgJiYgaGludCAhPT0gJ2RlZmF1bHQnKXRocm93IFR5cGVFcnJvcignSW5jb3JyZWN0IGhpbnQnKTtcclxuICByZXR1cm4gdG9QcmltaXRpdmUoYW5PYmplY3QodGhpcyksIGhpbnQgIT0gTlVNQkVSKTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG4vLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcclxuICBpZihpdCA9PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xyXG4gIHJldHVybiBpdDtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxyXG5tb2R1bGUuZXhwb3J0cyA9ICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIikoZnVuY3Rpb24oKXtcclxuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnYScsIHtnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiA3OyB9fSkuYSAhPSA3O1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgZG9jdW1lbnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKS5kb2N1bWVudFxyXG4gIC8vIGluIG9sZCBJRSB0eXBlb2YgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBpcyAnb2JqZWN0J1xyXG4gICwgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xyXG4gIHJldHVybiBpcyA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaXQpIDoge307XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19lbnVtLWJ1Zy1rZXlzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19lbnVtLWJ1Zy1rZXlzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xyXG5cclxuLy8gSUUgOC0gZG9uJ3QgZW51bSBidWcga2V5c1xyXG5tb2R1bGUuZXhwb3J0cyA9IChcclxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xyXG4pLnNwbGl0KCcsJyk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19lbnVtLWtleXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1rZXlzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBhbGwgZW51bWVyYWJsZSBvYmplY3Qga2V5cywgaW5jbHVkZXMgc3ltYm9sc1xyXG52YXIgZ2V0S2V5cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1rZXlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qc1wiKVxyXG4gICwgZ09QUyAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wcy5qc1wiKVxyXG4gICwgcElFICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1waWUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanNcIik7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xyXG4gIHZhciByZXN1bHQgICAgID0gZ2V0S2V5cyhpdClcclxuICAgICwgZ2V0U3ltYm9scyA9IGdPUFMuZjtcclxuICBpZihnZXRTeW1ib2xzKXtcclxuICAgIHZhciBzeW1ib2xzID0gZ2V0U3ltYm9scyhpdClcclxuICAgICAgLCBpc0VudW0gID0gcElFLmZcclxuICAgICAgLCBpICAgICAgID0gMFxyXG4gICAgICAsIGtleTtcclxuICAgIHdoaWxlKHN5bWJvbHMubGVuZ3RoID4gaSlpZihpc0VudW0uY2FsbChpdCwga2V5ID0gc3ltYm9sc1tpKytdKSlyZXN1bHQucHVzaChrZXkpO1xyXG4gIH0gcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBnbG9iYWwgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKVxyXG4gICwgY29yZSAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29yZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29yZS5qc1wiKVxyXG4gICwgaGlkZSAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faGlkZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qc1wiKVxyXG4gICwgcmVkZWZpbmUgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXCIpXHJcbiAgLCBjdHggICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jdHggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qc1wiKVxyXG4gICwgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XHJcblxyXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uKHR5cGUsIG5hbWUsIHNvdXJjZSl7XHJcbiAgdmFyIElTX0ZPUkNFRCA9IHR5cGUgJiAkZXhwb3J0LkZcclxuICAgICwgSVNfR0xPQkFMID0gdHlwZSAmICRleHBvcnQuR1xyXG4gICAgLCBJU19TVEFUSUMgPSB0eXBlICYgJGV4cG9ydC5TXHJcbiAgICAsIElTX1BST1RPICA9IHR5cGUgJiAkZXhwb3J0LlBcclxuICAgICwgSVNfQklORCAgID0gdHlwZSAmICRleHBvcnQuQlxyXG4gICAgLCB0YXJnZXQgICAgPSBJU19HTE9CQUwgPyBnbG9iYWwgOiBJU19TVEFUSUMgPyBnbG9iYWxbbmFtZV0gfHwgKGdsb2JhbFtuYW1lXSA9IHt9KSA6IChnbG9iYWxbbmFtZV0gfHwge30pW1BST1RPVFlQRV1cclxuICAgICwgZXhwb3J0cyAgID0gSVNfR0xPQkFMID8gY29yZSA6IGNvcmVbbmFtZV0gfHwgKGNvcmVbbmFtZV0gPSB7fSlcclxuICAgICwgZXhwUHJvdG8gID0gZXhwb3J0c1tQUk9UT1RZUEVdIHx8IChleHBvcnRzW1BST1RPVFlQRV0gPSB7fSlcclxuICAgICwga2V5LCBvd24sIG91dCwgZXhwO1xyXG4gIGlmKElTX0dMT0JBTClzb3VyY2UgPSBuYW1lO1xyXG4gIGZvcihrZXkgaW4gc291cmNlKXtcclxuICAgIC8vIGNvbnRhaW5zIGluIG5hdGl2ZVxyXG4gICAgb3duID0gIUlTX0ZPUkNFRCAmJiB0YXJnZXQgJiYgdGFyZ2V0W2tleV0gIT09IHVuZGVmaW5lZDtcclxuICAgIC8vIGV4cG9ydCBuYXRpdmUgb3IgcGFzc2VkXHJcbiAgICBvdXQgPSAob3duID8gdGFyZ2V0IDogc291cmNlKVtrZXldO1xyXG4gICAgLy8gYmluZCB0aW1lcnMgdG8gZ2xvYmFsIGZvciBjYWxsIGZyb20gZXhwb3J0IGNvbnRleHRcclxuICAgIGV4cCA9IElTX0JJTkQgJiYgb3duID8gY3R4KG91dCwgZ2xvYmFsKSA6IElTX1BST1RPICYmIHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJyA/IGN0eChGdW5jdGlvbi5jYWxsLCBvdXQpIDogb3V0O1xyXG4gICAgLy8gZXh0ZW5kIGdsb2JhbFxyXG4gICAgaWYodGFyZ2V0KXJlZGVmaW5lKHRhcmdldCwga2V5LCBvdXQsIHR5cGUgJiAkZXhwb3J0LlUpO1xyXG4gICAgLy8gZXhwb3J0XHJcbiAgICBpZihleHBvcnRzW2tleV0gIT0gb3V0KWhpZGUoZXhwb3J0cywga2V5LCBleHApO1xyXG4gICAgaWYoSVNfUFJPVE8gJiYgZXhwUHJvdG9ba2V5XSAhPSBvdXQpZXhwUHJvdG9ba2V5XSA9IG91dDtcclxuICB9XHJcbn07XHJcbmdsb2JhbC5jb3JlID0gY29yZTtcclxuLy8gdHlwZSBiaXRtYXBcclxuJGV4cG9ydC5GID0gMTsgICAvLyBmb3JjZWRcclxuJGV4cG9ydC5HID0gMjsgICAvLyBnbG9iYWxcclxuJGV4cG9ydC5TID0gNDsgICAvLyBzdGF0aWNcclxuJGV4cG9ydC5QID0gODsgICAvLyBwcm90b1xyXG4kZXhwb3J0LkIgPSAxNjsgIC8vIGJpbmRcclxuJGV4cG9ydC5XID0gMzI7ICAvLyB3cmFwXHJcbiRleHBvcnQuVSA9IDY0OyAgLy8gc2FmZVxyXG4kZXhwb3J0LlIgPSAxMjg7IC8vIHJlYWwgcHJvdG8gbWV0aG9kIGZvciBgbGlicmFyeWAgXHJcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLWlzLXJlZ2V4cC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy1pcy1yZWdleHAuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBNQVRDSCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCdtYXRjaCcpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKEtFWSl7XHJcbiAgdmFyIHJlID0gLy4vO1xyXG4gIHRyeSB7XHJcbiAgICAnLy4vJ1tLRVldKHJlKTtcclxuICB9IGNhdGNoKGUpe1xyXG4gICAgdHJ5IHtcclxuICAgICAgcmVbTUFUQ0hdID0gZmFsc2U7XHJcbiAgICAgIHJldHVybiAhJy8uLydbS0VZXShyZSk7XHJcbiAgICB9IGNhdGNoKGYpeyAvKiBlbXB0eSAqLyB9XHJcbiAgfSByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihleGVjKXtcclxuICB0cnkge1xyXG4gICAgcmV0dXJuICEhZXhlYygpO1xyXG4gIH0gY2F0Y2goZSl7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19maXgtcmUtd2tzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19maXgtcmUtd2tzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgaGlkZSAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oaWRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzXCIpXHJcbiAgLCByZWRlZmluZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3JlZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qc1wiKVxyXG4gICwgZmFpbHMgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIilcclxuICAsIGRlZmluZWQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVmaW5lZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVmaW5lZC5qc1wiKVxyXG4gICwgd2tzICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBsZW5ndGgsIGV4ZWMpe1xyXG4gIHZhciBTWU1CT0wgICA9IHdrcyhLRVkpXHJcbiAgICAsIGZucyAgICAgID0gZXhlYyhkZWZpbmVkLCBTWU1CT0wsICcnW0tFWV0pXHJcbiAgICAsIHN0cmZuICAgID0gZm5zWzBdXHJcbiAgICAsIHJ4Zm4gICAgID0gZm5zWzFdO1xyXG4gIGlmKGZhaWxzKGZ1bmN0aW9uKCl7XHJcbiAgICB2YXIgTyA9IHt9O1xyXG4gICAgT1tTWU1CT0xdID0gZnVuY3Rpb24oKXsgcmV0dXJuIDc7IH07XHJcbiAgICByZXR1cm4gJydbS0VZXShPKSAhPSA3O1xyXG4gIH0pKXtcclxuICAgIHJlZGVmaW5lKFN0cmluZy5wcm90b3R5cGUsIEtFWSwgc3RyZm4pO1xyXG4gICAgaGlkZShSZWdFeHAucHJvdG90eXBlLCBTWU1CT0wsIGxlbmd0aCA9PSAyXHJcbiAgICAgIC8vIDIxLjIuNS44IFJlZ0V4cC5wcm90b3R5cGVbQEByZXBsYWNlXShzdHJpbmcsIHJlcGxhY2VWYWx1ZSlcclxuICAgICAgLy8gMjEuMi41LjExIFJlZ0V4cC5wcm90b3R5cGVbQEBzcGxpdF0oc3RyaW5nLCBsaW1pdClcclxuICAgICAgPyBmdW5jdGlvbihzdHJpbmcsIGFyZyl7IHJldHVybiByeGZuLmNhbGwoc3RyaW5nLCB0aGlzLCBhcmcpOyB9XHJcbiAgICAgIC8vIDIxLjIuNS42IFJlZ0V4cC5wcm90b3R5cGVbQEBtYXRjaF0oc3RyaW5nKVxyXG4gICAgICAvLyAyMS4yLjUuOSBSZWdFeHAucHJvdG90eXBlW0BAc2VhcmNoXShzdHJpbmcpXHJcbiAgICAgIDogZnVuY3Rpb24oc3RyaW5nKXsgcmV0dXJuIHJ4Zm4uY2FsbChzdHJpbmcsIHRoaXMpOyB9XHJcbiAgICApO1xyXG4gIH1cclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZsYWdzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmxhZ3MuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyAyMS4yLjUuMyBnZXQgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xyXG52YXIgYW5PYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpe1xyXG4gIHZhciB0aGF0ICAgPSBhbk9iamVjdCh0aGlzKVxyXG4gICAgLCByZXN1bHQgPSAnJztcclxuICBpZih0aGF0Lmdsb2JhbCkgICAgIHJlc3VsdCArPSAnZyc7XHJcbiAgaWYodGhhdC5pZ25vcmVDYXNlKSByZXN1bHQgKz0gJ2knO1xyXG4gIGlmKHRoYXQubXVsdGlsaW5lKSAgcmVzdWx0ICs9ICdtJztcclxuICBpZih0aGF0LnVuaWNvZGUpICAgIHJlc3VsdCArPSAndSc7XHJcbiAgaWYodGhhdC5zdGlja3kpICAgICByZXN1bHQgKz0gJ3knO1xyXG4gIHJldHVybiByZXN1bHQ7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mb3Itb2YuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgY3R4ICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jdHggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qc1wiKVxyXG4gICwgY2FsbCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyLWNhbGwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY2FsbC5qc1wiKVxyXG4gICwgaXNBcnJheUl0ZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1hcnJheS1pdGVyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b0xlbmd0aCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWxlbmd0aCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzXCIpXHJcbiAgLCBnZXRJdGVyRm4gICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qc1wiKVxyXG4gICwgQlJFQUsgICAgICAgPSB7fVxyXG4gICwgUkVUVVJOICAgICAgPSB7fTtcclxudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0ZXJhYmxlLCBlbnRyaWVzLCBmbiwgdGhhdCwgSVRFUkFUT1Ipe1xyXG4gIHZhciBpdGVyRm4gPSBJVEVSQVRPUiA/IGZ1bmN0aW9uKCl7IHJldHVybiBpdGVyYWJsZTsgfSA6IGdldEl0ZXJGbihpdGVyYWJsZSlcclxuICAgICwgZiAgICAgID0gY3R4KGZuLCB0aGF0LCBlbnRyaWVzID8gMiA6IDEpXHJcbiAgICAsIGluZGV4ICA9IDBcclxuICAgICwgbGVuZ3RoLCBzdGVwLCBpdGVyYXRvciwgcmVzdWx0O1xyXG4gIGlmKHR5cGVvZiBpdGVyRm4gIT0gJ2Z1bmN0aW9uJyl0aHJvdyBUeXBlRXJyb3IoaXRlcmFibGUgKyAnIGlzIG5vdCBpdGVyYWJsZSEnKTtcclxuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcclxuICBpZihpc0FycmF5SXRlcihpdGVyRm4pKWZvcihsZW5ndGggPSB0b0xlbmd0aChpdGVyYWJsZS5sZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKyl7XHJcbiAgICByZXN1bHQgPSBlbnRyaWVzID8gZihhbk9iamVjdChzdGVwID0gaXRlcmFibGVbaW5kZXhdKVswXSwgc3RlcFsxXSkgOiBmKGl0ZXJhYmxlW2luZGV4XSk7XHJcbiAgICBpZihyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKXJldHVybiByZXN1bHQ7XHJcbiAgfSBlbHNlIGZvcihpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKGl0ZXJhYmxlKTsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyApe1xyXG4gICAgcmVzdWx0ID0gY2FsbChpdGVyYXRvciwgZiwgc3RlcC52YWx1ZSwgZW50cmllcyk7XHJcbiAgICBpZihyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKXJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG59O1xyXG5leHBvcnRzLkJSRUFLICA9IEJSRUFLO1xyXG5leHBvcnRzLlJFVFVSTiA9IFJFVFVSTjtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcclxuXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XHJcbnZhciBnbG9iYWwgPSBtb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiB3aW5kb3cgIT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lk1hdGggPT0gTWF0aFxyXG4gID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09IE1hdGggPyBzZWxmIDogRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcclxuaWYodHlwZW9mIF9fZyA9PSAnbnVtYmVyJylfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oYXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcclxuXHJcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IHt9Lmhhc093blByb3BlcnR5O1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBrZXkpe1xyXG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGl0LCBrZXkpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBkUCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWRwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcIilcclxuICAsIGNyZWF0ZURlc2MgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19wcm9wZXJ0eS1kZXNjICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Rlc2NyaXB0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qc1wiKSA/IGZ1bmN0aW9uKG9iamVjdCwga2V5LCB2YWx1ZSl7XHJcbiAgcmV0dXJuIGRQLmYob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcclxufSA6IGZ1bmN0aW9uKG9iamVjdCwga2V5LCB2YWx1ZSl7XHJcbiAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcclxuICByZXR1cm4gb2JqZWN0O1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIikuZG9jdW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9ICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZXNjcmlwdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanNcIikgJiYgIV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKShmdW5jdGlvbigpe1xyXG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZG9tLWNyZWF0ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qc1wiKSgnZGl2JyksICdhJywge2dldDogZnVuY3Rpb24oKXsgcmV0dXJuIDc7IH19KS5hICE9IDc7XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW5oZXJpdC1pZi1yZXF1aXJlZC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW5oZXJpdC1pZi1yZXF1aXJlZC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBpc09iamVjdCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzXCIpXHJcbiAgLCBzZXRQcm90b3R5cGVPZiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NldC1wcm90byAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzXCIpLnNldDtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0aGF0LCB0YXJnZXQsIEMpe1xyXG4gIHZhciBQLCBTID0gdGFyZ2V0LmNvbnN0cnVjdG9yO1xyXG4gIGlmKFMgIT09IEMgJiYgdHlwZW9mIFMgPT0gJ2Z1bmN0aW9uJyAmJiAoUCA9IFMucHJvdG90eXBlKSAhPT0gQy5wcm90b3R5cGUgJiYgaXNPYmplY3QoUCkgJiYgc2V0UHJvdG90eXBlT2Ype1xyXG4gICAgc2V0UHJvdG90eXBlT2YodGhhdCwgUCk7XHJcbiAgfSByZXR1cm4gdGhhdDtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pbnZva2UuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcclxuXHJcbi8vIGZhc3QgYXBwbHksIGh0dHA6Ly9qc3BlcmYubG5raXQuY29tL2Zhc3QtYXBwbHkvNVxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZuLCBhcmdzLCB0aGF0KXtcclxuICB2YXIgdW4gPSB0aGF0ID09PSB1bmRlZmluZWQ7XHJcbiAgc3dpdGNoKGFyZ3MubGVuZ3RoKXtcclxuICAgIGNhc2UgMDogcmV0dXJuIHVuID8gZm4oKVxyXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQpO1xyXG4gICAgY2FzZSAxOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0pO1xyXG4gICAgY2FzZSAyOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xyXG4gICAgY2FzZSAzOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xyXG4gICAgY2FzZSA0OiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xyXG4gIH0gcmV0dXJuICAgICAgICAgICAgICBmbi5hcHBseSh0aGF0LCBhcmdzKTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xyXG52YXIgY29mID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2YuanNcIik7XHJcbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0KCd6JykucHJvcGVydHlJc0VudW1lcmFibGUoMCkgPyBPYmplY3QgOiBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIGNvZihpdCkgPT0gJ1N0cmluZycgPyBpdC5zcGxpdCgnJykgOiBPYmplY3QoaXQpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIGNoZWNrIG9uIGRlZmF1bHQgQXJyYXkgaXRlcmF0b3JcclxudmFyIEl0ZXJhdG9ycyAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyYXRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXJhdG9ycy5qc1wiKVxyXG4gICwgSVRFUkFUT1IgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCdpdGVyYXRvcicpXHJcbiAgLCBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIGl0ICE9PSB1bmRlZmluZWQgJiYgKEl0ZXJhdG9ycy5BcnJheSA9PT0gaXQgfHwgQXJyYXlQcm90b1tJVEVSQVRPUl0gPT09IGl0KTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWFycmF5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gNy4yLjIgSXNBcnJheShhcmd1bWVudClcclxudmFyIGNvZiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gaXNBcnJheShhcmcpe1xyXG4gIHJldHVybiBjb2YoYXJnKSA9PSAnQXJyYXknO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtaW50ZWdlci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtaW50ZWdlci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjEuMi4zIE51bWJlci5pc0ludGVnZXIobnVtYmVyKVxyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgZmxvb3IgICAgPSBNYXRoLmZsb29yO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzSW50ZWdlcihpdCl7XHJcbiAgcmV0dXJuICFpc09iamVjdChpdCkgJiYgaXNGaW5pdGUoaXQpICYmIGZsb29yKGl0KSA9PT0gaXQ7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcclxuICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtcmVnZXhwLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLXJlZ2V4cC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gNy4yLjggSXNSZWdFeHAoYXJndW1lbnQpXHJcbnZhciBpc09iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzXCIpXHJcbiAgLCBjb2YgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzXCIpXHJcbiAgLCBNQVRDSCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCdtYXRjaCcpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcclxuICB2YXIgaXNSZWdFeHA7XHJcbiAgcmV0dXJuIGlzT2JqZWN0KGl0KSAmJiAoKGlzUmVnRXhwID0gaXRbTUFUQ0hdKSAhPT0gdW5kZWZpbmVkID8gISFpc1JlZ0V4cCA6IGNvZihpdCkgPT0gJ1JlZ0V4cCcpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jYWxsLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY2FsbC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxyXG52YXIgYW5PYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKXtcclxuICB0cnkge1xyXG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcclxuICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxyXG4gIH0gY2F0Y2goZSl7XHJcbiAgICB2YXIgcmV0ID0gaXRlcmF0b3JbJ3JldHVybiddO1xyXG4gICAgaWYocmV0ICE9PSB1bmRlZmluZWQpYW5PYmplY3QocmV0LmNhbGwoaXRlcmF0b3IpKTtcclxuICAgIHRocm93IGU7XHJcbiAgfVxyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jcmVhdGUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNyZWF0ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciBjcmVhdGUgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1jcmVhdGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanNcIilcclxuICAsIGRlc2NyaXB0b3IgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcHJvcGVydHktZGVzYyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qc1wiKVxyXG4gICwgc2V0VG9TdHJpbmdUYWcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zZXQtdG8tc3RyaW5nLXRhZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanNcIilcclxuICAsIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XHJcblxyXG4vLyAyNS4xLjIuMS4xICVJdGVyYXRvclByb3RvdHlwZSVbQEBpdGVyYXRvcl0oKVxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oaWRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzXCIpKEl0ZXJhdG9yUHJvdG90eXBlLCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgnaXRlcmF0b3InKSwgZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXM7IH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCl7XHJcbiAgQ29uc3RydWN0b3IucHJvdG90eXBlID0gY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlLCB7bmV4dDogZGVzY3JpcHRvcigxLCBuZXh0KX0pO1xyXG4gIHNldFRvU3RyaW5nVGFnKENvbnN0cnVjdG9yLCBOQU1FICsgJyBJdGVyYXRvcicpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZWZpbmUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciBMSUJSQVJZICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2xpYnJhcnkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanNcIilcclxuICAsICRleHBvcnQgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHJlZGVmaW5lICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXCIpXHJcbiAgLCBoaWRlICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hpZGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hpZGUuanNcIilcclxuICAsIGhhcyAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faGFzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oYXMuanNcIilcclxuICAsIEl0ZXJhdG9ycyAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXRlcmF0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanNcIilcclxuICAsICRpdGVyQ3JlYXRlICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXRlci1jcmVhdGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzXCIpXHJcbiAgLCBzZXRUb1N0cmluZ1RhZyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NldC10by1zdHJpbmctdGFnICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtdG8tc3RyaW5nLXRhZy5qc1wiKVxyXG4gICwgZ2V0UHJvdG90eXBlT2YgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ3BvICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzXCIpXHJcbiAgLCBJVEVSQVRPUiAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCdpdGVyYXRvcicpXHJcbiAgLCBCVUdHWSAgICAgICAgICA9ICEoW10ua2V5cyAmJiAnbmV4dCcgaW4gW10ua2V5cygpKSAvLyBTYWZhcmkgaGFzIGJ1Z2d5IGl0ZXJhdG9ycyB3L28gYG5leHRgXHJcbiAgLCBGRl9JVEVSQVRPUiAgICA9ICdAQGl0ZXJhdG9yJ1xyXG4gICwgS0VZUyAgICAgICAgICAgPSAna2V5cydcclxuICAsIFZBTFVFUyAgICAgICAgID0gJ3ZhbHVlcyc7XHJcblxyXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihCYXNlLCBOQU1FLCBDb25zdHJ1Y3RvciwgbmV4dCwgREVGQVVMVCwgSVNfU0VULCBGT1JDRUQpe1xyXG4gICRpdGVyQ3JlYXRlKENvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KTtcclxuICB2YXIgZ2V0TWV0aG9kID0gZnVuY3Rpb24oa2luZCl7XHJcbiAgICBpZighQlVHR1kgJiYga2luZCBpbiBwcm90bylyZXR1cm4gcHJvdG9ba2luZF07XHJcbiAgICBzd2l0Y2goa2luZCl7XHJcbiAgICAgIGNhc2UgS0VZUzogcmV0dXJuIGZ1bmN0aW9uIGtleXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcclxuICAgICAgY2FzZSBWQUxVRVM6IHJldHVybiBmdW5jdGlvbiB2YWx1ZXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcclxuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcclxuICB9O1xyXG4gIHZhciBUQUcgICAgICAgID0gTkFNRSArICcgSXRlcmF0b3InXHJcbiAgICAsIERFRl9WQUxVRVMgPSBERUZBVUxUID09IFZBTFVFU1xyXG4gICAgLCBWQUxVRVNfQlVHID0gZmFsc2VcclxuICAgICwgcHJvdG8gICAgICA9IEJhc2UucHJvdG90eXBlXHJcbiAgICAsICRuYXRpdmUgICAgPSBwcm90b1tJVEVSQVRPUl0gfHwgcHJvdG9bRkZfSVRFUkFUT1JdIHx8IERFRkFVTFQgJiYgcHJvdG9bREVGQVVMVF1cclxuICAgICwgJGRlZmF1bHQgICA9ICRuYXRpdmUgfHwgZ2V0TWV0aG9kKERFRkFVTFQpXHJcbiAgICAsICRlbnRyaWVzICAgPSBERUZBVUxUID8gIURFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZCgnZW50cmllcycpIDogdW5kZWZpbmVkXHJcbiAgICAsICRhbnlOYXRpdmUgPSBOQU1FID09ICdBcnJheScgPyBwcm90by5lbnRyaWVzIHx8ICRuYXRpdmUgOiAkbmF0aXZlXHJcbiAgICAsIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XHJcbiAgLy8gRml4IG5hdGl2ZVxyXG4gIGlmKCRhbnlOYXRpdmUpe1xyXG4gICAgSXRlcmF0b3JQcm90b3R5cGUgPSBnZXRQcm90b3R5cGVPZigkYW55TmF0aXZlLmNhbGwobmV3IEJhc2UpKTtcclxuICAgIGlmKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlKXtcclxuICAgICAgLy8gU2V0IEBAdG9TdHJpbmdUYWcgdG8gbmF0aXZlIGl0ZXJhdG9yc1xyXG4gICAgICBzZXRUb1N0cmluZ1RhZyhJdGVyYXRvclByb3RvdHlwZSwgVEFHLCB0cnVlKTtcclxuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXHJcbiAgICAgIGlmKCFMSUJSQVJZICYmICFoYXMoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SKSloaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcclxuICBpZihERUZfVkFMVUVTICYmICRuYXRpdmUgJiYgJG5hdGl2ZS5uYW1lICE9PSBWQUxVRVMpe1xyXG4gICAgVkFMVUVTX0JVRyA9IHRydWU7XHJcbiAgICAkZGVmYXVsdCA9IGZ1bmN0aW9uIHZhbHVlcygpeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xyXG4gIH1cclxuICAvLyBEZWZpbmUgaXRlcmF0b3JcclxuICBpZigoIUxJQlJBUlkgfHwgRk9SQ0VEKSAmJiAoQlVHR1kgfHwgVkFMVUVTX0JVRyB8fCAhcHJvdG9bSVRFUkFUT1JdKSl7XHJcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xyXG4gIH1cclxuICAvLyBQbHVnIGZvciBsaWJyYXJ5XHJcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XHJcbiAgSXRlcmF0b3JzW1RBR10gID0gcmV0dXJuVGhpcztcclxuICBpZihERUZBVUxUKXtcclxuICAgIG1ldGhvZHMgPSB7XHJcbiAgICAgIHZhbHVlczogIERFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChWQUxVRVMpLFxyXG4gICAgICBrZXlzOiAgICBJU19TRVQgICAgID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoS0VZUyksXHJcbiAgICAgIGVudHJpZXM6ICRlbnRyaWVzXHJcbiAgICB9O1xyXG4gICAgaWYoRk9SQ0VEKWZvcihrZXkgaW4gbWV0aG9kcyl7XHJcbiAgICAgIGlmKCEoa2V5IGluIHByb3RvKSlyZWRlZmluZShwcm90bywga2V5LCBtZXRob2RzW2tleV0pO1xyXG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcclxuICB9XHJcbiAgcmV0dXJuIG1ldGhvZHM7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRldGVjdC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGV0ZWN0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBJVEVSQVRPUiAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgnaXRlcmF0b3InKVxyXG4gICwgU0FGRV9DTE9TSU5HID0gZmFsc2U7XHJcblxyXG50cnkge1xyXG4gIHZhciByaXRlciA9IFs3XVtJVEVSQVRPUl0oKTtcclxuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbigpeyBTQUZFX0NMT1NJTkcgPSB0cnVlOyB9O1xyXG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uKCl7IHRocm93IDI7IH0pO1xyXG59IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGV4ZWMsIHNraXBDbG9zaW5nKXtcclxuICBpZighc2tpcENsb3NpbmcgJiYgIVNBRkVfQ0xPU0lORylyZXR1cm4gZmFsc2U7XHJcbiAgdmFyIHNhZmUgPSBmYWxzZTtcclxuICB0cnkge1xyXG4gICAgdmFyIGFyciAgPSBbN11cclxuICAgICAgLCBpdGVyID0gYXJyW0lURVJBVE9SXSgpO1xyXG4gICAgaXRlci5uZXh0ID0gZnVuY3Rpb24oKXsgcmV0dXJuIHtkb25lOiBzYWZlID0gdHJ1ZX07IH07XHJcbiAgICBhcnJbSVRFUkFUT1JdID0gZnVuY3Rpb24oKXsgcmV0dXJuIGl0ZXI7IH07XHJcbiAgICBleGVjKGFycik7XHJcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxyXG4gIHJldHVybiBzYWZlO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1zdGVwLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihkb25lLCB2YWx1ZSl7XHJcbiAgcmV0dXJuIHt2YWx1ZTogdmFsdWUsIGRvbmU6ICEhZG9uZX07XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHt9O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fa2V5b2YuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19rZXlvZi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgZ2V0S2V5cyAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLmpzXCIpXHJcbiAgLCB0b0lPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iamVjdCwgZWwpe1xyXG4gIHZhciBPICAgICAgPSB0b0lPYmplY3Qob2JqZWN0KVxyXG4gICAgLCBrZXlzICAgPSBnZXRLZXlzKE8pXHJcbiAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXHJcbiAgICAsIGluZGV4ICA9IDBcclxuICAgICwga2V5O1xyXG4gIHdoaWxlKGxlbmd0aCA+IGluZGV4KWlmKE9ba2V5ID0ga2V5c1tpbmRleCsrXV0gPT09IGVsKXJldHVybiBrZXk7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmYWxzZTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21hdGgtZXhwbTEuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21hdGgtZXhwbTEuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG4vLyAyMC4yLjIuMTQgTWF0aC5leHBtMSh4KVxyXG52YXIgJGV4cG0xID0gTWF0aC5leHBtMTtcclxubW9kdWxlLmV4cG9ydHMgPSAoISRleHBtMVxyXG4gIC8vIE9sZCBGRiBidWdcclxuICB8fCAkZXhwbTEoMTApID4gMjIwMjUuNDY1Nzk0ODA2NzE5IHx8ICRleHBtMSgxMCkgPCAyMjAyNS40NjU3OTQ4MDY3MTY1MTY4XHJcbiAgLy8gVG9yIEJyb3dzZXIgYnVnXHJcbiAgfHwgJGV4cG0xKC0yZS0xNykgIT0gLTJlLTE3XHJcbikgPyBmdW5jdGlvbiBleHBtMSh4KXtcclxuICByZXR1cm4gKHggPSAreCkgPT0gMCA/IHggOiB4ID4gLTFlLTYgJiYgeCA8IDFlLTYgPyB4ICsgeCAqIHggLyAyIDogTWF0aC5leHAoeCkgLSAxO1xyXG59IDogJGV4cG0xO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1sb2cxcC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1sb2cxcC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcclxuXHJcbi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXHJcbm1vZHVsZS5leHBvcnRzID0gTWF0aC5sb2cxcCB8fCBmdW5jdGlvbiBsb2cxcCh4KXtcclxuICByZXR1cm4gKHggPSAreCkgPiAtMWUtOCAmJiB4IDwgMWUtOCA/IHggLSB4ICogeCAvIDIgOiBNYXRoLmxvZygxICsgeCk7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLXNpZ24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG4vLyAyMC4yLjIuMjggTWF0aC5zaWduKHgpXHJcbm1vZHVsZS5leHBvcnRzID0gTWF0aC5zaWduIHx8IGZ1bmN0aW9uIHNpZ24oeCl7XHJcbiAgcmV0dXJuICh4ID0gK3gpID09IDAgfHwgeCAhPSB4ID8geCA6IHggPCAwID8gLTEgOiAxO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWV0YS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWV0YS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBNRVRBICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3VpZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzXCIpKCdtZXRhJylcclxuICAsIGlzT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIilcclxuICAsIGhhcyAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faGFzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oYXMuanNcIilcclxuICAsIHNldERlc2MgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWRwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcIikuZlxyXG4gICwgaWQgICAgICAgPSAwO1xyXG52YXIgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZSB8fCBmdW5jdGlvbigpe1xyXG4gIHJldHVybiB0cnVlO1xyXG59O1xyXG52YXIgRlJFRVpFID0gIV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKShmdW5jdGlvbigpe1xyXG4gIHJldHVybiBpc0V4dGVuc2libGUoT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHt9KSk7XHJcbn0pO1xyXG52YXIgc2V0TWV0YSA9IGZ1bmN0aW9uKGl0KXtcclxuICBzZXREZXNjKGl0LCBNRVRBLCB7dmFsdWU6IHtcclxuICAgIGk6ICdPJyArICsraWQsIC8vIG9iamVjdCBJRFxyXG4gICAgdzoge30gICAgICAgICAgLy8gd2VhayBjb2xsZWN0aW9ucyBJRHNcclxuICB9fSk7XHJcbn07XHJcbnZhciBmYXN0S2V5ID0gZnVuY3Rpb24oaXQsIGNyZWF0ZSl7XHJcbiAgLy8gcmV0dXJuIHByaW1pdGl2ZSB3aXRoIHByZWZpeFxyXG4gIGlmKCFpc09iamVjdChpdCkpcmV0dXJuIHR5cGVvZiBpdCA9PSAnc3ltYm9sJyA/IGl0IDogKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyA/ICdTJyA6ICdQJykgKyBpdDtcclxuICBpZighaGFzKGl0LCBNRVRBKSl7XHJcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxyXG4gICAgaWYoIWlzRXh0ZW5zaWJsZShpdCkpcmV0dXJuICdGJztcclxuICAgIC8vIG5vdCBuZWNlc3NhcnkgdG8gYWRkIG1ldGFkYXRhXHJcbiAgICBpZighY3JlYXRlKXJldHVybiAnRSc7XHJcbiAgICAvLyBhZGQgbWlzc2luZyBtZXRhZGF0YVxyXG4gICAgc2V0TWV0YShpdCk7XHJcbiAgLy8gcmV0dXJuIG9iamVjdCBJRFxyXG4gIH0gcmV0dXJuIGl0W01FVEFdLmk7XHJcbn07XHJcbnZhciBnZXRXZWFrID0gZnVuY3Rpb24oaXQsIGNyZWF0ZSl7XHJcbiAgaWYoIWhhcyhpdCwgTUVUQSkpe1xyXG4gICAgLy8gY2FuJ3Qgc2V0IG1ldGFkYXRhIHRvIHVuY2F1Z2h0IGZyb3plbiBvYmplY3RcclxuICAgIGlmKCFpc0V4dGVuc2libGUoaXQpKXJldHVybiB0cnVlO1xyXG4gICAgLy8gbm90IG5lY2Vzc2FyeSB0byBhZGQgbWV0YWRhdGFcclxuICAgIGlmKCFjcmVhdGUpcmV0dXJuIGZhbHNlO1xyXG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcclxuICAgIHNldE1ldGEoaXQpO1xyXG4gIC8vIHJldHVybiBoYXNoIHdlYWsgY29sbGVjdGlvbnMgSURzXHJcbiAgfSByZXR1cm4gaXRbTUVUQV0udztcclxufTtcclxuLy8gYWRkIG1ldGFkYXRhIG9uIGZyZWV6ZS1mYW1pbHkgbWV0aG9kcyBjYWxsaW5nXHJcbnZhciBvbkZyZWV6ZSA9IGZ1bmN0aW9uKGl0KXtcclxuICBpZihGUkVFWkUgJiYgbWV0YS5ORUVEICYmIGlzRXh0ZW5zaWJsZShpdCkgJiYgIWhhcyhpdCwgTUVUQSkpc2V0TWV0YShpdCk7XHJcbiAgcmV0dXJuIGl0O1xyXG59O1xyXG52YXIgbWV0YSA9IG1vZHVsZS5leHBvcnRzID0ge1xyXG4gIEtFWTogICAgICBNRVRBLFxyXG4gIE5FRUQ6ICAgICBmYWxzZSxcclxuICBmYXN0S2V5OiAgZmFzdEtleSxcclxuICBnZXRXZWFrOiAgZ2V0V2VhayxcclxuICBvbkZyZWV6ZTogb25GcmVlemVcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGFkYXRhLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWV0YWRhdGEuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIE1hcCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2VzNi5tYXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hcC5qc1wiKVxyXG4gICwgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBzaGFyZWQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2hhcmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanNcIikoJ21ldGFkYXRhJylcclxuICAsIHN0b3JlICAgPSBzaGFyZWQuc3RvcmUgfHwgKHNoYXJlZC5zdG9yZSA9IG5ldyAoX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9lczYud2Vhay1tYXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LndlYWstbWFwLmpzXCIpKSk7XHJcblxyXG52YXIgZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcCA9IGZ1bmN0aW9uKHRhcmdldCwgdGFyZ2V0S2V5LCBjcmVhdGUpe1xyXG4gIHZhciB0YXJnZXRNZXRhZGF0YSA9IHN0b3JlLmdldCh0YXJnZXQpO1xyXG4gIGlmKCF0YXJnZXRNZXRhZGF0YSl7XHJcbiAgICBpZighY3JlYXRlKXJldHVybiB1bmRlZmluZWQ7XHJcbiAgICBzdG9yZS5zZXQodGFyZ2V0LCB0YXJnZXRNZXRhZGF0YSA9IG5ldyBNYXApO1xyXG4gIH1cclxuICB2YXIga2V5TWV0YWRhdGEgPSB0YXJnZXRNZXRhZGF0YS5nZXQodGFyZ2V0S2V5KTtcclxuICBpZigha2V5TWV0YWRhdGEpe1xyXG4gICAgaWYoIWNyZWF0ZSlyZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgdGFyZ2V0TWV0YWRhdGEuc2V0KHRhcmdldEtleSwga2V5TWV0YWRhdGEgPSBuZXcgTWFwKTtcclxuICB9IHJldHVybiBrZXlNZXRhZGF0YTtcclxufTtcclxudmFyIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBmdW5jdGlvbihNZXRhZGF0YUtleSwgTywgUCl7XHJcbiAgdmFyIG1ldGFkYXRhTWFwID0gZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCBmYWxzZSk7XHJcbiAgcmV0dXJuIG1ldGFkYXRhTWFwID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IG1ldGFkYXRhTWFwLmhhcyhNZXRhZGF0YUtleSk7XHJcbn07XHJcbnZhciBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gZnVuY3Rpb24oTWV0YWRhdGFLZXksIE8sIFApe1xyXG4gIHZhciBtZXRhZGF0YU1hcCA9IGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgZmFsc2UpO1xyXG4gIHJldHVybiBtZXRhZGF0YU1hcCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogbWV0YWRhdGFNYXAuZ2V0KE1ldGFkYXRhS2V5KTtcclxufTtcclxudmFyIG9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEgPSBmdW5jdGlvbihNZXRhZGF0YUtleSwgTWV0YWRhdGFWYWx1ZSwgTywgUCl7XHJcbiAgZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCB0cnVlKS5zZXQoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUpO1xyXG59O1xyXG52YXIgb3JkaW5hcnlPd25NZXRhZGF0YUtleXMgPSBmdW5jdGlvbih0YXJnZXQsIHRhcmdldEtleSl7XHJcbiAgdmFyIG1ldGFkYXRhTWFwID0gZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcCh0YXJnZXQsIHRhcmdldEtleSwgZmFsc2UpXHJcbiAgICAsIGtleXMgICAgICAgID0gW107XHJcbiAgaWYobWV0YWRhdGFNYXApbWV0YWRhdGFNYXAuZm9yRWFjaChmdW5jdGlvbihfLCBrZXkpeyBrZXlzLnB1c2goa2V5KTsgfSk7XHJcbiAgcmV0dXJuIGtleXM7XHJcbn07XHJcbnZhciB0b01ldGFLZXkgPSBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIGl0ID09ICdzeW1ib2wnID8gaXQgOiBTdHJpbmcoaXQpO1xyXG59O1xyXG52YXIgZXhwID0gZnVuY3Rpb24oTyl7XHJcbiAgJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgTyk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuICBzdG9yZTogc3RvcmUsXHJcbiAgbWFwOiBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwLFxyXG4gIGhhczogb3JkaW5hcnlIYXNPd25NZXRhZGF0YSxcclxuICBnZXQ6IG9yZGluYXJ5R2V0T3duTWV0YWRhdGEsXHJcbiAgc2V0OiBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhLFxyXG4gIGtleXM6IG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzLFxyXG4gIGtleTogdG9NZXRhS2V5LFxyXG4gIGV4cDogZXhwXHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWljcm90YXNrLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgZ2xvYmFsICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIilcclxuICAsIG1hY3JvdGFzayA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3Rhc2sgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanNcIikuc2V0XHJcbiAgLCBPYnNlcnZlciAgPSBnbG9iYWwuTXV0YXRpb25PYnNlcnZlciB8fCBnbG9iYWwuV2ViS2l0TXV0YXRpb25PYnNlcnZlclxyXG4gICwgcHJvY2VzcyAgID0gZ2xvYmFsLnByb2Nlc3NcclxuICAsIFByb21pc2UgICA9IGdsb2JhbC5Qcm9taXNlXHJcbiAgLCBpc05vZGUgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvZi5qc1wiKShwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCl7XHJcbiAgdmFyIGhlYWQsIGxhc3QsIG5vdGlmeTtcclxuXHJcbiAgdmFyIGZsdXNoID0gZnVuY3Rpb24oKXtcclxuICAgIHZhciBwYXJlbnQsIGZuO1xyXG4gICAgaWYoaXNOb2RlICYmIChwYXJlbnQgPSBwcm9jZXNzLmRvbWFpbikpcGFyZW50LmV4aXQoKTtcclxuICAgIHdoaWxlKGhlYWQpe1xyXG4gICAgICBmbiAgID0gaGVhZC5mbjtcclxuICAgICAgaGVhZCA9IGhlYWQubmV4dDtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBmbigpO1xyXG4gICAgICB9IGNhdGNoKGUpe1xyXG4gICAgICAgIGlmKGhlYWQpbm90aWZ5KCk7XHJcbiAgICAgICAgZWxzZSBsYXN0ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRocm93IGU7XHJcbiAgICAgIH1cclxuICAgIH0gbGFzdCA9IHVuZGVmaW5lZDtcclxuICAgIGlmKHBhcmVudClwYXJlbnQuZW50ZXIoKTtcclxuICB9O1xyXG5cclxuICAvLyBOb2RlLmpzXHJcbiAgaWYoaXNOb2RlKXtcclxuICAgIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XHJcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soZmx1c2gpO1xyXG4gICAgfTtcclxuICAvLyBicm93c2VycyB3aXRoIE11dGF0aW9uT2JzZXJ2ZXJcclxuICB9IGVsc2UgaWYoT2JzZXJ2ZXIpe1xyXG4gICAgdmFyIHRvZ2dsZSA9IHRydWVcclxuICAgICAgLCBub2RlICAgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XHJcbiAgICBuZXcgT2JzZXJ2ZXIoZmx1c2gpLm9ic2VydmUobm9kZSwge2NoYXJhY3RlckRhdGE6IHRydWV9KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcclxuICAgIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XHJcbiAgICAgIG5vZGUuZGF0YSA9IHRvZ2dsZSA9ICF0b2dnbGU7XHJcbiAgICB9O1xyXG4gIC8vIGVudmlyb25tZW50cyB3aXRoIG1heWJlIG5vbi1jb21wbGV0ZWx5IGNvcnJlY3QsIGJ1dCBleGlzdGVudCBQcm9taXNlXHJcbiAgfSBlbHNlIGlmKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKXtcclxuICAgIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICBub3RpZnkgPSBmdW5jdGlvbigpe1xyXG4gICAgICBwcm9taXNlLnRoZW4oZmx1c2gpO1xyXG4gICAgfTtcclxuICAvLyBmb3Igb3RoZXIgZW52aXJvbm1lbnRzIC0gbWFjcm90YXNrIGJhc2VkIG9uOlxyXG4gIC8vIC0gc2V0SW1tZWRpYXRlXHJcbiAgLy8gLSBNZXNzYWdlQ2hhbm5lbFxyXG4gIC8vIC0gd2luZG93LnBvc3RNZXNzYWdcclxuICAvLyAtIG9ucmVhZHlzdGF0ZWNoYW5nZVxyXG4gIC8vIC0gc2V0VGltZW91dFxyXG4gIH0gZWxzZSB7XHJcbiAgICBub3RpZnkgPSBmdW5jdGlvbigpe1xyXG4gICAgICAvLyBzdHJhbmdlIElFICsgd2VicGFjayBkZXYgc2VydmVyIGJ1ZyAtIHVzZSAuY2FsbChnbG9iYWwpXHJcbiAgICAgIG1hY3JvdGFzay5jYWxsKGdsb2JhbCwgZmx1c2gpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmdW5jdGlvbihmbil7XHJcbiAgICB2YXIgdGFzayA9IHtmbjogZm4sIG5leHQ6IHVuZGVmaW5lZH07XHJcbiAgICBpZihsYXN0KWxhc3QubmV4dCA9IHRhc2s7XHJcbiAgICBpZighaGVhZCl7XHJcbiAgICAgIGhlYWQgPSB0YXNrO1xyXG4gICAgICBub3RpZnkoKTtcclxuICAgIH0gbGFzdCA9IHRhc2s7XHJcbiAgfTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1hc3NpZ24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1hc3NpZ24uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIDE5LjEuMi4xIE9iamVjdC5hc3NpZ24odGFyZ2V0LCBzb3VyY2UsIC4uLilcclxudmFyIGdldEtleXMgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLmpzXCIpXHJcbiAgLCBnT1BTICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wcy5qc1wiKVxyXG4gICwgcElFICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtcGllICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtcGllLmpzXCIpXHJcbiAgLCB0b09iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzXCIpXHJcbiAgLCBJT2JqZWN0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lvYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanNcIilcclxuICAsICRhc3NpZ24gID0gT2JqZWN0LmFzc2lnbjtcclxuXHJcbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxyXG5tb2R1bGUuZXhwb3J0cyA9ICEkYXNzaWduIHx8IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKShmdW5jdGlvbigpe1xyXG4gIHZhciBBID0ge31cclxuICAgICwgQiA9IHt9XHJcbiAgICAsIFMgPSBTeW1ib2woKVxyXG4gICAgLCBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcclxuICBBW1NdID0gNztcclxuICBLLnNwbGl0KCcnKS5mb3JFYWNoKGZ1bmN0aW9uKGspeyBCW2tdID0gazsgfSk7XHJcbiAgcmV0dXJuICRhc3NpZ24oe30sIEEpW1NdICE9IDcgfHwgT2JqZWN0LmtleXMoJGFzc2lnbih7fSwgQikpLmpvaW4oJycpICE9IEs7XHJcbn0pID8gZnVuY3Rpb24gYXNzaWduKHRhcmdldCwgc291cmNlKXsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xyXG4gIHZhciBUICAgICA9IHRvT2JqZWN0KHRhcmdldClcclxuICAgICwgYUxlbiAgPSBhcmd1bWVudHMubGVuZ3RoXHJcbiAgICAsIGluZGV4ID0gMVxyXG4gICAgLCBnZXRTeW1ib2xzID0gZ09QUy5mXHJcbiAgICAsIGlzRW51bSAgICAgPSBwSUUuZjtcclxuICB3aGlsZShhTGVuID4gaW5kZXgpe1xyXG4gICAgdmFyIFMgICAgICA9IElPYmplY3QoYXJndW1lbnRzW2luZGV4KytdKVxyXG4gICAgICAsIGtleXMgICA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUylcclxuICAgICAgLCBsZW5ndGggPSBrZXlzLmxlbmd0aFxyXG4gICAgICAsIGogICAgICA9IDBcclxuICAgICAgLCBrZXk7XHJcbiAgICB3aGlsZShsZW5ndGggPiBqKWlmKGlzRW51bS5jYWxsKFMsIGtleSA9IGtleXNbaisrXSkpVFtrZXldID0gU1trZXldO1xyXG4gIH0gcmV0dXJuIFQ7XHJcbn0gOiAkYXNzaWduO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWNyZWF0ZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWNyZWF0ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxyXG52YXIgYW5PYmplY3QgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKVxyXG4gICwgZFBzICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHBzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHBzLmpzXCIpXHJcbiAgLCBlbnVtQnVnS2V5cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2VudW0tYnVnLWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanNcIilcclxuICAsIElFX1BST1RPICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2hhcmVkLWtleSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qc1wiKSgnSUVfUFJPVE8nKVxyXG4gICwgRW1wdHkgICAgICAgPSBmdW5jdGlvbigpeyAvKiBlbXB0eSAqLyB9XHJcbiAgLCBQUk9UT1RZUEUgICA9ICdwcm90b3R5cGUnO1xyXG5cclxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxyXG52YXIgY3JlYXRlRGljdCA9IGZ1bmN0aW9uKCl7XHJcbiAgLy8gVGhyYXNoLCB3YXN0ZSBhbmQgc29kb215OiBJRSBHQyBidWdcclxuICB2YXIgaWZyYW1lID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZG9tLWNyZWF0ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qc1wiKSgnaWZyYW1lJylcclxuICAgICwgaSAgICAgID0gZW51bUJ1Z0tleXMubGVuZ3RoXHJcbiAgICAsIGx0ICAgICA9ICc8J1xyXG4gICAgLCBndCAgICAgPSAnPidcclxuICAgICwgaWZyYW1lRG9jdW1lbnQ7XHJcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faHRtbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qc1wiKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xyXG4gIGlmcmFtZS5zcmMgPSAnamF2YXNjcmlwdDonOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNjcmlwdC11cmxcclxuICAvLyBjcmVhdGVEaWN0ID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuT2JqZWN0O1xyXG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcclxuICBpZnJhbWVEb2N1bWVudCA9IGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50O1xyXG4gIGlmcmFtZURvY3VtZW50Lm9wZW4oKTtcclxuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XHJcbiAgaWZyYW1lRG9jdW1lbnQuY2xvc2UoKTtcclxuICBjcmVhdGVEaWN0ID0gaWZyYW1lRG9jdW1lbnQuRjtcclxuICB3aGlsZShpLS0pZGVsZXRlIGNyZWF0ZURpY3RbUFJPVE9UWVBFXVtlbnVtQnVnS2V5c1tpXV07XHJcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcyl7XHJcbiAgdmFyIHJlc3VsdDtcclxuICBpZihPICE9PSBudWxsKXtcclxuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcclxuICAgIHJlc3VsdCA9IG5ldyBFbXB0eTtcclxuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBudWxsO1xyXG4gICAgLy8gYWRkIFwiX19wcm90b19fXCIgZm9yIE9iamVjdC5nZXRQcm90b3R5cGVPZiBwb2x5ZmlsbFxyXG4gICAgcmVzdWx0W0lFX1BST1RPXSA9IE87XHJcbiAgfSBlbHNlIHJlc3VsdCA9IGNyZWF0ZURpY3QoKTtcclxuICByZXR1cm4gUHJvcGVydGllcyA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogZFBzKHJlc3VsdCwgUHJvcGVydGllcyk7XHJcbn07XHJcblxyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGFuT2JqZWN0ICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYW4tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcIilcclxuICAsIElFOF9ET01fREVGSU5FID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faWU4LWRvbS1kZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2llOC1kb20tZGVmaW5lLmpzXCIpXHJcbiAgLCB0b1ByaW1pdGl2ZSAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLXByaW1pdGl2ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzXCIpXHJcbiAgLCBkUCAgICAgICAgICAgICA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcclxuXHJcbmV4cG9ydHMuZiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Rlc2NyaXB0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qc1wiKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpe1xyXG4gIGFuT2JqZWN0KE8pO1xyXG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcclxuICBhbk9iamVjdChBdHRyaWJ1dGVzKTtcclxuICBpZihJRThfRE9NX0RFRklORSl0cnkge1xyXG4gICAgcmV0dXJuIGRQKE8sIFAsIEF0dHJpYnV0ZXMpO1xyXG4gIH0gY2F0Y2goZSl7IC8qIGVtcHR5ICovIH1cclxuICBpZignZ2V0JyBpbiBBdHRyaWJ1dGVzIHx8ICdzZXQnIGluIEF0dHJpYnV0ZXMpdGhyb3cgVHlwZUVycm9yKCdBY2Nlc3NvcnMgbm90IHN1cHBvcnRlZCEnKTtcclxuICBpZigndmFsdWUnIGluIEF0dHJpYnV0ZXMpT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XHJcbiAgcmV0dXJuIE87XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHBzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHBzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGRQICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWRwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcIilcclxuICAsIGFuT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYW4tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcIilcclxuICAsIGdldEtleXMgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLmpzXCIpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZXNjcmlwdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanNcIikgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcyl7XHJcbiAgYW5PYmplY3QoTyk7XHJcbiAgdmFyIGtleXMgICA9IGdldEtleXMoUHJvcGVydGllcylcclxuICAgICwgbGVuZ3RoID0ga2V5cy5sZW5ndGhcclxuICAgICwgaSA9IDBcclxuICAgICwgUDtcclxuICB3aGlsZShsZW5ndGggPiBpKWRQLmYoTywgUCA9IGtleXNbaSsrXSwgUHJvcGVydGllc1tQXSk7XHJcbiAgcmV0dXJuIE87XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZm9yY2VkLXBhbS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1mb3JjZWQtcGFtLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIEZvcmNlZCByZXBsYWNlbWVudCBwcm90b3R5cGUgYWNjZXNzb3JzIG1ldGhvZHNcclxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19saWJyYXJ5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzXCIpfHwgIV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKShmdW5jdGlvbigpe1xyXG4gIHZhciBLID0gTWF0aC5yYW5kb20oKTtcclxuICAvLyBJbiBGRiB0aHJvd3Mgb25seSBkZWZpbmUgbWV0aG9kc1xyXG4gIF9fZGVmaW5lU2V0dGVyX18uY2FsbChudWxsLCBLLCBmdW5jdGlvbigpeyAvKiBlbXB0eSAqL30pO1xyXG4gIGRlbGV0ZSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKVtLXTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBwSUUgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1waWUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanNcIilcclxuICAsIGNyZWF0ZURlc2MgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcHJvcGVydHktZGVzYyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qc1wiKVxyXG4gICwgdG9JT2JqZWN0ICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCIpXHJcbiAgLCB0b1ByaW1pdGl2ZSAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLXByaW1pdGl2ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzXCIpXHJcbiAgLCBoYXMgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgLCBJRThfRE9NX0RFRklORSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2llOC1kb20tZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qc1wiKVxyXG4gICwgZ09QRCAgICAgICAgICAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xyXG5cclxuZXhwb3J0cy5mID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpID8gZ09QRCA6IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBQKXtcclxuICBPID0gdG9JT2JqZWN0KE8pO1xyXG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcclxuICBpZihJRThfRE9NX0RFRklORSl0cnkge1xyXG4gICAgcmV0dXJuIGdPUEQoTywgUCk7XHJcbiAgfSBjYXRjaChlKXsgLyogZW1wdHkgKi8gfVxyXG4gIGlmKGhhcyhPLCBQKSlyZXR1cm4gY3JlYXRlRGVzYyghcElFLmYuY2FsbChPLCBQKSwgT1tQXSk7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi1leHQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4tZXh0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XHJcbnZhciB0b0lPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCIpXHJcbiAgLCBnT1BOICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ29wbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanNcIikuZlxyXG4gICwgdG9TdHJpbmcgID0ge30udG9TdHJpbmc7XHJcblxyXG52YXIgd2luZG93TmFtZXMgPSB0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnICYmIHdpbmRvdyAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lc1xyXG4gID8gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMod2luZG93KSA6IFtdO1xyXG5cclxudmFyIGdldFdpbmRvd05hbWVzID0gZnVuY3Rpb24oaXQpe1xyXG4gIHRyeSB7XHJcbiAgICByZXR1cm4gZ09QTihpdCk7XHJcbiAgfSBjYXRjaChlKXtcclxuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xyXG4gIH1cclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzLmYgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKGl0KXtcclxuICByZXR1cm4gd2luZG93TmFtZXMgJiYgdG9TdHJpbmcuY2FsbChpdCkgPT0gJ1tvYmplY3QgV2luZG93XScgPyBnZXRXaW5kb3dOYW1lcyhpdCkgOiBnT1BOKHRvSU9iamVjdChpdCkpO1xyXG59O1xyXG5cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BuLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4yLjcgLyAxNS4yLjMuNCBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxyXG52YXIgJGtleXMgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1rZXlzLWludGVybmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy1pbnRlcm5hbC5qc1wiKVxyXG4gICwgaGlkZGVuS2V5cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2VudW0tYnVnLWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanNcIikuY29uY2F0KCdsZW5ndGgnLCAncHJvdG90eXBlJyk7XHJcblxyXG5leHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB8fCBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKE8pe1xyXG4gIHJldHVybiAka2V5cyhPLCBoaWRkZW5LZXlzKTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xyXG5cclxuZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAxOS4xLjIuOSAvIDE1LjIuMy4yIE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxyXG52YXIgaGFzICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oYXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qc1wiKVxyXG4gICwgdG9PYmplY3QgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLW9iamVjdC5qc1wiKVxyXG4gICwgSUVfUFJPVE8gICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zaGFyZWQta2V5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQta2V5LmpzXCIpKCdJRV9QUk9UTycpXHJcbiAgLCBPYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbihPKXtcclxuICBPID0gdG9PYmplY3QoTyk7XHJcbiAgaWYoaGFzKE8sIElFX1BST1RPKSlyZXR1cm4gT1tJRV9QUk9UT107XHJcbiAgaWYodHlwZW9mIE8uY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBPIGluc3RhbmNlb2YgTy5jb25zdHJ1Y3Rvcil7XHJcbiAgICByZXR1cm4gTy5jb25zdHJ1Y3Rvci5wcm90b3R5cGU7XHJcbiAgfSByZXR1cm4gTyBpbnN0YW5jZW9mIE9iamVjdCA/IE9iamVjdFByb3RvIDogbnVsbDtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMtaW50ZXJuYWwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGhhcyAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgLCB0b0lPYmplY3QgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCIpXHJcbiAgLCBhcnJheUluZGV4T2YgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1pbmNsdWRlcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktaW5jbHVkZXMuanNcIikoZmFsc2UpXHJcbiAgLCBJRV9QUk9UTyAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zaGFyZWQta2V5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQta2V5LmpzXCIpKCdJRV9QUk9UTycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmplY3QsIG5hbWVzKXtcclxuICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KG9iamVjdClcclxuICAgICwgaSAgICAgID0gMFxyXG4gICAgLCByZXN1bHQgPSBbXVxyXG4gICAgLCBrZXk7XHJcbiAgZm9yKGtleSBpbiBPKWlmKGtleSAhPSBJRV9QUk9UTyloYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xyXG4gIC8vIERvbid0IGVudW0gYnVnICYgaGlkZGVuIGtleXNcclxuICB3aGlsZShuYW1lcy5sZW5ndGggPiBpKWlmKGhhcyhPLCBrZXkgPSBuYW1lc1tpKytdKSl7XHJcbiAgICB+YXJyYXlJbmRleE9mKHJlc3VsdCwga2V5KSB8fCByZXN1bHQucHVzaChrZXkpO1xyXG4gIH1cclxuICByZXR1cm4gcmVzdWx0O1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAxOS4xLjIuMTQgLyAxNS4yLjMuMTQgT2JqZWN0LmtleXMoTylcclxudmFyICRrZXlzICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWtleXMtaW50ZXJuYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzXCIpXHJcbiAgLCBlbnVtQnVnS2V5cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2VudW0tYnVnLWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanNcIik7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIGtleXMoTyl7XHJcbiAgcmV0dXJuICRrZXlzKE8sIGVudW1CdWdLZXlzKTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5leHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1zYXAuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1zYXAuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBtb3N0IE9iamVjdCBtZXRob2RzIGJ5IEVTNiBzaG91bGQgYWNjZXB0IHByaW1pdGl2ZXNcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgY29yZSAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvcmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvcmUuanNcIilcclxuICAsIGZhaWxzICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIik7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBleGVjKXtcclxuICB2YXIgZm4gID0gKGNvcmUuT2JqZWN0IHx8IHt9KVtLRVldIHx8IE9iamVjdFtLRVldXHJcbiAgICAsIGV4cCA9IHt9O1xyXG4gIGV4cFtLRVldID0gZXhlYyhmbik7XHJcbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbigpeyBmbigxKTsgfSksICdPYmplY3QnLCBleHApO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXRvLWFycmF5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC10by1hcnJheS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGdldEtleXMgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1rZXlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qc1wiKVxyXG4gICwgdG9JT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qc1wiKVxyXG4gICwgaXNFbnVtICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LXBpZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qc1wiKS5mO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGlzRW50cmllcyl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uKGl0KXtcclxuICAgIHZhciBPICAgICAgPSB0b0lPYmplY3QoaXQpXHJcbiAgICAgICwga2V5cyAgID0gZ2V0S2V5cyhPKVxyXG4gICAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXHJcbiAgICAgICwgaSAgICAgID0gMFxyXG4gICAgICAsIHJlc3VsdCA9IFtdXHJcbiAgICAgICwga2V5O1xyXG4gICAgd2hpbGUobGVuZ3RoID4gaSlpZihpc0VudW0uY2FsbChPLCBrZXkgPSBrZXlzW2krK10pKXtcclxuICAgICAgcmVzdWx0LnB1c2goaXNFbnRyaWVzID8gW2tleSwgT1trZXldXSA6IE9ba2V5XSk7XHJcbiAgICB9IHJldHVybiByZXN1bHQ7XHJcbiAgfTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX293bi1rZXlzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb3duLWtleXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gYWxsIG9iamVjdCBrZXlzLCBpbmNsdWRlcyBub24tZW51bWVyYWJsZSBhbmQgc3ltYm9sc1xyXG52YXIgZ09QTiAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ29wbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanNcIilcclxuICAsIGdPUFMgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BzLmpzXCIpXHJcbiAgLCBhbk9iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCBSZWZsZWN0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpLlJlZmxlY3Q7XHJcbm1vZHVsZS5leHBvcnRzID0gUmVmbGVjdCAmJiBSZWZsZWN0Lm93bktleXMgfHwgZnVuY3Rpb24gb3duS2V5cyhpdCl7XHJcbiAgdmFyIGtleXMgICAgICAgPSBnT1BOLmYoYW5PYmplY3QoaXQpKVxyXG4gICAgLCBnZXRTeW1ib2xzID0gZ09QUy5mO1xyXG4gIHJldHVybiBnZXRTeW1ib2xzID8ga2V5cy5jb25jYXQoZ2V0U3ltYm9scyhpdCkpIDoga2V5cztcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWZsb2F0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGFyc2UtZmxvYXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRwYXJzZUZsb2F0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIikucGFyc2VGbG9hdFxyXG4gICwgJHRyaW0gICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctdHJpbSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLXRyaW0uanNcIikudHJpbTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gMSAvICRwYXJzZUZsb2F0KF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy13cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLXdzLmpzXCIpICsgJy0wJykgIT09IC1JbmZpbml0eSA/IGZ1bmN0aW9uIHBhcnNlRmxvYXQoc3RyKXtcclxuICB2YXIgc3RyaW5nID0gJHRyaW0oU3RyaW5nKHN0ciksIDMpXHJcbiAgICAsIHJlc3VsdCA9ICRwYXJzZUZsb2F0KHN0cmluZyk7XHJcbiAgcmV0dXJuIHJlc3VsdCA9PT0gMCAmJiBzdHJpbmcuY2hhckF0KDApID09ICctJyA/IC0wIDogcmVzdWx0O1xyXG59IDogJHBhcnNlRmxvYXQ7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJzZS1pbnQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGFyc2UtaW50LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgJHBhcnNlSW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIikucGFyc2VJbnRcclxuICAsICR0cmltICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy10cmltICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctdHJpbS5qc1wiKS50cmltXHJcbiAgLCB3cyAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctd3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy13cy5qc1wiKVxyXG4gICwgaGV4ICAgICAgID0gL15bXFwtK10/MFt4WF0vO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSAkcGFyc2VJbnQod3MgKyAnMDgnKSAhPT0gOCB8fCAkcGFyc2VJbnQod3MgKyAnMHgxNicpICE9PSAyMiA/IGZ1bmN0aW9uIHBhcnNlSW50KHN0ciwgcmFkaXgpe1xyXG4gIHZhciBzdHJpbmcgPSAkdHJpbShTdHJpbmcoc3RyKSwgMyk7XHJcbiAgcmV0dXJuICRwYXJzZUludChzdHJpbmcsIChyYWRpeCA+Pj4gMCkgfHwgKGhleC50ZXN0KHN0cmluZykgPyAxNiA6IDEwKSk7XHJcbn0gOiAkcGFyc2VJbnQ7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJ0aWFsLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJ0aWFsLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgcGF0aCAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcGF0aCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGF0aC5qc1wiKVxyXG4gICwgaW52b2tlICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faW52b2tlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pbnZva2UuanNcIilcclxuICAsIGFGdW5jdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2EtZnVuY3Rpb24gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanNcIik7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oLyogLi4ucGFyZ3MgKi8pe1xyXG4gIHZhciBmbiAgICAgPSBhRnVuY3Rpb24odGhpcylcclxuICAgICwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aFxyXG4gICAgLCBwYXJncyAgPSBBcnJheShsZW5ndGgpXHJcbiAgICAsIGkgICAgICA9IDBcclxuICAgICwgXyAgICAgID0gcGF0aC5fXHJcbiAgICAsIGhvbGRlciA9IGZhbHNlO1xyXG4gIHdoaWxlKGxlbmd0aCA+IGkpaWYoKHBhcmdzW2ldID0gYXJndW1lbnRzW2krK10pID09PSBfKWhvbGRlciA9IHRydWU7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uKC8qIC4uLmFyZ3MgKi8pe1xyXG4gICAgdmFyIHRoYXQgPSB0aGlzXHJcbiAgICAgICwgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGhcclxuICAgICAgLCBqID0gMCwgayA9IDAsIGFyZ3M7XHJcbiAgICBpZighaG9sZGVyICYmICFhTGVuKXJldHVybiBpbnZva2UoZm4sIHBhcmdzLCB0aGF0KTtcclxuICAgIGFyZ3MgPSBwYXJncy5zbGljZSgpO1xyXG4gICAgaWYoaG9sZGVyKWZvcig7bGVuZ3RoID4gajsgaisrKWlmKGFyZ3Nbal0gPT09IF8pYXJnc1tqXSA9IGFyZ3VtZW50c1trKytdO1xyXG4gICAgd2hpbGUoYUxlbiA+IGspYXJncy5wdXNoKGFyZ3VtZW50c1trKytdKTtcclxuICAgIHJldHVybiBpbnZva2UoZm4sIGFyZ3MsIHRoYXQpO1xyXG4gIH07XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXRoLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXRoLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb3BlcnR5LWRlc2MuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb3BlcnR5LWRlc2MuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGJpdG1hcCwgdmFsdWUpe1xyXG4gIHJldHVybiB7XHJcbiAgICBlbnVtZXJhYmxlICA6ICEoYml0bWFwICYgMSksXHJcbiAgICBjb25maWd1cmFibGU6ICEoYml0bWFwICYgMiksXHJcbiAgICB3cml0YWJsZSAgICA6ICEoYml0bWFwICYgNCksXHJcbiAgICB2YWx1ZSAgICAgICA6IHZhbHVlXHJcbiAgfTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLWFsbC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciByZWRlZmluZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3JlZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qc1wiKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0YXJnZXQsIHNyYywgc2FmZSl7XHJcbiAgZm9yKHZhciBrZXkgaW4gc3JjKXJlZGVmaW5lKHRhcmdldCwga2V5LCBzcmNba2V5XSwgc2FmZSk7XHJcbiAgcmV0dXJuIHRhcmdldDtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGdsb2JhbCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgLCBoaWRlICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oaWRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzXCIpXHJcbiAgLCBoYXMgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oYXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qc1wiKVxyXG4gICwgU1JDICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdWlkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL191aWQuanNcIikoJ3NyYycpXHJcbiAgLCBUT19TVFJJTkcgPSAndG9TdHJpbmcnXHJcbiAgLCAkdG9TdHJpbmcgPSBGdW5jdGlvbltUT19TVFJJTkddXHJcbiAgLCBUUEwgICAgICAgPSAoJycgKyAkdG9TdHJpbmcpLnNwbGl0KFRPX1NUUklORyk7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb3JlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzXCIpLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuICR0b1N0cmluZy5jYWxsKGl0KTtcclxufTtcclxuXHJcbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE8sIGtleSwgdmFsLCBzYWZlKXtcclxuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcclxuICBpZihpc0Z1bmN0aW9uKWhhcyh2YWwsICduYW1lJykgfHwgaGlkZSh2YWwsICduYW1lJywga2V5KTtcclxuICBpZihPW2tleV0gPT09IHZhbClyZXR1cm47XHJcbiAgaWYoaXNGdW5jdGlvbiloYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcclxuICBpZihPID09PSBnbG9iYWwpe1xyXG4gICAgT1trZXldID0gdmFsO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBpZighc2FmZSl7XHJcbiAgICAgIGRlbGV0ZSBPW2tleV07XHJcbiAgICAgIGhpZGUoTywga2V5LCB2YWwpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYoT1trZXldKU9ba2V5XSA9IHZhbDtcclxuICAgICAgZWxzZSBoaWRlKE8sIGtleSwgdmFsKTtcclxuICAgIH1cclxuICB9XHJcbi8vIGFkZCBmYWtlIEZ1bmN0aW9uI3RvU3RyaW5nIGZvciBjb3JyZWN0IHdvcmsgd3JhcHBlZCBtZXRob2RzIC8gY29uc3RydWN0b3JzIHdpdGggbWV0aG9kcyBsaWtlIExvRGFzaCBpc05hdGl2ZVxyXG59KShGdW5jdGlvbi5wcm90b3R5cGUsIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKXtcclxuICByZXR1cm4gdHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzW1NSQ10gfHwgJHRvU3RyaW5nLmNhbGwodGhpcyk7XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2FtZS12YWx1ZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2FtZS12YWx1ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcclxuXHJcbi8vIDcuMi45IFNhbWVWYWx1ZSh4LCB5KVxyXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5pcyB8fCBmdW5jdGlvbiBpcyh4LCB5KXtcclxuICByZXR1cm4geCA9PT0geSA/IHggIT09IDAgfHwgMSAvIHggPT09IDEgLyB5IDogeCAhPSB4ICYmIHkgIT0geTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NldC1wcm90by5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtcHJvdG8uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIFdvcmtzIHdpdGggX19wcm90b19fIG9ubHkuIE9sZCB2OCBjYW4ndCB3b3JrIHdpdGggbnVsbCBwcm90byBvYmplY3RzLlxyXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgYW5PYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKTtcclxudmFyIGNoZWNrID0gZnVuY3Rpb24oTywgcHJvdG8pe1xyXG4gIGFuT2JqZWN0KE8pO1xyXG4gIGlmKCFpc09iamVjdChwcm90bykgJiYgcHJvdG8gIT09IG51bGwpdGhyb3cgVHlwZUVycm9yKHByb3RvICsgXCI6IGNhbid0IHNldCBhcyBwcm90b3R5cGUhXCIpO1xyXG59O1xyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuICBzZXQ6IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCAoJ19fcHJvdG9fXycgaW4ge30gPyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXHJcbiAgICBmdW5jdGlvbih0ZXN0LCBidWdneSwgc2V0KXtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBzZXQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jdHggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qc1wiKShGdW5jdGlvbi5jYWxsLCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ29wZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcGQuanNcIikuZihPYmplY3QucHJvdG90eXBlLCAnX19wcm90b19fJykuc2V0LCAyKTtcclxuICAgICAgICBzZXQodGVzdCwgW10pO1xyXG4gICAgICAgIGJ1Z2d5ID0gISh0ZXN0IGluc3RhbmNlb2YgQXJyYXkpO1xyXG4gICAgICB9IGNhdGNoKGUpeyBidWdneSA9IHRydWU7IH1cclxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKXtcclxuICAgICAgICBjaGVjayhPLCBwcm90byk7XHJcbiAgICAgICAgaWYoYnVnZ3kpTy5fX3Byb3RvX18gPSBwcm90bztcclxuICAgICAgICBlbHNlIHNldChPLCBwcm90byk7XHJcbiAgICAgICAgcmV0dXJuIE87XHJcbiAgICAgIH07XHJcbiAgICB9KHt9LCBmYWxzZSkgOiB1bmRlZmluZWQpLFxyXG4gIGNoZWNrOiBjaGVja1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciBnbG9iYWwgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgLCBkUCAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1kcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzXCIpXHJcbiAgLCBERVNDUklQVE9SUyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Rlc2NyaXB0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qc1wiKVxyXG4gICwgU1BFQ0lFUyAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgnc3BlY2llcycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihLRVkpe1xyXG4gIHZhciBDID0gZ2xvYmFsW0tFWV07XHJcbiAgaWYoREVTQ1JJUFRPUlMgJiYgQyAmJiAhQ1tTUEVDSUVTXSlkUC5mKEMsIFNQRUNJRVMsIHtcclxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcclxuICAgIGdldDogZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXM7IH1cclxuICB9KTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NldC10by1zdHJpbmctdGFnLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGRlZiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1kcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzXCIpLmZcclxuICAsIGhhcyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgLCBUQUcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgndG9TdHJpbmdUYWcnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIHRhZywgc3RhdCl7XHJcbiAgaWYoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSlkZWYoaXQsIFRBRywge2NvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHRhZ30pO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBzaGFyZWQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zaGFyZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qc1wiKSgna2V5cycpXHJcbiAgLCB1aWQgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL191aWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3VpZC5qc1wiKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xyXG4gIHJldHVybiBzaGFyZWRba2V5XSB8fCAoc2hhcmVkW2tleV0gPSB1aWQoa2V5KSk7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgZ2xvYmFsID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIilcclxuICAsIFNIQVJFRCA9ICdfX2NvcmUtanNfc2hhcmVkX18nXHJcbiAgLCBzdG9yZSAgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcclxuICByZXR1cm4gc3RvcmVba2V5XSB8fCAoc3RvcmVba2V5XSA9IHt9KTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NwZWNpZXMtY29uc3RydWN0b3IuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NwZWNpZXMtY29uc3RydWN0b3IuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyA3LjMuMjAgU3BlY2llc0NvbnN0cnVjdG9yKE8sIGRlZmF1bHRDb25zdHJ1Y3RvcilcclxudmFyIGFuT2JqZWN0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCBhRnVuY3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCBTUEVDSUVTICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgnc3BlY2llcycpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE8sIEQpe1xyXG4gIHZhciBDID0gYW5PYmplY3QoTykuY29uc3RydWN0b3IsIFM7XHJcbiAgcmV0dXJuIEMgPT09IHVuZGVmaW5lZCB8fCAoUyA9IGFuT2JqZWN0KEMpW1NQRUNJRVNdKSA9PSB1bmRlZmluZWQgPyBEIDogYUZ1bmN0aW9uKFMpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBmYWlscyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obWV0aG9kLCBhcmcpe1xyXG4gIHJldHVybiAhIW1ldGhvZCAmJiBmYWlscyhmdW5jdGlvbigpe1xyXG4gICAgYXJnID8gbWV0aG9kLmNhbGwobnVsbCwgZnVuY3Rpb24oKXt9LCAxKSA6IG1ldGhvZC5jYWxsKG51bGwpO1xyXG4gIH0pO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWF0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIHRvSW50ZWdlciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWludGVnZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWludGVnZXIuanNcIilcclxuICAsIGRlZmluZWQgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2RlZmluZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanNcIik7XHJcbi8vIHRydWUgIC0+IFN0cmluZyNhdFxyXG4vLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihUT19TVFJJTkcpe1xyXG4gIHJldHVybiBmdW5jdGlvbih0aGF0LCBwb3Mpe1xyXG4gICAgdmFyIHMgPSBTdHJpbmcoZGVmaW5lZCh0aGF0KSlcclxuICAgICAgLCBpID0gdG9JbnRlZ2VyKHBvcylcclxuICAgICAgLCBsID0gcy5sZW5ndGhcclxuICAgICAgLCBhLCBiO1xyXG4gICAgaWYoaSA8IDAgfHwgaSA+PSBsKXJldHVybiBUT19TVFJJTkcgPyAnJyA6IHVuZGVmaW5lZDtcclxuICAgIGEgPSBzLmNoYXJDb2RlQXQoaSk7XHJcbiAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxyXG4gICAgICA/IFRPX1NUUklORyA/IHMuY2hhckF0KGkpIDogYVxyXG4gICAgICA6IFRPX1NUUklORyA/IHMuc2xpY2UoaSwgaSArIDIpIDogKGEgLSAweGQ4MDAgPDwgMTApICsgKGIgLSAweGRjMDApICsgMHgxMDAwMDtcclxuICB9O1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWNvbnRleHQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctY29udGV4dC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBoZWxwZXIgZm9yIFN0cmluZyN7c3RhcnRzV2l0aCwgZW5kc1dpdGgsIGluY2x1ZGVzfVxyXG52YXIgaXNSZWdFeHAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1yZWdleHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLXJlZ2V4cC5qc1wiKVxyXG4gICwgZGVmaW5lZCAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZWZpbmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzXCIpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0aGF0LCBzZWFyY2hTdHJpbmcsIE5BTUUpe1xyXG4gIGlmKGlzUmVnRXhwKHNlYXJjaFN0cmluZykpdGhyb3cgVHlwZUVycm9yKCdTdHJpbmcjJyArIE5BTUUgKyBcIiBkb2Vzbid0IGFjY2VwdCByZWdleCFcIik7XHJcbiAgcmV0dXJuIFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1odG1sLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgZmFpbHMgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKVxyXG4gICwgZGVmaW5lZCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2RlZmluZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanNcIilcclxuICAsIHF1b3QgICAgPSAvXCIvZztcclxuLy8gQi4yLjMuMi4xIENyZWF0ZUhUTUwoc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpXHJcbnZhciBjcmVhdGVIVE1MID0gZnVuY3Rpb24oc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcclxuICB2YXIgUyAgPSBTdHJpbmcoZGVmaW5lZChzdHJpbmcpKVxyXG4gICAgLCBwMSA9ICc8JyArIHRhZztcclxuICBpZihhdHRyaWJ1dGUgIT09ICcnKXAxICs9ICcgJyArIGF0dHJpYnV0ZSArICc9XCInICsgU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHF1b3QsICcmcXVvdDsnKSArICdcIic7XHJcbiAgcmV0dXJuIHAxICsgJz4nICsgUyArICc8LycgKyB0YWcgKyAnPic7XHJcbn07XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oTkFNRSwgZXhlYyl7XHJcbiAgdmFyIE8gPSB7fTtcclxuICBPW05BTUVdID0gZXhlYyhjcmVhdGVIVE1MKTtcclxuICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZhaWxzKGZ1bmN0aW9uKCl7XHJcbiAgICB2YXIgdGVzdCA9ICcnW05BTUVdKCdcIicpO1xyXG4gICAgcmV0dXJuIHRlc3QgIT09IHRlc3QudG9Mb3dlckNhc2UoKSB8fCB0ZXN0LnNwbGl0KCdcIicpLmxlbmd0aCA+IDM7XHJcbiAgfSksICdTdHJpbmcnLCBPKTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1wYWQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1wYWQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxyXG52YXIgdG9MZW5ndGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1sZW5ndGggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWxlbmd0aC5qc1wiKVxyXG4gICwgcmVwZWF0ICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctcmVwZWF0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctcmVwZWF0LmpzXCIpXHJcbiAgLCBkZWZpbmVkICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2RlZmluZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanNcIik7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHRoYXQsIG1heExlbmd0aCwgZmlsbFN0cmluZywgbGVmdCl7XHJcbiAgdmFyIFMgICAgICAgICAgICA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKVxyXG4gICAgLCBzdHJpbmdMZW5ndGggPSBTLmxlbmd0aFxyXG4gICAgLCBmaWxsU3RyICAgICAgPSBmaWxsU3RyaW5nID09PSB1bmRlZmluZWQgPyAnICcgOiBTdHJpbmcoZmlsbFN0cmluZylcclxuICAgICwgaW50TWF4TGVuZ3RoID0gdG9MZW5ndGgobWF4TGVuZ3RoKTtcclxuICBpZihpbnRNYXhMZW5ndGggPD0gc3RyaW5nTGVuZ3RoIHx8IGZpbGxTdHIgPT0gJycpcmV0dXJuIFM7XHJcbiAgdmFyIGZpbGxMZW4gPSBpbnRNYXhMZW5ndGggLSBzdHJpbmdMZW5ndGhcclxuICAgICwgc3RyaW5nRmlsbGVyID0gcmVwZWF0LmNhbGwoZmlsbFN0ciwgTWF0aC5jZWlsKGZpbGxMZW4gLyBmaWxsU3RyLmxlbmd0aCkpO1xyXG4gIGlmKHN0cmluZ0ZpbGxlci5sZW5ndGggPiBmaWxsTGVuKXN0cmluZ0ZpbGxlciA9IHN0cmluZ0ZpbGxlci5zbGljZSgwLCBmaWxsTGVuKTtcclxuICByZXR1cm4gbGVmdCA/IHN0cmluZ0ZpbGxlciArIFMgOiBTICsgc3RyaW5nRmlsbGVyO1xyXG59O1xyXG5cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1yZXBlYXQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1yZXBlYXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciB0b0ludGVnZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pbnRlZ2VyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbnRlZ2VyLmpzXCIpXHJcbiAgLCBkZWZpbmVkICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZWZpbmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzXCIpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXBlYXQoY291bnQpe1xyXG4gIHZhciBzdHIgPSBTdHJpbmcoZGVmaW5lZCh0aGlzKSlcclxuICAgICwgcmVzID0gJydcclxuICAgICwgbiAgID0gdG9JbnRlZ2VyKGNvdW50KTtcclxuICBpZihuIDwgMCB8fCBuID09IEluZmluaXR5KXRocm93IFJhbmdlRXJyb3IoXCJDb3VudCBjYW4ndCBiZSBuZWdhdGl2ZVwiKTtcclxuICBmb3IoO24gPiAwOyAobiA+Pj49IDEpICYmIChzdHIgKz0gc3RyKSlpZihuICYgMSlyZXMgKz0gc3RyO1xyXG4gIHJldHVybiByZXM7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctdHJpbS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy10cmltLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGRlZmluZWQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZWZpbmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzXCIpXHJcbiAgLCBmYWlscyAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmFpbHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCIpXHJcbiAgLCBzcGFjZXMgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLXdzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctd3MuanNcIilcclxuICAsIHNwYWNlICAgPSAnWycgKyBzcGFjZXMgKyAnXSdcclxuICAsIG5vbiAgICAgPSAnXFx1MjAwYlxcdTAwODUnXHJcbiAgLCBsdHJpbSAgID0gUmVnRXhwKCdeJyArIHNwYWNlICsgc3BhY2UgKyAnKicpXHJcbiAgLCBydHJpbSAgID0gUmVnRXhwKHNwYWNlICsgc3BhY2UgKyAnKiQnKTtcclxuXHJcbnZhciBleHBvcnRlciA9IGZ1bmN0aW9uKEtFWSwgZXhlYywgQUxJQVMpe1xyXG4gIHZhciBleHAgICA9IHt9O1xyXG4gIHZhciBGT1JDRSA9IGZhaWxzKGZ1bmN0aW9uKCl7XHJcbiAgICByZXR1cm4gISFzcGFjZXNbS0VZXSgpIHx8IG5vbltLRVldKCkgIT0gbm9uO1xyXG4gIH0pO1xyXG4gIHZhciBmbiA9IGV4cFtLRVldID0gRk9SQ0UgPyBleGVjKHRyaW0pIDogc3BhY2VzW0tFWV07XHJcbiAgaWYoQUxJQVMpZXhwW0FMSUFTXSA9IGZuO1xyXG4gICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogRk9SQ0UsICdTdHJpbmcnLCBleHApO1xyXG59O1xyXG5cclxuLy8gMSAtPiBTdHJpbmcjdHJpbUxlZnRcclxuLy8gMiAtPiBTdHJpbmcjdHJpbVJpZ2h0XHJcbi8vIDMgLT4gU3RyaW5nI3RyaW1cclxudmFyIHRyaW0gPSBleHBvcnRlci50cmltID0gZnVuY3Rpb24oc3RyaW5nLCBUWVBFKXtcclxuICBzdHJpbmcgPSBTdHJpbmcoZGVmaW5lZChzdHJpbmcpKTtcclxuICBpZihUWVBFICYgMSlzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShsdHJpbSwgJycpO1xyXG4gIGlmKFRZUEUgJiAyKXN0cmluZyA9IHN0cmluZy5yZXBsYWNlKHJ0cmltLCAnJyk7XHJcbiAgcmV0dXJuIHN0cmluZztcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0ZXI7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctd3MuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLXdzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9ICdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycgK1xyXG4gICdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOFxcdTIwMjlcXHVGRUZGJztcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgY3R4ICAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY3R4ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jdHguanNcIilcclxuICAsIGludm9rZSAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ludm9rZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW52b2tlLmpzXCIpXHJcbiAgLCBodG1sICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19odG1sLmpzXCIpXHJcbiAgLCBjZWwgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kb20tY3JlYXRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kb20tY3JlYXRlLmpzXCIpXHJcbiAgLCBnbG9iYWwgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKVxyXG4gICwgcHJvY2VzcyAgICAgICAgICAgID0gZ2xvYmFsLnByb2Nlc3NcclxuICAsIHNldFRhc2sgICAgICAgICAgICA9IGdsb2JhbC5zZXRJbW1lZGlhdGVcclxuICAsIGNsZWFyVGFzayAgICAgICAgICA9IGdsb2JhbC5jbGVhckltbWVkaWF0ZVxyXG4gICwgTWVzc2FnZUNoYW5uZWwgICAgID0gZ2xvYmFsLk1lc3NhZ2VDaGFubmVsXHJcbiAgLCBjb3VudGVyICAgICAgICAgICAgPSAwXHJcbiAgLCBxdWV1ZSAgICAgICAgICAgICAgPSB7fVxyXG4gICwgT05SRUFEWVNUQVRFQ0hBTkdFID0gJ29ucmVhZHlzdGF0ZWNoYW5nZSdcclxuICAsIGRlZmVyLCBjaGFubmVsLCBwb3J0O1xyXG52YXIgcnVuID0gZnVuY3Rpb24oKXtcclxuICB2YXIgaWQgPSArdGhpcztcclxuICBpZihxdWV1ZS5oYXNPd25Qcm9wZXJ0eShpZCkpe1xyXG4gICAgdmFyIGZuID0gcXVldWVbaWRdO1xyXG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcclxuICAgIGZuKCk7XHJcbiAgfVxyXG59O1xyXG52YXIgbGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCl7XHJcbiAgcnVuLmNhbGwoZXZlbnQuZGF0YSk7XHJcbn07XHJcbi8vIE5vZGUuanMgMC45KyAmIElFMTArIGhhcyBzZXRJbW1lZGlhdGUsIG90aGVyd2lzZTpcclxuaWYoIXNldFRhc2sgfHwgIWNsZWFyVGFzayl7XHJcbiAgc2V0VGFzayA9IGZ1bmN0aW9uIHNldEltbWVkaWF0ZShmbil7XHJcbiAgICB2YXIgYXJncyA9IFtdLCBpID0gMTtcclxuICAgIHdoaWxlKGFyZ3VtZW50cy5sZW5ndGggPiBpKWFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XHJcbiAgICBxdWV1ZVsrK2NvdW50ZXJdID0gZnVuY3Rpb24oKXtcclxuICAgICAgaW52b2tlKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbiksIGFyZ3MpO1xyXG4gICAgfTtcclxuICAgIGRlZmVyKGNvdW50ZXIpO1xyXG4gICAgcmV0dXJuIGNvdW50ZXI7XHJcbiAgfTtcclxuICBjbGVhclRhc2sgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCl7XHJcbiAgICBkZWxldGUgcXVldWVbaWRdO1xyXG4gIH07XHJcbiAgLy8gTm9kZS5qcyAwLjgtXHJcbiAgaWYoX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2YuanNcIikocHJvY2VzcykgPT0gJ3Byb2Nlc3MnKXtcclxuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xyXG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGN0eChydW4sIGlkLCAxKSk7XHJcbiAgICB9O1xyXG4gIC8vIEJyb3dzZXJzIHdpdGggTWVzc2FnZUNoYW5uZWwsIGluY2x1ZGVzIFdlYldvcmtlcnNcclxuICB9IGVsc2UgaWYoTWVzc2FnZUNoYW5uZWwpe1xyXG4gICAgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbDtcclxuICAgIHBvcnQgICAgPSBjaGFubmVsLnBvcnQyO1xyXG4gICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaXN0ZW5lcjtcclxuICAgIGRlZmVyID0gY3R4KHBvcnQucG9zdE1lc3NhZ2UsIHBvcnQsIDEpO1xyXG4gIC8vIEJyb3dzZXJzIHdpdGggcG9zdE1lc3NhZ2UsIHNraXAgV2ViV29ya2Vyc1xyXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXHJcbiAgfSBlbHNlIGlmKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyICYmIHR5cGVvZiBwb3N0TWVzc2FnZSA9PSAnZnVuY3Rpb24nICYmICFnbG9iYWwuaW1wb3J0U2NyaXB0cyl7XHJcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcclxuICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKGlkICsgJycsICcqJyk7XHJcbiAgICB9O1xyXG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lciwgZmFsc2UpO1xyXG4gIC8vIElFOC1cclxuICB9IGVsc2UgaWYoT05SRUFEWVNUQVRFQ0hBTkdFIGluIGNlbCgnc2NyaXB0Jykpe1xyXG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XHJcbiAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoY2VsKCdzY3JpcHQnKSlbT05SRUFEWVNUQVRFQ0hBTkdFXSA9IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgaHRtbC5yZW1vdmVDaGlsZCh0aGlzKTtcclxuICAgICAgICBydW4uY2FsbChpZCk7XHJcbiAgICAgIH07XHJcbiAgICB9O1xyXG4gIC8vIFJlc3Qgb2xkIGJyb3dzZXJzXHJcbiAgfSBlbHNlIHtcclxuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xyXG4gICAgICBzZXRUaW1lb3V0KGN0eChydW4sIGlkLCAxKSwgMCk7XHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuICBzZXQ6ICAgc2V0VGFzayxcclxuICBjbGVhcjogY2xlYXJUYXNrXHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWluZGV4LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciB0b0ludGVnZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pbnRlZ2VyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbnRlZ2VyLmpzXCIpXHJcbiAgLCBtYXggICAgICAgPSBNYXRoLm1heFxyXG4gICwgbWluICAgICAgID0gTWF0aC5taW47XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaW5kZXgsIGxlbmd0aCl7XHJcbiAgaW5kZXggPSB0b0ludGVnZXIoaW5kZXgpO1xyXG4gIHJldHVybiBpbmRleCA8IDAgPyBtYXgoaW5kZXggKyBsZW5ndGgsIDApIDogbWluKGluZGV4LCBsZW5ndGgpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcclxuXHJcbi8vIDcuMS40IFRvSW50ZWdlclxyXG52YXIgY2VpbCAgPSBNYXRoLmNlaWxcclxuICAsIGZsb29yID0gTWF0aC5mbG9vcjtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXHJcbnZhciBJT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qc1wiKVxyXG4gICwgZGVmaW5lZCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2RlZmluZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RlZmluZWQuanNcIik7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xyXG4gIHJldHVybiBJT2JqZWN0KGRlZmluZWQoaXQpKTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWxlbmd0aC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDcuMS4xNSBUb0xlbmd0aFxyXG52YXIgdG9JbnRlZ2VyID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW50ZWdlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qc1wiKVxyXG4gICwgbWluICAgICAgID0gTWF0aC5taW47XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xyXG4gIHJldHVybiBpdCA+IDAgPyBtaW4odG9JbnRlZ2VyKGl0KSwgMHgxZmZmZmZmZmZmZmZmZikgOiAwOyAvLyBwb3coMiwgNTMpIC0gMSA9PSA5MDA3MTk5MjU0NzQwOTkxXHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyA3LjEuMTMgVG9PYmplY3QoYXJndW1lbnQpXHJcbnZhciBkZWZpbmVkID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVmaW5lZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVmaW5lZC5qc1wiKTtcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIE9iamVjdChkZWZpbmVkKGl0KSk7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1wcmltaXRpdmUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyA3LjEuMSBUb1ByaW1pdGl2ZShpbnB1dCBbLCBQcmVmZXJyZWRUeXBlXSlcclxudmFyIGlzT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIik7XHJcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXHJcbi8vIGFuZCB0aGUgc2Vjb25kIGFyZ3VtZW50IC0gZmxhZyAtIHByZWZlcnJlZCB0eXBlIGlzIGEgc3RyaW5nXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIFMpe1xyXG4gIGlmKCFpc09iamVjdChpdCkpcmV0dXJuIGl0O1xyXG4gIHZhciBmbiwgdmFsO1xyXG4gIGlmKFMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpcmV0dXJuIHZhbDtcclxuICBpZih0eXBlb2YgKGZuID0gaXQudmFsdWVPZikgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKXJldHVybiB2YWw7XHJcbiAgaWYoIVMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpcmV0dXJuIHZhbDtcclxuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC1hcnJheS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWFycmF5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuaWYoX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpKXtcclxuICB2YXIgTElCUkFSWSAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2xpYnJhcnkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanNcIilcclxuICAgICwgZ2xvYmFsICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgICAsIGZhaWxzICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIilcclxuICAgICwgJGV4cG9ydCAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgICAsICR0eXBlZCAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190eXBlZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQuanNcIilcclxuICAgICwgJGJ1ZmZlciAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3R5cGVkLWJ1ZmZlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYnVmZmVyLmpzXCIpXHJcbiAgICAsIGN0eCAgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jdHggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qc1wiKVxyXG4gICAgLCBhbkluc3RhbmNlICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYW4taW5zdGFuY2UgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLWluc3RhbmNlLmpzXCIpXHJcbiAgICAsIHByb3BlcnR5RGVzYyAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19wcm9wZXJ0eS1kZXNjICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzXCIpXHJcbiAgICAsIGhpZGUgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oaWRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzXCIpXHJcbiAgICAsIHJlZGVmaW5lQWxsICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19yZWRlZmluZS1hbGwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLWFsbC5qc1wiKVxyXG4gICAgLCB0b0ludGVnZXIgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW50ZWdlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qc1wiKVxyXG4gICAgLCB0b0xlbmd0aCAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIilcclxuICAgICwgdG9JbmRleCAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWluZGV4ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qc1wiKVxyXG4gICAgLCB0b1ByaW1pdGl2ZSAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tcHJpbWl0aXZlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1wcmltaXRpdmUuanNcIilcclxuICAgICwgaGFzICAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgICAsIHNhbWUgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zYW1lLXZhbHVlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zYW1lLXZhbHVlLmpzXCIpXHJcbiAgICAsIGNsYXNzb2YgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jbGFzc29mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jbGFzc29mLmpzXCIpXHJcbiAgICAsIGlzT2JqZWN0ICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICAgLCB0b09iamVjdCAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAgICwgaXNBcnJheUl0ZXIgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLWFycmF5LWl0ZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWFycmF5LWl0ZXIuanNcIilcclxuICAgICwgY3JlYXRlICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1jcmVhdGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanNcIilcclxuICAgICwgZ2V0UHJvdG90eXBlT2YgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1ncG8gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanNcIilcclxuICAgICwgZ09QTiAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BuICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi5qc1wiKS5mXHJcbiAgICAsIGdldEl0ZXJGbiAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QuanNcIilcclxuICAgICwgdWlkICAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3VpZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzXCIpXHJcbiAgICAsIHdrcyAgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKVxyXG4gICAgLCBjcmVhdGVBcnJheU1ldGhvZCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktbWV0aG9kcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qc1wiKVxyXG4gICAgLCBjcmVhdGVBcnJheUluY2x1ZGVzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktaW5jbHVkZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzXCIpXHJcbiAgICAsIHNwZWNpZXNDb25zdHJ1Y3RvciAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zcGVjaWVzLWNvbnN0cnVjdG9yICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zcGVjaWVzLWNvbnN0cnVjdG9yLmpzXCIpXHJcbiAgICAsIEFycmF5SXRlcmF0b3JzICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2VzNi5hcnJheS5pdGVyYXRvciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaXRlcmF0b3IuanNcIilcclxuICAgICwgSXRlcmF0b3JzICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2l0ZXJhdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzXCIpXHJcbiAgICAsICRpdGVyRGV0ZWN0ICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyLWRldGVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanNcIilcclxuICAgICwgc2V0U3BlY2llcyAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NldC1zcGVjaWVzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qc1wiKVxyXG4gICAgLCBhcnJheUZpbGwgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktZmlsbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktZmlsbC5qc1wiKVxyXG4gICAgLCBhcnJheUNvcHlXaXRoaW4gICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktY29weS13aXRoaW4gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWNvcHktd2l0aGluLmpzXCIpXHJcbiAgICAsICREUCAgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKVxyXG4gICAgLCAkR09QRCAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcGQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzXCIpXHJcbiAgICAsIGRQICAgICAgICAgICAgICAgICAgPSAkRFAuZlxyXG4gICAgLCBnT1BEICAgICAgICAgICAgICAgID0gJEdPUEQuZlxyXG4gICAgLCBSYW5nZUVycm9yICAgICAgICAgID0gZ2xvYmFsLlJhbmdlRXJyb3JcclxuICAgICwgVHlwZUVycm9yICAgICAgICAgICA9IGdsb2JhbC5UeXBlRXJyb3JcclxuICAgICwgVWludDhBcnJheSAgICAgICAgICA9IGdsb2JhbC5VaW50OEFycmF5XHJcbiAgICAsIEFSUkFZX0JVRkZFUiAgICAgICAgPSAnQXJyYXlCdWZmZXInXHJcbiAgICAsIFNIQVJFRF9CVUZGRVIgICAgICAgPSAnU2hhcmVkJyArIEFSUkFZX0JVRkZFUlxyXG4gICAgLCBCWVRFU19QRVJfRUxFTUVOVCAgID0gJ0JZVEVTX1BFUl9FTEVNRU5UJ1xyXG4gICAgLCBQUk9UT1RZUEUgICAgICAgICAgID0gJ3Byb3RvdHlwZSdcclxuICAgICwgQXJyYXlQcm90byAgICAgICAgICA9IEFycmF5W1BST1RPVFlQRV1cclxuICAgICwgJEFycmF5QnVmZmVyICAgICAgICA9ICRidWZmZXIuQXJyYXlCdWZmZXJcclxuICAgICwgJERhdGFWaWV3ICAgICAgICAgICA9ICRidWZmZXIuRGF0YVZpZXdcclxuICAgICwgYXJyYXlGb3JFYWNoICAgICAgICA9IGNyZWF0ZUFycmF5TWV0aG9kKDApXHJcbiAgICAsIGFycmF5RmlsdGVyICAgICAgICAgPSBjcmVhdGVBcnJheU1ldGhvZCgyKVxyXG4gICAgLCBhcnJheVNvbWUgICAgICAgICAgID0gY3JlYXRlQXJyYXlNZXRob2QoMylcclxuICAgICwgYXJyYXlFdmVyeSAgICAgICAgICA9IGNyZWF0ZUFycmF5TWV0aG9kKDQpXHJcbiAgICAsIGFycmF5RmluZCAgICAgICAgICAgPSBjcmVhdGVBcnJheU1ldGhvZCg1KVxyXG4gICAgLCBhcnJheUZpbmRJbmRleCAgICAgID0gY3JlYXRlQXJyYXlNZXRob2QoNilcclxuICAgICwgYXJyYXlJbmNsdWRlcyAgICAgICA9IGNyZWF0ZUFycmF5SW5jbHVkZXModHJ1ZSlcclxuICAgICwgYXJyYXlJbmRleE9mICAgICAgICA9IGNyZWF0ZUFycmF5SW5jbHVkZXMoZmFsc2UpXHJcbiAgICAsIGFycmF5VmFsdWVzICAgICAgICAgPSBBcnJheUl0ZXJhdG9ycy52YWx1ZXNcclxuICAgICwgYXJyYXlLZXlzICAgICAgICAgICA9IEFycmF5SXRlcmF0b3JzLmtleXNcclxuICAgICwgYXJyYXlFbnRyaWVzICAgICAgICA9IEFycmF5SXRlcmF0b3JzLmVudHJpZXNcclxuICAgICwgYXJyYXlMYXN0SW5kZXhPZiAgICA9IEFycmF5UHJvdG8ubGFzdEluZGV4T2ZcclxuICAgICwgYXJyYXlSZWR1Y2UgICAgICAgICA9IEFycmF5UHJvdG8ucmVkdWNlXHJcbiAgICAsIGFycmF5UmVkdWNlUmlnaHQgICAgPSBBcnJheVByb3RvLnJlZHVjZVJpZ2h0XHJcbiAgICAsIGFycmF5Sm9pbiAgICAgICAgICAgPSBBcnJheVByb3RvLmpvaW5cclxuICAgICwgYXJyYXlTb3J0ICAgICAgICAgICA9IEFycmF5UHJvdG8uc29ydFxyXG4gICAgLCBhcnJheVNsaWNlICAgICAgICAgID0gQXJyYXlQcm90by5zbGljZVxyXG4gICAgLCBhcnJheVRvU3RyaW5nICAgICAgID0gQXJyYXlQcm90by50b1N0cmluZ1xyXG4gICAgLCBhcnJheVRvTG9jYWxlU3RyaW5nID0gQXJyYXlQcm90by50b0xvY2FsZVN0cmluZ1xyXG4gICAgLCBJVEVSQVRPUiAgICAgICAgICAgID0gd2tzKCdpdGVyYXRvcicpXHJcbiAgICAsIFRBRyAgICAgICAgICAgICAgICAgPSB3a3MoJ3RvU3RyaW5nVGFnJylcclxuICAgICwgVFlQRURfQ09OU1RSVUNUT1IgICA9IHVpZCgndHlwZWRfY29uc3RydWN0b3InKVxyXG4gICAgLCBERUZfQ09OU1RSVUNUT1IgICAgID0gdWlkKCdkZWZfY29uc3RydWN0b3InKVxyXG4gICAgLCBBTExfQ09OU1RSVUNUT1JTICAgID0gJHR5cGVkLkNPTlNUUlxyXG4gICAgLCBUWVBFRF9BUlJBWSAgICAgICAgID0gJHR5cGVkLlRZUEVEXHJcbiAgICAsIFZJRVcgICAgICAgICAgICAgICAgPSAkdHlwZWQuVklFV1xyXG4gICAgLCBXUk9OR19MRU5HVEggICAgICAgID0gJ1dyb25nIGxlbmd0aCEnO1xyXG5cclxuICB2YXIgJG1hcCA9IGNyZWF0ZUFycmF5TWV0aG9kKDEsIGZ1bmN0aW9uKE8sIGxlbmd0aCl7XHJcbiAgICByZXR1cm4gYWxsb2NhdGUoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxlbmd0aCk7XHJcbiAgfSk7XHJcblxyXG4gIHZhciBMSVRUTEVfRU5ESUFOID0gZmFpbHMoZnVuY3Rpb24oKXtcclxuICAgIHJldHVybiBuZXcgVWludDhBcnJheShuZXcgVWludDE2QXJyYXkoWzFdKS5idWZmZXIpWzBdID09PSAxO1xyXG4gIH0pO1xyXG5cclxuICB2YXIgRk9SQ0VEX1NFVCA9ICEhVWludDhBcnJheSAmJiAhIVVpbnQ4QXJyYXlbUFJPVE9UWVBFXS5zZXQgJiYgZmFpbHMoZnVuY3Rpb24oKXtcclxuICAgIG5ldyBVaW50OEFycmF5KDEpLnNldCh7fSk7XHJcbiAgfSk7XHJcblxyXG4gIHZhciBzdHJpY3RUb0xlbmd0aCA9IGZ1bmN0aW9uKGl0LCBTQU1FKXtcclxuICAgIGlmKGl0ID09PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKFdST05HX0xFTkdUSCk7XHJcbiAgICB2YXIgbnVtYmVyID0gK2l0XHJcbiAgICAgICwgbGVuZ3RoID0gdG9MZW5ndGgoaXQpO1xyXG4gICAgaWYoU0FNRSAmJiAhc2FtZShudW1iZXIsIGxlbmd0aCkpdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xyXG4gICAgcmV0dXJuIGxlbmd0aDtcclxuICB9O1xyXG5cclxuICB2YXIgdG9PZmZzZXQgPSBmdW5jdGlvbihpdCwgQllURVMpe1xyXG4gICAgdmFyIG9mZnNldCA9IHRvSW50ZWdlcihpdCk7XHJcbiAgICBpZihvZmZzZXQgPCAwIHx8IG9mZnNldCAlIEJZVEVTKXRocm93IFJhbmdlRXJyb3IoJ1dyb25nIG9mZnNldCEnKTtcclxuICAgIHJldHVybiBvZmZzZXQ7XHJcbiAgfTtcclxuXHJcbiAgdmFyIHZhbGlkYXRlID0gZnVuY3Rpb24oaXQpe1xyXG4gICAgaWYoaXNPYmplY3QoaXQpICYmIFRZUEVEX0FSUkFZIGluIGl0KXJldHVybiBpdDtcclxuICAgIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgdHlwZWQgYXJyYXkhJyk7XHJcbiAgfTtcclxuXHJcbiAgdmFyIGFsbG9jYXRlID0gZnVuY3Rpb24oQywgbGVuZ3RoKXtcclxuICAgIGlmKCEoaXNPYmplY3QoQykgJiYgVFlQRURfQ09OU1RSVUNUT1IgaW4gQykpe1xyXG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ0l0IGlzIG5vdCBhIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9yIScpO1xyXG4gICAgfSByZXR1cm4gbmV3IEMobGVuZ3RoKTtcclxuICB9O1xyXG5cclxuICB2YXIgc3BlY2llc0Zyb21MaXN0ID0gZnVuY3Rpb24oTywgbGlzdCl7XHJcbiAgICByZXR1cm4gZnJvbUxpc3Qoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxpc3QpO1xyXG4gIH07XHJcblxyXG4gIHZhciBmcm9tTGlzdCA9IGZ1bmN0aW9uKEMsIGxpc3Qpe1xyXG4gICAgdmFyIGluZGV4ICA9IDBcclxuICAgICAgLCBsZW5ndGggPSBsaXN0Lmxlbmd0aFxyXG4gICAgICAsIHJlc3VsdCA9IGFsbG9jYXRlKEMsIGxlbmd0aCk7XHJcbiAgICB3aGlsZShsZW5ndGggPiBpbmRleClyZXN1bHRbaW5kZXhdID0gbGlzdFtpbmRleCsrXTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfTtcclxuXHJcbiAgdmFyIGFkZEdldHRlciA9IGZ1bmN0aW9uKGl0LCBrZXksIGludGVybmFsKXtcclxuICAgIGRQKGl0LCBrZXksIHtnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzLl9kW2ludGVybmFsXTsgfX0pO1xyXG4gIH07XHJcblxyXG4gIHZhciAkZnJvbSA9IGZ1bmN0aW9uIGZyb20oc291cmNlIC8qLCBtYXBmbiwgdGhpc0FyZyAqLyl7XHJcbiAgICB2YXIgTyAgICAgICA9IHRvT2JqZWN0KHNvdXJjZSlcclxuICAgICAgLCBhTGVuICAgID0gYXJndW1lbnRzLmxlbmd0aFxyXG4gICAgICAsIG1hcGZuICAgPSBhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZFxyXG4gICAgICAsIG1hcHBpbmcgPSBtYXBmbiAhPT0gdW5kZWZpbmVkXHJcbiAgICAgICwgaXRlckZuICA9IGdldEl0ZXJGbihPKVxyXG4gICAgICAsIGksIGxlbmd0aCwgdmFsdWVzLCByZXN1bHQsIHN0ZXAsIGl0ZXJhdG9yO1xyXG4gICAgaWYoaXRlckZuICE9IHVuZGVmaW5lZCAmJiAhaXNBcnJheUl0ZXIoaXRlckZuKSl7XHJcbiAgICAgIGZvcihpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCB2YWx1ZXMgPSBbXSwgaSA9IDA7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaSsrKXtcclxuICAgICAgICB2YWx1ZXMucHVzaChzdGVwLnZhbHVlKTtcclxuICAgICAgfSBPID0gdmFsdWVzO1xyXG4gICAgfVxyXG4gICAgaWYobWFwcGluZyAmJiBhTGVuID4gMiltYXBmbiA9IGN0eChtYXBmbiwgYXJndW1lbnRzWzJdLCAyKTtcclxuICAgIGZvcihpID0gMCwgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpLCByZXN1bHQgPSBhbGxvY2F0ZSh0aGlzLCBsZW5ndGgpOyBsZW5ndGggPiBpOyBpKyspe1xyXG4gICAgICByZXN1bHRbaV0gPSBtYXBwaW5nID8gbWFwZm4oT1tpXSwgaSkgOiBPW2ldO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9O1xyXG5cclxuICB2YXIgJG9mID0gZnVuY3Rpb24gb2YoLyouLi5pdGVtcyovKXtcclxuICAgIHZhciBpbmRleCAgPSAwXHJcbiAgICAgICwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aFxyXG4gICAgICAsIHJlc3VsdCA9IGFsbG9jYXRlKHRoaXMsIGxlbmd0aCk7XHJcbiAgICB3aGlsZShsZW5ndGggPiBpbmRleClyZXN1bHRbaW5kZXhdID0gYXJndW1lbnRzW2luZGV4KytdO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9O1xyXG5cclxuICAvLyBpT1MgU2FmYXJpIDYueCBmYWlscyBoZXJlXHJcbiAgdmFyIFRPX0xPQ0FMRV9CVUcgPSAhIVVpbnQ4QXJyYXkgJiYgZmFpbHMoZnVuY3Rpb24oKXsgYXJyYXlUb0xvY2FsZVN0cmluZy5jYWxsKG5ldyBVaW50OEFycmF5KDEpKTsgfSk7XHJcblxyXG4gIHZhciAkdG9Mb2NhbGVTdHJpbmcgPSBmdW5jdGlvbiB0b0xvY2FsZVN0cmluZygpe1xyXG4gICAgcmV0dXJuIGFycmF5VG9Mb2NhbGVTdHJpbmcuYXBwbHkoVE9fTE9DQUxFX0JVRyA/IGFycmF5U2xpY2UuY2FsbCh2YWxpZGF0ZSh0aGlzKSkgOiB2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcclxuICB9O1xyXG5cclxuICB2YXIgcHJvdG8gPSB7XHJcbiAgICBjb3B5V2l0aGluOiBmdW5jdGlvbiBjb3B5V2l0aGluKHRhcmdldCwgc3RhcnQgLyosIGVuZCAqLyl7XHJcbiAgICAgIHJldHVybiBhcnJheUNvcHlXaXRoaW4uY2FsbCh2YWxpZGF0ZSh0aGlzKSwgdGFyZ2V0LCBzdGFydCwgYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWQpO1xyXG4gICAgfSxcclxuICAgIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuIC8qLCB0aGlzQXJnICovKXtcclxuICAgICAgcmV0dXJuIGFycmF5RXZlcnkodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcclxuICAgIH0sXHJcbiAgICBmaWxsOiBmdW5jdGlvbiBmaWxsKHZhbHVlIC8qLCBzdGFydCwgZW5kICovKXsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xyXG4gICAgICByZXR1cm4gYXJyYXlGaWxsLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xyXG4gICAgfSxcclxuICAgIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKGNhbGxiYWNrZm4gLyosIHRoaXNBcmcgKi8pe1xyXG4gICAgICByZXR1cm4gc3BlY2llc0Zyb21MaXN0KHRoaXMsIGFycmF5RmlsdGVyKHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLFxyXG4gICAgICAgIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKSk7XHJcbiAgICB9LFxyXG4gICAgZmluZDogZnVuY3Rpb24gZmluZChwcmVkaWNhdGUgLyosIHRoaXNBcmcgKi8pe1xyXG4gICAgICByZXR1cm4gYXJyYXlGaW5kKHZhbGlkYXRlKHRoaXMpLCBwcmVkaWNhdGUsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcclxuICAgIH0sXHJcbiAgICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChwcmVkaWNhdGUgLyosIHRoaXNBcmcgKi8pe1xyXG4gICAgICByZXR1cm4gYXJyYXlGaW5kSW5kZXgodmFsaWRhdGUodGhpcyksIHByZWRpY2F0ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xyXG4gICAgfSxcclxuICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbiAvKiwgdGhpc0FyZyAqLyl7XHJcbiAgICAgIGFycmF5Rm9yRWFjaCh2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xyXG4gICAgfSxcclxuICAgIGluZGV4T2Y6IGZ1bmN0aW9uIGluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiwgZnJvbUluZGV4ICovKXtcclxuICAgICAgcmV0dXJuIGFycmF5SW5kZXhPZih2YWxpZGF0ZSh0aGlzKSwgc2VhcmNoRWxlbWVudCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xyXG4gICAgfSxcclxuICAgIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhzZWFyY2hFbGVtZW50IC8qLCBmcm9tSW5kZXggKi8pe1xyXG4gICAgICByZXR1cm4gYXJyYXlJbmNsdWRlcyh2YWxpZGF0ZSh0aGlzKSwgc2VhcmNoRWxlbWVudCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xyXG4gICAgfSxcclxuICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKXsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xyXG4gICAgICByZXR1cm4gYXJyYXlKb2luLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xyXG4gICAgfSxcclxuICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hFbGVtZW50IC8qLCBmcm9tSW5kZXggKi8peyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXHJcbiAgICAgIHJldHVybiBhcnJheUxhc3RJbmRleE9mLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xyXG4gICAgfSxcclxuICAgIG1hcDogZnVuY3Rpb24gbWFwKG1hcGZuIC8qLCB0aGlzQXJnICovKXtcclxuICAgICAgcmV0dXJuICRtYXAodmFsaWRhdGUodGhpcyksIG1hcGZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XHJcbiAgICB9LFxyXG4gICAgcmVkdWNlOiBmdW5jdGlvbiByZWR1Y2UoY2FsbGJhY2tmbiAvKiwgaW5pdGlhbFZhbHVlICovKXsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xyXG4gICAgICByZXR1cm4gYXJyYXlSZWR1Y2UuYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XHJcbiAgICB9LFxyXG4gICAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4gLyosIGluaXRpYWxWYWx1ZSAqLyl7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcclxuICAgICAgcmV0dXJuIGFycmF5UmVkdWNlUmlnaHQuYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XHJcbiAgICB9LFxyXG4gICAgcmV2ZXJzZTogZnVuY3Rpb24gcmV2ZXJzZSgpe1xyXG4gICAgICB2YXIgdGhhdCAgID0gdGhpc1xyXG4gICAgICAgICwgbGVuZ3RoID0gdmFsaWRhdGUodGhhdCkubGVuZ3RoXHJcbiAgICAgICAgLCBtaWRkbGUgPSBNYXRoLmZsb29yKGxlbmd0aCAvIDIpXHJcbiAgICAgICAgLCBpbmRleCAgPSAwXHJcbiAgICAgICAgLCB2YWx1ZTtcclxuICAgICAgd2hpbGUoaW5kZXggPCBtaWRkbGUpe1xyXG4gICAgICAgIHZhbHVlICAgICAgICAgPSB0aGF0W2luZGV4XTtcclxuICAgICAgICB0aGF0W2luZGV4KytdID0gdGhhdFstLWxlbmd0aF07XHJcbiAgICAgICAgdGhhdFtsZW5ndGhdICA9IHZhbHVlO1xyXG4gICAgICB9IHJldHVybiB0aGF0O1xyXG4gICAgfSxcclxuICAgIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiwgdGhpc0FyZyAqLyl7XHJcbiAgICAgIHJldHVybiBhcnJheVNvbWUodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcclxuICAgIH0sXHJcbiAgICBzb3J0OiBmdW5jdGlvbiBzb3J0KGNvbXBhcmVmbil7XHJcbiAgICAgIHJldHVybiBhcnJheVNvcnQuY2FsbCh2YWxpZGF0ZSh0aGlzKSwgY29tcGFyZWZuKTtcclxuICAgIH0sXHJcbiAgICBzdWJhcnJheTogZnVuY3Rpb24gc3ViYXJyYXkoYmVnaW4sIGVuZCl7XHJcbiAgICAgIHZhciBPICAgICAgPSB2YWxpZGF0ZSh0aGlzKVxyXG4gICAgICAgICwgbGVuZ3RoID0gTy5sZW5ndGhcclxuICAgICAgICAsICRiZWdpbiA9IHRvSW5kZXgoYmVnaW4sIGxlbmd0aCk7XHJcbiAgICAgIHJldHVybiBuZXcgKHNwZWNpZXNDb25zdHJ1Y3RvcihPLCBPW0RFRl9DT05TVFJVQ1RPUl0pKShcclxuICAgICAgICBPLmJ1ZmZlcixcclxuICAgICAgICBPLmJ5dGVPZmZzZXQgKyAkYmVnaW4gKiBPLkJZVEVTX1BFUl9FTEVNRU5ULFxyXG4gICAgICAgIHRvTGVuZ3RoKChlbmQgPT09IHVuZGVmaW5lZCA/IGxlbmd0aCA6IHRvSW5kZXgoZW5kLCBsZW5ndGgpKSAtICRiZWdpbilcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICB2YXIgJHNsaWNlID0gZnVuY3Rpb24gc2xpY2Uoc3RhcnQsIGVuZCl7XHJcbiAgICByZXR1cm4gc3BlY2llc0Zyb21MaXN0KHRoaXMsIGFycmF5U2xpY2UuY2FsbCh2YWxpZGF0ZSh0aGlzKSwgc3RhcnQsIGVuZCkpO1xyXG4gIH07XHJcblxyXG4gIHZhciAkc2V0ID0gZnVuY3Rpb24gc2V0KGFycmF5TGlrZSAvKiwgb2Zmc2V0ICovKXtcclxuICAgIHZhbGlkYXRlKHRoaXMpO1xyXG4gICAgdmFyIG9mZnNldCA9IHRvT2Zmc2V0KGFyZ3VtZW50c1sxXSwgMSlcclxuICAgICAgLCBsZW5ndGggPSB0aGlzLmxlbmd0aFxyXG4gICAgICAsIHNyYyAgICA9IHRvT2JqZWN0KGFycmF5TGlrZSlcclxuICAgICAgLCBsZW4gICAgPSB0b0xlbmd0aChzcmMubGVuZ3RoKVxyXG4gICAgICAsIGluZGV4ICA9IDA7XHJcbiAgICBpZihsZW4gKyBvZmZzZXQgPiBsZW5ndGgpdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xyXG4gICAgd2hpbGUoaW5kZXggPCBsZW4pdGhpc1tvZmZzZXQgKyBpbmRleF0gPSBzcmNbaW5kZXgrK107XHJcbiAgfTtcclxuXHJcbiAgdmFyICRpdGVyYXRvcnMgPSB7XHJcbiAgICBlbnRyaWVzOiBmdW5jdGlvbiBlbnRyaWVzKCl7XHJcbiAgICAgIHJldHVybiBhcnJheUVudHJpZXMuY2FsbCh2YWxpZGF0ZSh0aGlzKSk7XHJcbiAgICB9LFxyXG4gICAga2V5czogZnVuY3Rpb24ga2V5cygpe1xyXG4gICAgICByZXR1cm4gYXJyYXlLZXlzLmNhbGwodmFsaWRhdGUodGhpcykpO1xyXG4gICAgfSxcclxuICAgIHZhbHVlczogZnVuY3Rpb24gdmFsdWVzKCl7XHJcbiAgICAgIHJldHVybiBhcnJheVZhbHVlcy5jYWxsKHZhbGlkYXRlKHRoaXMpKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICB2YXIgaXNUQUluZGV4ID0gZnVuY3Rpb24odGFyZ2V0LCBrZXkpe1xyXG4gICAgcmV0dXJuIGlzT2JqZWN0KHRhcmdldClcclxuICAgICAgJiYgdGFyZ2V0W1RZUEVEX0FSUkFZXVxyXG4gICAgICAmJiB0eXBlb2Yga2V5ICE9ICdzeW1ib2wnXHJcbiAgICAgICYmIGtleSBpbiB0YXJnZXRcclxuICAgICAgJiYgU3RyaW5nKCtrZXkpID09IFN0cmluZyhrZXkpO1xyXG4gIH07XHJcbiAgdmFyICRnZXREZXNjID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KXtcclxuICAgIHJldHVybiBpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxyXG4gICAgICA/IHByb3BlcnR5RGVzYygyLCB0YXJnZXRba2V5XSlcclxuICAgICAgOiBnT1BEKHRhcmdldCwga2V5KTtcclxuICB9O1xyXG4gIHZhciAkc2V0RGVzYyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBkZXNjKXtcclxuICAgIGlmKGlzVEFJbmRleCh0YXJnZXQsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpXHJcbiAgICAgICYmIGlzT2JqZWN0KGRlc2MpXHJcbiAgICAgICYmIGhhcyhkZXNjLCAndmFsdWUnKVxyXG4gICAgICAmJiAhaGFzKGRlc2MsICdnZXQnKVxyXG4gICAgICAmJiAhaGFzKGRlc2MsICdzZXQnKVxyXG4gICAgICAvLyBUT0RPOiBhZGQgdmFsaWRhdGlvbiBkZXNjcmlwdG9yIHcvbyBjYWxsaW5nIGFjY2Vzc29yc1xyXG4gICAgICAmJiAhZGVzYy5jb25maWd1cmFibGVcclxuICAgICAgJiYgKCFoYXMoZGVzYywgJ3dyaXRhYmxlJykgfHwgZGVzYy53cml0YWJsZSlcclxuICAgICAgJiYgKCFoYXMoZGVzYywgJ2VudW1lcmFibGUnKSB8fCBkZXNjLmVudW1lcmFibGUpXHJcbiAgICApe1xyXG4gICAgICB0YXJnZXRba2V5XSA9IGRlc2MudmFsdWU7XHJcbiAgICAgIHJldHVybiB0YXJnZXQ7XHJcbiAgICB9IGVsc2UgcmV0dXJuIGRQKHRhcmdldCwga2V5LCBkZXNjKTtcclxuICB9O1xyXG5cclxuICBpZighQUxMX0NPTlNUUlVDVE9SUyl7XHJcbiAgICAkR09QRC5mID0gJGdldERlc2M7XHJcbiAgICAkRFAuZiAgID0gJHNldERlc2M7XHJcbiAgfVxyXG5cclxuICAkZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFBTExfQ09OU1RSVUNUT1JTLCAnT2JqZWN0Jywge1xyXG4gICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0RGVzYyxcclxuICAgIGRlZmluZVByb3BlcnR5OiAgICAgICAgICAgJHNldERlc2NcclxuICB9KTtcclxuXHJcbiAgaWYoZmFpbHMoZnVuY3Rpb24oKXsgYXJyYXlUb1N0cmluZy5jYWxsKHt9KTsgfSkpe1xyXG4gICAgYXJyYXlUb1N0cmluZyA9IGFycmF5VG9Mb2NhbGVTdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpe1xyXG4gICAgICByZXR1cm4gYXJyYXlKb2luLmNhbGwodGhpcyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB2YXIgJFR5cGVkQXJyYXlQcm90b3R5cGUkID0gcmVkZWZpbmVBbGwoe30sIHByb3RvKTtcclxuICByZWRlZmluZUFsbCgkVHlwZWRBcnJheVByb3RvdHlwZSQsICRpdGVyYXRvcnMpO1xyXG4gIGhpZGUoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCBJVEVSQVRPUiwgJGl0ZXJhdG9ycy52YWx1ZXMpO1xyXG4gIHJlZGVmaW5lQWxsKCRUeXBlZEFycmF5UHJvdG90eXBlJCwge1xyXG4gICAgc2xpY2U6ICAgICAgICAgICRzbGljZSxcclxuICAgIHNldDogICAgICAgICAgICAkc2V0LFxyXG4gICAgY29uc3RydWN0b3I6ICAgIGZ1bmN0aW9uKCl7IC8qIG5vb3AgKi8gfSxcclxuICAgIHRvU3RyaW5nOiAgICAgICBhcnJheVRvU3RyaW5nLFxyXG4gICAgdG9Mb2NhbGVTdHJpbmc6ICR0b0xvY2FsZVN0cmluZ1xyXG4gIH0pO1xyXG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdidWZmZXInLCAnYicpO1xyXG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdieXRlT2Zmc2V0JywgJ28nKTtcclxuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnl0ZUxlbmd0aCcsICdsJyk7XHJcbiAgYWRkR2V0dGVyKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgJ2xlbmd0aCcsICdlJyk7XHJcbiAgZFAoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCBUQUcsIHtcclxuICAgIGdldDogZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXNbVFlQRURfQVJSQVldOyB9XHJcbiAgfSk7XHJcblxyXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBCWVRFUywgd3JhcHBlciwgQ0xBTVBFRCl7XHJcbiAgICBDTEFNUEVEID0gISFDTEFNUEVEO1xyXG4gICAgdmFyIE5BTUUgICAgICAgPSBLRVkgKyAoQ0xBTVBFRCA/ICdDbGFtcGVkJyA6ICcnKSArICdBcnJheSdcclxuICAgICAgLCBJU05UX1VJTlQ4ID0gTkFNRSAhPSAnVWludDhBcnJheSdcclxuICAgICAgLCBHRVRURVIgICAgID0gJ2dldCcgKyBLRVlcclxuICAgICAgLCBTRVRURVIgICAgID0gJ3NldCcgKyBLRVlcclxuICAgICAgLCBUeXBlZEFycmF5ID0gZ2xvYmFsW05BTUVdXHJcbiAgICAgICwgQmFzZSAgICAgICA9IFR5cGVkQXJyYXkgfHwge31cclxuICAgICAgLCBUQUMgICAgICAgID0gVHlwZWRBcnJheSAmJiBnZXRQcm90b3R5cGVPZihUeXBlZEFycmF5KVxyXG4gICAgICAsIEZPUkNFRCAgICAgPSAhVHlwZWRBcnJheSB8fCAhJHR5cGVkLkFCVlxyXG4gICAgICAsIE8gICAgICAgICAgPSB7fVxyXG4gICAgICAsIFR5cGVkQXJyYXlQcm90b3R5cGUgPSBUeXBlZEFycmF5ICYmIFR5cGVkQXJyYXlbUFJPVE9UWVBFXTtcclxuICAgIHZhciBnZXR0ZXIgPSBmdW5jdGlvbih0aGF0LCBpbmRleCl7XHJcbiAgICAgIHZhciBkYXRhID0gdGhhdC5fZDtcclxuICAgICAgcmV0dXJuIGRhdGEudltHRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIExJVFRMRV9FTkRJQU4pO1xyXG4gICAgfTtcclxuICAgIHZhciBzZXR0ZXIgPSBmdW5jdGlvbih0aGF0LCBpbmRleCwgdmFsdWUpe1xyXG4gICAgICB2YXIgZGF0YSA9IHRoYXQuX2Q7XHJcbiAgICAgIGlmKENMQU1QRUQpdmFsdWUgPSAodmFsdWUgPSBNYXRoLnJvdW5kKHZhbHVlKSkgPCAwID8gMCA6IHZhbHVlID4gMHhmZiA/IDB4ZmYgOiB2YWx1ZSAmIDB4ZmY7XHJcbiAgICAgIGRhdGEudltTRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIHZhbHVlLCBMSVRUTEVfRU5ESUFOKTtcclxuICAgIH07XHJcbiAgICB2YXIgYWRkRWxlbWVudCA9IGZ1bmN0aW9uKHRoYXQsIGluZGV4KXtcclxuICAgICAgZFAodGhhdCwgaW5kZXgsIHtcclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICByZXR1cm4gZ2V0dGVyKHRoaXMsIGluZGV4KTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHNldDogZnVuY3Rpb24odmFsdWUpe1xyXG4gICAgICAgICAgcmV0dXJuIHNldHRlcih0aGlzLCBpbmRleCwgdmFsdWUpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZVxyXG4gICAgICB9KTtcclxuICAgIH07XHJcbiAgICBpZihGT1JDRUQpe1xyXG4gICAgICBUeXBlZEFycmF5ID0gd3JhcHBlcihmdW5jdGlvbih0aGF0LCBkYXRhLCAkb2Zmc2V0LCAkbGVuZ3RoKXtcclxuICAgICAgICBhbkluc3RhbmNlKHRoYXQsIFR5cGVkQXJyYXksIE5BTUUsICdfZCcpO1xyXG4gICAgICAgIHZhciBpbmRleCAgPSAwXHJcbiAgICAgICAgICAsIG9mZnNldCA9IDBcclxuICAgICAgICAgICwgYnVmZmVyLCBieXRlTGVuZ3RoLCBsZW5ndGgsIGtsYXNzO1xyXG4gICAgICAgIGlmKCFpc09iamVjdChkYXRhKSl7XHJcbiAgICAgICAgICBsZW5ndGggICAgID0gc3RyaWN0VG9MZW5ndGgoZGF0YSwgdHJ1ZSlcclxuICAgICAgICAgIGJ5dGVMZW5ndGggPSBsZW5ndGggKiBCWVRFUztcclxuICAgICAgICAgIGJ1ZmZlciAgICAgPSBuZXcgJEFycmF5QnVmZmVyKGJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIH0gZWxzZSBpZihkYXRhIGluc3RhbmNlb2YgJEFycmF5QnVmZmVyIHx8IChrbGFzcyA9IGNsYXNzb2YoZGF0YSkpID09IEFSUkFZX0JVRkZFUiB8fCBrbGFzcyA9PSBTSEFSRURfQlVGRkVSKXtcclxuICAgICAgICAgIGJ1ZmZlciA9IGRhdGE7XHJcbiAgICAgICAgICBvZmZzZXQgPSB0b09mZnNldCgkb2Zmc2V0LCBCWVRFUyk7XHJcbiAgICAgICAgICB2YXIgJGxlbiA9IGRhdGEuYnl0ZUxlbmd0aDtcclxuICAgICAgICAgIGlmKCRsZW5ndGggPT09IHVuZGVmaW5lZCl7XHJcbiAgICAgICAgICAgIGlmKCRsZW4gJSBCWVRFUyl0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XHJcbiAgICAgICAgICAgIGJ5dGVMZW5ndGggPSAkbGVuIC0gb2Zmc2V0O1xyXG4gICAgICAgICAgICBpZihieXRlTGVuZ3RoIDwgMCl0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gdG9MZW5ndGgoJGxlbmd0aCkgKiBCWVRFUztcclxuICAgICAgICAgICAgaWYoYnl0ZUxlbmd0aCArIG9mZnNldCA+ICRsZW4pdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgbGVuZ3RoID0gYnl0ZUxlbmd0aCAvIEJZVEVTO1xyXG4gICAgICAgIH0gZWxzZSBpZihUWVBFRF9BUlJBWSBpbiBkYXRhKXtcclxuICAgICAgICAgIHJldHVybiBmcm9tTGlzdChUeXBlZEFycmF5LCBkYXRhKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgcmV0dXJuICRmcm9tLmNhbGwoVHlwZWRBcnJheSwgZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGhpZGUodGhhdCwgJ19kJywge1xyXG4gICAgICAgICAgYjogYnVmZmVyLFxyXG4gICAgICAgICAgbzogb2Zmc2V0LFxyXG4gICAgICAgICAgbDogYnl0ZUxlbmd0aCxcclxuICAgICAgICAgIGU6IGxlbmd0aCxcclxuICAgICAgICAgIHY6IG5ldyAkRGF0YVZpZXcoYnVmZmVyKVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHdoaWxlKGluZGV4IDwgbGVuZ3RoKWFkZEVsZW1lbnQodGhhdCwgaW5kZXgrKyk7XHJcbiAgICAgIH0pO1xyXG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gY3JlYXRlKCRUeXBlZEFycmF5UHJvdG90eXBlJCk7XHJcbiAgICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgJ2NvbnN0cnVjdG9yJywgVHlwZWRBcnJheSk7XHJcbiAgICB9IGVsc2UgaWYoISRpdGVyRGV0ZWN0KGZ1bmN0aW9uKGl0ZXIpe1xyXG4gICAgICAvLyBWOCB3b3JrcyB3aXRoIGl0ZXJhdG9ycywgYnV0IGZhaWxzIGluIG1hbnkgb3RoZXIgY2FzZXNcclxuICAgICAgLy8gaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTQ1NTJcclxuICAgICAgbmV3IFR5cGVkQXJyYXkobnVsbCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XHJcbiAgICAgIG5ldyBUeXBlZEFycmF5KGl0ZXIpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xyXG4gICAgfSwgdHJ1ZSkpe1xyXG4gICAgICBUeXBlZEFycmF5ID0gd3JhcHBlcihmdW5jdGlvbih0aGF0LCBkYXRhLCAkb2Zmc2V0LCAkbGVuZ3RoKXtcclxuICAgICAgICBhbkluc3RhbmNlKHRoYXQsIFR5cGVkQXJyYXksIE5BTUUpO1xyXG4gICAgICAgIHZhciBrbGFzcztcclxuICAgICAgICAvLyBgd3NgIG1vZHVsZSBidWcsIHRlbXBvcmFyaWx5IHJlbW92ZSB2YWxpZGF0aW9uIGxlbmd0aCBmb3IgVWludDhBcnJheVxyXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJzb2NrZXRzL3dzL3B1bGwvNjQ1XHJcbiAgICAgICAgaWYoIWlzT2JqZWN0KGRhdGEpKXJldHVybiBuZXcgQmFzZShzdHJpY3RUb0xlbmd0aChkYXRhLCBJU05UX1VJTlQ4KSk7XHJcbiAgICAgICAgaWYoZGF0YSBpbnN0YW5jZW9mICRBcnJheUJ1ZmZlciB8fCAoa2xhc3MgPSBjbGFzc29mKGRhdGEpKSA9PSBBUlJBWV9CVUZGRVIgfHwga2xhc3MgPT0gU0hBUkVEX0JVRkZFUil7XHJcbiAgICAgICAgICByZXR1cm4gJGxlbmd0aCAhPT0gdW5kZWZpbmVkXHJcbiAgICAgICAgICAgID8gbmV3IEJhc2UoZGF0YSwgdG9PZmZzZXQoJG9mZnNldCwgQllURVMpLCAkbGVuZ3RoKVxyXG4gICAgICAgICAgICA6ICRvZmZzZXQgIT09IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgID8gbmV3IEJhc2UoZGF0YSwgdG9PZmZzZXQoJG9mZnNldCwgQllURVMpKVxyXG4gICAgICAgICAgICAgIDogbmV3IEJhc2UoZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKFRZUEVEX0FSUkFZIGluIGRhdGEpcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xyXG4gICAgICAgIHJldHVybiAkZnJvbS5jYWxsKFR5cGVkQXJyYXksIGRhdGEpO1xyXG4gICAgICB9KTtcclxuICAgICAgYXJyYXlGb3JFYWNoKFRBQyAhPT0gRnVuY3Rpb24ucHJvdG90eXBlID8gZ09QTihCYXNlKS5jb25jYXQoZ09QTihUQUMpKSA6IGdPUE4oQmFzZSksIGZ1bmN0aW9uKGtleSl7XHJcbiAgICAgICAgaWYoIShrZXkgaW4gVHlwZWRBcnJheSkpaGlkZShUeXBlZEFycmF5LCBrZXksIEJhc2Vba2V5XSk7XHJcbiAgICAgIH0pO1xyXG4gICAgICBUeXBlZEFycmF5W1BST1RPVFlQRV0gPSBUeXBlZEFycmF5UHJvdG90eXBlO1xyXG4gICAgICBpZighTElCUkFSWSlUeXBlZEFycmF5UHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVHlwZWRBcnJheTtcclxuICAgIH1cclxuICAgIHZhciAkbmF0aXZlSXRlcmF0b3IgICA9IFR5cGVkQXJyYXlQcm90b3R5cGVbSVRFUkFUT1JdXHJcbiAgICAgICwgQ09SUkVDVF9JVEVSX05BTUUgPSAhISRuYXRpdmVJdGVyYXRvciAmJiAoJG5hdGl2ZUl0ZXJhdG9yLm5hbWUgPT0gJ3ZhbHVlcycgfHwgJG5hdGl2ZUl0ZXJhdG9yLm5hbWUgPT0gdW5kZWZpbmVkKVxyXG4gICAgICAsICRpdGVyYXRvciAgICAgICAgID0gJGl0ZXJhdG9ycy52YWx1ZXM7XHJcbiAgICBoaWRlKFR5cGVkQXJyYXksIFRZUEVEX0NPTlNUUlVDVE9SLCB0cnVlKTtcclxuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgVFlQRURfQVJSQVksIE5BTUUpO1xyXG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBWSUVXLCB0cnVlKTtcclxuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgREVGX0NPTlNUUlVDVE9SLCBUeXBlZEFycmF5KTtcclxuXHJcbiAgICBpZihDTEFNUEVEID8gbmV3IFR5cGVkQXJyYXkoMSlbVEFHXSAhPSBOQU1FIDogIShUQUcgaW4gVHlwZWRBcnJheVByb3RvdHlwZSkpe1xyXG4gICAgICBkUChUeXBlZEFycmF5UHJvdG90eXBlLCBUQUcsIHtcclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiBOQU1FOyB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIE9bTkFNRV0gPSBUeXBlZEFycmF5O1xyXG5cclxuICAgICRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogKFR5cGVkQXJyYXkgIT0gQmFzZSksIE8pO1xyXG5cclxuICAgICRleHBvcnQoJGV4cG9ydC5TLCBOQU1FLCB7XHJcbiAgICAgIEJZVEVTX1BFUl9FTEVNRU5UOiBCWVRFUyxcclxuICAgICAgZnJvbTogJGZyb20sXHJcbiAgICAgIG9mOiAkb2ZcclxuICAgIH0pO1xyXG5cclxuICAgIGlmKCEoQllURVNfUEVSX0VMRU1FTlQgaW4gVHlwZWRBcnJheVByb3RvdHlwZSkpaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBCWVRFU19QRVJfRUxFTUVOVCwgQllURVMpO1xyXG5cclxuICAgICRleHBvcnQoJGV4cG9ydC5QLCBOQU1FLCBwcm90byk7XHJcblxyXG4gICAgc2V0U3BlY2llcyhOQU1FKTtcclxuXHJcbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIEZPUkNFRF9TRVQsIE5BTUUsIHtzZXQ6ICRzZXR9KTtcclxuXHJcbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFDT1JSRUNUX0lURVJfTkFNRSwgTkFNRSwgJGl0ZXJhdG9ycyk7XHJcblxyXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoVHlwZWRBcnJheVByb3RvdHlwZS50b1N0cmluZyAhPSBhcnJheVRvU3RyaW5nKSwgTkFNRSwge3RvU3RyaW5nOiBhcnJheVRvU3RyaW5nfSk7XHJcblxyXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbigpe1xyXG4gICAgICBuZXcgVHlwZWRBcnJheSgxKS5zbGljZSgpO1xyXG4gICAgfSksIE5BTUUsIHtzbGljZTogJHNsaWNlfSk7XHJcblxyXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24oKXtcclxuICAgICAgcmV0dXJuIFsxLCAyXS50b0xvY2FsZVN0cmluZygpICE9IG5ldyBUeXBlZEFycmF5KFsxLCAyXSkudG9Mb2NhbGVTdHJpbmcoKVxyXG4gICAgfSkgfHwgIWZhaWxzKGZ1bmN0aW9uKCl7XHJcbiAgICAgIFR5cGVkQXJyYXlQcm90b3R5cGUudG9Mb2NhbGVTdHJpbmcuY2FsbChbMSwgMl0pO1xyXG4gICAgfSkpLCBOQU1FLCB7dG9Mb2NhbGVTdHJpbmc6ICR0b0xvY2FsZVN0cmluZ30pO1xyXG5cclxuICAgIEl0ZXJhdG9yc1tOQU1FXSA9IENPUlJFQ1RfSVRFUl9OQU1FID8gJG5hdGl2ZUl0ZXJhdG9yIDogJGl0ZXJhdG9yO1xyXG4gICAgaWYoIUxJQlJBUlkgJiYgIUNPUlJFQ1RfSVRFUl9OQU1FKWhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgSVRFUkFUT1IsICRpdGVyYXRvcik7XHJcbiAgfTtcclxufSBlbHNlIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKXsgLyogZW1wdHkgKi8gfTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWJ1ZmZlci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC1idWZmZXIuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIGdsb2JhbCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIilcclxuICAsIERFU0NSSVBUT1JTICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpXHJcbiAgLCBMSUJSQVJZICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2xpYnJhcnkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanNcIilcclxuICAsICR0eXBlZCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdHlwZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLmpzXCIpXHJcbiAgLCBoaWRlICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hpZGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hpZGUuanNcIilcclxuICAsIHJlZGVmaW5lQWxsICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUtYWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanNcIilcclxuICAsIGZhaWxzICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmFpbHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCIpXHJcbiAgLCBhbkluc3RhbmNlICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLWluc3RhbmNlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qc1wiKVxyXG4gICwgdG9JbnRlZ2VyICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pbnRlZ2VyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbnRlZ2VyLmpzXCIpXHJcbiAgLCB0b0xlbmd0aCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWxlbmd0aCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzXCIpXHJcbiAgLCBnT1BOICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BuICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi5qc1wiKS5mXHJcbiAgLCBkUCAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1kcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzXCIpLmZcclxuICAsIGFycmF5RmlsbCAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktZmlsbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktZmlsbC5qc1wiKVxyXG4gICwgc2V0VG9TdHJpbmdUYWcgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zZXQtdG8tc3RyaW5nLXRhZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanNcIilcclxuICAsIEFSUkFZX0JVRkZFUiAgID0gJ0FycmF5QnVmZmVyJ1xyXG4gICwgREFUQV9WSUVXICAgICAgPSAnRGF0YVZpZXcnXHJcbiAgLCBQUk9UT1RZUEUgICAgICA9ICdwcm90b3R5cGUnXHJcbiAgLCBXUk9OR19MRU5HVEggICA9ICdXcm9uZyBsZW5ndGghJ1xyXG4gICwgV1JPTkdfSU5ERVggICAgPSAnV3JvbmcgaW5kZXghJ1xyXG4gICwgJEFycmF5QnVmZmVyICAgPSBnbG9iYWxbQVJSQVlfQlVGRkVSXVxyXG4gICwgJERhdGFWaWV3ICAgICAgPSBnbG9iYWxbREFUQV9WSUVXXVxyXG4gICwgTWF0aCAgICAgICAgICAgPSBnbG9iYWwuTWF0aFxyXG4gICwgUmFuZ2VFcnJvciAgICAgPSBnbG9iYWwuUmFuZ2VFcnJvclxyXG4gICwgSW5maW5pdHkgICAgICAgPSBnbG9iYWwuSW5maW5pdHlcclxuICAsIEJhc2VCdWZmZXIgICAgID0gJEFycmF5QnVmZmVyXHJcbiAgLCBhYnMgICAgICAgICAgICA9IE1hdGguYWJzXHJcbiAgLCBwb3cgICAgICAgICAgICA9IE1hdGgucG93XHJcbiAgLCBmbG9vciAgICAgICAgICA9IE1hdGguZmxvb3JcclxuICAsIGxvZyAgICAgICAgICAgID0gTWF0aC5sb2dcclxuICAsIExOMiAgICAgICAgICAgID0gTWF0aC5MTjJcclxuICAsIEJVRkZFUiAgICAgICAgID0gJ2J1ZmZlcidcclxuICAsIEJZVEVfTEVOR1RIICAgID0gJ2J5dGVMZW5ndGgnXHJcbiAgLCBCWVRFX09GRlNFVCAgICA9ICdieXRlT2Zmc2V0J1xyXG4gICwgJEJVRkZFUiAgICAgICAgPSBERVNDUklQVE9SUyA/ICdfYicgOiBCVUZGRVJcclxuICAsICRMRU5HVEggICAgICAgID0gREVTQ1JJUFRPUlMgPyAnX2wnIDogQllURV9MRU5HVEhcclxuICAsICRPRkZTRVQgICAgICAgID0gREVTQ1JJUFRPUlMgPyAnX28nIDogQllURV9PRkZTRVQ7XHJcblxyXG4vLyBJRUVFNzU0IGNvbnZlcnNpb25zIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvaWVlZTc1NFxyXG52YXIgcGFja0lFRUU3NTQgPSBmdW5jdGlvbih2YWx1ZSwgbUxlbiwgbkJ5dGVzKXtcclxuICB2YXIgYnVmZmVyID0gQXJyYXkobkJ5dGVzKVxyXG4gICAgLCBlTGVuICAgPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcclxuICAgICwgZU1heCAgID0gKDEgPDwgZUxlbikgLSAxXHJcbiAgICAsIGVCaWFzICA9IGVNYXggPj4gMVxyXG4gICAgLCBydCAgICAgPSBtTGVuID09PSAyMyA/IHBvdygyLCAtMjQpIC0gcG93KDIsIC03NykgOiAwXHJcbiAgICAsIGkgICAgICA9IDBcclxuICAgICwgcyAgICAgID0gdmFsdWUgPCAwIHx8IHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDAgPyAxIDogMFxyXG4gICAgLCBlLCBtLCBjO1xyXG4gIHZhbHVlID0gYWJzKHZhbHVlKVxyXG4gIGlmKHZhbHVlICE9IHZhbHVlIHx8IHZhbHVlID09PSBJbmZpbml0eSl7XHJcbiAgICBtID0gdmFsdWUgIT0gdmFsdWUgPyAxIDogMDtcclxuICAgIGUgPSBlTWF4O1xyXG4gIH0gZWxzZSB7XHJcbiAgICBlID0gZmxvb3IobG9nKHZhbHVlKSAvIExOMik7XHJcbiAgICBpZih2YWx1ZSAqIChjID0gcG93KDIsIC1lKSkgPCAxKXtcclxuICAgICAgZS0tO1xyXG4gICAgICBjICo9IDI7XHJcbiAgICB9XHJcbiAgICBpZihlICsgZUJpYXMgPj0gMSl7XHJcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHZhbHVlICs9IHJ0ICogcG93KDIsIDEgLSBlQmlhcyk7XHJcbiAgICB9XHJcbiAgICBpZih2YWx1ZSAqIGMgPj0gMil7XHJcbiAgICAgIGUrKztcclxuICAgICAgYyAvPSAyO1xyXG4gICAgfVxyXG4gICAgaWYoZSArIGVCaWFzID49IGVNYXgpe1xyXG4gICAgICBtID0gMDtcclxuICAgICAgZSA9IGVNYXg7XHJcbiAgICB9IGVsc2UgaWYoZSArIGVCaWFzID49IDEpe1xyXG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogcG93KDIsIG1MZW4pO1xyXG4gICAgICBlID0gZSArIGVCaWFzO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbSA9IHZhbHVlICogcG93KDIsIGVCaWFzIC0gMSkgKiBwb3coMiwgbUxlbik7XHJcbiAgICAgIGUgPSAwO1xyXG4gICAgfVxyXG4gIH1cclxuICBmb3IoOyBtTGVuID49IDg7IGJ1ZmZlcltpKytdID0gbSAmIDI1NSwgbSAvPSAyNTYsIG1MZW4gLT0gOCk7XHJcbiAgZSA9IGUgPDwgbUxlbiB8IG07XHJcbiAgZUxlbiArPSBtTGVuO1xyXG4gIGZvcig7IGVMZW4gPiAwOyBidWZmZXJbaSsrXSA9IGUgJiAyNTUsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xyXG4gIGJ1ZmZlclstLWldIHw9IHMgKiAxMjg7XHJcbiAgcmV0dXJuIGJ1ZmZlcjtcclxufTtcclxudmFyIHVucGFja0lFRUU3NTQgPSBmdW5jdGlvbihidWZmZXIsIG1MZW4sIG5CeXRlcyl7XHJcbiAgdmFyIGVMZW4gID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXHJcbiAgICAsIGVNYXggID0gKDEgPDwgZUxlbikgLSAxXHJcbiAgICAsIGVCaWFzID0gZU1heCA+PiAxXHJcbiAgICAsIG5CaXRzID0gZUxlbiAtIDdcclxuICAgICwgaSAgICAgPSBuQnl0ZXMgLSAxXHJcbiAgICAsIHMgICAgID0gYnVmZmVyW2ktLV1cclxuICAgICwgZSAgICAgPSBzICYgMTI3XHJcbiAgICAsIG07XHJcbiAgcyA+Pj0gNztcclxuICBmb3IoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW2ldLCBpLS0sIG5CaXRzIC09IDgpO1xyXG4gIG0gPSBlICYgKDEgPDwgLW5CaXRzKSAtIDE7XHJcbiAgZSA+Pj0gLW5CaXRzO1xyXG4gIG5CaXRzICs9IG1MZW47XHJcbiAgZm9yKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltpXSwgaS0tLCBuQml0cyAtPSA4KTtcclxuICBpZihlID09PSAwKXtcclxuICAgIGUgPSAxIC0gZUJpYXM7XHJcbiAgfSBlbHNlIGlmKGUgPT09IGVNYXgpe1xyXG4gICAgcmV0dXJuIG0gPyBOYU4gOiBzID8gLUluZmluaXR5IDogSW5maW5pdHk7XHJcbiAgfSBlbHNlIHtcclxuICAgIG0gPSBtICsgcG93KDIsIG1MZW4pO1xyXG4gICAgZSA9IGUgLSBlQmlhcztcclxuICB9IHJldHVybiAocyA/IC0xIDogMSkgKiBtICogcG93KDIsIGUgLSBtTGVuKTtcclxufTtcclxuXHJcbnZhciB1bnBhY2tJMzIgPSBmdW5jdGlvbihieXRlcyl7XHJcbiAgcmV0dXJuIGJ5dGVzWzNdIDw8IDI0IHwgYnl0ZXNbMl0gPDwgMTYgfCBieXRlc1sxXSA8PCA4IHwgYnl0ZXNbMF07XHJcbn07XHJcbnZhciBwYWNrSTggPSBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIFtpdCAmIDB4ZmZdO1xyXG59O1xyXG52YXIgcGFja0kxNiA9IGZ1bmN0aW9uKGl0KXtcclxuICByZXR1cm4gW2l0ICYgMHhmZiwgaXQgPj4gOCAmIDB4ZmZdO1xyXG59O1xyXG52YXIgcGFja0kzMiA9IGZ1bmN0aW9uKGl0KXtcclxuICByZXR1cm4gW2l0ICYgMHhmZiwgaXQgPj4gOCAmIDB4ZmYsIGl0ID4+IDE2ICYgMHhmZiwgaXQgPj4gMjQgJiAweGZmXTtcclxufTtcclxudmFyIHBhY2tGNjQgPSBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIHBhY2tJRUVFNzU0KGl0LCA1MiwgOCk7XHJcbn07XHJcbnZhciBwYWNrRjMyID0gZnVuY3Rpb24oaXQpe1xyXG4gIHJldHVybiBwYWNrSUVFRTc1NChpdCwgMjMsIDQpO1xyXG59O1xyXG5cclxudmFyIGFkZEdldHRlciA9IGZ1bmN0aW9uKEMsIGtleSwgaW50ZXJuYWwpe1xyXG4gIGRQKENbUFJPVE9UWVBFXSwga2V5LCB7Z2V0OiBmdW5jdGlvbigpeyByZXR1cm4gdGhpc1tpbnRlcm5hbF07IH19KTtcclxufTtcclxuXHJcbnZhciBnZXQgPSBmdW5jdGlvbih2aWV3LCBieXRlcywgaW5kZXgsIGlzTGl0dGxlRW5kaWFuKXtcclxuICB2YXIgbnVtSW5kZXggPSAraW5kZXhcclxuICAgICwgaW50SW5kZXggPSB0b0ludGVnZXIobnVtSW5kZXgpO1xyXG4gIGlmKG51bUluZGV4ICE9IGludEluZGV4IHx8IGludEluZGV4IDwgMCB8fCBpbnRJbmRleCArIGJ5dGVzID4gdmlld1skTEVOR1RIXSl0aHJvdyBSYW5nZUVycm9yKFdST05HX0lOREVYKTtcclxuICB2YXIgc3RvcmUgPSB2aWV3WyRCVUZGRVJdLl9iXHJcbiAgICAsIHN0YXJ0ID0gaW50SW5kZXggKyB2aWV3WyRPRkZTRVRdXHJcbiAgICAsIHBhY2sgID0gc3RvcmUuc2xpY2Uoc3RhcnQsIHN0YXJ0ICsgYnl0ZXMpO1xyXG4gIHJldHVybiBpc0xpdHRsZUVuZGlhbiA/IHBhY2sgOiBwYWNrLnJldmVyc2UoKTtcclxufTtcclxudmFyIHNldCA9IGZ1bmN0aW9uKHZpZXcsIGJ5dGVzLCBpbmRleCwgY29udmVyc2lvbiwgdmFsdWUsIGlzTGl0dGxlRW5kaWFuKXtcclxuICB2YXIgbnVtSW5kZXggPSAraW5kZXhcclxuICAgICwgaW50SW5kZXggPSB0b0ludGVnZXIobnVtSW5kZXgpO1xyXG4gIGlmKG51bUluZGV4ICE9IGludEluZGV4IHx8IGludEluZGV4IDwgMCB8fCBpbnRJbmRleCArIGJ5dGVzID4gdmlld1skTEVOR1RIXSl0aHJvdyBSYW5nZUVycm9yKFdST05HX0lOREVYKTtcclxuICB2YXIgc3RvcmUgPSB2aWV3WyRCVUZGRVJdLl9iXHJcbiAgICAsIHN0YXJ0ID0gaW50SW5kZXggKyB2aWV3WyRPRkZTRVRdXHJcbiAgICAsIHBhY2sgID0gY29udmVyc2lvbigrdmFsdWUpO1xyXG4gIGZvcih2YXIgaSA9IDA7IGkgPCBieXRlczsgaSsrKXN0b3JlW3N0YXJ0ICsgaV0gPSBwYWNrW2lzTGl0dGxlRW5kaWFuID8gaSA6IGJ5dGVzIC0gaSAtIDFdO1xyXG59O1xyXG5cclxudmFyIHZhbGlkYXRlQXJyYXlCdWZmZXJBcmd1bWVudHMgPSBmdW5jdGlvbih0aGF0LCBsZW5ndGgpe1xyXG4gIGFuSW5zdGFuY2UodGhhdCwgJEFycmF5QnVmZmVyLCBBUlJBWV9CVUZGRVIpO1xyXG4gIHZhciBudW1iZXJMZW5ndGggPSArbGVuZ3RoXHJcbiAgICAsIGJ5dGVMZW5ndGggICA9IHRvTGVuZ3RoKG51bWJlckxlbmd0aCk7XHJcbiAgaWYobnVtYmVyTGVuZ3RoICE9IGJ5dGVMZW5ndGgpdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xyXG4gIHJldHVybiBieXRlTGVuZ3RoO1xyXG59O1xyXG5cclxuaWYoISR0eXBlZC5BQlYpe1xyXG4gICRBcnJheUJ1ZmZlciA9IGZ1bmN0aW9uIEFycmF5QnVmZmVyKGxlbmd0aCl7XHJcbiAgICB2YXIgYnl0ZUxlbmd0aCA9IHZhbGlkYXRlQXJyYXlCdWZmZXJBcmd1bWVudHModGhpcywgbGVuZ3RoKTtcclxuICAgIHRoaXMuX2IgICAgICAgPSBhcnJheUZpbGwuY2FsbChBcnJheShieXRlTGVuZ3RoKSwgMCk7XHJcbiAgICB0aGlzWyRMRU5HVEhdID0gYnl0ZUxlbmd0aDtcclxuICB9O1xyXG5cclxuICAkRGF0YVZpZXcgPSBmdW5jdGlvbiBEYXRhVmlldyhidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpe1xyXG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkRGF0YVZpZXcsIERBVEFfVklFVyk7XHJcbiAgICBhbkluc3RhbmNlKGJ1ZmZlciwgJEFycmF5QnVmZmVyLCBEQVRBX1ZJRVcpO1xyXG4gICAgdmFyIGJ1ZmZlckxlbmd0aCA9IGJ1ZmZlclskTEVOR1RIXVxyXG4gICAgICAsIG9mZnNldCAgICAgICA9IHRvSW50ZWdlcihieXRlT2Zmc2V0KTtcclxuICAgIGlmKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gYnVmZmVyTGVuZ3RoKXRocm93IFJhbmdlRXJyb3IoJ1dyb25nIG9mZnNldCEnKTtcclxuICAgIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID09PSB1bmRlZmluZWQgPyBidWZmZXJMZW5ndGggLSBvZmZzZXQgOiB0b0xlbmd0aChieXRlTGVuZ3RoKTtcclxuICAgIGlmKG9mZnNldCArIGJ5dGVMZW5ndGggPiBidWZmZXJMZW5ndGgpdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xyXG4gICAgdGhpc1skQlVGRkVSXSA9IGJ1ZmZlcjtcclxuICAgIHRoaXNbJE9GRlNFVF0gPSBvZmZzZXQ7XHJcbiAgICB0aGlzWyRMRU5HVEhdID0gYnl0ZUxlbmd0aDtcclxuICB9O1xyXG5cclxuICBpZihERVNDUklQVE9SUyl7XHJcbiAgICBhZGRHZXR0ZXIoJEFycmF5QnVmZmVyLCBCWVRFX0xFTkdUSCwgJ19sJyk7XHJcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCVUZGRVIsICdfYicpO1xyXG4gICAgYWRkR2V0dGVyKCREYXRhVmlldywgQllURV9MRU5HVEgsICdfbCcpO1xyXG4gICAgYWRkR2V0dGVyKCREYXRhVmlldywgQllURV9PRkZTRVQsICdfbycpO1xyXG4gIH1cclxuXHJcbiAgcmVkZWZpbmVBbGwoJERhdGFWaWV3W1BST1RPVFlQRV0sIHtcclxuICAgIGdldEludDg6IGZ1bmN0aW9uIGdldEludDgoYnl0ZU9mZnNldCl7XHJcbiAgICAgIHJldHVybiBnZXQodGhpcywgMSwgYnl0ZU9mZnNldClbMF0gPDwgMjQgPj4gMjQ7XHJcbiAgICB9LFxyXG4gICAgZ2V0VWludDg6IGZ1bmN0aW9uIGdldFVpbnQ4KGJ5dGVPZmZzZXQpe1xyXG4gICAgICByZXR1cm4gZ2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQpWzBdO1xyXG4gICAgfSxcclxuICAgIGdldEludDE2OiBmdW5jdGlvbiBnZXRJbnQxNihieXRlT2Zmc2V0IC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xyXG4gICAgICB2YXIgYnl0ZXMgPSBnZXQodGhpcywgMiwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKTtcclxuICAgICAgcmV0dXJuIChieXRlc1sxXSA8PCA4IHwgYnl0ZXNbMF0pIDw8IDE2ID4+IDE2O1xyXG4gICAgfSxcclxuICAgIGdldFVpbnQxNjogZnVuY3Rpb24gZ2V0VWludDE2KGJ5dGVPZmZzZXQgLyosIGxpdHRsZUVuZGlhbiAqLyl7XHJcbiAgICAgIHZhciBieXRlcyA9IGdldCh0aGlzLCAyLCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pO1xyXG4gICAgICByZXR1cm4gYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xyXG4gICAgfSxcclxuICAgIGdldEludDMyOiBmdW5jdGlvbiBnZXRJbnQzMihieXRlT2Zmc2V0IC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xyXG4gICAgICByZXR1cm4gdW5wYWNrSTMyKGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pKTtcclxuICAgIH0sXHJcbiAgICBnZXRVaW50MzI6IGZ1bmN0aW9uIGdldFVpbnQzMihieXRlT2Zmc2V0IC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xyXG4gICAgICByZXR1cm4gdW5wYWNrSTMyKGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pKSA+Pj4gMDtcclxuICAgIH0sXHJcbiAgICBnZXRGbG9hdDMyOiBmdW5jdGlvbiBnZXRGbG9hdDMyKGJ5dGVPZmZzZXQgLyosIGxpdHRsZUVuZGlhbiAqLyl7XHJcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCAyMywgNCk7XHJcbiAgICB9LFxyXG4gICAgZ2V0RmxvYXQ2NDogZnVuY3Rpb24gZ2V0RmxvYXQ2NChieXRlT2Zmc2V0IC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xyXG4gICAgICByZXR1cm4gdW5wYWNrSUVFRTc1NChnZXQodGhpcywgOCwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKSwgNTIsIDgpO1xyXG4gICAgfSxcclxuICAgIHNldEludDg6IGZ1bmN0aW9uIHNldEludDgoYnl0ZU9mZnNldCwgdmFsdWUpe1xyXG4gICAgICBzZXQodGhpcywgMSwgYnl0ZU9mZnNldCwgcGFja0k4LCB2YWx1ZSk7XHJcbiAgICB9LFxyXG4gICAgc2V0VWludDg6IGZ1bmN0aW9uIHNldFVpbnQ4KGJ5dGVPZmZzZXQsIHZhbHVlKXtcclxuICAgICAgc2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQsIHBhY2tJOCwgdmFsdWUpO1xyXG4gICAgfSxcclxuICAgIHNldEludDE2OiBmdW5jdGlvbiBzZXRJbnQxNihieXRlT2Zmc2V0LCB2YWx1ZSAvKiwgbGl0dGxlRW5kaWFuICovKXtcclxuICAgICAgc2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIHBhY2tJMTYsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xyXG4gICAgfSxcclxuICAgIHNldFVpbnQxNjogZnVuY3Rpb24gc2V0VWludDE2KGJ5dGVPZmZzZXQsIHZhbHVlIC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xyXG4gICAgICBzZXQodGhpcywgMiwgYnl0ZU9mZnNldCwgcGFja0kxNiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XHJcbiAgICB9LFxyXG4gICAgc2V0SW50MzI6IGZ1bmN0aW9uIHNldEludDMyKGJ5dGVPZmZzZXQsIHZhbHVlIC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xyXG4gICAgICBzZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgcGFja0kzMiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XHJcbiAgICB9LFxyXG4gICAgc2V0VWludDMyOiBmdW5jdGlvbiBzZXRVaW50MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyosIGxpdHRsZUVuZGlhbiAqLyl7XHJcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrSTMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcclxuICAgIH0sXHJcbiAgICBzZXRGbG9hdDMyOiBmdW5jdGlvbiBzZXRGbG9hdDMyKGJ5dGVPZmZzZXQsIHZhbHVlIC8qLCBsaXR0bGVFbmRpYW4gKi8pe1xyXG4gICAgICBzZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgcGFja0YzMiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XHJcbiAgICB9LFxyXG4gICAgc2V0RmxvYXQ2NDogZnVuY3Rpb24gc2V0RmxvYXQ2NChieXRlT2Zmc2V0LCB2YWx1ZSAvKiwgbGl0dGxlRW5kaWFuICovKXtcclxuICAgICAgc2V0KHRoaXMsIDgsIGJ5dGVPZmZzZXQsIHBhY2tGNjQsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59IGVsc2Uge1xyXG4gIGlmKCFmYWlscyhmdW5jdGlvbigpe1xyXG4gICAgbmV3ICRBcnJheUJ1ZmZlcjsgICAgIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XHJcbiAgfSkgfHwgIWZhaWxzKGZ1bmN0aW9uKCl7XHJcbiAgICBuZXcgJEFycmF5QnVmZmVyKC41KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcclxuICB9KSl7XHJcbiAgICAkQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpe1xyXG4gICAgICByZXR1cm4gbmV3IEJhc2VCdWZmZXIodmFsaWRhdGVBcnJheUJ1ZmZlckFyZ3VtZW50cyh0aGlzLCBsZW5ndGgpKTtcclxuICAgIH07XHJcbiAgICB2YXIgQXJyYXlCdWZmZXJQcm90byA9ICRBcnJheUJ1ZmZlcltQUk9UT1RZUEVdID0gQmFzZUJ1ZmZlcltQUk9UT1RZUEVdO1xyXG4gICAgZm9yKHZhciBrZXlzID0gZ09QTihCYXNlQnVmZmVyKSwgaiA9IDAsIGtleTsga2V5cy5sZW5ndGggPiBqOyApe1xyXG4gICAgICBpZighKChrZXkgPSBrZXlzW2orK10pIGluICRBcnJheUJ1ZmZlcikpaGlkZSgkQXJyYXlCdWZmZXIsIGtleSwgQmFzZUJ1ZmZlcltrZXldKTtcclxuICAgIH07XHJcbiAgICBpZighTElCUkFSWSlBcnJheUJ1ZmZlclByb3RvLmNvbnN0cnVjdG9yID0gJEFycmF5QnVmZmVyO1xyXG4gIH1cclxuICAvLyBpT1MgU2FmYXJpIDcueCBidWdcclxuICB2YXIgdmlldyA9IG5ldyAkRGF0YVZpZXcobmV3ICRBcnJheUJ1ZmZlcigyKSlcclxuICAgICwgJHNldEludDggPSAkRGF0YVZpZXdbUFJPVE9UWVBFXS5zZXRJbnQ4O1xyXG4gIHZpZXcuc2V0SW50OCgwLCAyMTQ3NDgzNjQ4KTtcclxuICB2aWV3LnNldEludDgoMSwgMjE0NzQ4MzY0OSk7XHJcbiAgaWYodmlldy5nZXRJbnQ4KDApIHx8ICF2aWV3LmdldEludDgoMSkpcmVkZWZpbmVBbGwoJERhdGFWaWV3W1BST1RPVFlQRV0sIHtcclxuICAgIHNldEludDg6IGZ1bmN0aW9uIHNldEludDgoYnl0ZU9mZnNldCwgdmFsdWUpe1xyXG4gICAgICAkc2V0SW50OC5jYWxsKHRoaXMsIGJ5dGVPZmZzZXQsIHZhbHVlIDw8IDI0ID4+IDI0KTtcclxuICAgIH0sXHJcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpe1xyXG4gICAgICAkc2V0SW50OC5jYWxsKHRoaXMsIGJ5dGVPZmZzZXQsIHZhbHVlIDw8IDI0ID4+IDI0KTtcclxuICAgIH1cclxuICB9LCB0cnVlKTtcclxufVxyXG5zZXRUb1N0cmluZ1RhZygkQXJyYXlCdWZmZXIsIEFSUkFZX0JVRkZFUik7XHJcbnNldFRvU3RyaW5nVGFnKCREYXRhVmlldywgREFUQV9WSUVXKTtcclxuaGlkZSgkRGF0YVZpZXdbUFJPVE9UWVBFXSwgJHR5cGVkLlZJRVcsIHRydWUpO1xyXG5leHBvcnRzW0FSUkFZX0JVRkZFUl0gPSAkQXJyYXlCdWZmZXI7XHJcbmV4cG9ydHNbREFUQV9WSUVXXSA9ICREYXRhVmlldztcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGdsb2JhbCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgLCBoaWRlICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oaWRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzXCIpXHJcbiAgLCB1aWQgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL191aWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3VpZC5qc1wiKVxyXG4gICwgVFlQRUQgID0gdWlkKCd0eXBlZF9hcnJheScpXHJcbiAgLCBWSUVXICAgPSB1aWQoJ3ZpZXcnKVxyXG4gICwgQUJWICAgID0gISEoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGdsb2JhbC5EYXRhVmlldylcclxuICAsIENPTlNUUiA9IEFCVlxyXG4gICwgaSA9IDAsIGwgPSA5LCBUeXBlZDtcclxuXHJcbnZhciBUeXBlZEFycmF5Q29uc3RydWN0b3JzID0gKFxyXG4gICdJbnQ4QXJyYXksVWludDhBcnJheSxVaW50OENsYW1wZWRBcnJheSxJbnQxNkFycmF5LFVpbnQxNkFycmF5LEludDMyQXJyYXksVWludDMyQXJyYXksRmxvYXQzMkFycmF5LEZsb2F0NjRBcnJheSdcclxuKS5zcGxpdCgnLCcpO1xyXG5cclxud2hpbGUoaSA8IGwpe1xyXG4gIGlmKFR5cGVkID0gZ2xvYmFsW1R5cGVkQXJyYXlDb25zdHJ1Y3RvcnNbaSsrXV0pe1xyXG4gICAgaGlkZShUeXBlZC5wcm90b3R5cGUsIFRZUEVELCB0cnVlKTtcclxuICAgIGhpZGUoVHlwZWQucHJvdG90eXBlLCBWSUVXLCB0cnVlKTtcclxuICB9IGVsc2UgQ09OU1RSID0gZmFsc2U7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0ge1xyXG4gIEFCVjogICAgQUJWLFxyXG4gIENPTlNUUjogQ09OU1RSLFxyXG4gIFRZUEVEOiAgVFlQRUQsXHJcbiAgVklFVzogICBWSUVXXHJcbn07XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL191aWQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XHJcblxyXG52YXIgaWQgPSAwXHJcbiAgLCBweCA9IE1hdGgucmFuZG9tKCk7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcclxuICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xyXG59O1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBnbG9iYWwgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgLCBjb3JlICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvcmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvcmUuanNcIilcclxuICAsIExJQlJBUlkgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fbGlicmFyeSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbGlicmFyeS5qc1wiKVxyXG4gICwgd2tzRXh0ICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MtZXh0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MtZXh0LmpzXCIpXHJcbiAgLCBkZWZpbmVQcm9wZXJ0eSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1kcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzXCIpLmY7XHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obmFtZSl7XHJcbiAgdmFyICRTeW1ib2wgPSBjb3JlLlN5bWJvbCB8fCAoY29yZS5TeW1ib2wgPSBMSUJSQVJZID8ge30gOiBnbG9iYWwuU3ltYm9sIHx8IHt9KTtcclxuICBpZihuYW1lLmNoYXJBdCgwKSAhPSAnXycgJiYgIShuYW1lIGluICRTeW1ib2wpKWRlZmluZVByb3BlcnR5KCRTeW1ib2wsIG5hbWUsIHt2YWx1ZTogd2tzRXh0LmYobmFtZSl9KTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy1leHQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy1leHQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5leHBvcnRzLmYgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBzdG9yZSAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2hhcmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanNcIikoJ3drcycpXHJcbiAgLCB1aWQgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdWlkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL191aWQuanNcIilcclxuICAsIFN5bWJvbCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKS5TeW1ib2xcclxuICAsIFVTRV9TWU1CT0wgPSB0eXBlb2YgU3ltYm9sID09ICdmdW5jdGlvbic7XHJcblxyXG52YXIgJGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG5hbWUpe1xyXG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxyXG4gICAgVVNFX1NZTUJPTCAmJiBTeW1ib2xbbmFtZV0gfHwgKFVTRV9TWU1CT0wgPyBTeW1ib2wgOiB1aWQpKCdTeW1ib2wuJyArIG5hbWUpKTtcclxufTtcclxuXHJcbiRleHBvcnRzLnN0b3JlID0gc3RvcmU7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBjbGFzc29mICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jbGFzc29mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jbGFzc29mLmpzXCIpXHJcbiAgLCBJVEVSQVRPUiAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgnaXRlcmF0b3InKVxyXG4gICwgSXRlcmF0b3JzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXRlcmF0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanNcIik7XHJcbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29yZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29yZS5qc1wiKS5nZXRJdGVyYXRvck1ldGhvZCA9IGZ1bmN0aW9uKGl0KXtcclxuICBpZihpdCAhPSB1bmRlZmluZWQpcmV0dXJuIGl0W0lURVJBVE9SXVxyXG4gICAgfHwgaXRbJ0BAaXRlcmF0b3InXVxyXG4gICAgfHwgSXRlcmF0b3JzW2NsYXNzb2YoaXQpXTtcclxufTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmNvcHktd2l0aGluLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuY29weS13aXRoaW4uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjIuMS4zLjMgQXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCwgZW5kID0gdGhpcy5sZW5ndGgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge2NvcHlXaXRoaW46IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FycmF5LWNvcHktd2l0aGluICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1jb3B5LXdpdGhpbi5qc1wiKX0pO1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYWRkLXRvLXVuc2NvcGFibGVzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanNcIikoJ2NvcHlXaXRoaW4nKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmV2ZXJ5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZXZlcnkuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkZXZlcnkgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktbWV0aG9kcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qc1wiKSg0KTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmljdC1tZXRob2QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmljdC1tZXRob2QuanNcIikoW10uZXZlcnksIHRydWUpLCAnQXJyYXknLCB7XHJcbiAgLy8gMjIuMS4zLjUgLyAxNS40LjQuMTYgQXJyYXkucHJvdG90eXBlLmV2ZXJ5KGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXHJcbiAgZXZlcnk6IGZ1bmN0aW9uIGV2ZXJ5KGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKXtcclxuICAgIHJldHVybiAkZXZlcnkodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsbC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsbC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIyLjEuMy42IEFycmF5LnByb3RvdHlwZS5maWxsKHZhbHVlLCBzdGFydCA9IDAsIGVuZCA9IHRoaXMubGVuZ3RoKVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAsICdBcnJheScsIHtmaWxsOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1maWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1maWxsLmpzXCIpfSk7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hZGQtdG8tdW5zY29wYWJsZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qc1wiKSgnZmlsbCcpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsdGVyLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbHRlci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkZmlsdGVyID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktbWV0aG9kcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qc1wiKSgyKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmljdC1tZXRob2QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmljdC1tZXRob2QuanNcIikoW10uZmlsdGVyLCB0cnVlKSwgJ0FycmF5Jywge1xyXG4gIC8vIDIyLjEuMy43IC8gMTUuNC40LjIwIEFycmF5LnByb3RvdHlwZS5maWx0ZXIoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcclxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcihjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLyl7XHJcbiAgICByZXR1cm4gJGZpbHRlcih0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLWluZGV4LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLWluZGV4LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyAyMi4xLjMuOSBBcnJheS5wcm90b3R5cGUuZmluZEluZGV4KHByZWRpY2F0ZSwgdGhpc0FyZyA9IHVuZGVmaW5lZClcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgJGZpbmQgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FycmF5LW1ldGhvZHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LW1ldGhvZHMuanNcIikoNilcclxuICAsIEtFWSAgICAgPSAnZmluZEluZGV4J1xyXG4gICwgZm9yY2VkICA9IHRydWU7XHJcbi8vIFNob3VsZG4ndCBza2lwIGhvbGVzXHJcbmlmKEtFWSBpbiBbXSlBcnJheSgxKVtLRVldKGZ1bmN0aW9uKCl7IGZvcmNlZCA9IGZhbHNlOyB9KTtcclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmb3JjZWQsICdBcnJheScsIHtcclxuICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChjYWxsYmFja2ZuLyosIHRoYXQgPSB1bmRlZmluZWQgKi8pe1xyXG4gICAgcmV0dXJuICRmaW5kKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcclxuICB9XHJcbn0pO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hZGQtdG8tdW5zY29wYWJsZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qc1wiKShLRVkpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmluZC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmluZC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gMjIuMS4zLjggQXJyYXkucHJvdG90eXBlLmZpbmQocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkZmluZCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktbWV0aG9kcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qc1wiKSg1KVxyXG4gICwgS0VZICAgICA9ICdmaW5kJ1xyXG4gICwgZm9yY2VkICA9IHRydWU7XHJcbi8vIFNob3VsZG4ndCBza2lwIGhvbGVzXHJcbmlmKEtFWSBpbiBbXSlBcnJheSgxKVtLRVldKGZ1bmN0aW9uKCl7IGZvcmNlZCA9IGZhbHNlOyB9KTtcclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmb3JjZWQsICdBcnJheScsIHtcclxuICBmaW5kOiBmdW5jdGlvbiBmaW5kKGNhbGxiYWNrZm4vKiwgdGhhdCA9IHVuZGVmaW5lZCAqLyl7XHJcbiAgICByZXR1cm4gJGZpbmQodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xyXG4gIH1cclxufSk7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FkZC10by11bnNjb3BhYmxlcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYWRkLXRvLXVuc2NvcGFibGVzLmpzXCIpKEtFWSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5mb3ItZWFjaC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZvci1lYWNoLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyICRleHBvcnQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsICRmb3JFYWNoID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktbWV0aG9kcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qc1wiKSgwKVxyXG4gICwgU1RSSUNUICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpY3QtbWV0aG9kICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpY3QtbWV0aG9kLmpzXCIpKFtdLmZvckVhY2gsIHRydWUpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhU1RSSUNULCAnQXJyYXknLCB7XHJcbiAgLy8gMjIuMS4zLjEwIC8gMTUuNC40LjE4IEFycmF5LnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXHJcbiAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLyl7XHJcbiAgICByZXR1cm4gJGZvckVhY2godGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZnJvbS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZnJvbS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIGN0eCAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY3R4ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jdHguanNcIilcclxuICAsICRleHBvcnQgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHRvT2JqZWN0ICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAsIGNhbGwgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXRlci1jYWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanNcIilcclxuICAsIGlzQXJyYXlJdGVyICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtYXJyYXktaXRlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qc1wiKVxyXG4gICwgdG9MZW5ndGggICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1sZW5ndGggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWxlbmd0aC5qc1wiKVxyXG4gICwgY3JlYXRlUHJvcGVydHkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jcmVhdGUtcHJvcGVydHkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qc1wiKVxyXG4gICwgZ2V0SXRlckZuICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyLWRldGVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanNcIikoZnVuY3Rpb24oaXRlcil7IEFycmF5LmZyb20oaXRlcik7IH0pLCAnQXJyYXknLCB7XHJcbiAgLy8gMjIuMS4yLjEgQXJyYXkuZnJvbShhcnJheUxpa2UsIG1hcGZuID0gdW5kZWZpbmVkLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxyXG4gIGZyb206IGZ1bmN0aW9uIGZyb20oYXJyYXlMaWtlLyosIG1hcGZuID0gdW5kZWZpbmVkLCB0aGlzQXJnID0gdW5kZWZpbmVkKi8pe1xyXG4gICAgdmFyIE8gICAgICAgPSB0b09iamVjdChhcnJheUxpa2UpXHJcbiAgICAgICwgQyAgICAgICA9IHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgPyB0aGlzIDogQXJyYXlcclxuICAgICAgLCBhTGVuICAgID0gYXJndW1lbnRzLmxlbmd0aFxyXG4gICAgICAsIG1hcGZuICAgPSBhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZFxyXG4gICAgICAsIG1hcHBpbmcgPSBtYXBmbiAhPT0gdW5kZWZpbmVkXHJcbiAgICAgICwgaW5kZXggICA9IDBcclxuICAgICAgLCBpdGVyRm4gID0gZ2V0SXRlckZuKE8pXHJcbiAgICAgICwgbGVuZ3RoLCByZXN1bHQsIHN0ZXAsIGl0ZXJhdG9yO1xyXG4gICAgaWYobWFwcGluZyltYXBmbiA9IGN0eChtYXBmbiwgYUxlbiA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWQsIDIpO1xyXG4gICAgLy8gaWYgb2JqZWN0IGlzbid0IGl0ZXJhYmxlIG9yIGl0J3MgYXJyYXkgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yIC0gdXNlIHNpbXBsZSBjYXNlXHJcbiAgICBpZihpdGVyRm4gIT0gdW5kZWZpbmVkICYmICEoQyA9PSBBcnJheSAmJiBpc0FycmF5SXRlcihpdGVyRm4pKSl7XHJcbiAgICAgIGZvcihpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCByZXN1bHQgPSBuZXcgQzsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyBpbmRleCsrKXtcclxuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gY2FsbChpdGVyYXRvciwgbWFwZm4sIFtzdGVwLnZhbHVlLCBpbmRleF0sIHRydWUpIDogc3RlcC52YWx1ZSk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcclxuICAgICAgZm9yKHJlc3VsdCA9IG5ldyBDKGxlbmd0aCk7IGxlbmd0aCA+IGluZGV4OyBpbmRleCsrKXtcclxuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gbWFwZm4oT1tpbmRleF0sIGluZGV4KSA6IE9baW5kZXhdKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmVzdWx0Lmxlbmd0aCA9IGluZGV4O1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcbn0pO1xyXG5cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmluZGV4LW9mLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaW5kZXgtb2YuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkaW5kZXhPZiAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktaW5jbHVkZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzXCIpKGZhbHNlKVxyXG4gICwgJG5hdGl2ZSAgICAgICA9IFtdLmluZGV4T2ZcclxuICAsIE5FR0FUSVZFX1pFUk8gPSAhISRuYXRpdmUgJiYgMSAvIFsxXS5pbmRleE9mKDEsIC0wKSA8IDA7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChORUdBVElWRV9aRVJPIHx8ICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpY3QtbWV0aG9kICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpY3QtbWV0aG9kLmpzXCIpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xyXG4gIC8vIDIyLjEuMy4xMSAvIDE1LjQuNC4xNCBBcnJheS5wcm90b3R5cGUuaW5kZXhPZihzZWFyY2hFbGVtZW50IFssIGZyb21JbmRleF0pXHJcbiAgaW5kZXhPZjogZnVuY3Rpb24gaW5kZXhPZihzZWFyY2hFbGVtZW50IC8qLCBmcm9tSW5kZXggPSAwICovKXtcclxuICAgIHJldHVybiBORUdBVElWRV9aRVJPXHJcbiAgICAgIC8vIGNvbnZlcnQgLTAgdG8gKzBcclxuICAgICAgPyAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMFxyXG4gICAgICA6ICRpbmRleE9mKHRoaXMsIHNlYXJjaEVsZW1lbnQsIGFyZ3VtZW50c1sxXSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmlzLWFycmF5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXkuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjIuMS4yLjIgLyAxNS40LjMuMiBBcnJheS5pc0FycmF5KGFyZylcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnQXJyYXknLCB7aXNBcnJheTogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWFycmF5LmpzXCIpfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIGFkZFRvVW5zY29wYWJsZXMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hZGQtdG8tdW5zY29wYWJsZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qc1wiKVxyXG4gICwgc3RlcCAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2l0ZXItc3RlcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1zdGVwLmpzXCIpXHJcbiAgLCBJdGVyYXRvcnMgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXRlcmF0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanNcIilcclxuICAsIHRvSU9iamVjdCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCIpO1xyXG5cclxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxyXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmtleXMoKVxyXG4vLyAyMi4xLjMuMjkgQXJyYXkucHJvdG90eXBlLnZhbHVlcygpXHJcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxyXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2l0ZXItZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qc1wiKShBcnJheSwgJ0FycmF5JywgZnVuY3Rpb24oaXRlcmF0ZWQsIGtpbmQpe1xyXG4gIHRoaXMuX3QgPSB0b0lPYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcclxuICB0aGlzLl9pID0gMDsgICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxyXG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXHJcbi8vIDIyLjEuNS4yLjEgJUFycmF5SXRlcmF0b3JQcm90b3R5cGUlLm5leHQoKVxyXG59LCBmdW5jdGlvbigpe1xyXG4gIHZhciBPICAgICA9IHRoaXMuX3RcclxuICAgICwga2luZCAgPSB0aGlzLl9rXHJcbiAgICAsIGluZGV4ID0gdGhpcy5faSsrO1xyXG4gIGlmKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKXtcclxuICAgIHRoaXMuX3QgPSB1bmRlZmluZWQ7XHJcbiAgICByZXR1cm4gc3RlcCgxKTtcclxuICB9XHJcbiAgaWYoa2luZCA9PSAna2V5cycgIClyZXR1cm4gc3RlcCgwLCBpbmRleCk7XHJcbiAgaWYoa2luZCA9PSAndmFsdWVzJylyZXR1cm4gc3RlcCgwLCBPW2luZGV4XSk7XHJcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xyXG59LCAndmFsdWVzJyk7XHJcblxyXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXHJcbkl0ZXJhdG9ycy5Bcmd1bWVudHMgPSBJdGVyYXRvcnMuQXJyYXk7XHJcblxyXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XHJcbmFkZFRvVW5zY29wYWJsZXMoJ3ZhbHVlcycpO1xyXG5hZGRUb1Vuc2NvcGFibGVzKCdlbnRyaWVzJyk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5qb2luLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5qb2luLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmpvaW4oc2VwYXJhdG9yKVxyXG52YXIgJGV4cG9ydCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHRvSU9iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWlvYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWlvYmplY3QuanNcIilcclxuICAsIGFycmF5Sm9pbiA9IFtdLmpvaW47XHJcblxyXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2Ugc3RyaW5nc1xyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pb2JqZWN0LmpzXCIpICE9IE9iamVjdCB8fCAhX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaWN0LW1ldGhvZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qc1wiKShhcnJheUpvaW4pKSwgJ0FycmF5Jywge1xyXG4gIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKXtcclxuICAgIHJldHVybiBhcnJheUpvaW4uY2FsbCh0b0lPYmplY3QodGhpcyksIHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkID8gJywnIDogc2VwYXJhdG9yKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubGFzdC1pbmRleC1vZi5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubGFzdC1pbmRleC1vZi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyICRleHBvcnQgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgdG9JT2JqZWN0ICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWlvYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWlvYmplY3QuanNcIilcclxuICAsIHRvSW50ZWdlciAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pbnRlZ2VyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbnRlZ2VyLmpzXCIpXHJcbiAgLCB0b0xlbmd0aCAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIilcclxuICAsICRuYXRpdmUgICAgICAgPSBbXS5sYXN0SW5kZXhPZlxyXG4gICwgTkVHQVRJVkVfWkVSTyA9ICEhJG5hdGl2ZSAmJiAxIC8gWzFdLmxhc3RJbmRleE9mKDEsIC0wKSA8IDA7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChORUdBVElWRV9aRVJPIHx8ICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpY3QtbWV0aG9kICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpY3QtbWV0aG9kLmpzXCIpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xyXG4gIC8vIDIyLjEuMy4xNCAvIDE1LjQuNC4xNSBBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudCBbLCBmcm9tSW5kZXhdKVxyXG4gIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hFbGVtZW50IC8qLCBmcm9tSW5kZXggPSBAWyotMV0gKi8pe1xyXG4gICAgLy8gY29udmVydCAtMCB0byArMFxyXG4gICAgaWYoTkVHQVRJVkVfWkVSTylyZXR1cm4gJG5hdGl2ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IDA7XHJcbiAgICB2YXIgTyAgICAgID0gdG9JT2JqZWN0KHRoaXMpXHJcbiAgICAgICwgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpXHJcbiAgICAgICwgaW5kZXggID0gbGVuZ3RoIC0gMTtcclxuICAgIGlmKGFyZ3VtZW50cy5sZW5ndGggPiAxKWluZGV4ID0gTWF0aC5taW4oaW5kZXgsIHRvSW50ZWdlcihhcmd1bWVudHNbMV0pKTtcclxuICAgIGlmKGluZGV4IDwgMClpbmRleCA9IGxlbmd0aCArIGluZGV4O1xyXG4gICAgZm9yKDtpbmRleCA+PSAwOyBpbmRleC0tKWlmKGluZGV4IGluIE8paWYoT1tpbmRleF0gPT09IHNlYXJjaEVsZW1lbnQpcmV0dXJuIGluZGV4IHx8IDA7XHJcbiAgICByZXR1cm4gLTE7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lm1hcC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5tYXAuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgJG1hcCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FycmF5LW1ldGhvZHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LW1ldGhvZHMuanNcIikoMSk7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpY3QtbWV0aG9kICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpY3QtbWV0aG9kLmpzXCIpKFtdLm1hcCwgdHJ1ZSksICdBcnJheScsIHtcclxuICAvLyAyMi4xLjMuMTUgLyAxNS40LjQuMTkgQXJyYXkucHJvdG90eXBlLm1hcChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxyXG4gIG1hcDogZnVuY3Rpb24gbWFwKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKXtcclxuICAgIHJldHVybiAkbWFwKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lm9mLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkub2YuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgY3JlYXRlUHJvcGVydHkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jcmVhdGUtcHJvcGVydHkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qc1wiKTtcclxuXHJcbi8vIFdlYktpdCBBcnJheS5vZiBpc24ndCBnZW5lcmljXHJcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmFpbHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCIpKGZ1bmN0aW9uKCl7XHJcbiAgZnVuY3Rpb24gRigpe31cclxuICByZXR1cm4gIShBcnJheS5vZi5jYWxsKEYpIGluc3RhbmNlb2YgRik7XHJcbn0pLCAnQXJyYXknLCB7XHJcbiAgLy8gMjIuMS4yLjMgQXJyYXkub2YoIC4uLml0ZW1zKVxyXG4gIG9mOiBmdW5jdGlvbiBvZigvKiAuLi5hcmdzICovKXtcclxuICAgIHZhciBpbmRleCAgPSAwXHJcbiAgICAgICwgYUxlbiAgID0gYXJndW1lbnRzLmxlbmd0aFxyXG4gICAgICAsIHJlc3VsdCA9IG5ldyAodHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheSkoYUxlbik7XHJcbiAgICB3aGlsZShhTGVuID4gaW5kZXgpY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgYXJndW1lbnRzW2luZGV4KytdKTtcclxuICAgIHJlc3VsdC5sZW5ndGggPSBhTGVuO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlLXJpZ2h0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS1yaWdodC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkcmVkdWNlID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktcmVkdWNlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1yZWR1Y2UuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpY3QtbWV0aG9kICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpY3QtbWV0aG9kLmpzXCIpKFtdLnJlZHVjZVJpZ2h0LCB0cnVlKSwgJ0FycmF5Jywge1xyXG4gIC8vIDIyLjEuMy4xOSAvIDE1LjQuNC4yMiBBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQoY2FsbGJhY2tmbiBbLCBpbml0aWFsVmFsdWVdKVxyXG4gIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbiByZWR1Y2VSaWdodChjYWxsYmFja2ZuIC8qICwgaW5pdGlhbFZhbHVlICovKXtcclxuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgdHJ1ZSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgJHJlZHVjZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FycmF5LXJlZHVjZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktcmVkdWNlLmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaWN0LW1ldGhvZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qc1wiKShbXS5yZWR1Y2UsIHRydWUpLCAnQXJyYXknLCB7XHJcbiAgLy8gMjIuMS4zLjE4IC8gMTUuNC40LjIxIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UoY2FsbGJhY2tmbiBbLCBpbml0aWFsVmFsdWVdKVxyXG4gIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pe1xyXG4gICAgcmV0dXJuICRyZWR1Y2UodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCwgYXJndW1lbnRzWzFdLCBmYWxzZSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNsaWNlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuc2xpY2UuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBodG1sICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faHRtbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qc1wiKVxyXG4gICwgY29mICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzXCIpXHJcbiAgLCB0b0luZGV4ICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW5kZXggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWluZGV4LmpzXCIpXHJcbiAgLCB0b0xlbmd0aCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIilcclxuICAsIGFycmF5U2xpY2UgPSBbXS5zbGljZTtcclxuXHJcbi8vIGZhbGxiYWNrIGZvciBub3QgYXJyYXktbGlrZSBFUzMgc3RyaW5ncyBhbmQgRE9NIG9iamVjdHNcclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIikoZnVuY3Rpb24oKXtcclxuICBpZihodG1sKWFycmF5U2xpY2UuY2FsbChodG1sKTtcclxufSksICdBcnJheScsIHtcclxuICBzbGljZTogZnVuY3Rpb24gc2xpY2UoYmVnaW4sIGVuZCl7XHJcbiAgICB2YXIgbGVuICAgPSB0b0xlbmd0aCh0aGlzLmxlbmd0aClcclxuICAgICAgLCBrbGFzcyA9IGNvZih0aGlzKTtcclxuICAgIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogZW5kO1xyXG4gICAgaWYoa2xhc3MgPT0gJ0FycmF5JylyZXR1cm4gYXJyYXlTbGljZS5jYWxsKHRoaXMsIGJlZ2luLCBlbmQpO1xyXG4gICAgdmFyIHN0YXJ0ICA9IHRvSW5kZXgoYmVnaW4sIGxlbilcclxuICAgICAgLCB1cFRvICAgPSB0b0luZGV4KGVuZCwgbGVuKVxyXG4gICAgICAsIHNpemUgICA9IHRvTGVuZ3RoKHVwVG8gLSBzdGFydClcclxuICAgICAgLCBjbG9uZWQgPSBBcnJheShzaXplKVxyXG4gICAgICAsIGkgICAgICA9IDA7XHJcbiAgICBmb3IoOyBpIDwgc2l6ZTsgaSsrKWNsb25lZFtpXSA9IGtsYXNzID09ICdTdHJpbmcnXHJcbiAgICAgID8gdGhpcy5jaGFyQXQoc3RhcnQgKyBpKVxyXG4gICAgICA6IHRoaXNbc3RhcnQgKyBpXTtcclxuICAgIHJldHVybiBjbG9uZWQ7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvbWUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvbWUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsICRzb21lICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1tZXRob2RzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1tZXRob2RzLmpzXCIpKDMpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaWN0LW1ldGhvZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qc1wiKShbXS5zb21lLCB0cnVlKSwgJ0FycmF5Jywge1xyXG4gIC8vIDIyLjEuMy4yMyAvIDE1LjQuNC4xNyBBcnJheS5wcm90b3R5cGUuc29tZShjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxyXG4gIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pe1xyXG4gICAgcmV0dXJuICRzb21lKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvcnQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvcnQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciAkZXhwb3J0ICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgYUZ1bmN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYS1mdW5jdGlvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qc1wiKVxyXG4gICwgdG9PYmplY3QgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAsIGZhaWxzICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKVxyXG4gICwgJHNvcnQgICAgID0gW10uc29ydFxyXG4gICwgdGVzdCAgICAgID0gWzEsIDIsIDNdO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24oKXtcclxuICAvLyBJRTgtXHJcbiAgdGVzdC5zb3J0KHVuZGVmaW5lZCk7XHJcbn0pIHx8ICFmYWlscyhmdW5jdGlvbigpe1xyXG4gIC8vIFY4IGJ1Z1xyXG4gIHRlc3Quc29ydChudWxsKTtcclxuICAvLyBPbGQgV2ViS2l0XHJcbn0pIHx8ICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpY3QtbWV0aG9kICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpY3QtbWV0aG9kLmpzXCIpKCRzb3J0KSksICdBcnJheScsIHtcclxuICAvLyAyMi4xLjMuMjUgQXJyYXkucHJvdG90eXBlLnNvcnQoY29tcGFyZWZuKVxyXG4gIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZWZuKXtcclxuICAgIHJldHVybiBjb21wYXJlZm4gPT09IHVuZGVmaW5lZFxyXG4gICAgICA/ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcykpXHJcbiAgICAgIDogJHNvcnQuY2FsbCh0b09iamVjdCh0aGlzKSwgYUZ1bmN0aW9uKGNvbXBhcmVmbikpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2V0LXNwZWNpZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NldC1zcGVjaWVzLmpzXCIpKCdBcnJheScpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS5ub3cuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLm5vdy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMC4zLjMuMSAvIDE1LjkuNC40IERhdGUubm93KClcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnRGF0ZScsIHtub3c6IGZ1bmN0aW9uKCl7IHJldHVybiBuZXcgRGF0ZSgpLmdldFRpbWUoKTsgfX0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1pc28tc3RyaW5nLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8taXNvLXN0cmluZy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyAyMC4zLjQuMzYgLyAxNS45LjUuNDMgRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcoKVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBmYWlscyAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmFpbHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCIpXHJcbiAgLCBnZXRUaW1lID0gRGF0ZS5wcm90b3R5cGUuZ2V0VGltZTtcclxuXHJcbnZhciBseiA9IGZ1bmN0aW9uKG51bSl7XHJcbiAgcmV0dXJuIG51bSA+IDkgPyBudW0gOiAnMCcgKyBudW07XHJcbn07XHJcblxyXG4vLyBQaGFudG9tSlMgLyBvbGQgV2ViS2l0IGhhcyBhIGJyb2tlbiBpbXBsZW1lbnRhdGlvbnNcclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24oKXtcclxuICByZXR1cm4gbmV3IERhdGUoLTVlMTMgLSAxKS50b0lTT1N0cmluZygpICE9ICcwMzg1LTA3LTI1VDA3OjA2OjM5Ljk5OVonO1xyXG59KSB8fCAhZmFpbHMoZnVuY3Rpb24oKXtcclxuICBuZXcgRGF0ZShOYU4pLnRvSVNPU3RyaW5nKCk7XHJcbn0pKSwgJ0RhdGUnLCB7XHJcbiAgdG9JU09TdHJpbmc6IGZ1bmN0aW9uIHRvSVNPU3RyaW5nKCl7XHJcbiAgICBpZighaXNGaW5pdGUoZ2V0VGltZS5jYWxsKHRoaXMpKSl0aHJvdyBSYW5nZUVycm9yKCdJbnZhbGlkIHRpbWUgdmFsdWUnKTtcclxuICAgIHZhciBkID0gdGhpc1xyXG4gICAgICAsIHkgPSBkLmdldFVUQ0Z1bGxZZWFyKClcclxuICAgICAgLCBtID0gZC5nZXRVVENNaWxsaXNlY29uZHMoKVxyXG4gICAgICAsIHMgPSB5IDwgMCA/ICctJyA6IHkgPiA5OTk5ID8gJysnIDogJyc7XHJcbiAgICByZXR1cm4gcyArICgnMDAwMDAnICsgTWF0aC5hYnMoeSkpLnNsaWNlKHMgPyAtNiA6IC00KSArXHJcbiAgICAgICctJyArIGx6KGQuZ2V0VVRDTW9udGgoKSArIDEpICsgJy0nICsgbHooZC5nZXRVVENEYXRlKCkpICtcclxuICAgICAgJ1QnICsgbHooZC5nZXRVVENIb3VycygpKSArICc6JyArIGx6KGQuZ2V0VVRDTWludXRlcygpKSArXHJcbiAgICAgICc6JyArIGx6KGQuZ2V0VVRDU2Vjb25kcygpKSArICcuJyArIChtID4gOTkgPyBtIDogJzAnICsgbHoobSkpICsgJ1onO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLWpzb24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1qc29uLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciAkZXhwb3J0ICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCB0b09iamVjdCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b1ByaW1pdGl2ZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLXByaW1pdGl2ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIikoZnVuY3Rpb24oKXtcclxuICByZXR1cm4gbmV3IERhdGUoTmFOKS50b0pTT04oKSAhPT0gbnVsbCB8fCBEYXRlLnByb3RvdHlwZS50b0pTT04uY2FsbCh7dG9JU09TdHJpbmc6IGZ1bmN0aW9uKCl7IHJldHVybiAxOyB9fSkgIT09IDE7XHJcbn0pLCAnRGF0ZScsIHtcclxuICB0b0pTT046IGZ1bmN0aW9uIHRvSlNPTihrZXkpe1xyXG4gICAgdmFyIE8gID0gdG9PYmplY3QodGhpcylcclxuICAgICAgLCBwdiA9IHRvUHJpbWl0aXZlKE8pO1xyXG4gICAgcmV0dXJuIHR5cGVvZiBwdiA9PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUocHYpID8gbnVsbCA6IE8udG9JU09TdHJpbmcoKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1wcmltaXRpdmUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLXByaW1pdGl2ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgVE9fUFJJTUlUSVZFID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fd2tzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MuanNcIikoJ3RvUHJpbWl0aXZlJylcclxuICAsIHByb3RvICAgICAgICA9IERhdGUucHJvdG90eXBlO1xyXG5cclxuaWYoIShUT19QUklNSVRJVkUgaW4gcHJvdG8pKV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hpZGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hpZGUuanNcIikocHJvdG8sIFRPX1BSSU1JVElWRSwgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGF0ZS10by1wcmltaXRpdmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RhdGUtdG8tcHJpbWl0aXZlLmpzXCIpKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tc3RyaW5nLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1zdHJpbmcuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIERhdGVQcm90byAgICA9IERhdGUucHJvdG90eXBlXHJcbiAgLCBJTlZBTElEX0RBVEUgPSAnSW52YWxpZCBEYXRlJ1xyXG4gICwgVE9fU1RSSU5HICAgID0gJ3RvU3RyaW5nJ1xyXG4gICwgJHRvU3RyaW5nICAgID0gRGF0ZVByb3RvW1RPX1NUUklOR11cclxuICAsIGdldFRpbWUgICAgICA9IERhdGVQcm90by5nZXRUaW1lO1xyXG5pZihuZXcgRGF0ZShOYU4pICsgJycgIT0gSU5WQUxJRF9EQVRFKXtcclxuICBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19yZWRlZmluZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanNcIikoRGF0ZVByb3RvLCBUT19TVFJJTkcsIGZ1bmN0aW9uIHRvU3RyaW5nKCl7XHJcbiAgICB2YXIgdmFsdWUgPSBnZXRUaW1lLmNhbGwodGhpcyk7XHJcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gJHRvU3RyaW5nLmNhbGwodGhpcykgOiBJTlZBTElEX0RBVEU7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmJpbmQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmJpbmQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAxOS4yLjMuMiAvIDE1LjMuNC41IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKHRoaXNBcmcsIGFyZ3MuLi4pXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0Z1bmN0aW9uJywge2JpbmQ6IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2JpbmQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2JpbmQuanNcIil9KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmhhcy1pbnN0YW5jZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5oYXMtaW5zdGFuY2UuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIGlzT2JqZWN0ICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIilcclxuICAsIGdldFByb3RvdHlwZU9mID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdwbyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdwby5qc1wiKVxyXG4gICwgSEFTX0lOU1RBTkNFICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgnaGFzSW5zdGFuY2UnKVxyXG4gICwgRnVuY3Rpb25Qcm90byAgPSBGdW5jdGlvbi5wcm90b3R5cGU7XHJcbi8vIDE5LjIuMy42IEZ1bmN0aW9uLnByb3RvdHlwZVtAQGhhc0luc3RhbmNlXShWKVxyXG5pZighKEhBU19JTlNUQU5DRSBpbiBGdW5jdGlvblByb3RvKSlfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKS5mKEZ1bmN0aW9uUHJvdG8sIEhBU19JTlNUQU5DRSwge3ZhbHVlOiBmdW5jdGlvbihPKXtcclxuICBpZih0eXBlb2YgdGhpcyAhPSAnZnVuY3Rpb24nIHx8ICFpc09iamVjdChPKSlyZXR1cm4gZmFsc2U7XHJcbiAgaWYoIWlzT2JqZWN0KHRoaXMucHJvdG90eXBlKSlyZXR1cm4gTyBpbnN0YW5jZW9mIHRoaXM7XHJcbiAgLy8gZm9yIGVudmlyb25tZW50IHcvbyBuYXRpdmUgYEBAaGFzSW5zdGFuY2VgIGxvZ2ljIGVub3VnaCBgaW5zdGFuY2VvZmAsIGJ1dCBhZGQgdGhpczpcclxuICB3aGlsZShPID0gZ2V0UHJvdG90eXBlT2YoTykpaWYodGhpcy5wcm90b3R5cGUgPT09IE8pcmV0dXJuIHRydWU7XHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59fSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIGRQICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKS5mXHJcbiAgLCBjcmVhdGVEZXNjID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcHJvcGVydHktZGVzYyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qc1wiKVxyXG4gICwgaGFzICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgLCBGUHJvdG8gICAgID0gRnVuY3Rpb24ucHJvdG90eXBlXHJcbiAgLCBuYW1lUkUgICAgID0gL15cXHMqZnVuY3Rpb24gKFteIChdKikvXHJcbiAgLCBOQU1FICAgICAgID0gJ25hbWUnO1xyXG5cclxudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGUgfHwgZnVuY3Rpb24oKXtcclxuICByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbi8vIDE5LjIuNC4yIG5hbWVcclxuTkFNRSBpbiBGUHJvdG8gfHwgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpICYmIGRQKEZQcm90bywgTkFNRSwge1xyXG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcclxuICBnZXQ6IGZ1bmN0aW9uKCl7XHJcbiAgICB0cnkge1xyXG4gICAgICB2YXIgdGhhdCA9IHRoaXNcclxuICAgICAgICAsIG5hbWUgPSAoJycgKyB0aGF0KS5tYXRjaChuYW1lUkUpWzFdO1xyXG4gICAgICBoYXModGhhdCwgTkFNRSkgfHwgIWlzRXh0ZW5zaWJsZSh0aGF0KSB8fCBkUCh0aGF0LCBOQU1FLCBjcmVhdGVEZXNjKDUsIG5hbWUpKTtcclxuICAgICAgcmV0dXJuIG5hbWU7XHJcbiAgICB9IGNhdGNoKGUpe1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hcC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXAuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIHN0cm9uZyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvbGxlY3Rpb24tc3Ryb25nICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qc1wiKTtcclxuXHJcbi8vIDIzLjEgTWFwIE9iamVjdHNcclxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb2xsZWN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLmpzXCIpKCdNYXAnLCBmdW5jdGlvbihnZXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBNYXAoKXsgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7IH07XHJcbn0sIHtcclxuICAvLyAyMy4xLjMuNiBNYXAucHJvdG90eXBlLmdldChrZXkpXHJcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoa2V5KXtcclxuICAgIHZhciBlbnRyeSA9IHN0cm9uZy5nZXRFbnRyeSh0aGlzLCBrZXkpO1xyXG4gICAgcmV0dXJuIGVudHJ5ICYmIGVudHJ5LnY7XHJcbiAgfSxcclxuICAvLyAyMy4xLjMuOSBNYXAucHJvdG90eXBlLnNldChrZXksIHZhbHVlKVxyXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpe1xyXG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodGhpcywga2V5ID09PSAwID8gMCA6IGtleSwgdmFsdWUpO1xyXG4gIH1cclxufSwgc3Ryb25nLCB0cnVlKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYWNvc2guanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYWNvc2guanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMC4yLjIuMyBNYXRoLmFjb3NoKHgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGxvZzFwICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tYXRoLWxvZzFwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWxvZzFwLmpzXCIpXHJcbiAgLCBzcXJ0ICAgID0gTWF0aC5zcXJ0XHJcbiAgLCAkYWNvc2ggID0gTWF0aC5hY29zaDtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISgkYWNvc2hcclxuICAvLyBWOCBidWc6IGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zNTA5XHJcbiAgJiYgTWF0aC5mbG9vcigkYWNvc2goTnVtYmVyLk1BWF9WQUxVRSkpID09IDcxMFxyXG4gIC8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hY29zaChJbmZpbml0eSkgLT4gTmFOIFxyXG4gICYmICRhY29zaChJbmZpbml0eSkgPT0gSW5maW5pdHlcclxuKSwgJ01hdGgnLCB7XHJcbiAgYWNvc2g6IGZ1bmN0aW9uIGFjb3NoKHgpe1xyXG4gICAgcmV0dXJuICh4ID0gK3gpIDwgMSA/IE5hTiA6IHggPiA5NDkwNjI2NS42MjQyNTE1NlxyXG4gICAgICA/IE1hdGgubG9nKHgpICsgTWF0aC5MTjJcclxuICAgICAgOiBsb2cxcCh4IC0gMSArIHNxcnQoeCAtIDEpICogc3FydCh4ICsgMSkpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmFzaW5oLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmFzaW5oLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMi4yLjUgTWF0aC5hc2luaCh4KVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkYXNpbmggID0gTWF0aC5hc2luaDtcclxuXHJcbmZ1bmN0aW9uIGFzaW5oKHgpe1xyXG4gIHJldHVybiAhaXNGaW5pdGUoeCA9ICt4KSB8fCB4ID09IDAgPyB4IDogeCA8IDAgPyAtYXNpbmgoLXgpIDogTWF0aC5sb2coeCArIE1hdGguc3FydCh4ICogeCArIDEpKTtcclxufVxyXG5cclxuLy8gVG9yIEJyb3dzZXIgYnVnOiBNYXRoLmFzaW5oKDApIC0+IC0wIFxyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEoJGFzaW5oICYmIDEgLyAkYXNpbmgoMCkgPiAwKSwgJ01hdGgnLCB7YXNpbmg6IGFzaW5ofSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmF0YW5oLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmF0YW5oLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMi4yLjcgTWF0aC5hdGFuaCh4KVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkYXRhbmggID0gTWF0aC5hdGFuaDtcclxuXHJcbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hdGFuaCgtMCkgLT4gMCBcclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhdGFuaCAmJiAxIC8gJGF0YW5oKC0wKSA8IDApLCAnTWF0aCcsIHtcclxuICBhdGFuaDogZnVuY3Rpb24gYXRhbmgoeCl7XHJcbiAgICByZXR1cm4gKHggPSAreCkgPT0gMCA/IHggOiBNYXRoLmxvZygoMSArIHgpIC8gKDEgLSB4KSkgLyAyO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNicnQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jYnJ0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMC4yLjIuOSBNYXRoLmNicnQoeClcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgc2lnbiAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21hdGgtc2lnbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xyXG4gIGNicnQ6IGZ1bmN0aW9uIGNicnQoeCl7XHJcbiAgICByZXR1cm4gc2lnbih4ID0gK3gpICogTWF0aC5wb3coTWF0aC5hYnMoeCksIDEgLyAzKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jbHozMi5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jbHozMi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjIuMi4xMSBNYXRoLmNsejMyKHgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XHJcbiAgY2x6MzI6IGZ1bmN0aW9uIGNsejMyKHgpe1xyXG4gICAgcmV0dXJuICh4ID4+Pj0gMCkgPyAzMSAtIE1hdGguZmxvb3IoTWF0aC5sb2coeCArIDAuNSkgKiBNYXRoLkxPRzJFKSA6IDMyO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNvc2guanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jb3NoLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMC4yLjIuMTIgTWF0aC5jb3NoKHgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGV4cCAgICAgPSBNYXRoLmV4cDtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcclxuICBjb3NoOiBmdW5jdGlvbiBjb3NoKHgpe1xyXG4gICAgcmV0dXJuIChleHAoeCA9ICt4KSArIGV4cCgteCkpIC8gMjtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5leHBtMS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5leHBtMS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjIuMi4xNCBNYXRoLmV4cG0xKHgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsICRleHBtMSAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tYXRoLWV4cG0xICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoJGV4cG0xICE9IE1hdGguZXhwbTEpLCAnTWF0aCcsIHtleHBtMTogJGV4cG0xfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmZyb3VuZC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguZnJvdW5kLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjIuMi4xNiBNYXRoLmZyb3VuZCh4KVxyXG52YXIgJGV4cG9ydCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHNpZ24gICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21hdGgtc2lnbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzXCIpXHJcbiAgLCBwb3cgICAgICAgPSBNYXRoLnBvd1xyXG4gICwgRVBTSUxPTiAgID0gcG93KDIsIC01MilcclxuICAsIEVQU0lMT04zMiA9IHBvdygyLCAtMjMpXHJcbiAgLCBNQVgzMiAgICAgPSBwb3coMiwgMTI3KSAqICgyIC0gRVBTSUxPTjMyKVxyXG4gICwgTUlOMzIgICAgID0gcG93KDIsIC0xMjYpO1xyXG5cclxudmFyIHJvdW5kVGllc1RvRXZlbiA9IGZ1bmN0aW9uKG4pe1xyXG4gIHJldHVybiBuICsgMSAvIEVQU0lMT04gLSAxIC8gRVBTSUxPTjtcclxufTtcclxuXHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XHJcbiAgZnJvdW5kOiBmdW5jdGlvbiBmcm91bmQoeCl7XHJcbiAgICB2YXIgJGFicyAgPSBNYXRoLmFicyh4KVxyXG4gICAgICAsICRzaWduID0gc2lnbih4KVxyXG4gICAgICAsIGEsIHJlc3VsdDtcclxuICAgIGlmKCRhYnMgPCBNSU4zMilyZXR1cm4gJHNpZ24gKiByb3VuZFRpZXNUb0V2ZW4oJGFicyAvIE1JTjMyIC8gRVBTSUxPTjMyKSAqIE1JTjMyICogRVBTSUxPTjMyO1xyXG4gICAgYSA9ICgxICsgRVBTSUxPTjMyIC8gRVBTSUxPTikgKiAkYWJzO1xyXG4gICAgcmVzdWx0ID0gYSAtIChhIC0gJGFicyk7XHJcbiAgICBpZihyZXN1bHQgPiBNQVgzMiB8fCByZXN1bHQgIT0gcmVzdWx0KXJldHVybiAkc2lnbiAqIEluZmluaXR5O1xyXG4gICAgcmV0dXJuICRzaWduICogcmVzdWx0O1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmh5cG90LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmh5cG90LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMi4yLjE3IE1hdGguaHlwb3QoW3ZhbHVlMVssIHZhbHVlMlssIOKApiBdXV0pXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGFicyAgICAgPSBNYXRoLmFicztcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcclxuICBoeXBvdDogZnVuY3Rpb24gaHlwb3QodmFsdWUxLCB2YWx1ZTIpeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXHJcbiAgICB2YXIgc3VtICA9IDBcclxuICAgICAgLCBpICAgID0gMFxyXG4gICAgICAsIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoXHJcbiAgICAgICwgbGFyZyA9IDBcclxuICAgICAgLCBhcmcsIGRpdjtcclxuICAgIHdoaWxlKGkgPCBhTGVuKXtcclxuICAgICAgYXJnID0gYWJzKGFyZ3VtZW50c1tpKytdKTtcclxuICAgICAgaWYobGFyZyA8IGFyZyl7XHJcbiAgICAgICAgZGl2ICA9IGxhcmcgLyBhcmc7XHJcbiAgICAgICAgc3VtICA9IHN1bSAqIGRpdiAqIGRpdiArIDE7XHJcbiAgICAgICAgbGFyZyA9IGFyZztcclxuICAgICAgfSBlbHNlIGlmKGFyZyA+IDApe1xyXG4gICAgICAgIGRpdiAgPSBhcmcgLyBsYXJnO1xyXG4gICAgICAgIHN1bSArPSBkaXYgKiBkaXY7XHJcbiAgICAgIH0gZWxzZSBzdW0gKz0gYXJnO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGxhcmcgPT09IEluZmluaXR5ID8gSW5maW5pdHkgOiBsYXJnICogTWF0aC5zcXJ0KHN1bSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguaW11bC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmltdWwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjIuMi4xOCBNYXRoLmltdWwoeCwgeSlcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgJGltdWwgICA9IE1hdGguaW11bDtcclxuXHJcbi8vIHNvbWUgV2ViS2l0IHZlcnNpb25zIGZhaWxzIHdpdGggYmlnIG51bWJlcnMsIHNvbWUgaGFzIHdyb25nIGFyaXR5XHJcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmFpbHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCIpKGZ1bmN0aW9uKCl7XHJcbiAgcmV0dXJuICRpbXVsKDB4ZmZmZmZmZmYsIDUpICE9IC01IHx8ICRpbXVsLmxlbmd0aCAhPSAyO1xyXG59KSwgJ01hdGgnLCB7XHJcbiAgaW11bDogZnVuY3Rpb24gaW11bCh4LCB5KXtcclxuICAgIHZhciBVSU5UMTYgPSAweGZmZmZcclxuICAgICAgLCB4biA9ICt4XHJcbiAgICAgICwgeW4gPSAreVxyXG4gICAgICAsIHhsID0gVUlOVDE2ICYgeG5cclxuICAgICAgLCB5bCA9IFVJTlQxNiAmIHluO1xyXG4gICAgcmV0dXJuIDAgfCB4bCAqIHlsICsgKChVSU5UMTYgJiB4biA+Pj4gMTYpICogeWwgKyB4bCAqIChVSU5UMTYgJiB5biA+Pj4gMTYpIDw8IDE2ID4+PiAwKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5sb2cxMC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5sb2cxMC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjIuMi4yMSBNYXRoLmxvZzEwKHgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XHJcbiAgbG9nMTA6IGZ1bmN0aW9uIGxvZzEwKHgpe1xyXG4gICAgcmV0dXJuIE1hdGgubG9nKHgpIC8gTWF0aC5MTjEwO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzFwLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzFwLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMi4yLjIwIE1hdGgubG9nMXAoeClcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtsb2cxcDogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fbWF0aC1sb2cxcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1sb2cxcC5qc1wiKX0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5sb2cyLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMi4yLjIyIE1hdGgubG9nMih4KVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xyXG4gIGxvZzI6IGZ1bmN0aW9uIGxvZzIoeCl7XHJcbiAgICByZXR1cm4gTWF0aC5sb2coeCkgLyBNYXRoLkxOMjtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5zaWduLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguc2lnbi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMi4yLjI4IE1hdGguc2lnbih4KVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge3NpZ246IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21hdGgtc2lnbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzXCIpfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnNpbmguanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5zaW5oLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMC4yLjIuMzAgTWF0aC5zaW5oKHgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGV4cG0xICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tYXRoLWV4cG0xICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzXCIpXHJcbiAgLCBleHAgICAgID0gTWF0aC5leHA7XHJcblxyXG4vLyBWOCBuZWFyIENocm9taXVtIDM4IGhhcyBhIHByb2JsZW0gd2l0aCB2ZXJ5IHNtYWxsIG51bWJlcnNcclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIikoZnVuY3Rpb24oKXtcclxuICByZXR1cm4gIU1hdGguc2luaCgtMmUtMTcpICE9IC0yZS0xNztcclxufSksICdNYXRoJywge1xyXG4gIHNpbmg6IGZ1bmN0aW9uIHNpbmgoeCl7XHJcbiAgICByZXR1cm4gTWF0aC5hYnMoeCA9ICt4KSA8IDFcclxuICAgICAgPyAoZXhwbTEoeCkgLSBleHBtMSgteCkpIC8gMlxyXG4gICAgICA6IChleHAoeCAtIDEpIC0gZXhwKC14IC0gMSkpICogKE1hdGguRSAvIDIpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnRhbmguanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC50YW5oLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMC4yLjIuMzMgTWF0aC50YW5oKHgpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGV4cG0xICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tYXRoLWV4cG0xICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzXCIpXHJcbiAgLCBleHAgICAgID0gTWF0aC5leHA7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XHJcbiAgdGFuaDogZnVuY3Rpb24gdGFuaCh4KXtcclxuICAgIHZhciBhID0gZXhwbTEoeCA9ICt4KVxyXG4gICAgICAsIGIgPSBleHBtMSgteCk7XHJcbiAgICByZXR1cm4gYSA9PSBJbmZpbml0eSA/IDEgOiBiID09IEluZmluaXR5ID8gLTEgOiAoYSAtIGIpIC8gKGV4cCh4KSArIGV4cCgteCkpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnRydW5jLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnRydW5jLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMi4yLjM0IE1hdGgudHJ1bmMoeClcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcclxuICB0cnVuYzogZnVuY3Rpb24gdHJ1bmMoaXQpe1xyXG4gICAgcmV0dXJuIChpdCA+IDAgPyBNYXRoLmZsb29yIDogTWF0aC5jZWlsKShpdCk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5jb25zdHJ1Y3Rvci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuY29uc3RydWN0b3IuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIGdsb2JhbCAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIilcclxuICAsIGhhcyAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faGFzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oYXMuanNcIilcclxuICAsIGNvZiAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2YuanNcIilcclxuICAsIGluaGVyaXRJZlJlcXVpcmVkID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faW5oZXJpdC1pZi1yZXF1aXJlZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW5oZXJpdC1pZi1yZXF1aXJlZC5qc1wiKVxyXG4gICwgdG9QcmltaXRpdmUgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1wcmltaXRpdmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qc1wiKVxyXG4gICwgZmFpbHMgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIilcclxuICAsIGdPUE4gICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcG4gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BuLmpzXCIpLmZcclxuICAsIGdPUEQgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcGQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzXCIpLmZcclxuICAsIGRQICAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWRwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcIikuZlxyXG4gICwgJHRyaW0gICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctdHJpbSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLXRyaW0uanNcIikudHJpbVxyXG4gICwgTlVNQkVSICAgICAgICAgICAgPSAnTnVtYmVyJ1xyXG4gICwgJE51bWJlciAgICAgICAgICAgPSBnbG9iYWxbTlVNQkVSXVxyXG4gICwgQmFzZSAgICAgICAgICAgICAgPSAkTnVtYmVyXHJcbiAgLCBwcm90byAgICAgICAgICAgICA9ICROdW1iZXIucHJvdG90eXBlXHJcbiAgLy8gT3BlcmEgfjEyIGhhcyBicm9rZW4gT2JqZWN0I3RvU3RyaW5nXHJcbiAgLCBCUk9LRU5fQ09GICAgICAgICA9IGNvZihfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtY3JlYXRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzXCIpKHByb3RvKSkgPT0gTlVNQkVSXHJcbiAgLCBUUklNICAgICAgICAgICAgICA9ICd0cmltJyBpbiBTdHJpbmcucHJvdG90eXBlO1xyXG5cclxuLy8gNy4xLjMgVG9OdW1iZXIoYXJndW1lbnQpXHJcbnZhciB0b051bWJlciA9IGZ1bmN0aW9uKGFyZ3VtZW50KXtcclxuICB2YXIgaXQgPSB0b1ByaW1pdGl2ZShhcmd1bWVudCwgZmFsc2UpO1xyXG4gIGlmKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyAmJiBpdC5sZW5ndGggPiAyKXtcclxuICAgIGl0ID0gVFJJTSA/IGl0LnRyaW0oKSA6ICR0cmltKGl0LCAzKTtcclxuICAgIHZhciBmaXJzdCA9IGl0LmNoYXJDb2RlQXQoMClcclxuICAgICAgLCB0aGlyZCwgcmFkaXgsIG1heENvZGU7XHJcbiAgICBpZihmaXJzdCA9PT0gNDMgfHwgZmlyc3QgPT09IDQ1KXtcclxuICAgICAgdGhpcmQgPSBpdC5jaGFyQ29kZUF0KDIpO1xyXG4gICAgICBpZih0aGlyZCA9PT0gODggfHwgdGhpcmQgPT09IDEyMClyZXR1cm4gTmFOOyAvLyBOdW1iZXIoJysweDEnKSBzaG91bGQgYmUgTmFOLCBvbGQgVjggZml4XHJcbiAgICB9IGVsc2UgaWYoZmlyc3QgPT09IDQ4KXtcclxuICAgICAgc3dpdGNoKGl0LmNoYXJDb2RlQXQoMSkpe1xyXG4gICAgICAgIGNhc2UgNjYgOiBjYXNlIDk4ICA6IHJhZGl4ID0gMjsgbWF4Q29kZSA9IDQ5OyBicmVhazsgLy8gZmFzdCBlcXVhbCAvXjBiWzAxXSskL2lcclxuICAgICAgICBjYXNlIDc5IDogY2FzZSAxMTEgOiByYWRpeCA9IDg7IG1heENvZGUgPSA1NTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wb1swLTddKyQvaVxyXG4gICAgICAgIGRlZmF1bHQgOiByZXR1cm4gK2l0O1xyXG4gICAgICB9XHJcbiAgICAgIGZvcih2YXIgZGlnaXRzID0gaXQuc2xpY2UoMiksIGkgPSAwLCBsID0gZGlnaXRzLmxlbmd0aCwgY29kZTsgaSA8IGw7IGkrKyl7XHJcbiAgICAgICAgY29kZSA9IGRpZ2l0cy5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgIC8vIHBhcnNlSW50IHBhcnNlcyBhIHN0cmluZyB0byBhIGZpcnN0IHVuYXZhaWxhYmxlIHN5bWJvbFxyXG4gICAgICAgIC8vIGJ1dCBUb051bWJlciBzaG91bGQgcmV0dXJuIE5hTiBpZiBhIHN0cmluZyBjb250YWlucyB1bmF2YWlsYWJsZSBzeW1ib2xzXHJcbiAgICAgICAgaWYoY29kZSA8IDQ4IHx8IGNvZGUgPiBtYXhDb2RlKXJldHVybiBOYU47XHJcbiAgICAgIH0gcmV0dXJuIHBhcnNlSW50KGRpZ2l0cywgcmFkaXgpO1xyXG4gICAgfVxyXG4gIH0gcmV0dXJuICtpdDtcclxufTtcclxuXHJcbmlmKCEkTnVtYmVyKCcgMG8xJykgfHwgISROdW1iZXIoJzBiMScpIHx8ICROdW1iZXIoJysweDEnKSl7XHJcbiAgJE51bWJlciA9IGZ1bmN0aW9uIE51bWJlcih2YWx1ZSl7XHJcbiAgICB2YXIgaXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMSA/IDAgOiB2YWx1ZVxyXG4gICAgICAsIHRoYXQgPSB0aGlzO1xyXG4gICAgcmV0dXJuIHRoYXQgaW5zdGFuY2VvZiAkTnVtYmVyXHJcbiAgICAgIC8vIGNoZWNrIG9uIDEuLmNvbnN0cnVjdG9yKGZvbykgY2FzZVxyXG4gICAgICAmJiAoQlJPS0VOX0NPRiA/IGZhaWxzKGZ1bmN0aW9uKCl7IHByb3RvLnZhbHVlT2YuY2FsbCh0aGF0KTsgfSkgOiBjb2YodGhhdCkgIT0gTlVNQkVSKVxyXG4gICAgICAgID8gaW5oZXJpdElmUmVxdWlyZWQobmV3IEJhc2UodG9OdW1iZXIoaXQpKSwgdGhhdCwgJE51bWJlcikgOiB0b051bWJlcihpdCk7XHJcbiAgfTtcclxuICBmb3IodmFyIGtleXMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZXNjcmlwdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanNcIikgPyBnT1BOKEJhc2UpIDogKFxyXG4gICAgLy8gRVMzOlxyXG4gICAgJ01BWF9WQUxVRSxNSU5fVkFMVUUsTmFOLE5FR0FUSVZFX0lORklOSVRZLFBPU0lUSVZFX0lORklOSVRZLCcgK1xyXG4gICAgLy8gRVM2IChpbiBjYXNlLCBpZiBtb2R1bGVzIHdpdGggRVM2IE51bWJlciBzdGF0aWNzIHJlcXVpcmVkIGJlZm9yZSk6XHJcbiAgICAnRVBTSUxPTixpc0Zpbml0ZSxpc0ludGVnZXIsaXNOYU4saXNTYWZlSW50ZWdlcixNQVhfU0FGRV9JTlRFR0VSLCcgK1xyXG4gICAgJ01JTl9TQUZFX0lOVEVHRVIscGFyc2VGbG9hdCxwYXJzZUludCxpc0ludGVnZXInXHJcbiAgKS5zcGxpdCgnLCcpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7IGorKyl7XHJcbiAgICBpZihoYXMoQmFzZSwga2V5ID0ga2V5c1tqXSkgJiYgIWhhcygkTnVtYmVyLCBrZXkpKXtcclxuICAgICAgZFAoJE51bWJlciwga2V5LCBnT1BEKEJhc2UsIGtleSkpO1xyXG4gICAgfVxyXG4gIH1cclxuICAkTnVtYmVyLnByb3RvdHlwZSA9IHByb3RvO1xyXG4gIHByb3RvLmNvbnN0cnVjdG9yID0gJE51bWJlcjtcclxuICBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19yZWRlZmluZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanNcIikoZ2xvYmFsLCBOVU1CRVIsICROdW1iZXIpO1xyXG59XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuZXBzaWxvbi5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5lcHNpbG9uLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjEuMi4xIE51bWJlci5FUFNJTE9OXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtFUFNJTE9OOiBNYXRoLnBvdygyLCAtNTIpfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtZmluaXRlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtZmluaXRlLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMS4yLjIgTnVtYmVyLmlzRmluaXRlKG51bWJlcilcclxudmFyICRleHBvcnQgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBfaXNGaW5pdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKS5pc0Zpbml0ZTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywge1xyXG4gIGlzRmluaXRlOiBmdW5jdGlvbiBpc0Zpbml0ZShpdCl7XHJcbiAgICByZXR1cm4gdHlwZW9mIGl0ID09ICdudW1iZXInICYmIF9pc0Zpbml0ZShpdCk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1pbnRlZ2VyLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLWludGVnZXIuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjAuMS4yLjMgTnVtYmVyLmlzSW50ZWdlcihudW1iZXIpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtpc0ludGVnZXI6IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLWludGVnZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWludGVnZXIuanNcIil9KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1uYW4uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1uYW4uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyMC4xLjIuNCBOdW1iZXIuaXNOYU4obnVtYmVyKVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XHJcbiAgaXNOYU46IGZ1bmN0aW9uIGlzTmFOKG51bWJlcil7XHJcbiAgICByZXR1cm4gbnVtYmVyICE9IG51bWJlcjtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLXNhZmUtaW50ZWdlci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLXNhZmUtaW50ZWdlci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjEuMi41IE51bWJlci5pc1NhZmVJbnRlZ2VyKG51bWJlcilcclxudmFyICRleHBvcnQgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBpc0ludGVnZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1pbnRlZ2VyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1pbnRlZ2VyLmpzXCIpXHJcbiAgLCBhYnMgICAgICAgPSBNYXRoLmFicztcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywge1xyXG4gIGlzU2FmZUludGVnZXI6IGZ1bmN0aW9uIGlzU2FmZUludGVnZXIobnVtYmVyKXtcclxuICAgIHJldHVybiBpc0ludGVnZXIobnVtYmVyKSAmJiBhYnMobnVtYmVyKSA8PSAweDFmZmZmZmZmZmZmZmZmO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIubWF4LXNhZmUtaW50ZWdlci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5tYXgtc2FmZS1pbnRlZ2VyLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjEuMi42IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtNQVhfU0FGRV9JTlRFR0VSOiAweDFmZmZmZmZmZmZmZmZmfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIubWluLXNhZmUtaW50ZWdlci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5taW4tc2FmZS1pbnRlZ2VyLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDIwLjEuMi4xMCBOdW1iZXIuTUlOX1NBRkVfSU5URUdFUlxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7TUlOX1NBRkVfSU5URUdFUjogLTB4MWZmZmZmZmZmZmZmZmZ9KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtZmxvYXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciAkZXhwb3J0ICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkcGFyc2VGbG9hdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3BhcnNlLWZsb2F0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJzZS1mbG9hdC5qc1wiKTtcclxuLy8gMjAuMS4yLjEyIE51bWJlci5wYXJzZUZsb2F0KHN0cmluZylcclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoTnVtYmVyLnBhcnNlRmxvYXQgIT0gJHBhcnNlRmxvYXQpLCAnTnVtYmVyJywge3BhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0fSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRleHBvcnQgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkcGFyc2VJbnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19wYXJzZS1pbnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWludC5qc1wiKTtcclxuLy8gMjAuMS4yLjEzIE51bWJlci5wYXJzZUludChzdHJpbmcsIHJhZGl4KVxyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChOdW1iZXIucGFyc2VJbnQgIT0gJHBhcnNlSW50KSwgJ051bWJlcicsIHtwYXJzZUludDogJHBhcnNlSW50fSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIudG8tZml4ZWQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnRvLWZpeGVkLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciAkZXhwb3J0ICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgdG9JbnRlZ2VyICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW50ZWdlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qc1wiKVxyXG4gICwgYU51bWJlclZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYS1udW1iZXItdmFsdWUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtbnVtYmVyLXZhbHVlLmpzXCIpXHJcbiAgLCByZXBlYXQgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctcmVwZWF0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctcmVwZWF0LmpzXCIpXHJcbiAgLCAkdG9GaXhlZCAgICAgPSAxLi50b0ZpeGVkXHJcbiAgLCBmbG9vciAgICAgICAgPSBNYXRoLmZsb29yXHJcbiAgLCBkYXRhICAgICAgICAgPSBbMCwgMCwgMCwgMCwgMCwgMF1cclxuICAsIEVSUk9SICAgICAgICA9ICdOdW1iZXIudG9GaXhlZDogaW5jb3JyZWN0IGludm9jYXRpb24hJ1xyXG4gICwgWkVSTyAgICAgICAgID0gJzAnO1xyXG5cclxudmFyIG11bHRpcGx5ID0gZnVuY3Rpb24obiwgYyl7XHJcbiAgdmFyIGkgID0gLTFcclxuICAgICwgYzIgPSBjO1xyXG4gIHdoaWxlKCsraSA8IDYpe1xyXG4gICAgYzIgKz0gbiAqIGRhdGFbaV07XHJcbiAgICBkYXRhW2ldID0gYzIgJSAxZTc7XHJcbiAgICBjMiA9IGZsb29yKGMyIC8gMWU3KTtcclxuICB9XHJcbn07XHJcbnZhciBkaXZpZGUgPSBmdW5jdGlvbihuKXtcclxuICB2YXIgaSA9IDZcclxuICAgICwgYyA9IDA7XHJcbiAgd2hpbGUoLS1pID49IDApe1xyXG4gICAgYyArPSBkYXRhW2ldO1xyXG4gICAgZGF0YVtpXSA9IGZsb29yKGMgLyBuKTtcclxuICAgIGMgPSAoYyAlIG4pICogMWU3O1xyXG4gIH1cclxufTtcclxudmFyIG51bVRvU3RyaW5nID0gZnVuY3Rpb24oKXtcclxuICB2YXIgaSA9IDZcclxuICAgICwgcyA9ICcnO1xyXG4gIHdoaWxlKC0taSA+PSAwKXtcclxuICAgIGlmKHMgIT09ICcnIHx8IGkgPT09IDAgfHwgZGF0YVtpXSAhPT0gMCl7XHJcbiAgICAgIHZhciB0ID0gU3RyaW5nKGRhdGFbaV0pO1xyXG4gICAgICBzID0gcyA9PT0gJycgPyB0IDogcyArIHJlcGVhdC5jYWxsKFpFUk8sIDcgLSB0Lmxlbmd0aCkgKyB0O1xyXG4gICAgfVxyXG4gIH0gcmV0dXJuIHM7XHJcbn07XHJcbnZhciBwb3cgPSBmdW5jdGlvbih4LCBuLCBhY2Mpe1xyXG4gIHJldHVybiBuID09PSAwID8gYWNjIDogbiAlIDIgPT09IDEgPyBwb3coeCwgbiAtIDEsIGFjYyAqIHgpIDogcG93KHggKiB4LCBuIC8gMiwgYWNjKTtcclxufTtcclxudmFyIGxvZyA9IGZ1bmN0aW9uKHgpe1xyXG4gIHZhciBuICA9IDBcclxuICAgICwgeDIgPSB4O1xyXG4gIHdoaWxlKHgyID49IDQwOTYpe1xyXG4gICAgbiArPSAxMjtcclxuICAgIHgyIC89IDQwOTY7XHJcbiAgfVxyXG4gIHdoaWxlKHgyID49IDIpe1xyXG4gICAgbiAgKz0gMTtcclxuICAgIHgyIC89IDI7XHJcbiAgfSByZXR1cm4gbjtcclxufTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKCEhJHRvRml4ZWQgJiYgKFxyXG4gIDAuMDAwMDgudG9GaXhlZCgzKSAhPT0gJzAuMDAwJyB8fFxyXG4gIDAuOS50b0ZpeGVkKDApICE9PSAnMScgfHxcclxuICAxLjI1NS50b0ZpeGVkKDIpICE9PSAnMS4yNScgfHxcclxuICAxMDAwMDAwMDAwMDAwMDAwMTI4Li50b0ZpeGVkKDApICE9PSAnMTAwMDAwMDAwMDAwMDAwMDEyOCdcclxuKSB8fCAhX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmFpbHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCIpKGZ1bmN0aW9uKCl7XHJcbiAgLy8gVjggfiBBbmRyb2lkIDQuMy1cclxuICAkdG9GaXhlZC5jYWxsKHt9KTtcclxufSkpLCAnTnVtYmVyJywge1xyXG4gIHRvRml4ZWQ6IGZ1bmN0aW9uIHRvRml4ZWQoZnJhY3Rpb25EaWdpdHMpe1xyXG4gICAgdmFyIHggPSBhTnVtYmVyVmFsdWUodGhpcywgRVJST1IpXHJcbiAgICAgICwgZiA9IHRvSW50ZWdlcihmcmFjdGlvbkRpZ2l0cylcclxuICAgICAgLCBzID0gJydcclxuICAgICAgLCBtID0gWkVST1xyXG4gICAgICAsIGUsIHosIGosIGs7XHJcbiAgICBpZihmIDwgMCB8fCBmID4gMjApdGhyb3cgUmFuZ2VFcnJvcihFUlJPUik7XHJcbiAgICBpZih4ICE9IHgpcmV0dXJuICdOYU4nO1xyXG4gICAgaWYoeCA8PSAtMWUyMSB8fCB4ID49IDFlMjEpcmV0dXJuIFN0cmluZyh4KTtcclxuICAgIGlmKHggPCAwKXtcclxuICAgICAgcyA9ICctJztcclxuICAgICAgeCA9IC14O1xyXG4gICAgfVxyXG4gICAgaWYoeCA+IDFlLTIxKXtcclxuICAgICAgZSA9IGxvZyh4ICogcG93KDIsIDY5LCAxKSkgLSA2OTtcclxuICAgICAgeiA9IGUgPCAwID8geCAqIHBvdygyLCAtZSwgMSkgOiB4IC8gcG93KDIsIGUsIDEpO1xyXG4gICAgICB6ICo9IDB4MTAwMDAwMDAwMDAwMDA7XHJcbiAgICAgIGUgPSA1MiAtIGU7XHJcbiAgICAgIGlmKGUgPiAwKXtcclxuICAgICAgICBtdWx0aXBseSgwLCB6KTtcclxuICAgICAgICBqID0gZjtcclxuICAgICAgICB3aGlsZShqID49IDcpe1xyXG4gICAgICAgICAgbXVsdGlwbHkoMWU3LCAwKTtcclxuICAgICAgICAgIGogLT0gNztcclxuICAgICAgICB9XHJcbiAgICAgICAgbXVsdGlwbHkocG93KDEwLCBqLCAxKSwgMCk7XHJcbiAgICAgICAgaiA9IGUgLSAxO1xyXG4gICAgICAgIHdoaWxlKGogPj0gMjMpe1xyXG4gICAgICAgICAgZGl2aWRlKDEgPDwgMjMpO1xyXG4gICAgICAgICAgaiAtPSAyMztcclxuICAgICAgICB9XHJcbiAgICAgICAgZGl2aWRlKDEgPDwgaik7XHJcbiAgICAgICAgbXVsdGlwbHkoMSwgMSk7XHJcbiAgICAgICAgZGl2aWRlKDIpO1xyXG4gICAgICAgIG0gPSBudW1Ub1N0cmluZygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG11bHRpcGx5KDAsIHopO1xyXG4gICAgICAgIG11bHRpcGx5KDEgPDwgLWUsIDApO1xyXG4gICAgICAgIG0gPSBudW1Ub1N0cmluZygpICsgcmVwZWF0LmNhbGwoWkVSTywgZik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmKGYgPiAwKXtcclxuICAgICAgayA9IG0ubGVuZ3RoO1xyXG4gICAgICBtID0gcyArIChrIDw9IGYgPyAnMC4nICsgcmVwZWF0LmNhbGwoWkVSTywgZiAtIGspICsgbSA6IG0uc2xpY2UoMCwgayAtIGYpICsgJy4nICsgbS5zbGljZShrIC0gZikpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbSA9IHMgKyBtO1xyXG4gICAgfSByZXR1cm4gbTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnRvLXByZWNpc2lvbi5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnRvLXByZWNpc2lvbi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyICRleHBvcnQgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkZmFpbHMgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIilcclxuICAsIGFOdW1iZXJWYWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2EtbnVtYmVyLXZhbHVlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLW51bWJlci12YWx1ZS5qc1wiKVxyXG4gICwgJHRvUHJlY2lzaW9uID0gMS4udG9QcmVjaXNpb247XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICgkZmFpbHMoZnVuY3Rpb24oKXtcclxuICAvLyBJRTctXHJcbiAgcmV0dXJuICR0b1ByZWNpc2lvbi5jYWxsKDEsIHVuZGVmaW5lZCkgIT09ICcxJztcclxufSkgfHwgISRmYWlscyhmdW5jdGlvbigpe1xyXG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXHJcbiAgJHRvUHJlY2lzaW9uLmNhbGwoe30pO1xyXG59KSksICdOdW1iZXInLCB7XHJcbiAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbil7XHJcbiAgICB2YXIgdGhhdCA9IGFOdW1iZXJWYWx1ZSh0aGlzLCAnTnVtYmVyI3RvUHJlY2lzaW9uOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcclxuICAgIHJldHVybiBwcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/ICR0b1ByZWNpc2lvbi5jYWxsKHRoYXQpIDogJHRvUHJlY2lzaW9uLmNhbGwodGhhdCwgcHJlY2lzaW9uKTsgXHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAxOS4xLjMuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlKVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYsICdPYmplY3QnLCB7YXNzaWduOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtYXNzaWduICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzXCIpfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuY3JlYXRlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuY3JlYXRlLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4vLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcclxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7Y3JlYXRlOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtY3JlYXRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzXCIpfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0aWVzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG4vLyAxOS4xLjIuMyAvIDE1LjIuMy43IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpXHJcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Rlc2NyaXB0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qc1wiKSwgJ09iamVjdCcsIHtkZWZpbmVQcm9wZXJ0aWVzOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHBzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHBzLmpzXCIpfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnR5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnR5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuLy8gMTkuMS4yLjQgLyAxNS4yLjMuNiBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcylcclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpLCAnT2JqZWN0Jywge2RlZmluZVByb3BlcnR5OiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKS5mfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZnJlZXplLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZnJlZXplLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4yLjUgT2JqZWN0LmZyZWV6ZShPKVxyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgbWV0YSAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tZXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzXCIpLm9uRnJlZXplO1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LXNhcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXNhcC5qc1wiKSgnZnJlZXplJywgZnVuY3Rpb24oJGZyZWV6ZSl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIGZyZWV6ZShpdCl7XHJcbiAgICByZXR1cm4gJGZyZWV6ZSAmJiBpc09iamVjdChpdCkgPyAkZnJlZXplKG1ldGEoaXQpKSA6IGl0O1xyXG4gIH07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDE5LjEuMi42IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUClcclxudmFyIHRvSU9iamVjdCAgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCIpXHJcbiAgLCAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcGQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzXCIpLmY7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3Qtc2FwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qtc2FwLmpzXCIpKCdnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3InLCBmdW5jdGlvbigpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaXQsIGtleSl7XHJcbiAgICByZXR1cm4gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0b0lPYmplY3QoaXQpLCBrZXkpO1xyXG4gIH07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktbmFtZXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1uYW1lcy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3Qtc2FwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qtc2FwLmpzXCIpKCdnZXRPd25Qcm9wZXJ0eU5hbWVzJywgZnVuY3Rpb24oKXtcclxuICByZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcG4tZXh0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi1leHQuanNcIikuZjtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LXByb3RvdHlwZS1vZi5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtcHJvdG90eXBlLW9mLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDE5LjEuMi45IE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxyXG52YXIgdG9PYmplY3QgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAsICRnZXRQcm90b3R5cGVPZiA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1ncG8gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanNcIik7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3Qtc2FwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qtc2FwLmpzXCIpKCdnZXRQcm90b3R5cGVPZicsIGZ1bmN0aW9uKCl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIGdldFByb3RvdHlwZU9mKGl0KXtcclxuICAgIHJldHVybiAkZ2V0UHJvdG90eXBlT2YodG9PYmplY3QoaXQpKTtcclxuICB9O1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1leHRlbnNpYmxlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLWV4dGVuc2libGUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4yLjExIE9iamVjdC5pc0V4dGVuc2libGUoTylcclxudmFyIGlzT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIik7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3Qtc2FwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qtc2FwLmpzXCIpKCdpc0V4dGVuc2libGUnLCBmdW5jdGlvbigkaXNFeHRlbnNpYmxlKXtcclxuICByZXR1cm4gZnVuY3Rpb24gaXNFeHRlbnNpYmxlKGl0KXtcclxuICAgIHJldHVybiBpc09iamVjdChpdCkgPyAkaXNFeHRlbnNpYmxlID8gJGlzRXh0ZW5zaWJsZShpdCkgOiB0cnVlIDogZmFsc2U7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZnJvemVuLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZnJvemVuLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4yLjEyIE9iamVjdC5pc0Zyb3plbihPKVxyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKTtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1zYXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1zYXAuanNcIikoJ2lzRnJvemVuJywgZnVuY3Rpb24oJGlzRnJvemVuKXtcclxuICByZXR1cm4gZnVuY3Rpb24gaXNGcm96ZW4oaXQpe1xyXG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc0Zyb3plbiA/ICRpc0Zyb3plbihpdCkgOiBmYWxzZSA6IHRydWU7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtc2VhbGVkLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtc2VhbGVkLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4yLjEzIE9iamVjdC5pc1NlYWxlZChPKVxyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKTtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1zYXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1zYXAuanNcIikoJ2lzU2VhbGVkJywgZnVuY3Rpb24oJGlzU2VhbGVkKXtcclxuICByZXR1cm4gZnVuY3Rpb24gaXNTZWFsZWQoaXQpe1xyXG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc1NlYWxlZCA/ICRpc1NlYWxlZChpdCkgOiBmYWxzZSA6IHRydWU7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAxOS4xLjMuMTAgT2JqZWN0LmlzKHZhbHVlMSwgdmFsdWUyKVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtpczogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2FtZS12YWx1ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2FtZS12YWx1ZS5qc1wiKX0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmtleXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAxOS4xLjIuMTQgT2JqZWN0LmtleXMoTylcclxudmFyIHRvT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAsICRrZXlzICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLmpzXCIpO1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LXNhcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXNhcC5qc1wiKSgna2V5cycsIGZ1bmN0aW9uKCl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIGtleXMoaXQpe1xyXG4gICAgcmV0dXJuICRrZXlzKHRvT2JqZWN0KGl0KSk7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QucHJldmVudC1leHRlbnNpb25zLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QucHJldmVudC1leHRlbnNpb25zLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4yLjE1IE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyhPKVxyXG52YXIgaXNPYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgbWV0YSAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tZXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzXCIpLm9uRnJlZXplO1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LXNhcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXNhcC5qc1wiKSgncHJldmVudEV4dGVuc2lvbnMnLCBmdW5jdGlvbigkcHJldmVudEV4dGVuc2lvbnMpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBwcmV2ZW50RXh0ZW5zaW9ucyhpdCl7XHJcbiAgICByZXR1cm4gJHByZXZlbnRFeHRlbnNpb25zICYmIGlzT2JqZWN0KGl0KSA/ICRwcmV2ZW50RXh0ZW5zaW9ucyhtZXRhKGl0KSkgOiBpdDtcclxuICB9O1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnNlYWwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4yLjE3IE9iamVjdC5zZWFsKE8pXHJcbnZhciBpc09iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzXCIpXHJcbiAgLCBtZXRhICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21ldGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGEuanNcIikub25GcmVlemU7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3Qtc2FwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qtc2FwLmpzXCIpKCdzZWFsJywgZnVuY3Rpb24oJHNlYWwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBzZWFsKGl0KXtcclxuICAgIHJldHVybiAkc2VhbCAmJiBpc09iamVjdChpdCkgPyAkc2VhbChtZXRhKGl0KSkgOiBpdDtcclxuICB9O1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnNldC1wcm90b3R5cGUtb2YuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7c2V0UHJvdG90eXBlT2Y6IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NldC1wcm90byAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzXCIpLnNldH0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXHJcbnZhciBjbGFzc29mID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY2xhc3NvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qc1wiKVxyXG4gICwgdGVzdCAgICA9IHt9O1xyXG50ZXN0W19fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCd0b1N0cmluZ1RhZycpXSA9ICd6JztcclxuaWYodGVzdCArICcnICE9ICdbb2JqZWN0IHpdJyl7XHJcbiAgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXCIpKE9iamVjdC5wcm90b3R5cGUsICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCl7XHJcbiAgICByZXR1cm4gJ1tvYmplY3QgJyArIGNsYXNzb2YodGhpcykgKyAnXSc7XHJcbiAgfSwgdHJ1ZSk7XHJcbn1cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnBhcnNlLWZsb2F0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtZmxvYXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRleHBvcnQgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsICRwYXJzZUZsb2F0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcGFyc2UtZmxvYXQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWZsb2F0LmpzXCIpO1xyXG4vLyAxOC4yLjQgcGFyc2VGbG9hdChzdHJpbmcpXHJcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5GICogKHBhcnNlRmxvYXQgIT0gJHBhcnNlRmxvYXQpLCB7cGFyc2VGbG9hdDogJHBhcnNlRmxvYXR9KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnBhcnNlLWludC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5wYXJzZS1pbnQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciAkZXhwb3J0ICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgJHBhcnNlSW50ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcGFyc2UtaW50ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJzZS1pbnQuanNcIik7XHJcbi8vIDE4LjIuNSBwYXJzZUludChzdHJpbmcsIHJhZGl4KVxyXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuRiAqIChwYXJzZUludCAhPSAkcGFyc2VJbnQpLCB7cGFyc2VJbnQ6ICRwYXJzZUludH0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIExJQlJBUlkgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2xpYnJhcnkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanNcIilcclxuICAsIGdsb2JhbCAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgLCBjdHggICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jdHggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qc1wiKVxyXG4gICwgY2xhc3NvZiAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY2xhc3NvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qc1wiKVxyXG4gICwgJGV4cG9ydCAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGlzT2JqZWN0ICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzXCIpXHJcbiAgLCBhRnVuY3Rpb24gICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCBhbkluc3RhbmNlICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1pbnN0YW5jZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanNcIilcclxuICAsIGZvck9mICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Zvci1vZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzXCIpXHJcbiAgLCBzcGVjaWVzQ29uc3RydWN0b3IgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zcGVjaWVzLWNvbnN0cnVjdG9yICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zcGVjaWVzLWNvbnN0cnVjdG9yLmpzXCIpXHJcbiAgLCB0YXNrICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190YXNrICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190YXNrLmpzXCIpLnNldFxyXG4gICwgbWljcm90YXNrICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fbWljcm90YXNrICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanNcIikoKVxyXG4gICwgUFJPTUlTRSAgICAgICAgICAgID0gJ1Byb21pc2UnXHJcbiAgLCBUeXBlRXJyb3IgICAgICAgICAgPSBnbG9iYWwuVHlwZUVycm9yXHJcbiAgLCBwcm9jZXNzICAgICAgICAgICAgPSBnbG9iYWwucHJvY2Vzc1xyXG4gICwgJFByb21pc2UgICAgICAgICAgID0gZ2xvYmFsW1BST01JU0VdXHJcbiAgLCBwcm9jZXNzICAgICAgICAgICAgPSBnbG9iYWwucHJvY2Vzc1xyXG4gICwgaXNOb2RlICAgICAgICAgICAgID0gY2xhc3NvZihwcm9jZXNzKSA9PSAncHJvY2VzcydcclxuICAsIGVtcHR5ICAgICAgICAgICAgICA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH1cclxuICAsIEludGVybmFsLCBHZW5lcmljUHJvbWlzZUNhcGFiaWxpdHksIFdyYXBwZXI7XHJcblxyXG52YXIgVVNFX05BVElWRSA9ICEhZnVuY3Rpb24oKXtcclxuICB0cnkge1xyXG4gICAgLy8gY29ycmVjdCBzdWJjbGFzc2luZyB3aXRoIEBAc3BlY2llcyBzdXBwb3J0XHJcbiAgICB2YXIgcHJvbWlzZSAgICAgPSAkUHJvbWlzZS5yZXNvbHZlKDEpXHJcbiAgICAgICwgRmFrZVByb21pc2UgPSAocHJvbWlzZS5jb25zdHJ1Y3RvciA9IHt9KVtfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qc1wiKSgnc3BlY2llcycpXSA9IGZ1bmN0aW9uKGV4ZWMpeyBleGVjKGVtcHR5LCBlbXB0eSk7IH07XHJcbiAgICAvLyB1bmhhbmRsZWQgcmVqZWN0aW9ucyB0cmFja2luZyBzdXBwb3J0LCBOb2RlSlMgUHJvbWlzZSB3aXRob3V0IGl0IGZhaWxzIEBAc3BlY2llcyB0ZXN0XHJcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpICYmIHByb21pc2UudGhlbihlbXB0eSkgaW5zdGFuY2VvZiBGYWtlUHJvbWlzZTtcclxuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XHJcbn0oKTtcclxuXHJcbi8vIGhlbHBlcnNcclxudmFyIHNhbWVDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uKGEsIGIpe1xyXG4gIC8vIHdpdGggbGlicmFyeSB3cmFwcGVyIHNwZWNpYWwgY2FzZVxyXG4gIHJldHVybiBhID09PSBiIHx8IGEgPT09ICRQcm9taXNlICYmIGIgPT09IFdyYXBwZXI7XHJcbn07XHJcbnZhciBpc1RoZW5hYmxlID0gZnVuY3Rpb24oaXQpe1xyXG4gIHZhciB0aGVuO1xyXG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcclxufTtcclxudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24oQyl7XHJcbiAgcmV0dXJuIHNhbWVDb25zdHJ1Y3RvcigkUHJvbWlzZSwgQylcclxuICAgID8gbmV3IFByb21pc2VDYXBhYmlsaXR5KEMpXHJcbiAgICA6IG5ldyBHZW5lcmljUHJvbWlzZUNhcGFiaWxpdHkoQyk7XHJcbn07XHJcbnZhciBQcm9taXNlQ2FwYWJpbGl0eSA9IEdlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uKEMpe1xyXG4gIHZhciByZXNvbHZlLCByZWplY3Q7XHJcbiAgdGhpcy5wcm9taXNlID0gbmV3IEMoZnVuY3Rpb24oJCRyZXNvbHZlLCAkJHJlamVjdCl7XHJcbiAgICBpZihyZXNvbHZlICE9PSB1bmRlZmluZWQgfHwgcmVqZWN0ICE9PSB1bmRlZmluZWQpdGhyb3cgVHlwZUVycm9yKCdCYWQgUHJvbWlzZSBjb25zdHJ1Y3RvcicpO1xyXG4gICAgcmVzb2x2ZSA9ICQkcmVzb2x2ZTtcclxuICAgIHJlamVjdCAgPSAkJHJlamVjdDtcclxuICB9KTtcclxuICB0aGlzLnJlc29sdmUgPSBhRnVuY3Rpb24ocmVzb2x2ZSk7XHJcbiAgdGhpcy5yZWplY3QgID0gYUZ1bmN0aW9uKHJlamVjdCk7XHJcbn07XHJcbnZhciBwZXJmb3JtID0gZnVuY3Rpb24oZXhlYyl7XHJcbiAgdHJ5IHtcclxuICAgIGV4ZWMoKTtcclxuICB9IGNhdGNoKGUpe1xyXG4gICAgcmV0dXJuIHtlcnJvcjogZX07XHJcbiAgfVxyXG59O1xyXG52YXIgbm90aWZ5ID0gZnVuY3Rpb24ocHJvbWlzZSwgaXNSZWplY3Qpe1xyXG4gIGlmKHByb21pc2UuX24pcmV0dXJuO1xyXG4gIHByb21pc2UuX24gPSB0cnVlO1xyXG4gIHZhciBjaGFpbiA9IHByb21pc2UuX2M7XHJcbiAgbWljcm90YXNrKGZ1bmN0aW9uKCl7XHJcbiAgICB2YXIgdmFsdWUgPSBwcm9taXNlLl92XHJcbiAgICAgICwgb2sgICAgPSBwcm9taXNlLl9zID09IDFcclxuICAgICAgLCBpICAgICA9IDA7XHJcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24ocmVhY3Rpb24pe1xyXG4gICAgICB2YXIgaGFuZGxlciA9IG9rID8gcmVhY3Rpb24ub2sgOiByZWFjdGlvbi5mYWlsXHJcbiAgICAgICAgLCByZXNvbHZlID0gcmVhY3Rpb24ucmVzb2x2ZVxyXG4gICAgICAgICwgcmVqZWN0ICA9IHJlYWN0aW9uLnJlamVjdFxyXG4gICAgICAgICwgZG9tYWluICA9IHJlYWN0aW9uLmRvbWFpblxyXG4gICAgICAgICwgcmVzdWx0LCB0aGVuO1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGlmKGhhbmRsZXIpe1xyXG4gICAgICAgICAgaWYoIW9rKXtcclxuICAgICAgICAgICAgaWYocHJvbWlzZS5faCA9PSAyKW9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xyXG4gICAgICAgICAgICBwcm9taXNlLl9oID0gMTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmKGhhbmRsZXIgPT09IHRydWUpcmVzdWx0ID0gdmFsdWU7XHJcbiAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYoZG9tYWluKWRvbWFpbi5lbnRlcigpO1xyXG4gICAgICAgICAgICByZXN1bHQgPSBoYW5kbGVyKHZhbHVlKTtcclxuICAgICAgICAgICAgaWYoZG9tYWluKWRvbWFpbi5leGl0KCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZihyZXN1bHQgPT09IHJlYWN0aW9uLnByb21pc2Upe1xyXG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xyXG4gICAgICAgICAgfSBlbHNlIGlmKHRoZW4gPSBpc1RoZW5hYmxlKHJlc3VsdCkpe1xyXG4gICAgICAgICAgICB0aGVuLmNhbGwocmVzdWx0LCByZXNvbHZlLCByZWplY3QpO1xyXG4gICAgICAgICAgfSBlbHNlIHJlc29sdmUocmVzdWx0KTtcclxuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcclxuICAgICAgfSBjYXRjaChlKXtcclxuICAgICAgICByZWplY3QoZSk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgICB3aGlsZShjaGFpbi5sZW5ndGggPiBpKXJ1bihjaGFpbltpKytdKTsgLy8gdmFyaWFibGUgbGVuZ3RoIC0gY2FuJ3QgdXNlIGZvckVhY2hcclxuICAgIHByb21pc2UuX2MgPSBbXTtcclxuICAgIHByb21pc2UuX24gPSBmYWxzZTtcclxuICAgIGlmKGlzUmVqZWN0ICYmICFwcm9taXNlLl9oKW9uVW5oYW5kbGVkKHByb21pc2UpO1xyXG4gIH0pO1xyXG59O1xyXG52YXIgb25VbmhhbmRsZWQgPSBmdW5jdGlvbihwcm9taXNlKXtcclxuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xyXG4gICAgdmFyIHZhbHVlID0gcHJvbWlzZS5fdlxyXG4gICAgICAsIGFicnVwdCwgaGFuZGxlciwgY29uc29sZTtcclxuICAgIGlmKGlzVW5oYW5kbGVkKHByb21pc2UpKXtcclxuICAgICAgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xyXG4gICAgICAgIGlmKGlzTm9kZSl7XHJcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcclxuICAgICAgICB9IGVsc2UgaWYoaGFuZGxlciA9IGdsb2JhbC5vbnVuaGFuZGxlZHJlamVjdGlvbil7XHJcbiAgICAgICAgICBoYW5kbGVyKHtwcm9taXNlOiBwcm9taXNlLCByZWFzb246IHZhbHVlfSk7XHJcbiAgICAgICAgfSBlbHNlIGlmKChjb25zb2xlID0gZ2xvYmFsLmNvbnNvbGUpICYmIGNvbnNvbGUuZXJyb3Ipe1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcignVW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uJywgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIC8vIEJyb3dzZXJzIHNob3VsZCBub3QgdHJpZ2dlciBgcmVqZWN0aW9uSGFuZGxlZGAgZXZlbnQgaWYgaXQgd2FzIGhhbmRsZWQgaGVyZSwgTm9kZUpTIC0gc2hvdWxkXHJcbiAgICAgIHByb21pc2UuX2ggPSBpc05vZGUgfHwgaXNVbmhhbmRsZWQocHJvbWlzZSkgPyAyIDogMTtcclxuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcclxuICAgIGlmKGFicnVwdCl0aHJvdyBhYnJ1cHQuZXJyb3I7XHJcbiAgfSk7XHJcbn07XHJcbnZhciBpc1VuaGFuZGxlZCA9IGZ1bmN0aW9uKHByb21pc2Upe1xyXG4gIGlmKHByb21pc2UuX2ggPT0gMSlyZXR1cm4gZmFsc2U7XHJcbiAgdmFyIGNoYWluID0gcHJvbWlzZS5fYSB8fCBwcm9taXNlLl9jXHJcbiAgICAsIGkgICAgID0gMFxyXG4gICAgLCByZWFjdGlvbjtcclxuICB3aGlsZShjaGFpbi5sZW5ndGggPiBpKXtcclxuICAgIHJlYWN0aW9uID0gY2hhaW5baSsrXTtcclxuICAgIGlmKHJlYWN0aW9uLmZhaWwgfHwgIWlzVW5oYW5kbGVkKHJlYWN0aW9uLnByb21pc2UpKXJldHVybiBmYWxzZTtcclxuICB9IHJldHVybiB0cnVlO1xyXG59O1xyXG52YXIgb25IYW5kbGVVbmhhbmRsZWQgPSBmdW5jdGlvbihwcm9taXNlKXtcclxuICB0YXNrLmNhbGwoZ2xvYmFsLCBmdW5jdGlvbigpe1xyXG4gICAgdmFyIGhhbmRsZXI7XHJcbiAgICBpZihpc05vZGUpe1xyXG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcclxuICAgIH0gZWxzZSBpZihoYW5kbGVyID0gZ2xvYmFsLm9ucmVqZWN0aW9uaGFuZGxlZCl7XHJcbiAgICAgIGhhbmRsZXIoe3Byb21pc2U6IHByb21pc2UsIHJlYXNvbjogcHJvbWlzZS5fdn0pO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59O1xyXG52YXIgJHJlamVjdCA9IGZ1bmN0aW9uKHZhbHVlKXtcclxuICB2YXIgcHJvbWlzZSA9IHRoaXM7XHJcbiAgaWYocHJvbWlzZS5fZClyZXR1cm47XHJcbiAgcHJvbWlzZS5fZCA9IHRydWU7XHJcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXHJcbiAgcHJvbWlzZS5fdiA9IHZhbHVlO1xyXG4gIHByb21pc2UuX3MgPSAyO1xyXG4gIGlmKCFwcm9taXNlLl9hKXByb21pc2UuX2EgPSBwcm9taXNlLl9jLnNsaWNlKCk7XHJcbiAgbm90aWZ5KHByb21pc2UsIHRydWUpO1xyXG59O1xyXG52YXIgJHJlc29sdmUgPSBmdW5jdGlvbih2YWx1ZSl7XHJcbiAgdmFyIHByb21pc2UgPSB0aGlzXHJcbiAgICAsIHRoZW47XHJcbiAgaWYocHJvbWlzZS5fZClyZXR1cm47XHJcbiAgcHJvbWlzZS5fZCA9IHRydWU7XHJcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXHJcbiAgdHJ5IHtcclxuICAgIGlmKHByb21pc2UgPT09IHZhbHVlKXRocm93IFR5cGVFcnJvcihcIlByb21pc2UgY2FuJ3QgYmUgcmVzb2x2ZWQgaXRzZWxmXCIpO1xyXG4gICAgaWYodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKXtcclxuICAgICAgbWljcm90YXNrKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgdmFyIHdyYXBwZXIgPSB7X3c6IHByb21pc2UsIF9kOiBmYWxzZX07IC8vIHdyYXBcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xyXG4gICAgICAgIH0gY2F0Y2goZSl7XHJcbiAgICAgICAgICAkcmVqZWN0LmNhbGwod3JhcHBlciwgZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHByb21pc2UuX3YgPSB2YWx1ZTtcclxuICAgICAgcHJvbWlzZS5fcyA9IDE7XHJcbiAgICAgIG5vdGlmeShwcm9taXNlLCBmYWxzZSk7XHJcbiAgICB9XHJcbiAgfSBjYXRjaChlKXtcclxuICAgICRyZWplY3QuY2FsbCh7X3c6IHByb21pc2UsIF9kOiBmYWxzZX0sIGUpOyAvLyB3cmFwXHJcbiAgfVxyXG59O1xyXG5cclxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcclxuaWYoIVVTRV9OQVRJVkUpe1xyXG4gIC8vIDI1LjQuMy4xIFByb21pc2UoZXhlY3V0b3IpXHJcbiAgJFByb21pc2UgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKXtcclxuICAgIGFuSW5zdGFuY2UodGhpcywgJFByb21pc2UsIFBST01JU0UsICdfaCcpO1xyXG4gICAgYUZ1bmN0aW9uKGV4ZWN1dG9yKTtcclxuICAgIEludGVybmFsLmNhbGwodGhpcyk7XHJcbiAgICB0cnkge1xyXG4gICAgICBleGVjdXRvcihjdHgoJHJlc29sdmUsIHRoaXMsIDEpLCBjdHgoJHJlamVjdCwgdGhpcywgMSkpO1xyXG4gICAgfSBjYXRjaChlcnIpe1xyXG4gICAgICAkcmVqZWN0LmNhbGwodGhpcywgZXJyKTtcclxuICAgIH1cclxuICB9O1xyXG4gIEludGVybmFsID0gZnVuY3Rpb24gUHJvbWlzZShleGVjdXRvcil7XHJcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xyXG4gICAgdGhpcy5fYSA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSBjaGVja2VkIGluIGlzVW5oYW5kbGVkIHJlYWN0aW9uc1xyXG4gICAgdGhpcy5fcyA9IDA7ICAgICAgICAgICAgICAvLyA8LSBzdGF0ZVxyXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXHJcbiAgICB0aGlzLl92ID0gdW5kZWZpbmVkOyAgICAgIC8vIDwtIHZhbHVlXHJcbiAgICB0aGlzLl9oID0gMDsgICAgICAgICAgICAgIC8vIDwtIHJlamVjdGlvbiBzdGF0ZSwgMCAtIGRlZmF1bHQsIDEgLSBoYW5kbGVkLCAyIC0gdW5oYW5kbGVkXHJcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxyXG4gIH07XHJcbiAgSW50ZXJuYWwucHJvdG90eXBlID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUtYWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanNcIikoJFByb21pc2UucHJvdG90eXBlLCB7XHJcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxyXG4gICAgdGhlbjogZnVuY3Rpb24gdGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCl7XHJcbiAgICAgIHZhciByZWFjdGlvbiAgICA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkUHJvbWlzZSkpO1xyXG4gICAgICByZWFjdGlvbi5vayAgICAgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcclxuICAgICAgcmVhY3Rpb24uZmFpbCAgID0gdHlwZW9mIG9uUmVqZWN0ZWQgPT0gJ2Z1bmN0aW9uJyAmJiBvblJlamVjdGVkO1xyXG4gICAgICByZWFjdGlvbi5kb21haW4gPSBpc05vZGUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcclxuICAgICAgdGhpcy5fYy5wdXNoKHJlYWN0aW9uKTtcclxuICAgICAgaWYodGhpcy5fYSl0aGlzLl9hLnB1c2gocmVhY3Rpb24pO1xyXG4gICAgICBpZih0aGlzLl9zKW5vdGlmeSh0aGlzLCBmYWxzZSk7XHJcbiAgICAgIHJldHVybiByZWFjdGlvbi5wcm9taXNlO1xyXG4gICAgfSxcclxuICAgIC8vIDI1LjQuNS4xIFByb21pc2UucHJvdG90eXBlLmNhdGNoKG9uUmVqZWN0ZWQpXHJcbiAgICAnY2F0Y2gnOiBmdW5jdGlvbihvblJlamVjdGVkKXtcclxuICAgICAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIG9uUmVqZWN0ZWQpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIFByb21pc2VDYXBhYmlsaXR5ID0gZnVuY3Rpb24oKXtcclxuICAgIHZhciBwcm9taXNlICA9IG5ldyBJbnRlcm5hbDtcclxuICAgIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XHJcbiAgICB0aGlzLnJlc29sdmUgPSBjdHgoJHJlc29sdmUsIHByb21pc2UsIDEpO1xyXG4gICAgdGhpcy5yZWplY3QgID0gY3R4KCRyZWplY3QsIHByb21pc2UsIDEpO1xyXG4gIH07XHJcbn1cclxuXHJcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIHtQcm9taXNlOiAkUHJvbWlzZX0pO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zZXQtdG8tc3RyaW5nLXRhZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanNcIikoJFByb21pc2UsIFBST01JU0UpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zZXQtc3BlY2llcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanNcIikoUFJPTUlTRSk7XHJcbldyYXBwZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb3JlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzXCIpW1BST01JU0VdO1xyXG5cclxuLy8gc3RhdGljc1xyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCBQUk9NSVNFLCB7XHJcbiAgLy8gMjUuNC40LjUgUHJvbWlzZS5yZWplY3QocilcclxuICByZWplY3Q6IGZ1bmN0aW9uIHJlamVjdChyKXtcclxuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcylcclxuICAgICAgLCAkJHJlamVjdCAgID0gY2FwYWJpbGl0eS5yZWplY3Q7XHJcbiAgICAkJHJlamVjdChyKTtcclxuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XHJcbiAgfVxyXG59KTtcclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoTElCUkFSWSB8fCAhVVNFX05BVElWRSksIFBST01JU0UsIHtcclxuICAvLyAyNS40LjQuNiBQcm9taXNlLnJlc29sdmUoeClcclxuICByZXNvbHZlOiBmdW5jdGlvbiByZXNvbHZlKHgpe1xyXG4gICAgLy8gaW5zdGFuY2VvZiBpbnN0ZWFkIG9mIGludGVybmFsIHNsb3QgY2hlY2sgYmVjYXVzZSB3ZSBzaG91bGQgZml4IGl0IHdpdGhvdXQgcmVwbGFjZW1lbnQgbmF0aXZlIFByb21pc2UgY29yZVxyXG4gICAgaWYoeCBpbnN0YW5jZW9mICRQcm9taXNlICYmIHNhbWVDb25zdHJ1Y3Rvcih4LmNvbnN0cnVjdG9yLCB0aGlzKSlyZXR1cm4geDtcclxuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcylcclxuICAgICAgLCAkJHJlc29sdmUgID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xyXG4gICAgJCRyZXNvbHZlKHgpO1xyXG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcclxuICB9XHJcbn0pO1xyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEoVVNFX05BVElWRSAmJiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyLWRldGVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanNcIikoZnVuY3Rpb24oaXRlcil7XHJcbiAgJFByb21pc2UuYWxsKGl0ZXIpWydjYXRjaCddKGVtcHR5KTtcclxufSkpLCBQUk9NSVNFLCB7XHJcbiAgLy8gMjUuNC40LjEgUHJvbWlzZS5hbGwoaXRlcmFibGUpXHJcbiAgYWxsOiBmdW5jdGlvbiBhbGwoaXRlcmFibGUpe1xyXG4gICAgdmFyIEMgICAgICAgICAgPSB0aGlzXHJcbiAgICAgICwgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpXHJcbiAgICAgICwgcmVzb2x2ZSAgICA9IGNhcGFiaWxpdHkucmVzb2x2ZVxyXG4gICAgICAsIHJlamVjdCAgICAgPSBjYXBhYmlsaXR5LnJlamVjdDtcclxuICAgIHZhciBhYnJ1cHQgPSBwZXJmb3JtKGZ1bmN0aW9uKCl7XHJcbiAgICAgIHZhciB2YWx1ZXMgICAgPSBbXVxyXG4gICAgICAgICwgaW5kZXggICAgID0gMFxyXG4gICAgICAgICwgcmVtYWluaW5nID0gMTtcclxuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbihwcm9taXNlKXtcclxuICAgICAgICB2YXIgJGluZGV4ICAgICAgICA9IGluZGV4KytcclxuICAgICAgICAgICwgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xyXG4gICAgICAgIHZhbHVlcy5wdXNoKHVuZGVmaW5lZCk7XHJcbiAgICAgICAgcmVtYWluaW5nKys7XHJcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24odmFsdWUpe1xyXG4gICAgICAgICAgaWYoYWxyZWFkeUNhbGxlZClyZXR1cm47XHJcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkICA9IHRydWU7XHJcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xyXG4gICAgICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xyXG4gICAgICAgIH0sIHJlamVjdCk7XHJcbiAgICAgIH0pO1xyXG4gICAgICAtLXJlbWFpbmluZyB8fCByZXNvbHZlKHZhbHVlcyk7XHJcbiAgICB9KTtcclxuICAgIGlmKGFicnVwdClyZWplY3QoYWJydXB0LmVycm9yKTtcclxuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XHJcbiAgfSxcclxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXHJcbiAgcmFjZTogZnVuY3Rpb24gcmFjZShpdGVyYWJsZSl7XHJcbiAgICB2YXIgQyAgICAgICAgICA9IHRoaXNcclxuICAgICAgLCBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkoQylcclxuICAgICAgLCByZWplY3QgICAgID0gY2FwYWJpbGl0eS5yZWplY3Q7XHJcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xyXG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uKHByb21pc2Upe1xyXG4gICAgICAgIEMucmVzb2x2ZShwcm9taXNlKS50aGVuKGNhcGFiaWxpdHkucmVzb2x2ZSwgcmVqZWN0KTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIGlmKGFicnVwdClyZWplY3QoYWJydXB0LmVycm9yKTtcclxuICAgIHJldHVybiBjYXBhYmlsaXR5LnByb21pc2U7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuYXBwbHkuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuYXBwbHkuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyNi4xLjEgUmVmbGVjdC5hcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdClcclxudmFyICRleHBvcnQgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBhRnVuY3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKVxyXG4gICwgckFwcGx5ICAgID0gKF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpLlJlZmxlY3QgfHwge30pLmFwcGx5XHJcbiAgLCBmQXBwbHkgICAgPSBGdW5jdGlvbi5hcHBseTtcclxuLy8gTVMgRWRnZSBhcmd1bWVudHNMaXN0IGFyZ3VtZW50IGlzIG9wdGlvbmFsXHJcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIV9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKShmdW5jdGlvbigpe1xyXG4gIHJBcHBseShmdW5jdGlvbigpe30pO1xyXG59KSwgJ1JlZmxlY3QnLCB7XHJcbiAgYXBwbHk6IGZ1bmN0aW9uIGFwcGx5KHRhcmdldCwgdGhpc0FyZ3VtZW50LCBhcmd1bWVudHNMaXN0KXtcclxuICAgIHZhciBUID0gYUZ1bmN0aW9uKHRhcmdldClcclxuICAgICAgLCBMID0gYW5PYmplY3QoYXJndW1lbnRzTGlzdCk7XHJcbiAgICByZXR1cm4gckFwcGx5ID8gckFwcGx5KFQsIHRoaXNBcmd1bWVudCwgTCkgOiBmQXBwbHkuY2FsbChULCB0aGlzQXJndW1lbnQsIEwpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmNvbnN0cnVjdC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuY29uc3RydWN0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDI2LjEuMiBSZWZsZWN0LmNvbnN0cnVjdCh0YXJnZXQsIGFyZ3VtZW50c0xpc3QgWywgbmV3VGFyZ2V0XSlcclxudmFyICRleHBvcnQgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgY3JlYXRlICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1jcmVhdGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanNcIilcclxuICAsIGFGdW5jdGlvbiAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYW4tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcIilcclxuICAsIGlzT2JqZWN0ICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgZmFpbHMgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKVxyXG4gICwgYmluZCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2JpbmQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2JpbmQuanNcIilcclxuICAsIHJDb25zdHJ1Y3QgPSAoX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIikuUmVmbGVjdCB8fCB7fSkuY29uc3RydWN0O1xyXG5cclxuLy8gTVMgRWRnZSBzdXBwb3J0cyBvbmx5IDIgYXJndW1lbnRzIGFuZCBhcmd1bWVudHNMaXN0IGFyZ3VtZW50IGlzIG9wdGlvbmFsXHJcbi8vIEZGIE5pZ2h0bHkgc2V0cyB0aGlyZCBhcmd1bWVudCBhcyBgbmV3LnRhcmdldGAsIGJ1dCBkb2VzIG5vdCBjcmVhdGUgYHRoaXNgIGZyb20gaXRcclxudmFyIE5FV19UQVJHRVRfQlVHID0gZmFpbHMoZnVuY3Rpb24oKXtcclxuICBmdW5jdGlvbiBGKCl7fVxyXG4gIHJldHVybiAhKHJDb25zdHJ1Y3QoZnVuY3Rpb24oKXt9LCBbXSwgRikgaW5zdGFuY2VvZiBGKTtcclxufSk7XHJcbnZhciBBUkdTX0JVRyA9ICFmYWlscyhmdW5jdGlvbigpe1xyXG4gIHJDb25zdHJ1Y3QoZnVuY3Rpb24oKXt9KTtcclxufSk7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChORVdfVEFSR0VUX0JVRyB8fCBBUkdTX0JVRyksICdSZWZsZWN0Jywge1xyXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gY29uc3RydWN0KFRhcmdldCwgYXJncyAvKiwgbmV3VGFyZ2V0Ki8pe1xyXG4gICAgYUZ1bmN0aW9uKFRhcmdldCk7XHJcbiAgICBhbk9iamVjdChhcmdzKTtcclxuICAgIHZhciBuZXdUYXJnZXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IFRhcmdldCA6IGFGdW5jdGlvbihhcmd1bWVudHNbMl0pO1xyXG4gICAgaWYoQVJHU19CVUcgJiYgIU5FV19UQVJHRVRfQlVHKXJldHVybiByQ29uc3RydWN0KFRhcmdldCwgYXJncywgbmV3VGFyZ2V0KTtcclxuICAgIGlmKFRhcmdldCA9PSBuZXdUYXJnZXQpe1xyXG4gICAgICAvLyB3L28gYWx0ZXJlZCBuZXdUYXJnZXQsIG9wdGltaXphdGlvbiBmb3IgMC00IGFyZ3VtZW50c1xyXG4gICAgICBzd2l0Y2goYXJncy5sZW5ndGgpe1xyXG4gICAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBUYXJnZXQ7XHJcbiAgICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IFRhcmdldChhcmdzWzBdKTtcclxuICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0pO1xyXG4gICAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBUYXJnZXQoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XHJcbiAgICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IFRhcmdldChhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcclxuICAgICAgfVxyXG4gICAgICAvLyB3L28gYWx0ZXJlZCBuZXdUYXJnZXQsIGxvdCBvZiBhcmd1bWVudHMgY2FzZVxyXG4gICAgICB2YXIgJGFyZ3MgPSBbbnVsbF07XHJcbiAgICAgICRhcmdzLnB1c2guYXBwbHkoJGFyZ3MsIGFyZ3MpO1xyXG4gICAgICByZXR1cm4gbmV3IChiaW5kLmFwcGx5KFRhcmdldCwgJGFyZ3MpKTtcclxuICAgIH1cclxuICAgIC8vIHdpdGggYWx0ZXJlZCBuZXdUYXJnZXQsIG5vdCBzdXBwb3J0IGJ1aWx0LWluIGNvbnN0cnVjdG9yc1xyXG4gICAgdmFyIHByb3RvICAgID0gbmV3VGFyZ2V0LnByb3RvdHlwZVxyXG4gICAgICAsIGluc3RhbmNlID0gY3JlYXRlKGlzT2JqZWN0KHByb3RvKSA/IHByb3RvIDogT2JqZWN0LnByb3RvdHlwZSlcclxuICAgICAgLCByZXN1bHQgICA9IEZ1bmN0aW9uLmFwcGx5LmNhbGwoVGFyZ2V0LCBpbnN0YW5jZSwgYXJncyk7XHJcbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IGluc3RhbmNlO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlZmluZS1wcm9wZXJ0eS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVmaW5lLXByb3BlcnR5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDI2LjEuMyBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpXHJcbnZhciBkUCAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1kcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzXCIpXHJcbiAgLCAkZXhwb3J0ICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b1ByaW1pdGl2ZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLXByaW1pdGl2ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzXCIpO1xyXG5cclxuLy8gTVMgRWRnZSBoYXMgYnJva2VuIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkgLSB0aHJvd2luZyBpbnN0ZWFkIG9mIHJldHVybmluZyBmYWxzZVxyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qc1wiKShmdW5jdGlvbigpe1xyXG4gIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkoZFAuZih7fSwgMSwge3ZhbHVlOiAxfSksIDEsIHt2YWx1ZTogMn0pO1xyXG59KSwgJ1JlZmxlY3QnLCB7XHJcbiAgZGVmaW5lUHJvcGVydHk6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpe1xyXG4gICAgYW5PYmplY3QodGFyZ2V0KTtcclxuICAgIHByb3BlcnR5S2V5ID0gdG9QcmltaXRpdmUocHJvcGVydHlLZXksIHRydWUpO1xyXG4gICAgYW5PYmplY3QoYXR0cmlidXRlcyk7XHJcbiAgICB0cnkge1xyXG4gICAgICBkUC5mKHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpO1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0gY2F0Y2goZSl7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5kZWxldGUtcHJvcGVydHkuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlbGV0ZS1wcm9wZXJ0eS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyNi4xLjQgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5KVxyXG52YXIgJGV4cG9ydCAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgZ09QRCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ29wZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcGQuanNcIikuZlxyXG4gICwgYW5PYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcclxuICBkZWxldGVQcm9wZXJ0eTogZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSl7XHJcbiAgICB2YXIgZGVzYyA9IGdPUEQoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xyXG4gICAgcmV0dXJuIGRlc2MgJiYgIWRlc2MuY29uZmlndXJhYmxlID8gZmFsc2UgOiBkZWxldGUgdGFyZ2V0W3Byb3BlcnR5S2V5XTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5lbnVtZXJhdGUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmVudW1lcmF0ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIDI2LjEuNSBSZWZsZWN0LmVudW1lcmF0ZSh0YXJnZXQpXHJcbnZhciAkZXhwb3J0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBhbk9iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpO1xyXG52YXIgRW51bWVyYXRlID0gZnVuY3Rpb24oaXRlcmF0ZWQpe1xyXG4gIHRoaXMuX3QgPSBhbk9iamVjdChpdGVyYXRlZCk7IC8vIHRhcmdldFxyXG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcclxuICB2YXIga2V5cyA9IHRoaXMuX2sgPSBbXSAgICAgICAvLyBrZXlzXHJcbiAgICAsIGtleTtcclxuICBmb3Ioa2V5IGluIGl0ZXJhdGVkKWtleXMucHVzaChrZXkpO1xyXG59O1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyLWNyZWF0ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jcmVhdGUuanNcIikoRW51bWVyYXRlLCAnT2JqZWN0JywgZnVuY3Rpb24oKXtcclxuICB2YXIgdGhhdCA9IHRoaXNcclxuICAgICwga2V5cyA9IHRoYXQuX2tcclxuICAgICwga2V5O1xyXG4gIGRvIHtcclxuICAgIGlmKHRoYXQuX2kgPj0ga2V5cy5sZW5ndGgpcmV0dXJuIHt2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlfTtcclxuICB9IHdoaWxlKCEoKGtleSA9IGtleXNbdGhhdC5faSsrXSkgaW4gdGhhdC5fdCkpO1xyXG4gIHJldHVybiB7dmFsdWU6IGtleSwgZG9uZTogZmFsc2V9O1xyXG59KTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcclxuICBlbnVtZXJhdGU6IGZ1bmN0aW9uIGVudW1lcmF0ZSh0YXJnZXQpe1xyXG4gICAgcmV0dXJuIG5ldyBFbnVtZXJhdGUodGFyZ2V0KTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyNi4xLjcgUmVmbGVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSlcclxudmFyIGdPUEQgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcGQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzXCIpXHJcbiAgLCAkZXhwb3J0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBhbk9iamVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xyXG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpe1xyXG4gICAgcmV0dXJuIGdPUEQuZihhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LXByb3RvdHlwZS1vZi5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDI2LjEuOCBSZWZsZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldClcclxudmFyICRleHBvcnQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGdldFByb3RvID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdwbyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdwby5qc1wiKVxyXG4gICwgYW5PYmplY3QgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcclxuICBnZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KXtcclxuICAgIHJldHVybiBnZXRQcm90byhhbk9iamVjdCh0YXJnZXQpKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyNi4xLjYgUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSBbLCByZWNlaXZlcl0pXHJcbnZhciBnT1BEICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qc1wiKVxyXG4gICwgZ2V0UHJvdG90eXBlT2YgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ3BvICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzXCIpXHJcbiAgLCBoYXMgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgLCAkZXhwb3J0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBpc09iamVjdCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpO1xyXG5cclxuZnVuY3Rpb24gZ2V0KHRhcmdldCwgcHJvcGVydHlLZXkvKiwgcmVjZWl2ZXIqLyl7XHJcbiAgdmFyIHJlY2VpdmVyID0gYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB0YXJnZXQgOiBhcmd1bWVudHNbMl1cclxuICAgICwgZGVzYywgcHJvdG87XHJcbiAgaWYoYW5PYmplY3QodGFyZ2V0KSA9PT0gcmVjZWl2ZXIpcmV0dXJuIHRhcmdldFtwcm9wZXJ0eUtleV07XHJcbiAgaWYoZGVzYyA9IGdPUEQuZih0YXJnZXQsIHByb3BlcnR5S2V5KSlyZXR1cm4gaGFzKGRlc2MsICd2YWx1ZScpXHJcbiAgICA/IGRlc2MudmFsdWVcclxuICAgIDogZGVzYy5nZXQgIT09IHVuZGVmaW5lZFxyXG4gICAgICA/IGRlc2MuZ2V0LmNhbGwocmVjZWl2ZXIpXHJcbiAgICAgIDogdW5kZWZpbmVkO1xyXG4gIGlmKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpcmV0dXJuIGdldChwcm90bywgcHJvcGVydHlLZXksIHJlY2VpdmVyKTtcclxufVxyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge2dldDogZ2V0fSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0Lmhhcy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuaGFzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDI2LjEuOSBSZWZsZWN0Lmhhcyh0YXJnZXQsIHByb3BlcnR5S2V5KVxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xyXG4gIGhhczogZnVuY3Rpb24gaGFzKHRhcmdldCwgcHJvcGVydHlLZXkpe1xyXG4gICAgcmV0dXJuIHByb3BlcnR5S2V5IGluIHRhcmdldDtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5pcy1leHRlbnNpYmxlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuaXMtZXh0ZW5zaWJsZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjYuMS4xMCBSZWZsZWN0LmlzRXh0ZW5zaWJsZSh0YXJnZXQpXHJcbnZhciAkZXhwb3J0ICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGFuT2JqZWN0ICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKVxyXG4gICwgJGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XHJcbiAgaXNFeHRlbnNpYmxlOiBmdW5jdGlvbiBpc0V4dGVuc2libGUodGFyZ2V0KXtcclxuICAgIGFuT2JqZWN0KHRhcmdldCk7XHJcbiAgICByZXR1cm4gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUodGFyZ2V0KSA6IHRydWU7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyNi4xLjExIFJlZmxlY3Qub3duS2V5cyh0YXJnZXQpXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7b3duS2V5czogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb3duLWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX293bi1rZXlzLmpzXCIpfSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnByZXZlbnQtZXh0ZW5zaW9ucy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QucHJldmVudC1leHRlbnNpb25zLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDI2LjEuMTIgUmVmbGVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpXHJcbnZhciAkZXhwb3J0ICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgYW5PYmplY3QgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYW4tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcIilcclxuICAsICRwcmV2ZW50RXh0ZW5zaW9ucyA9IE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucztcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcclxuICBwcmV2ZW50RXh0ZW5zaW9uczogZnVuY3Rpb24gcHJldmVudEV4dGVuc2lvbnModGFyZ2V0KXtcclxuICAgIGFuT2JqZWN0KHRhcmdldCk7XHJcbiAgICB0cnkge1xyXG4gICAgICBpZigkcHJldmVudEV4dGVuc2lvbnMpJHByZXZlbnRFeHRlbnNpb25zKHRhcmdldCk7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSBjYXRjaChlKXtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC1wcm90b3R5cGUtb2YuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5zZXQtcHJvdG90eXBlLW9mLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyAyNi4xLjE0IFJlZmxlY3Quc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90bylcclxudmFyICRleHBvcnQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHNldFByb3RvID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2V0LXByb3RvICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtcHJvdG8uanNcIik7XHJcblxyXG5pZihzZXRQcm90bykkZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XHJcbiAgc2V0UHJvdG90eXBlT2Y6IGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKHRhcmdldCwgcHJvdG8pe1xyXG4gICAgc2V0UHJvdG8uY2hlY2sodGFyZ2V0LCBwcm90byk7XHJcbiAgICB0cnkge1xyXG4gICAgICBzZXRQcm90by5zZXQodGFyZ2V0LCBwcm90byk7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSBjYXRjaChlKXtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIDI2LjEuMTMgUmVmbGVjdC5zZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSwgViBbLCByZWNlaXZlcl0pXHJcbnZhciBkUCAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1kcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwLmpzXCIpXHJcbiAgLCBnT1BEICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qc1wiKVxyXG4gICwgZ2V0UHJvdG90eXBlT2YgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ3BvICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzXCIpXHJcbiAgLCBoYXMgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hhcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzXCIpXHJcbiAgLCAkZXhwb3J0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBjcmVhdGVEZXNjICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3Byb3BlcnR5LWRlc2MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb3BlcnR5LWRlc2MuanNcIilcclxuICAsIGFuT2JqZWN0ICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYW4tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcIilcclxuICAsIGlzT2JqZWN0ICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIik7XHJcblxyXG5mdW5jdGlvbiBzZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSwgVi8qLCByZWNlaXZlciovKXtcclxuICB2YXIgcmVjZWl2ZXIgPSBhcmd1bWVudHMubGVuZ3RoIDwgNCA/IHRhcmdldCA6IGFyZ3VtZW50c1szXVxyXG4gICAgLCBvd25EZXNjICA9IGdPUEQuZihhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSlcclxuICAgICwgZXhpc3RpbmdEZXNjcmlwdG9yLCBwcm90bztcclxuICBpZighb3duRGVzYyl7XHJcbiAgICBpZihpc09iamVjdChwcm90byA9IGdldFByb3RvdHlwZU9mKHRhcmdldCkpKXtcclxuICAgICAgcmV0dXJuIHNldChwcm90bywgcHJvcGVydHlLZXksIFYsIHJlY2VpdmVyKTtcclxuICAgIH1cclxuICAgIG93bkRlc2MgPSBjcmVhdGVEZXNjKDApO1xyXG4gIH1cclxuICBpZihoYXMob3duRGVzYywgJ3ZhbHVlJykpe1xyXG4gICAgaWYob3duRGVzYy53cml0YWJsZSA9PT0gZmFsc2UgfHwgIWlzT2JqZWN0KHJlY2VpdmVyKSlyZXR1cm4gZmFsc2U7XHJcbiAgICBleGlzdGluZ0Rlc2NyaXB0b3IgPSBnT1BELmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5KSB8fCBjcmVhdGVEZXNjKDApO1xyXG4gICAgZXhpc3RpbmdEZXNjcmlwdG9yLnZhbHVlID0gVjtcclxuICAgIGRQLmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5LCBleGlzdGluZ0Rlc2NyaXB0b3IpO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG4gIHJldHVybiBvd25EZXNjLnNldCA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiAob3duRGVzYy5zZXQuY2FsbChyZWNlaXZlciwgViksIHRydWUpO1xyXG59XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7c2V0OiBzZXR9KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5jb25zdHJ1Y3Rvci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuY29uc3RydWN0b3IuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBnbG9iYWwgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpXHJcbiAgLCBpbmhlcml0SWZSZXF1aXJlZCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2luaGVyaXQtaWYtcmVxdWlyZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanNcIilcclxuICAsIGRQICAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWRwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcIikuZlxyXG4gICwgZ09QTiAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ29wbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanNcIikuZlxyXG4gICwgaXNSZWdFeHAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1yZWdleHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLXJlZ2V4cC5qc1wiKVxyXG4gICwgJGZsYWdzICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mbGFncyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmxhZ3MuanNcIilcclxuICAsICRSZWdFeHAgICAgICAgICAgID0gZ2xvYmFsLlJlZ0V4cFxyXG4gICwgQmFzZSAgICAgICAgICAgICAgPSAkUmVnRXhwXHJcbiAgLCBwcm90byAgICAgICAgICAgICA9ICRSZWdFeHAucHJvdG90eXBlXHJcbiAgLCByZTEgICAgICAgICAgICAgICA9IC9hL2dcclxuICAsIHJlMiAgICAgICAgICAgICAgID0gL2EvZ1xyXG4gIC8vIFwibmV3XCIgY3JlYXRlcyBhIG5ldyBvYmplY3QsIG9sZCB3ZWJraXQgYnVnZ3kgaGVyZVxyXG4gICwgQ09SUkVDVF9ORVcgICAgICAgPSBuZXcgJFJlZ0V4cChyZTEpICE9PSByZTE7XHJcblxyXG5pZihfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZXNjcmlwdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanNcIikgJiYgKCFDT1JSRUNUX05FVyB8fCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIikoZnVuY3Rpb24oKXtcclxuICByZTJbX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fd2tzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MuanNcIikoJ21hdGNoJyldID0gZmFsc2U7XHJcbiAgLy8gUmVnRXhwIGNvbnN0cnVjdG9yIGNhbiBhbHRlciBmbGFncyBhbmQgSXNSZWdFeHAgd29ya3MgY29ycmVjdCB3aXRoIEBAbWF0Y2hcclxuICByZXR1cm4gJFJlZ0V4cChyZTEpICE9IHJlMSB8fCAkUmVnRXhwKHJlMikgPT0gcmUyIHx8ICRSZWdFeHAocmUxLCAnaScpICE9ICcvYS9pJztcclxufSkpKXtcclxuICAkUmVnRXhwID0gZnVuY3Rpb24gUmVnRXhwKHAsIGYpe1xyXG4gICAgdmFyIHRpUkUgPSB0aGlzIGluc3RhbmNlb2YgJFJlZ0V4cFxyXG4gICAgICAsIHBpUkUgPSBpc1JlZ0V4cChwKVxyXG4gICAgICAsIGZpVSAgPSBmID09PSB1bmRlZmluZWQ7XHJcbiAgICByZXR1cm4gIXRpUkUgJiYgcGlSRSAmJiBwLmNvbnN0cnVjdG9yID09PSAkUmVnRXhwICYmIGZpVSA/IHBcclxuICAgICAgOiBpbmhlcml0SWZSZXF1aXJlZChDT1JSRUNUX05FV1xyXG4gICAgICAgID8gbmV3IEJhc2UocGlSRSAmJiAhZmlVID8gcC5zb3VyY2UgOiBwLCBmKVxyXG4gICAgICAgIDogQmFzZSgocGlSRSA9IHAgaW5zdGFuY2VvZiAkUmVnRXhwKSA/IHAuc291cmNlIDogcCwgcGlSRSAmJiBmaVUgPyAkZmxhZ3MuY2FsbChwKSA6IGYpXHJcbiAgICAgICwgdGlSRSA/IHRoaXMgOiBwcm90bywgJFJlZ0V4cCk7XHJcbiAgfTtcclxuICB2YXIgcHJveHkgPSBmdW5jdGlvbihrZXkpe1xyXG4gICAga2V5IGluICRSZWdFeHAgfHwgZFAoJFJlZ0V4cCwga2V5LCB7XHJcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcclxuICAgICAgZ2V0OiBmdW5jdGlvbigpeyByZXR1cm4gQmFzZVtrZXldOyB9LFxyXG4gICAgICBzZXQ6IGZ1bmN0aW9uKGl0KXsgQmFzZVtrZXldID0gaXQ7IH1cclxuICAgIH0pO1xyXG4gIH07XHJcbiAgZm9yKHZhciBrZXlzID0gZ09QTihCYXNlKSwgaSA9IDA7IGtleXMubGVuZ3RoID4gaTsgKXByb3h5KGtleXNbaSsrXSk7XHJcbiAgcHJvdG8uY29uc3RydWN0b3IgPSAkUmVnRXhwO1xyXG4gICRSZWdFeHAucHJvdG90eXBlID0gcHJvdG87XHJcbiAgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXCIpKGdsb2JhbCwgJ1JlZ0V4cCcsICRSZWdFeHApO1xyXG59XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zZXQtc3BlY2llcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanNcIikoJ1JlZ0V4cCcpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLmZsYWdzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5mbGFncy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gMjEuMi41LjMgZ2V0IFJlZ0V4cC5wcm90b3R5cGUuZmxhZ3MoKVxyXG5pZihfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZXNjcmlwdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanNcIikgJiYgLy4vZy5mbGFncyAhPSAnZycpX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWRwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanNcIikuZihSZWdFeHAucHJvdG90eXBlLCAnZmxhZ3MnLCB7XHJcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxyXG4gIGdldDogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmxhZ3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZsYWdzLmpzXCIpXHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLm1hdGNoLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5tYXRjaC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gQEBtYXRjaCBsb2dpY1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19maXgtcmUtd2tzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19maXgtcmUtd2tzLmpzXCIpKCdtYXRjaCcsIDEsIGZ1bmN0aW9uKGRlZmluZWQsIE1BVENILCAkbWF0Y2gpe1xyXG4gIC8vIDIxLjEuMy4xMSBTdHJpbmcucHJvdG90eXBlLm1hdGNoKHJlZ2V4cClcclxuICByZXR1cm4gW2Z1bmN0aW9uIG1hdGNoKHJlZ2V4cCl7XHJcbiAgICAndXNlIHN0cmljdCc7XHJcbiAgICB2YXIgTyAgPSBkZWZpbmVkKHRoaXMpXHJcbiAgICAgICwgZm4gPSByZWdleHAgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcmVnZXhwW01BVENIXTtcclxuICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW01BVENIXShTdHJpbmcoTykpO1xyXG4gIH0sICRtYXRjaF07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnJlcGxhY2UuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAucmVwbGFjZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBAQHJlcGxhY2UgbG9naWNcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZml4LXJlLXdrcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZml4LXJlLXdrcy5qc1wiKSgncmVwbGFjZScsIDIsIGZ1bmN0aW9uKGRlZmluZWQsIFJFUExBQ0UsICRyZXBsYWNlKXtcclxuICAvLyAyMS4xLjMuMTQgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpXHJcbiAgcmV0dXJuIFtmdW5jdGlvbiByZXBsYWNlKHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpe1xyXG4gICAgJ3VzZSBzdHJpY3QnO1xyXG4gICAgdmFyIE8gID0gZGVmaW5lZCh0aGlzKVxyXG4gICAgICAsIGZuID0gc2VhcmNoVmFsdWUgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogc2VhcmNoVmFsdWVbUkVQTEFDRV07XHJcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZFxyXG4gICAgICA/IGZuLmNhbGwoc2VhcmNoVmFsdWUsIE8sIHJlcGxhY2VWYWx1ZSlcclxuICAgICAgOiAkcmVwbGFjZS5jYWxsKFN0cmluZyhPKSwgc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSk7XHJcbiAgfSwgJHJlcGxhY2VdO1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5zZWFyY2guanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5zZWFyY2guanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBAQHNlYXJjaCBsb2dpY1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19maXgtcmUtd2tzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19maXgtcmUtd2tzLmpzXCIpKCdzZWFyY2gnLCAxLCBmdW5jdGlvbihkZWZpbmVkLCBTRUFSQ0gsICRzZWFyY2gpe1xyXG4gIC8vIDIxLjEuMy4xNSBTdHJpbmcucHJvdG90eXBlLnNlYXJjaChyZWdleHApXHJcbiAgcmV0dXJuIFtmdW5jdGlvbiBzZWFyY2gocmVnZXhwKXtcclxuICAgICd1c2Ugc3RyaWN0JztcclxuICAgIHZhciBPICA9IGRlZmluZWQodGhpcylcclxuICAgICAgLCBmbiA9IHJlZ2V4cCA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZWdleHBbU0VBUkNIXTtcclxuICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW1NFQVJDSF0oU3RyaW5nKE8pKTtcclxuICB9LCAkc2VhcmNoXTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuc3BsaXQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnNwbGl0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBAQHNwbGl0IGxvZ2ljXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZpeC1yZS13a3MgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZpeC1yZS13a3MuanNcIikoJ3NwbGl0JywgMiwgZnVuY3Rpb24oZGVmaW5lZCwgU1BMSVQsICRzcGxpdCl7XHJcbiAgJ3VzZSBzdHJpY3QnO1xyXG4gIHZhciBpc1JlZ0V4cCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtcmVnZXhwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1yZWdleHAuanNcIilcclxuICAgICwgX3NwbGl0ICAgICA9ICRzcGxpdFxyXG4gICAgLCAkcHVzaCAgICAgID0gW10ucHVzaFxyXG4gICAgLCAkU1BMSVQgICAgID0gJ3NwbGl0J1xyXG4gICAgLCBMRU5HVEggICAgID0gJ2xlbmd0aCdcclxuICAgICwgTEFTVF9JTkRFWCA9ICdsYXN0SW5kZXgnO1xyXG4gIGlmKFxyXG4gICAgJ2FiYmMnWyRTUExJVF0oLyhiKSovKVsxXSA9PSAnYycgfHxcclxuICAgICd0ZXN0J1skU1BMSVRdKC8oPzopLywgLTEpW0xFTkdUSF0gIT0gNCB8fFxyXG4gICAgJ2FiJ1skU1BMSVRdKC8oPzphYikqLylbTEVOR1RIXSAhPSAyIHx8XHJcbiAgICAnLidbJFNQTElUXSgvKC4/KSguPykvKVtMRU5HVEhdICE9IDQgfHxcclxuICAgICcuJ1skU1BMSVRdKC8oKSgpLylbTEVOR1RIXSA+IDEgfHxcclxuICAgICcnWyRTUExJVF0oLy4/LylbTEVOR1RIXVxyXG4gICl7XHJcbiAgICB2YXIgTlBDRyA9IC8oKT8/Ly5leGVjKCcnKVsxXSA9PT0gdW5kZWZpbmVkOyAvLyBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cFxyXG4gICAgLy8gYmFzZWQgb24gZXM1LXNoaW0gaW1wbGVtZW50YXRpb24sIG5lZWQgdG8gcmV3b3JrIGl0XHJcbiAgICAkc3BsaXQgPSBmdW5jdGlvbihzZXBhcmF0b3IsIGxpbWl0KXtcclxuICAgICAgdmFyIHN0cmluZyA9IFN0cmluZyh0aGlzKTtcclxuICAgICAgaWYoc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDApcmV0dXJuIFtdO1xyXG4gICAgICAvLyBJZiBgc2VwYXJhdG9yYCBpcyBub3QgYSByZWdleCwgdXNlIG5hdGl2ZSBzcGxpdFxyXG4gICAgICBpZighaXNSZWdFeHAoc2VwYXJhdG9yKSlyZXR1cm4gX3NwbGl0LmNhbGwoc3RyaW5nLCBzZXBhcmF0b3IsIGxpbWl0KTtcclxuICAgICAgdmFyIG91dHB1dCA9IFtdO1xyXG4gICAgICB2YXIgZmxhZ3MgPSAoc2VwYXJhdG9yLmlnbm9yZUNhc2UgPyAnaScgOiAnJykgK1xyXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLm11bHRpbGluZSA/ICdtJyA6ICcnKSArXHJcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArXHJcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3Iuc3RpY2t5ID8gJ3knIDogJycpO1xyXG4gICAgICB2YXIgbGFzdExhc3RJbmRleCA9IDA7XHJcbiAgICAgIHZhciBzcGxpdExpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IDQyOTQ5NjcyOTUgOiBsaW1pdCA+Pj4gMDtcclxuICAgICAgLy8gTWFrZSBgZ2xvYmFsYCBhbmQgYXZvaWQgYGxhc3RJbmRleGAgaXNzdWVzIGJ5IHdvcmtpbmcgd2l0aCBhIGNvcHlcclxuICAgICAgdmFyIHNlcGFyYXRvckNvcHkgPSBuZXcgUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIGZsYWdzICsgJ2cnKTtcclxuICAgICAgdmFyIHNlcGFyYXRvcjIsIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGgsIGk7XHJcbiAgICAgIC8vIERvZXNuJ3QgbmVlZCBmbGFncyBneSwgYnV0IHRoZXkgZG9uJ3QgaHVydFxyXG4gICAgICBpZighTlBDRylzZXBhcmF0b3IyID0gbmV3IFJlZ0V4cCgnXicgKyBzZXBhcmF0b3JDb3B5LnNvdXJjZSArICckKD8hXFxcXHMpJywgZmxhZ3MpO1xyXG4gICAgICB3aGlsZShtYXRjaCA9IHNlcGFyYXRvckNvcHkuZXhlYyhzdHJpbmcpKXtcclxuICAgICAgICAvLyBgc2VwYXJhdG9yQ29weS5sYXN0SW5kZXhgIGlzIG5vdCByZWxpYWJsZSBjcm9zcy1icm93c2VyXHJcbiAgICAgICAgbGFzdEluZGV4ID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXVtMRU5HVEhdO1xyXG4gICAgICAgIGlmKGxhc3RJbmRleCA+IGxhc3RMYXN0SW5kZXgpe1xyXG4gICAgICAgICAgb3V0cHV0LnB1c2goc3RyaW5nLnNsaWNlKGxhc3RMYXN0SW5kZXgsIG1hdGNoLmluZGV4KSk7XHJcbiAgICAgICAgICAvLyBGaXggYnJvd3NlcnMgd2hvc2UgYGV4ZWNgIG1ldGhvZHMgZG9uJ3QgY29uc2lzdGVudGx5IHJldHVybiBgdW5kZWZpbmVkYCBmb3IgTlBDR1xyXG4gICAgICAgICAgaWYoIU5QQ0cgJiYgbWF0Y2hbTEVOR1RIXSA+IDEpbWF0Y2hbMF0ucmVwbGFjZShzZXBhcmF0b3IyLCBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICBmb3IoaSA9IDE7IGkgPCBhcmd1bWVudHNbTEVOR1RIXSAtIDI7IGkrKylpZihhcmd1bWVudHNbaV0gPT09IHVuZGVmaW5lZCltYXRjaFtpXSA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgaWYobWF0Y2hbTEVOR1RIXSA+IDEgJiYgbWF0Y2guaW5kZXggPCBzdHJpbmdbTEVOR1RIXSkkcHVzaC5hcHBseShvdXRwdXQsIG1hdGNoLnNsaWNlKDEpKTtcclxuICAgICAgICAgIGxhc3RMZW5ndGggPSBtYXRjaFswXVtMRU5HVEhdO1xyXG4gICAgICAgICAgbGFzdExhc3RJbmRleCA9IGxhc3RJbmRleDtcclxuICAgICAgICAgIGlmKG91dHB1dFtMRU5HVEhdID49IHNwbGl0TGltaXQpYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKHNlcGFyYXRvckNvcHlbTEFTVF9JTkRFWF0gPT09IG1hdGNoLmluZGV4KXNlcGFyYXRvckNvcHlbTEFTVF9JTkRFWF0rKzsgLy8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcFxyXG4gICAgICB9XHJcbiAgICAgIGlmKGxhc3RMYXN0SW5kZXggPT09IHN0cmluZ1tMRU5HVEhdKXtcclxuICAgICAgICBpZihsYXN0TGVuZ3RoIHx8ICFzZXBhcmF0b3JDb3B5LnRlc3QoJycpKW91dHB1dC5wdXNoKCcnKTtcclxuICAgICAgfSBlbHNlIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4KSk7XHJcbiAgICAgIHJldHVybiBvdXRwdXRbTEVOR1RIXSA+IHNwbGl0TGltaXQgPyBvdXRwdXQuc2xpY2UoMCwgc3BsaXRMaW1pdCkgOiBvdXRwdXQ7XHJcbiAgICB9O1xyXG4gIC8vIENoYWtyYSwgVjhcclxuICB9IGVsc2UgaWYoJzAnWyRTUExJVF0odW5kZWZpbmVkLCAwKVtMRU5HVEhdKXtcclxuICAgICRzcGxpdCA9IGZ1bmN0aW9uKHNlcGFyYXRvciwgbGltaXQpe1xyXG4gICAgICByZXR1cm4gc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDAgPyBbXSA6IF9zcGxpdC5jYWxsKHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xyXG4gICAgfTtcclxuICB9XHJcbiAgLy8gMjEuMS4zLjE3IFN0cmluZy5wcm90b3R5cGUuc3BsaXQoc2VwYXJhdG9yLCBsaW1pdClcclxuICByZXR1cm4gW2Z1bmN0aW9uIHNwbGl0KHNlcGFyYXRvciwgbGltaXQpe1xyXG4gICAgdmFyIE8gID0gZGVmaW5lZCh0aGlzKVxyXG4gICAgICAsIGZuID0gc2VwYXJhdG9yID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNlcGFyYXRvcltTUExJVF07XHJcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZCA/IGZuLmNhbGwoc2VwYXJhdG9yLCBPLCBsaW1pdCkgOiAkc3BsaXQuY2FsbChTdHJpbmcoTyksIHNlcGFyYXRvciwgbGltaXQpO1xyXG4gIH0sICRzcGxpdF07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnRvLXN0cmluZy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnRvLXN0cmluZy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9lczYucmVnZXhwLmZsYWdzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuZmxhZ3MuanNcIik7XHJcbnZhciBhbk9iamVjdCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCAkZmxhZ3MgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZsYWdzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mbGFncy5qc1wiKVxyXG4gICwgREVTQ1JJUFRPUlMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZXNjcmlwdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanNcIilcclxuICAsIFRPX1NUUklORyAgID0gJ3RvU3RyaW5nJ1xyXG4gICwgJHRvU3RyaW5nICAgPSAvLi9bVE9fU1RSSU5HXTtcclxuXHJcbnZhciBkZWZpbmUgPSBmdW5jdGlvbihmbil7XHJcbiAgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXCIpKFJlZ0V4cC5wcm90b3R5cGUsIFRPX1NUUklORywgZm4sIHRydWUpO1xyXG59O1xyXG5cclxuLy8gMjEuMi41LjE0IFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcoKVxyXG5pZihfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIikoZnVuY3Rpb24oKXsgcmV0dXJuICR0b1N0cmluZy5jYWxsKHtzb3VyY2U6ICdhJywgZmxhZ3M6ICdiJ30pICE9ICcvYS9iJzsgfSkpe1xyXG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpe1xyXG4gICAgdmFyIFIgPSBhbk9iamVjdCh0aGlzKTtcclxuICAgIHJldHVybiAnLycuY29uY2F0KFIuc291cmNlLCAnLycsXHJcbiAgICAgICdmbGFncycgaW4gUiA/IFIuZmxhZ3MgOiAhREVTQ1JJUFRPUlMgJiYgUiBpbnN0YW5jZW9mIFJlZ0V4cCA/ICRmbGFncy5jYWxsKFIpIDogdW5kZWZpbmVkKTtcclxuICB9KTtcclxuLy8gRkY0NC0gUmVnRXhwI3RvU3RyaW5nIGhhcyBhIHdyb25nIG5hbWVcclxufSBlbHNlIGlmKCR0b1N0cmluZy5uYW1lICE9IFRPX1NUUklORyl7XHJcbiAgZGVmaW5lKGZ1bmN0aW9uIHRvU3RyaW5nKCl7XHJcbiAgICByZXR1cm4gJHRvU3RyaW5nLmNhbGwodGhpcyk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnNldC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zZXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyIHN0cm9uZyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvbGxlY3Rpb24tc3Ryb25nICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qc1wiKTtcclxuXHJcbi8vIDIzLjIgU2V0IE9iamVjdHNcclxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb2xsZWN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLmpzXCIpKCdTZXQnLCBmdW5jdGlvbihnZXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBTZXQoKXsgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7IH07XHJcbn0sIHtcclxuICAvLyAyMy4yLjMuMSBTZXQucHJvdG90eXBlLmFkZCh2YWx1ZSlcclxuICBhZGQ6IGZ1bmN0aW9uIGFkZCh2YWx1ZSl7XHJcbiAgICByZXR1cm4gc3Ryb25nLmRlZih0aGlzLCB2YWx1ZSA9IHZhbHVlID09PSAwID8gMCA6IHZhbHVlLCB2YWx1ZSk7XHJcbiAgfVxyXG59LCBzdHJvbmcpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gQi4yLjMuMiBTdHJpbmcucHJvdG90eXBlLmFuY2hvcihuYW1lKVxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctaHRtbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanNcIikoJ2FuY2hvcicsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBhbmNob3IobmFtZSl7XHJcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYScsICduYW1lJywgbmFtZSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5iaWcuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5iaWcuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIEIuMi4zLjMgU3RyaW5nLnByb3RvdHlwZS5iaWcoKVxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctaHRtbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanNcIikoJ2JpZycsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBiaWcoKXtcclxuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdiaWcnLCAnJywgJycpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuYmxpbmsuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJsaW5rLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIEIuMi4zLjQgU3RyaW5nLnByb3RvdHlwZS5ibGluaygpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnYmxpbmsnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcclxuICByZXR1cm4gZnVuY3Rpb24gYmxpbmsoKXtcclxuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdibGluaycsICcnLCAnJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5ib2xkLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJvbGQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyBCLjIuMy41IFN0cmluZy5wcm90b3R5cGUuYm9sZCgpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnYm9sZCcsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBib2xkKCl7XHJcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYicsICcnLCAnJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5jb2RlLXBvaW50LWF0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmNvZGUtcG9pbnQtYXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkYXQgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLWF0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctYXQuanNcIikoZmFsc2UpO1xyXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcclxuICAvLyAyMS4xLjMuMyBTdHJpbmcucHJvdG90eXBlLmNvZGVQb2ludEF0KHBvcylcclxuICBjb2RlUG9pbnRBdDogZnVuY3Rpb24gY29kZVBvaW50QXQocG9zKXtcclxuICAgIHJldHVybiAkYXQodGhpcywgcG9zKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmVuZHMtd2l0aC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmVuZHMtd2l0aC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG4vLyAyMS4xLjMuNiBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKHNlYXJjaFN0cmluZyBbLCBlbmRQb3NpdGlvbl0pXHJcblxyXG52YXIgJGV4cG9ydCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHRvTGVuZ3RoICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWxlbmd0aCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzXCIpXHJcbiAgLCBjb250ZXh0ICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctY29udGV4dCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWNvbnRleHQuanNcIilcclxuICAsIEVORFNfV0lUSCA9ICdlbmRzV2l0aCdcclxuICAsICRlbmRzV2l0aCA9ICcnW0VORFNfV0lUSF07XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzLWlzLXJlZ2V4cCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMtaXMtcmVnZXhwLmpzXCIpKEVORFNfV0lUSCksICdTdHJpbmcnLCB7XHJcbiAgZW5kc1dpdGg6IGZ1bmN0aW9uIGVuZHNXaXRoKHNlYXJjaFN0cmluZyAvKiwgZW5kUG9zaXRpb24gPSBAbGVuZ3RoICovKXtcclxuICAgIHZhciB0aGF0ID0gY29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIEVORFNfV0lUSClcclxuICAgICAgLCBlbmRQb3NpdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkXHJcbiAgICAgICwgbGVuICAgID0gdG9MZW5ndGgodGhhdC5sZW5ndGgpXHJcbiAgICAgICwgZW5kICAgID0gZW5kUG9zaXRpb24gPT09IHVuZGVmaW5lZCA/IGxlbiA6IE1hdGgubWluKHRvTGVuZ3RoKGVuZFBvc2l0aW9uKSwgbGVuKVxyXG4gICAgICAsIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hTdHJpbmcpO1xyXG4gICAgcmV0dXJuICRlbmRzV2l0aFxyXG4gICAgICA/ICRlbmRzV2l0aC5jYWxsKHRoYXQsIHNlYXJjaCwgZW5kKVxyXG4gICAgICA6IHRoYXQuc2xpY2UoZW5kIC0gc2VhcmNoLmxlbmd0aCwgZW5kKSA9PT0gc2VhcmNoO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZpeGVkLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIEIuMi4zLjYgU3RyaW5nLnByb3RvdHlwZS5maXhlZCgpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnZml4ZWQnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcclxuICByZXR1cm4gZnVuY3Rpb24gZml4ZWQoKXtcclxuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICd0dCcsICcnLCAnJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3IuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3IuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIEIuMi4zLjcgU3RyaW5nLnByb3RvdHlwZS5mb250Y29sb3IoY29sb3IpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnZm9udGNvbG9yJywgZnVuY3Rpb24oY3JlYXRlSFRNTCl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbnRjb2xvcihjb2xvcil7XHJcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnZm9udCcsICdjb2xvcicsIGNvbG9yKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRzaXplLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5mb250c2l6ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyBCLjIuMy44IFN0cmluZy5wcm90b3R5cGUuZm9udHNpemUoc2l6ZSlcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLWh0bWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1odG1sLmpzXCIpKCdmb250c2l6ZScsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBmb250c2l6ZShzaXplKXtcclxuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdmb250JywgJ3NpemUnLCBzaXplKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZyb20tY29kZS1wb2ludC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZyb20tY29kZS1wb2ludC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciAkZXhwb3J0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCB0b0luZGV4ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWluZGV4ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qc1wiKVxyXG4gICwgZnJvbUNoYXJDb2RlICAgPSBTdHJpbmcuZnJvbUNoYXJDb2RlXHJcbiAgLCAkZnJvbUNvZGVQb2ludCA9IFN0cmluZy5mcm9tQ29kZVBvaW50O1xyXG5cclxuLy8gbGVuZ3RoIHNob3VsZCBiZSAxLCBvbGQgRkYgcHJvYmxlbVxyXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICghISRmcm9tQ29kZVBvaW50ICYmICRmcm9tQ29kZVBvaW50Lmxlbmd0aCAhPSAxKSwgJ1N0cmluZycsIHtcclxuICAvLyAyMS4xLjIuMiBTdHJpbmcuZnJvbUNvZGVQb2ludCguLi5jb2RlUG9pbnRzKVxyXG4gIGZyb21Db2RlUG9pbnQ6IGZ1bmN0aW9uIGZyb21Db2RlUG9pbnQoeCl7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcclxuICAgIHZhciByZXMgID0gW11cclxuICAgICAgLCBhTGVuID0gYXJndW1lbnRzLmxlbmd0aFxyXG4gICAgICAsIGkgICAgPSAwXHJcbiAgICAgICwgY29kZTtcclxuICAgIHdoaWxlKGFMZW4gPiBpKXtcclxuICAgICAgY29kZSA9ICthcmd1bWVudHNbaSsrXTtcclxuICAgICAgaWYodG9JbmRleChjb2RlLCAweDEwZmZmZikgIT09IGNvZGUpdGhyb3cgUmFuZ2VFcnJvcihjb2RlICsgJyBpcyBub3QgYSB2YWxpZCBjb2RlIHBvaW50Jyk7XHJcbiAgICAgIHJlcy5wdXNoKGNvZGUgPCAweDEwMDAwXHJcbiAgICAgICAgPyBmcm9tQ2hhckNvZGUoY29kZSlcclxuICAgICAgICA6IGZyb21DaGFyQ29kZSgoKGNvZGUgLT0gMHgxMDAwMCkgPj4gMTApICsgMHhkODAwLCBjb2RlICUgMHg0MDAgKyAweGRjMDApXHJcbiAgICAgICk7XHJcbiAgICB9IHJldHVybiByZXMuam9pbignJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pbmNsdWRlcy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaW5jbHVkZXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG4vLyAyMS4xLjMuNyBTdHJpbmcucHJvdG90eXBlLmluY2x1ZGVzKHNlYXJjaFN0cmluZywgcG9zaXRpb24gPSAwKVxyXG5cclxudmFyICRleHBvcnQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGNvbnRleHQgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLWNvbnRleHQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1jb250ZXh0LmpzXCIpXHJcbiAgLCBJTkNMVURFUyA9ICdpbmNsdWRlcyc7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzLWlzLXJlZ2V4cCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMtaXMtcmVnZXhwLmpzXCIpKElOQ0xVREVTKSwgJ1N0cmluZycsIHtcclxuICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoc2VhcmNoU3RyaW5nIC8qLCBwb3NpdGlvbiA9IDAgKi8pe1xyXG4gICAgcmV0dXJuICEhfmNvbnRleHQodGhpcywgc2VhcmNoU3RyaW5nLCBJTkNMVURFUylcclxuICAgICAgLmluZGV4T2Yoc2VhcmNoU3RyaW5nLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGFsaWNzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0YWxpY3MuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyBCLjIuMy45IFN0cmluZy5wcm90b3R5cGUuaXRhbGljcygpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnaXRhbGljcycsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBpdGFsaWNzKCl7XHJcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnaScsICcnLCAnJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvci5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxudmFyICRhdCAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctYXQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qc1wiKSh0cnVlKTtcclxuXHJcbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXRlci1kZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGVmaW5lLmpzXCIpKFN0cmluZywgJ1N0cmluZycsIGZ1bmN0aW9uKGl0ZXJhdGVkKXtcclxuICB0aGlzLl90ID0gU3RyaW5nKGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XHJcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcclxuLy8gMjEuMS41LjIuMSAlU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlLm5leHQoKVxyXG59LCBmdW5jdGlvbigpe1xyXG4gIHZhciBPICAgICA9IHRoaXMuX3RcclxuICAgICwgaW5kZXggPSB0aGlzLl9pXHJcbiAgICAsIHBvaW50O1xyXG4gIGlmKGluZGV4ID49IE8ubGVuZ3RoKXJldHVybiB7dmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZX07XHJcbiAgcG9pbnQgPSAkYXQoTywgaW5kZXgpO1xyXG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xyXG4gIHJldHVybiB7dmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZX07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmxpbmsuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcubGluay5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIEIuMi4zLjEwIFN0cmluZy5wcm90b3R5cGUubGluayh1cmwpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnbGluaycsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBsaW5rKHVybCl7XHJcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYScsICdocmVmJywgdXJsKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnJhdy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnJhdy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciAkZXhwb3J0ICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgdG9JT2JqZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8taW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qc1wiKVxyXG4gICwgdG9MZW5ndGggID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ1N0cmluZycsIHtcclxuICAvLyAyMS4xLjIuNCBTdHJpbmcucmF3KGNhbGxTaXRlLCAuLi5zdWJzdGl0dXRpb25zKVxyXG4gIHJhdzogZnVuY3Rpb24gcmF3KGNhbGxTaXRlKXtcclxuICAgIHZhciB0cGwgID0gdG9JT2JqZWN0KGNhbGxTaXRlLnJhdylcclxuICAgICAgLCBsZW4gID0gdG9MZW5ndGgodHBsLmxlbmd0aClcclxuICAgICAgLCBhTGVuID0gYXJndW1lbnRzLmxlbmd0aFxyXG4gICAgICAsIHJlcyAgPSBbXVxyXG4gICAgICAsIGkgICAgPSAwO1xyXG4gICAgd2hpbGUobGVuID4gaSl7XHJcbiAgICAgIHJlcy5wdXNoKFN0cmluZyh0cGxbaSsrXSkpO1xyXG4gICAgICBpZihpIDwgYUxlbilyZXMucHVzaChTdHJpbmcoYXJndW1lbnRzW2ldKSk7XHJcbiAgICB9IHJldHVybiByZXMuam9pbignJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5yZXBlYXQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5yZXBlYXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAsICdTdHJpbmcnLCB7XHJcbiAgLy8gMjEuMS4zLjEzIFN0cmluZy5wcm90b3R5cGUucmVwZWF0KGNvdW50KVxyXG4gIHJlcGVhdDogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLXJlcGVhdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLXJlcGVhdC5qc1wiKVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zbWFsbC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc21hbGwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gQi4yLjMuMTEgU3RyaW5nLnByb3RvdHlwZS5zbWFsbCgpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnc21hbGwnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcclxuICByZXR1cm4gZnVuY3Rpb24gc21hbGwoKXtcclxuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzbWFsbCcsICcnLCAnJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdGFydHMtd2l0aC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3RhcnRzLXdpdGguanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG4vLyAyMS4xLjMuMTggU3RyaW5nLnByb3RvdHlwZS5zdGFydHNXaXRoKHNlYXJjaFN0cmluZyBbLCBwb3NpdGlvbiBdKVxyXG5cclxudmFyICRleHBvcnQgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHRvTGVuZ3RoICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tbGVuZ3RoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanNcIilcclxuICAsIGNvbnRleHQgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLWNvbnRleHQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1jb250ZXh0LmpzXCIpXHJcbiAgLCBTVEFSVFNfV0lUSCA9ICdzdGFydHNXaXRoJ1xyXG4gICwgJHN0YXJ0c1dpdGggPSAnJ1tTVEFSVFNfV0lUSF07XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZhaWxzLWlzLXJlZ2V4cCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMtaXMtcmVnZXhwLmpzXCIpKFNUQVJUU19XSVRIKSwgJ1N0cmluZycsIHtcclxuICBzdGFydHNXaXRoOiBmdW5jdGlvbiBzdGFydHNXaXRoKHNlYXJjaFN0cmluZyAvKiwgcG9zaXRpb24gPSAwICovKXtcclxuICAgIHZhciB0aGF0ICAgPSBjb250ZXh0KHRoaXMsIHNlYXJjaFN0cmluZywgU1RBUlRTX1dJVEgpXHJcbiAgICAgICwgaW5kZXggID0gdG9MZW5ndGgoTWF0aC5taW4oYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIHRoYXQubGVuZ3RoKSlcclxuICAgICAgLCBzZWFyY2ggPSBTdHJpbmcoc2VhcmNoU3RyaW5nKTtcclxuICAgIHJldHVybiAkc3RhcnRzV2l0aFxyXG4gICAgICA/ICRzdGFydHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBpbmRleClcclxuICAgICAgOiB0aGF0LnNsaWNlKGluZGV4LCBpbmRleCArIHNlYXJjaC5sZW5ndGgpID09PSBzZWFyY2g7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIEIuMi4zLjEyIFN0cmluZy5wcm90b3R5cGUuc3RyaWtlKClcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLWh0bWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1odG1sLmpzXCIpKCdzdHJpa2UnLCBmdW5jdGlvbihjcmVhdGVIVE1MKXtcclxuICByZXR1cm4gZnVuY3Rpb24gc3RyaWtlKCl7XHJcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3RyaWtlJywgJycsICcnKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN1Yi5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN1Yi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gQi4yLjMuMTMgU3RyaW5nLnByb3RvdHlwZS5zdWIoKVxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctaHRtbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanNcIikoJ3N1YicsIGZ1bmN0aW9uKGNyZWF0ZUhUTUwpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBzdWIoKXtcclxuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzdWInLCAnJywgJycpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3VwLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3VwLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyBCLjIuMy4xNCBTdHJpbmcucHJvdG90eXBlLnN1cCgpXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1odG1sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctaHRtbC5qc1wiKSgnc3VwJywgZnVuY3Rpb24oY3JlYXRlSFRNTCl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIHN1cCgpe1xyXG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N1cCcsICcnLCAnJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy50cmltLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0uanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyAyMS4xLjMuMjUgU3RyaW5nLnByb3RvdHlwZS50cmltKClcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLXRyaW0gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy10cmltLmpzXCIpKCd0cmltJywgZnVuY3Rpb24oJHRyaW0pe1xyXG4gIHJldHVybiBmdW5jdGlvbiB0cmltKCl7XHJcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMyk7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3ltYm9sLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIEVDTUFTY3JpcHQgNiBzeW1ib2xzIHNoaW1cclxudmFyIGdsb2JhbCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIilcclxuICAsIGhhcyAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faGFzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oYXMuanNcIilcclxuICAsIERFU0NSSVBUT1JTICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpXHJcbiAgLCAkZXhwb3J0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCByZWRlZmluZSAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3JlZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qc1wiKVxyXG4gICwgTUVUQSAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tZXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzXCIpLktFWVxyXG4gICwgJGZhaWxzICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mYWlscyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanNcIilcclxuICAsIHNoYXJlZCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2hhcmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanNcIilcclxuICAsIHNldFRvU3RyaW5nVGFnID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc2V0LXRvLXN0cmluZy10YWcgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NldC10by1zdHJpbmctdGFnLmpzXCIpXHJcbiAgLCB1aWQgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3VpZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzXCIpXHJcbiAgLCB3a3MgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpXHJcbiAgLCB3a3NFeHQgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcy1leHQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy1leHQuanNcIilcclxuICAsIHdrc0RlZmluZSAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fd2tzLWRlZmluZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qc1wiKVxyXG4gICwga2V5T2YgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19rZXlvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fa2V5b2YuanNcIilcclxuICAsIGVudW1LZXlzICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZW51bS1rZXlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19lbnVtLWtleXMuanNcIilcclxuICAsIGlzQXJyYXkgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWFycmF5LmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b0lPYmplY3QgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWlvYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWlvYmplY3QuanNcIilcclxuICAsIHRvUHJpbWl0aXZlICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tcHJpbWl0aXZlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1wcmltaXRpdmUuanNcIilcclxuICAsIGNyZWF0ZURlc2MgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcHJvcGVydHktZGVzYyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qc1wiKVxyXG4gICwgX2NyZWF0ZSAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtY3JlYXRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzXCIpXHJcbiAgLCBnT1BORXh0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BuLWV4dCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4tZXh0LmpzXCIpXHJcbiAgLCAkR09QRCAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qc1wiKVxyXG4gICwgJERQICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKVxyXG4gICwgJGtleXMgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3Qta2V5cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanNcIilcclxuICAsIGdPUEQgICAgICAgICAgID0gJEdPUEQuZlxyXG4gICwgZFAgICAgICAgICAgICAgPSAkRFAuZlxyXG4gICwgZ09QTiAgICAgICAgICAgPSBnT1BORXh0LmZcclxuICAsICRTeW1ib2wgICAgICAgID0gZ2xvYmFsLlN5bWJvbFxyXG4gICwgJEpTT04gICAgICAgICAgPSBnbG9iYWwuSlNPTlxyXG4gICwgX3N0cmluZ2lmeSAgICAgPSAkSlNPTiAmJiAkSlNPTi5zdHJpbmdpZnlcclxuICAsIFBST1RPVFlQRSAgICAgID0gJ3Byb3RvdHlwZSdcclxuICAsIEhJRERFTiAgICAgICAgID0gd2tzKCdfaGlkZGVuJylcclxuICAsIFRPX1BSSU1JVElWRSAgID0gd2tzKCd0b1ByaW1pdGl2ZScpXHJcbiAgLCBpc0VudW0gICAgICAgICA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlXHJcbiAgLCBTeW1ib2xSZWdpc3RyeSA9IHNoYXJlZCgnc3ltYm9sLXJlZ2lzdHJ5JylcclxuICAsIEFsbFN5bWJvbHMgICAgID0gc2hhcmVkKCdzeW1ib2xzJylcclxuICAsIE9QU3ltYm9scyAgICAgID0gc2hhcmVkKCdvcC1zeW1ib2xzJylcclxuICAsIE9iamVjdFByb3RvICAgID0gT2JqZWN0W1BST1RPVFlQRV1cclxuICAsIFVTRV9OQVRJVkUgICAgID0gdHlwZW9mICRTeW1ib2wgPT0gJ2Z1bmN0aW9uJ1xyXG4gICwgUU9iamVjdCAgICAgICAgPSBnbG9iYWwuUU9iamVjdDtcclxuLy8gRG9uJ3QgdXNlIHNldHRlcnMgaW4gUXQgU2NyaXB0LCBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMTczXHJcbnZhciBzZXR0ZXIgPSAhUU9iamVjdCB8fCAhUU9iamVjdFtQUk9UT1RZUEVdIHx8ICFRT2JqZWN0W1BST1RPVFlQRV0uZmluZENoaWxkO1xyXG5cclxuLy8gZmFsbGJhY2sgZm9yIG9sZCBBbmRyb2lkLCBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9Njg3XHJcbnZhciBzZXRTeW1ib2xEZXNjID0gREVTQ1JJUFRPUlMgJiYgJGZhaWxzKGZ1bmN0aW9uKCl7XHJcbiAgcmV0dXJuIF9jcmVhdGUoZFAoe30sICdhJywge1xyXG4gICAgZ2V0OiBmdW5jdGlvbigpeyByZXR1cm4gZFAodGhpcywgJ2EnLCB7dmFsdWU6IDd9KS5hOyB9XHJcbiAgfSkpLmEgIT0gNztcclxufSkgPyBmdW5jdGlvbihpdCwga2V5LCBEKXtcclxuICB2YXIgcHJvdG9EZXNjID0gZ09QRChPYmplY3RQcm90bywga2V5KTtcclxuICBpZihwcm90b0Rlc2MpZGVsZXRlIE9iamVjdFByb3RvW2tleV07XHJcbiAgZFAoaXQsIGtleSwgRCk7XHJcbiAgaWYocHJvdG9EZXNjICYmIGl0ICE9PSBPYmplY3RQcm90bylkUChPYmplY3RQcm90bywga2V5LCBwcm90b0Rlc2MpO1xyXG59IDogZFA7XHJcblxyXG52YXIgd3JhcCA9IGZ1bmN0aW9uKHRhZyl7XHJcbiAgdmFyIHN5bSA9IEFsbFN5bWJvbHNbdGFnXSA9IF9jcmVhdGUoJFN5bWJvbFtQUk9UT1RZUEVdKTtcclxuICBzeW0uX2sgPSB0YWc7XHJcbiAgcmV0dXJuIHN5bTtcclxufTtcclxuXHJcbnZhciBpc1N5bWJvbCA9IFVTRV9OQVRJVkUgJiYgdHlwZW9mICRTeW1ib2wuaXRlcmF0b3IgPT0gJ3N5bWJvbCcgPyBmdW5jdGlvbihpdCl7XHJcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PSAnc3ltYm9sJztcclxufSA6IGZ1bmN0aW9uKGl0KXtcclxuICByZXR1cm4gaXQgaW5zdGFuY2VvZiAkU3ltYm9sO1xyXG59O1xyXG5cclxudmFyICRkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KGl0LCBrZXksIEQpe1xyXG4gIGlmKGl0ID09PSBPYmplY3RQcm90bykkZGVmaW5lUHJvcGVydHkoT1BTeW1ib2xzLCBrZXksIEQpO1xyXG4gIGFuT2JqZWN0KGl0KTtcclxuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xyXG4gIGFuT2JqZWN0KEQpO1xyXG4gIGlmKGhhcyhBbGxTeW1ib2xzLCBrZXkpKXtcclxuICAgIGlmKCFELmVudW1lcmFibGUpe1xyXG4gICAgICBpZighaGFzKGl0LCBISURERU4pKWRQKGl0LCBISURERU4sIGNyZWF0ZURlc2MoMSwge30pKTtcclxuICAgICAgaXRbSElEREVOXVtrZXldID0gdHJ1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0paXRbSElEREVOXVtrZXldID0gZmFsc2U7XHJcbiAgICAgIEQgPSBfY3JlYXRlKEQsIHtlbnVtZXJhYmxlOiBjcmVhdGVEZXNjKDAsIGZhbHNlKX0pO1xyXG4gICAgfSByZXR1cm4gc2V0U3ltYm9sRGVzYyhpdCwga2V5LCBEKTtcclxuICB9IHJldHVybiBkUChpdCwga2V5LCBEKTtcclxufTtcclxudmFyICRkZWZpbmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhpdCwgUCl7XHJcbiAgYW5PYmplY3QoaXQpO1xyXG4gIHZhciBrZXlzID0gZW51bUtleXMoUCA9IHRvSU9iamVjdChQKSlcclxuICAgICwgaSAgICA9IDBcclxuICAgICwgbCA9IGtleXMubGVuZ3RoXHJcbiAgICAsIGtleTtcclxuICB3aGlsZShsID4gaSkkZGVmaW5lUHJvcGVydHkoaXQsIGtleSA9IGtleXNbaSsrXSwgUFtrZXldKTtcclxuICByZXR1cm4gaXQ7XHJcbn07XHJcbnZhciAkY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKGl0LCBQKXtcclxuICByZXR1cm4gUCA9PT0gdW5kZWZpbmVkID8gX2NyZWF0ZShpdCkgOiAkZGVmaW5lUHJvcGVydGllcyhfY3JlYXRlKGl0KSwgUCk7XHJcbn07XHJcbnZhciAkcHJvcGVydHlJc0VudW1lcmFibGUgPSBmdW5jdGlvbiBwcm9wZXJ0eUlzRW51bWVyYWJsZShrZXkpe1xyXG4gIHZhciBFID0gaXNFbnVtLmNhbGwodGhpcywga2V5ID0gdG9QcmltaXRpdmUoa2V5LCB0cnVlKSk7XHJcbiAgaWYodGhpcyA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpcmV0dXJuIGZhbHNlO1xyXG4gIHJldHVybiBFIHx8ICFoYXModGhpcywga2V5KSB8fCAhaGFzKEFsbFN5bWJvbHMsIGtleSkgfHwgaGFzKHRoaXMsIEhJRERFTikgJiYgdGhpc1tISURERU5dW2tleV0gPyBFIDogdHJ1ZTtcclxufTtcclxudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaXQsIGtleSl7XHJcbiAgaXQgID0gdG9JT2JqZWN0KGl0KTtcclxuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xyXG4gIGlmKGl0ID09PSBPYmplY3RQcm90byAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhaGFzKE9QU3ltYm9scywga2V5KSlyZXR1cm47XHJcbiAgdmFyIEQgPSBnT1BEKGl0LCBrZXkpO1xyXG4gIGlmKEQgJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIShoYXMoaXQsIEhJRERFTikgJiYgaXRbSElEREVOXVtrZXldKSlELmVudW1lcmFibGUgPSB0cnVlO1xyXG4gIHJldHVybiBEO1xyXG59O1xyXG52YXIgJGdldE93blByb3BlcnR5TmFtZXMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKGl0KXtcclxuICB2YXIgbmFtZXMgID0gZ09QTih0b0lPYmplY3QoaXQpKVxyXG4gICAgLCByZXN1bHQgPSBbXVxyXG4gICAgLCBpICAgICAgPSAwXHJcbiAgICAsIGtleTtcclxuICB3aGlsZShuYW1lcy5sZW5ndGggPiBpKXtcclxuICAgIGlmKCFoYXMoQWxsU3ltYm9scywga2V5ID0gbmFtZXNbaSsrXSkgJiYga2V5ICE9IEhJRERFTiAmJiBrZXkgIT0gTUVUQSlyZXN1bHQucHVzaChrZXkpO1xyXG4gIH0gcmV0dXJuIHJlc3VsdDtcclxufTtcclxudmFyICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoaXQpe1xyXG4gIHZhciBJU19PUCAgPSBpdCA9PT0gT2JqZWN0UHJvdG9cclxuICAgICwgbmFtZXMgID0gZ09QTihJU19PUCA/IE9QU3ltYm9scyA6IHRvSU9iamVjdChpdCkpXHJcbiAgICAsIHJlc3VsdCA9IFtdXHJcbiAgICAsIGkgICAgICA9IDBcclxuICAgICwga2V5O1xyXG4gIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpe1xyXG4gICAgaWYoaGFzKEFsbFN5bWJvbHMsIGtleSA9IG5hbWVzW2krK10pICYmIChJU19PUCA/IGhhcyhPYmplY3RQcm90bywga2V5KSA6IHRydWUpKXJlc3VsdC5wdXNoKEFsbFN5bWJvbHNba2V5XSk7XHJcbiAgfSByZXR1cm4gcmVzdWx0O1xyXG59O1xyXG5cclxuLy8gMTkuNC4xLjEgU3ltYm9sKFtkZXNjcmlwdGlvbl0pXHJcbmlmKCFVU0VfTkFUSVZFKXtcclxuICAkU3ltYm9sID0gZnVuY3Rpb24gU3ltYm9sKCl7XHJcbiAgICBpZih0aGlzIGluc3RhbmNlb2YgJFN5bWJvbCl0aHJvdyBUeXBlRXJyb3IoJ1N5bWJvbCBpcyBub3QgYSBjb25zdHJ1Y3RvciEnKTtcclxuICAgIHZhciB0YWcgPSB1aWQoYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xyXG4gICAgdmFyICRzZXQgPSBmdW5jdGlvbih2YWx1ZSl7XHJcbiAgICAgIGlmKHRoaXMgPT09IE9iamVjdFByb3RvKSRzZXQuY2FsbChPUFN5bWJvbHMsIHZhbHVlKTtcclxuICAgICAgaWYoaGFzKHRoaXMsIEhJRERFTikgJiYgaGFzKHRoaXNbSElEREVOXSwgdGFnKSl0aGlzW0hJRERFTl1bdGFnXSA9IGZhbHNlO1xyXG4gICAgICBzZXRTeW1ib2xEZXNjKHRoaXMsIHRhZywgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xyXG4gICAgfTtcclxuICAgIGlmKERFU0NSSVBUT1JTICYmIHNldHRlcilzZXRTeW1ib2xEZXNjKE9iamVjdFByb3RvLCB0YWcsIHtjb25maWd1cmFibGU6IHRydWUsIHNldDogJHNldH0pO1xyXG4gICAgcmV0dXJuIHdyYXAodGFnKTtcclxuICB9O1xyXG4gIHJlZGVmaW5lKCRTeW1ib2xbUFJPVE9UWVBFXSwgJ3RvU3RyaW5nJywgZnVuY3Rpb24gdG9TdHJpbmcoKXtcclxuICAgIHJldHVybiB0aGlzLl9rO1xyXG4gIH0pO1xyXG5cclxuICAkR09QRC5mID0gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcclxuICAkRFAuZiAgID0gJGRlZmluZVByb3BlcnR5O1xyXG4gIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BuICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi5qc1wiKS5mID0gZ09QTkV4dC5mID0gJGdldE93blByb3BlcnR5TmFtZXM7XHJcbiAgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LXBpZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qc1wiKS5mICA9ICRwcm9wZXJ0eUlzRW51bWVyYWJsZTtcclxuICBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ29wcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanNcIikuZiA9ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XHJcblxyXG4gIGlmKERFU0NSSVBUT1JTICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19saWJyYXJ5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzXCIpKXtcclxuICAgIHJlZGVmaW5lKE9iamVjdFByb3RvLCAncHJvcGVydHlJc0VudW1lcmFibGUnLCAkcHJvcGVydHlJc0VudW1lcmFibGUsIHRydWUpO1xyXG4gIH1cclxuXHJcbiAgd2tzRXh0LmYgPSBmdW5jdGlvbihuYW1lKXtcclxuICAgIHJldHVybiB3cmFwKHdrcyhuYW1lKSk7XHJcbiAgfVxyXG59XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCB7U3ltYm9sOiAkU3ltYm9sfSk7XHJcblxyXG5mb3IodmFyIHN5bWJvbHMgPSAoXHJcbiAgLy8gMTkuNC4yLjIsIDE5LjQuMi4zLCAxOS40LjIuNCwgMTkuNC4yLjYsIDE5LjQuMi44LCAxOS40LjIuOSwgMTkuNC4yLjEwLCAxOS40LjIuMTEsIDE5LjQuMi4xMiwgMTkuNC4yLjEzLCAxOS40LjIuMTRcclxuICAnaGFzSW5zdGFuY2UsaXNDb25jYXRTcHJlYWRhYmxlLGl0ZXJhdG9yLG1hdGNoLHJlcGxhY2Usc2VhcmNoLHNwZWNpZXMsc3BsaXQsdG9QcmltaXRpdmUsdG9TdHJpbmdUYWcsdW5zY29wYWJsZXMnXHJcbikuc3BsaXQoJywnKSwgaSA9IDA7IHN5bWJvbHMubGVuZ3RoID4gaTsgKXdrcyhzeW1ib2xzW2krK10pO1xyXG5cclxuZm9yKHZhciBzeW1ib2xzID0gJGtleXMod2tzLnN0b3JlKSwgaSA9IDA7IHN5bWJvbHMubGVuZ3RoID4gaTsgKXdrc0RlZmluZShzeW1ib2xzW2krK10pO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgJ1N5bWJvbCcsIHtcclxuICAvLyAxOS40LjIuMSBTeW1ib2wuZm9yKGtleSlcclxuICAnZm9yJzogZnVuY3Rpb24oa2V5KXtcclxuICAgIHJldHVybiBoYXMoU3ltYm9sUmVnaXN0cnksIGtleSArPSAnJylcclxuICAgICAgPyBTeW1ib2xSZWdpc3RyeVtrZXldXHJcbiAgICAgIDogU3ltYm9sUmVnaXN0cnlba2V5XSA9ICRTeW1ib2woa2V5KTtcclxuICB9LFxyXG4gIC8vIDE5LjQuMi41IFN5bWJvbC5rZXlGb3Ioc3ltKVxyXG4gIGtleUZvcjogZnVuY3Rpb24ga2V5Rm9yKGtleSl7XHJcbiAgICBpZihpc1N5bWJvbChrZXkpKXJldHVybiBrZXlPZihTeW1ib2xSZWdpc3RyeSwga2V5KTtcclxuICAgIHRocm93IFR5cGVFcnJvcihrZXkgKyAnIGlzIG5vdCBhIHN5bWJvbCEnKTtcclxuICB9LFxyXG4gIHVzZVNldHRlcjogZnVuY3Rpb24oKXsgc2V0dGVyID0gdHJ1ZTsgfSxcclxuICB1c2VTaW1wbGU6IGZ1bmN0aW9uKCl7IHNldHRlciA9IGZhbHNlOyB9XHJcbn0pO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgJ09iamVjdCcsIHtcclxuICAvLyAxOS4xLjIuMiBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXHJcbiAgY3JlYXRlOiAkY3JlYXRlLFxyXG4gIC8vIDE5LjEuMi40IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKVxyXG4gIGRlZmluZVByb3BlcnR5OiAkZGVmaW5lUHJvcGVydHksXHJcbiAgLy8gMTkuMS4yLjMgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcclxuICBkZWZpbmVQcm9wZXJ0aWVzOiAkZGVmaW5lUHJvcGVydGllcyxcclxuICAvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXHJcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLFxyXG4gIC8vIDE5LjEuMi43IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE8pXHJcbiAgZ2V0T3duUHJvcGVydHlOYW1lczogJGdldE93blByb3BlcnR5TmFtZXMsXHJcbiAgLy8gMTkuMS4yLjggT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhPKVxyXG4gIGdldE93blByb3BlcnR5U3ltYm9sczogJGdldE93blByb3BlcnR5U3ltYm9sc1xyXG59KTtcclxuXHJcbi8vIDI0LjMuMiBKU09OLnN0cmluZ2lmeSh2YWx1ZSBbLCByZXBsYWNlciBbLCBzcGFjZV1dKVxyXG4kSlNPTiAmJiAkZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICghVVNFX05BVElWRSB8fCAkZmFpbHMoZnVuY3Rpb24oKXtcclxuICB2YXIgUyA9ICRTeW1ib2woKTtcclxuICAvLyBNUyBFZGdlIGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyB7fVxyXG4gIC8vIFdlYktpdCBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMgbnVsbFxyXG4gIC8vIFY4IHRocm93cyBvbiBib3hlZCBzeW1ib2xzXHJcbiAgcmV0dXJuIF9zdHJpbmdpZnkoW1NdKSAhPSAnW251bGxdJyB8fCBfc3RyaW5naWZ5KHthOiBTfSkgIT0gJ3t9JyB8fCBfc3RyaW5naWZ5KE9iamVjdChTKSkgIT0gJ3t9JztcclxufSkpLCAnSlNPTicsIHtcclxuICBzdHJpbmdpZnk6IGZ1bmN0aW9uIHN0cmluZ2lmeShpdCl7XHJcbiAgICBpZihpdCA9PT0gdW5kZWZpbmVkIHx8IGlzU3ltYm9sKGl0KSlyZXR1cm47IC8vIElFOCByZXR1cm5zIHN0cmluZyBvbiB1bmRlZmluZWRcclxuICAgIHZhciBhcmdzID0gW2l0XVxyXG4gICAgICAsIGkgICAgPSAxXHJcbiAgICAgICwgcmVwbGFjZXIsICRyZXBsYWNlcjtcclxuICAgIHdoaWxlKGFyZ3VtZW50cy5sZW5ndGggPiBpKWFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XHJcbiAgICByZXBsYWNlciA9IGFyZ3NbMV07XHJcbiAgICBpZih0eXBlb2YgcmVwbGFjZXIgPT0gJ2Z1bmN0aW9uJykkcmVwbGFjZXIgPSByZXBsYWNlcjtcclxuICAgIGlmKCRyZXBsYWNlciB8fCAhaXNBcnJheShyZXBsYWNlcikpcmVwbGFjZXIgPSBmdW5jdGlvbihrZXksIHZhbHVlKXtcclxuICAgICAgaWYoJHJlcGxhY2VyKXZhbHVlID0gJHJlcGxhY2VyLmNhbGwodGhpcywga2V5LCB2YWx1ZSk7XHJcbiAgICAgIGlmKCFpc1N5bWJvbCh2YWx1ZSkpcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuICAgIGFyZ3NbMV0gPSByZXBsYWNlcjtcclxuICAgIHJldHVybiBfc3RyaW5naWZ5LmFwcGx5KCRKU09OLCBhcmdzKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLy8gMTkuNC4zLjQgU3ltYm9sLnByb3RvdHlwZVtAQHRvUHJpbWl0aXZlXShoaW50KVxyXG4kU3ltYm9sW1BST1RPVFlQRV1bVE9fUFJJTUlUSVZFXSB8fCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19oaWRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzXCIpKCRTeW1ib2xbUFJPVE9UWVBFXSwgVE9fUFJJTUlUSVZFLCAkU3ltYm9sW1BST1RPVFlQRV0udmFsdWVPZik7XHJcbi8vIDE5LjQuMy41IFN5bWJvbC5wcm90b3R5cGVbQEB0b1N0cmluZ1RhZ11cclxuc2V0VG9TdHJpbmdUYWcoJFN5bWJvbCwgJ1N5bWJvbCcpO1xyXG4vLyAyMC4yLjEuOSBNYXRoW0BAdG9TdHJpbmdUYWddXHJcbnNldFRvU3RyaW5nVGFnKE1hdGgsICdNYXRoJywgdHJ1ZSk7XHJcbi8vIDI0LjMuMyBKU09OW0BAdG9TdHJpbmdUYWddXHJcbnNldFRvU3RyaW5nVGFnKGdsb2JhbC5KU09OLCAnSlNPTicsIHRydWUpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuYXJyYXktYnVmZmVyLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmFycmF5LWJ1ZmZlci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsICR0eXBlZCAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3R5cGVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC5qc1wiKVxyXG4gICwgYnVmZmVyICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdHlwZWQtYnVmZmVyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC1idWZmZXIuanNcIilcclxuICAsIGFuT2JqZWN0ICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b0luZGV4ICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pbmRleCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW5kZXguanNcIilcclxuICAsIHRvTGVuZ3RoICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWxlbmd0aCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzXCIpXHJcbiAgLCBpc09iamVjdCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pcy1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qc1wiKVxyXG4gICwgQXJyYXlCdWZmZXIgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIikuQXJyYXlCdWZmZXJcclxuICAsIHNwZWNpZXNDb25zdHJ1Y3RvciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NwZWNpZXMtY29uc3RydWN0b3IgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NwZWNpZXMtY29uc3RydWN0b3IuanNcIilcclxuICAsICRBcnJheUJ1ZmZlciA9IGJ1ZmZlci5BcnJheUJ1ZmZlclxyXG4gICwgJERhdGFWaWV3ICAgID0gYnVmZmVyLkRhdGFWaWV3XHJcbiAgLCAkaXNWaWV3ICAgICAgPSAkdHlwZWQuQUJWICYmIEFycmF5QnVmZmVyLmlzVmlld1xyXG4gICwgJHNsaWNlICAgICAgID0gJEFycmF5QnVmZmVyLnByb3RvdHlwZS5zbGljZVxyXG4gICwgVklFVyAgICAgICAgID0gJHR5cGVkLlZJRVdcclxuICAsIEFSUkFZX0JVRkZFUiA9ICdBcnJheUJ1ZmZlcic7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChBcnJheUJ1ZmZlciAhPT0gJEFycmF5QnVmZmVyKSwge0FycmF5QnVmZmVyOiAkQXJyYXlCdWZmZXJ9KTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISR0eXBlZC5DT05TVFIsIEFSUkFZX0JVRkZFUiwge1xyXG4gIC8vIDI0LjEuMy4xIEFycmF5QnVmZmVyLmlzVmlldyhhcmcpXHJcbiAgaXNWaWV3OiBmdW5jdGlvbiBpc1ZpZXcoaXQpe1xyXG4gICAgcmV0dXJuICRpc1ZpZXcgJiYgJGlzVmlldyhpdCkgfHwgaXNPYmplY3QoaXQpICYmIFZJRVcgaW4gaXQ7XHJcbiAgfVxyXG59KTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5VICsgJGV4cG9ydC5GICogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZmFpbHMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzXCIpKGZ1bmN0aW9uKCl7XHJcbiAgcmV0dXJuICFuZXcgJEFycmF5QnVmZmVyKDIpLnNsaWNlKDEsIHVuZGVmaW5lZCkuYnl0ZUxlbmd0aDtcclxufSksIEFSUkFZX0JVRkZFUiwge1xyXG4gIC8vIDI0LjEuNC4zIEFycmF5QnVmZmVyLnByb3RvdHlwZS5zbGljZShzdGFydCwgZW5kKVxyXG4gIHNsaWNlOiBmdW5jdGlvbiBzbGljZShzdGFydCwgZW5kKXtcclxuICAgIGlmKCRzbGljZSAhPT0gdW5kZWZpbmVkICYmIGVuZCA9PT0gdW5kZWZpbmVkKXJldHVybiAkc2xpY2UuY2FsbChhbk9iamVjdCh0aGlzKSwgc3RhcnQpOyAvLyBGRiBmaXhcclxuICAgIHZhciBsZW4gICAgPSBhbk9iamVjdCh0aGlzKS5ieXRlTGVuZ3RoXHJcbiAgICAgICwgZmlyc3QgID0gdG9JbmRleChzdGFydCwgbGVuKVxyXG4gICAgICAsIGZpbmFsICA9IHRvSW5kZXgoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiBlbmQsIGxlbilcclxuICAgICAgLCByZXN1bHQgPSBuZXcgKHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkQXJyYXlCdWZmZXIpKSh0b0xlbmd0aChmaW5hbCAtIGZpcnN0KSlcclxuICAgICAgLCB2aWV3UyAgPSBuZXcgJERhdGFWaWV3KHRoaXMpXHJcbiAgICAgICwgdmlld1QgID0gbmV3ICREYXRhVmlldyhyZXN1bHQpXHJcbiAgICAgICwgaW5kZXggID0gMDtcclxuICAgIHdoaWxlKGZpcnN0IDwgZmluYWwpe1xyXG4gICAgICB2aWV3VC5zZXRVaW50OChpbmRleCsrLCB2aWV3Uy5nZXRVaW50OChmaXJzdCsrKSk7XHJcbiAgICB9IHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG59KTtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NldC1zcGVjaWVzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qc1wiKShBUlJBWV9CVUZGRVIpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZGF0YS12aWV3LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmRhdGEtdmlldy5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdHlwZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLmpzXCIpLkFCViwge1xyXG4gIERhdGFWaWV3OiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190eXBlZC1idWZmZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWJ1ZmZlci5qc1wiKS5EYXRhVmlld1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0MzItYXJyYXkuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0MzItYXJyYXkuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190eXBlZC1hcnJheSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYXJyYXkuanNcIikoJ0Zsb2F0MzInLCA0LCBmdW5jdGlvbihpbml0KXtcclxuICByZXR1cm4gZnVuY3Rpb24gRmxvYXQzMkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCl7XHJcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xyXG4gIH07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZmxvYXQ2NC1hcnJheS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZmxvYXQ2NC1hcnJheS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3R5cGVkLWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC1hcnJheS5qc1wiKSgnRmxvYXQ2NCcsIDgsIGZ1bmN0aW9uKGluaXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBGbG9hdDY0QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcclxuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmludDE2LWFycmF5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3R5cGVkLWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC1hcnJheS5qc1wiKSgnSW50MTYnLCAyLCBmdW5jdGlvbihpbml0KXtcclxuICByZXR1cm4gZnVuY3Rpb24gSW50MTZBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpe1xyXG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuICB9O1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmludDMyLWFycmF5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50MzItYXJyYXkuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdHlwZWQtYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWFycmF5LmpzXCIpKCdJbnQzMicsIDQsIGZ1bmN0aW9uKGluaXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBJbnQzMkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCl7XHJcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xyXG4gIH07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50OC1hcnJheS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50OC1hcnJheS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3R5cGVkLWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC1hcnJheS5qc1wiKSgnSW50OCcsIDEsIGZ1bmN0aW9uKGluaXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBJbnQ4QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcclxuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50MTYtYXJyYXkuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDE2LWFycmF5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190eXBlZC1hcnJheSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYXJyYXkuanNcIikoJ1VpbnQxNicsIDIsIGZ1bmN0aW9uKGluaXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBVaW50MTZBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpe1xyXG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuICB9O1xyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQzMi1hcnJheS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50MzItYXJyYXkuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3R5cGVkLWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190eXBlZC1hcnJheS5qc1wiKSgnVWludDMyJywgNCwgZnVuY3Rpb24oaW5pdCl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQzMkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCl7XHJcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xyXG4gIH07XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDgtYXJyYXkuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1hcnJheS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190eXBlZC1hcnJheSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYXJyYXkuanNcIikoJ1VpbnQ4JywgMSwgZnVuY3Rpb24oaW5pdCl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQ4QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKXtcclxuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XHJcbiAgfTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdHlwZWQtYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWFycmF5LmpzXCIpKCdVaW50OCcsIDEsIGZ1bmN0aW9uKGluaXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBVaW50OENsYW1wZWRBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpe1xyXG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuICB9O1xyXG59LCB0cnVlKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LndlYWstbWFwLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1tYXAuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgZWFjaCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYXJyYXktbWV0aG9kcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qc1wiKSgwKVxyXG4gICwgcmVkZWZpbmUgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzXCIpXHJcbiAgLCBtZXRhICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tZXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzXCIpXHJcbiAgLCBhc3NpZ24gICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtYXNzaWduICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzXCIpXHJcbiAgLCB3ZWFrICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb2xsZWN0aW9uLXdlYWsgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24td2Vhay5qc1wiKVxyXG4gICwgaXNPYmplY3QgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faXMtb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanNcIilcclxuICAsIGdldFdlYWsgICAgICA9IG1ldGEuZ2V0V2Vha1xyXG4gICwgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZVxyXG4gICwgdW5jYXVnaHRGcm96ZW5TdG9yZSA9IHdlYWsudWZzdG9yZVxyXG4gICwgdG1wICAgICAgICAgID0ge31cclxuICAsIEludGVybmFsTWFwO1xyXG5cclxudmFyIHdyYXBwZXIgPSBmdW5jdGlvbihnZXQpe1xyXG4gIHJldHVybiBmdW5jdGlvbiBXZWFrTWFwKCl7XHJcbiAgICByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTtcclxuICB9O1xyXG59O1xyXG5cclxudmFyIG1ldGhvZHMgPSB7XHJcbiAgLy8gMjMuMy4zLjMgV2Vha01hcC5wcm90b3R5cGUuZ2V0KGtleSlcclxuICBnZXQ6IGZ1bmN0aW9uIGdldChrZXkpe1xyXG4gICAgaWYoaXNPYmplY3Qoa2V5KSl7XHJcbiAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xyXG4gICAgICBpZihkYXRhID09PSB0cnVlKXJldHVybiB1bmNhdWdodEZyb3plblN0b3JlKHRoaXMpLmdldChrZXkpO1xyXG4gICAgICByZXR1cm4gZGF0YSA/IGRhdGFbdGhpcy5faV0gOiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgfSxcclxuICAvLyAyMy4zLjMuNSBXZWFrTWFwLnByb3RvdHlwZS5zZXQoa2V5LCB2YWx1ZSlcclxuICBzZXQ6IGZ1bmN0aW9uIHNldChrZXksIHZhbHVlKXtcclxuICAgIHJldHVybiB3ZWFrLmRlZih0aGlzLCBrZXksIHZhbHVlKTtcclxuICB9XHJcbn07XHJcblxyXG4vLyAyMy4zIFdlYWtNYXAgT2JqZWN0c1xyXG52YXIgJFdlYWtNYXAgPSBtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvbGxlY3Rpb24gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24uanNcIikoJ1dlYWtNYXAnLCB3cmFwcGVyLCBtZXRob2RzLCB3ZWFrLCB0cnVlLCB0cnVlKTtcclxuXHJcbi8vIElFMTEgV2Vha01hcCBmcm96ZW4ga2V5cyBmaXhcclxuaWYobmV3ICRXZWFrTWFwKCkuc2V0KChPYmplY3QuZnJlZXplIHx8IE9iamVjdCkodG1wKSwgNykuZ2V0KHRtcCkgIT0gNyl7XHJcbiAgSW50ZXJuYWxNYXAgPSB3ZWFrLmdldENvbnN0cnVjdG9yKHdyYXBwZXIpO1xyXG4gIGFzc2lnbihJbnRlcm5hbE1hcC5wcm90b3R5cGUsIG1ldGhvZHMpO1xyXG4gIG1ldGEuTkVFRCA9IHRydWU7XHJcbiAgZWFjaChbJ2RlbGV0ZScsICdoYXMnLCAnZ2V0JywgJ3NldCddLCBmdW5jdGlvbihrZXkpe1xyXG4gICAgdmFyIHByb3RvICA9ICRXZWFrTWFwLnByb3RvdHlwZVxyXG4gICAgICAsIG1ldGhvZCA9IHByb3RvW2tleV07XHJcbiAgICByZWRlZmluZShwcm90bywga2V5LCBmdW5jdGlvbihhLCBiKXtcclxuICAgICAgLy8gc3RvcmUgZnJvemVuIG9iamVjdHMgb24gaW50ZXJuYWwgd2Vha21hcCBzaGltXHJcbiAgICAgIGlmKGlzT2JqZWN0KGEpICYmICFpc0V4dGVuc2libGUoYSkpe1xyXG4gICAgICAgIGlmKCF0aGlzLl9mKXRoaXMuX2YgPSBuZXcgSW50ZXJuYWxNYXA7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuX2Zba2V5XShhLCBiKTtcclxuICAgICAgICByZXR1cm4ga2V5ID09ICdzZXQnID8gdGhpcyA6IHJlc3VsdDtcclxuICAgICAgLy8gc3RvcmUgYWxsIHRoZSByZXN0IG9uIG5hdGl2ZSB3ZWFrbWFwXHJcbiAgICAgIH0gcmV0dXJuIG1ldGhvZC5jYWxsKHRoaXMsIGEsIGIpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LndlYWstc2V0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1zZXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgd2VhayA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvbGxlY3Rpb24td2VhayAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi13ZWFrLmpzXCIpO1xyXG5cclxuLy8gMjMuNCBXZWFrU2V0IE9iamVjdHNcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29sbGVjdGlvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi5qc1wiKSgnV2Vha1NldCcsIGZ1bmN0aW9uKGdldCl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIFdlYWtTZXQoKXsgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7IH07XHJcbn0sIHtcclxuICAvLyAyMy40LjMuMSBXZWFrU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXHJcbiAgYWRkOiBmdW5jdGlvbiBhZGQodmFsdWUpe1xyXG4gICAgcmV0dXJuIHdlYWsuZGVmKHRoaXMsIHZhbHVlLCB0cnVlKTtcclxuICB9XHJcbn0sIHdlYWssIGZhbHNlLCB0cnVlKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LmFycmF5LmluY2x1ZGVzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuYXJyYXkuaW5jbHVkZXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9BcnJheS5wcm90b3R5cGUuaW5jbHVkZXNcclxudmFyICRleHBvcnQgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkaW5jbHVkZXMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1pbmNsdWRlcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktaW5jbHVkZXMuanNcIikodHJ1ZSk7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge1xyXG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhlbCAvKiwgZnJvbUluZGV4ID0gMCAqLyl7XHJcbiAgICByZXR1cm4gJGluY2x1ZGVzKHRoaXMsIGVsLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XHJcbiAgfVxyXG59KTtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FkZC10by11bnNjb3BhYmxlcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYWRkLXRvLXVuc2NvcGFibGVzLmpzXCIpKCdpbmNsdWRlcycpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuYXNhcC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuYXNhcC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9yd2FsZHJvbi90YzM5LW5vdGVzL2Jsb2IvbWFzdGVyL2VzNi8yMDE0LTA5L3NlcHQtMjUubWQjNTEwLWdsb2JhbGFzYXAtZm9yLWVucXVldWluZy1hLW1pY3JvdGFza1xyXG52YXIgJGV4cG9ydCAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIG1pY3JvdGFzayA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21pY3JvdGFzayAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWljcm90YXNrLmpzXCIpKClcclxuICAsIHByb2Nlc3MgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2dsb2JhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzXCIpLnByb2Nlc3NcclxuICAsIGlzTm9kZSAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2NvZiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzXCIpKHByb2Nlc3MpID09ICdwcm9jZXNzJztcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5HLCB7XHJcbiAgYXNhcDogZnVuY3Rpb24gYXNhcChmbil7XHJcbiAgICB2YXIgZG9tYWluID0gaXNOb2RlICYmIHByb2Nlc3MuZG9tYWluO1xyXG4gICAgbWljcm90YXNrKGRvbWFpbiA/IGRvbWFpbi5iaW5kKGZuKSA6IGZuKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuZXJyb3IuaXMtZXJyb3IuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5lcnJvci5pcy1lcnJvci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL3Byb3Bvc2FsLWlzLWVycm9yXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGNvZiAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvZi5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnRXJyb3InLCB7XHJcbiAgaXNFcnJvcjogZnVuY3Rpb24gaXNFcnJvcihpdCl7XHJcbiAgICByZXR1cm4gY29mKGl0KSA9PT0gJ0Vycm9yJztcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWFwLnRvLWpzb24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXAudG8tanNvbi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXHJcbnZhciAkZXhwb3J0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdNYXAnLCB7dG9KU09OOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb2xsZWN0aW9uLXRvLWpzb24gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24tdG8tanNvbi5qc1wiKSgnTWFwJyl9KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaWFkZGguanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaWFkZGguanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9CcmVuZGFuRWljaC80Mjk0ZDVjMjEyYTZkMjI1NDcwM1xyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xyXG4gIGlhZGRoOiBmdW5jdGlvbiBpYWRkaCh4MCwgeDEsIHkwLCB5MSl7XHJcbiAgICB2YXIgJHgwID0geDAgPj4+IDBcclxuICAgICAgLCAkeDEgPSB4MSA+Pj4gMFxyXG4gICAgICAsICR5MCA9IHkwID4+PiAwO1xyXG4gICAgcmV0dXJuICR4MSArICh5MSA+Pj4gMCkgKyAoKCR4MCAmICR5MCB8ICgkeDAgfCAkeTApICYgfigkeDAgKyAkeTAgPj4+IDApKSA+Pj4gMzEpIHwgMDtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5pbXVsaC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5pbXVsaC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XHJcbiAgaW11bGg6IGZ1bmN0aW9uIGltdWxoKHUsIHYpe1xyXG4gICAgdmFyIFVJTlQxNiA9IDB4ZmZmZlxyXG4gICAgICAsICR1ID0gK3VcclxuICAgICAgLCAkdiA9ICt2XHJcbiAgICAgICwgdTAgPSAkdSAmIFVJTlQxNlxyXG4gICAgICAsIHYwID0gJHYgJiBVSU5UMTZcclxuICAgICAgLCB1MSA9ICR1ID4+IDE2XHJcbiAgICAgICwgdjEgPSAkdiA+PiAxNlxyXG4gICAgICAsIHQgID0gKHUxICogdjAgPj4+IDApICsgKHUwICogdjAgPj4+IDE2KTtcclxuICAgIHJldHVybiB1MSAqIHYxICsgKHQgPj4gMTYpICsgKCh1MCAqIHYxID4+PiAwKSArICh0ICYgVUlOVDE2KSA+PiAxNik7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaXN1YmguanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaXN1YmguanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9CcmVuZGFuRWljaC80Mjk0ZDVjMjEyYTZkMjI1NDcwM1xyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xyXG4gIGlzdWJoOiBmdW5jdGlvbiBpc3ViaCh4MCwgeDEsIHkwLCB5MSl7XHJcbiAgICB2YXIgJHgwID0geDAgPj4+IDBcclxuICAgICAgLCAkeDEgPSB4MSA+Pj4gMFxyXG4gICAgICAsICR5MCA9IHkwID4+PiAwO1xyXG4gICAgcmV0dXJuICR4MSAtICh5MSA+Pj4gMCkgLSAoKH4keDAgJiAkeTAgfCB+KCR4MCBeICR5MCkgJiAkeDAgLSAkeTAgPj4+IDApID4+PiAzMSkgfCAwO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXRoLnVtdWxoLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXRoLnVtdWxoLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vQnJlbmRhbkVpY2gvNDI5NGQ1YzIxMmE2ZDIyNTQ3MDNcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcclxuICB1bXVsaDogZnVuY3Rpb24gdW11bGgodSwgdil7XHJcbiAgICB2YXIgVUlOVDE2ID0gMHhmZmZmXHJcbiAgICAgICwgJHUgPSArdVxyXG4gICAgICAsICR2ID0gK3ZcclxuICAgICAgLCB1MCA9ICR1ICYgVUlOVDE2XHJcbiAgICAgICwgdjAgPSAkdiAmIFVJTlQxNlxyXG4gICAgICAsIHUxID0gJHUgPj4+IDE2XHJcbiAgICAgICwgdjEgPSAkdiA+Pj4gMTZcclxuICAgICAgLCB0ICA9ICh1MSAqIHYwID4+PiAwKSArICh1MCAqIHYwID4+PiAxNik7XHJcbiAgICByZXR1cm4gdTEgKiB2MSArICh0ID4+PiAxNikgKyAoKHUwICogdjEgPj4+IDApICsgKHQgJiBVSU5UMTYpID4+PiAxNik7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5kZWZpbmUtZ2V0dGVyLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1nZXR0ZXIuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHRvT2JqZWN0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzXCIpXHJcbiAgLCBhRnVuY3Rpb24gICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCAkZGVmaW5lUHJvcGVydHkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKTtcclxuXHJcbi8vIEIuMi4yLjIgT2JqZWN0LnByb3RvdHlwZS5fX2RlZmluZUdldHRlcl9fKFAsIGdldHRlcilcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpICYmICRleHBvcnQoJGV4cG9ydC5QICsgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWZvcmNlZC1wYW0gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1mb3JjZWQtcGFtLmpzXCIpLCAnT2JqZWN0Jywge1xyXG4gIF9fZGVmaW5lR2V0dGVyX186IGZ1bmN0aW9uIF9fZGVmaW5lR2V0dGVyX18oUCwgZ2V0dGVyKXtcclxuICAgICRkZWZpbmVQcm9wZXJ0eS5mKHRvT2JqZWN0KHRoaXMpLCBQLCB7Z2V0OiBhRnVuY3Rpb24oZ2V0dGVyKSwgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlfSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5kZWZpbmUtc2V0dGVyLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXIuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHRvT2JqZWN0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzXCIpXHJcbiAgLCBhRnVuY3Rpb24gICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hLWZ1bmN0aW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzXCIpXHJcbiAgLCAkZGVmaW5lUHJvcGVydHkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZHAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qc1wiKTtcclxuXHJcbi8vIEIuMi4yLjMgT2JqZWN0LnByb3RvdHlwZS5fX2RlZmluZVNldHRlcl9fKFAsIHNldHRlcilcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzXCIpICYmICRleHBvcnQoJGV4cG9ydC5QICsgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWZvcmNlZC1wYW0gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1mb3JjZWQtcGFtLmpzXCIpLCAnT2JqZWN0Jywge1xyXG4gIF9fZGVmaW5lU2V0dGVyX186IGZ1bmN0aW9uIF9fZGVmaW5lU2V0dGVyX18oUCwgc2V0dGVyKXtcclxuICAgICRkZWZpbmVQcm9wZXJ0eS5mKHRvT2JqZWN0KHRoaXMpLCBQLCB7c2V0OiBhRnVuY3Rpb24oc2V0dGVyKSwgZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlfSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5lbnRyaWVzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LXZhbHVlcy1lbnRyaWVzXHJcbnZhciAkZXhwb3J0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkZW50cmllcyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC10by1hcnJheSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXRvLWFycmF5LmpzXCIpKHRydWUpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7XHJcbiAgZW50cmllczogZnVuY3Rpb24gZW50cmllcyhpdCl7XHJcbiAgICByZXR1cm4gJGVudHJpZXMoaXQpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9ycy5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLW9iamVjdC1nZXRvd25wcm9wZXJ0eWRlc2NyaXB0b3JzXHJcbnZhciAkZXhwb3J0ICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCBvd25LZXlzICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX293bi1rZXlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vd24ta2V5cy5qc1wiKVxyXG4gICwgdG9JT2JqZWN0ICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1pb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pb2JqZWN0LmpzXCIpXHJcbiAgLCBnT1BEICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1nb3BkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qc1wiKVxyXG4gICwgY3JlYXRlUHJvcGVydHkgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jcmVhdGUtcHJvcGVydHkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qc1wiKTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge1xyXG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcnM6IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcnMob2JqZWN0KXtcclxuICAgIHZhciBPICAgICAgID0gdG9JT2JqZWN0KG9iamVjdClcclxuICAgICAgLCBnZXREZXNjID0gZ09QRC5mXHJcbiAgICAgICwga2V5cyAgICA9IG93bktleXMoTylcclxuICAgICAgLCByZXN1bHQgID0ge31cclxuICAgICAgLCBpICAgICAgID0gMFxyXG4gICAgICAsIGtleTtcclxuICAgIHdoaWxlKGtleXMubGVuZ3RoID4gaSljcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGtleSA9IGtleXNbaSsrXSwgZ2V0RGVzYyhPLCBrZXkpKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5sb29rdXAtZ2V0dGVyLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXIuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgJGV4cG9ydCAgICAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIHRvT2JqZWN0ICAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b1ByaW1pdGl2ZSAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL190by1wcmltaXRpdmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qc1wiKVxyXG4gICwgZ2V0UHJvdG90eXBlT2YgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdwbyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdwby5qc1wiKVxyXG4gICwgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdvcGQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzXCIpLmY7XHJcblxyXG4vLyBCLjIuMi40IE9iamVjdC5wcm90b3R5cGUuX19sb29rdXBHZXR0ZXJfXyhQKVxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZXNjcmlwdG9ycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanNcIikgJiYgJGV4cG9ydCgkZXhwb3J0LlAgKyBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZm9yY2VkLXBhbSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWZvcmNlZC1wYW0uanNcIiksICdPYmplY3QnLCB7XHJcbiAgX19sb29rdXBHZXR0ZXJfXzogZnVuY3Rpb24gX19sb29rdXBHZXR0ZXJfXyhQKXtcclxuICAgIHZhciBPID0gdG9PYmplY3QodGhpcylcclxuICAgICAgLCBLID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSlcclxuICAgICAgLCBEO1xyXG4gICAgZG8ge1xyXG4gICAgICBpZihEID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIEspKXJldHVybiBELmdldDtcclxuICAgIH0gd2hpbGUoTyA9IGdldFByb3RvdHlwZU9mKE8pKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1zZXR0ZXIuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QubG9va3VwLXNldHRlci5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbnZhciAkZXhwb3J0ICAgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgdG9PYmplY3QgICAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fdG8tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanNcIilcclxuICAsIHRvUHJpbWl0aXZlICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLXByaW1pdGl2ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzXCIpXHJcbiAgLCBnZXRQcm90b3R5cGVPZiAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ3BvICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzXCIpXHJcbiAgLCBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ29wZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcGQuanNcIikuZjtcclxuXHJcbi8vIEIuMi4yLjUgT2JqZWN0LnByb3RvdHlwZS5fX2xvb2t1cFNldHRlcl9fKFApXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2Rlc2NyaXB0b3JzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qc1wiKSAmJiAkZXhwb3J0KCRleHBvcnQuUCArIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX29iamVjdC1mb3JjZWQtcGFtICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZm9yY2VkLXBhbS5qc1wiKSwgJ09iamVjdCcsIHtcclxuICBfX2xvb2t1cFNldHRlcl9fOiBmdW5jdGlvbiBfX2xvb2t1cFNldHRlcl9fKFApe1xyXG4gICAgdmFyIE8gPSB0b09iamVjdCh0aGlzKVxyXG4gICAgICAsIEsgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKVxyXG4gICAgICAsIEQ7XHJcbiAgICBkbyB7XHJcbiAgICAgIGlmKEQgPSBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgSykpcmV0dXJuIEQuc2V0O1xyXG4gICAgfSB3aGlsZShPID0gZ2V0UHJvdG90eXBlT2YoTykpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QudmFsdWVzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QudmFsdWVzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LXZhbHVlcy1lbnRyaWVzXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsICR2YWx1ZXMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtdG8tYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC10by1hcnJheS5qc1wiKShmYWxzZSk7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcclxuICB2YWx1ZXM6IGZ1bmN0aW9uIHZhbHVlcyhpdCl7XHJcbiAgICByZXR1cm4gJHZhbHVlcyhpdCk7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9ic2VydmFibGUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9ic2VydmFibGUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96ZW5wYXJzaW5nL2VzLW9ic2VydmFibGVcclxudmFyICRleHBvcnQgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsIGdsb2JhbCAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIilcclxuICAsIGNvcmUgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fY29yZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29yZS5qc1wiKVxyXG4gICwgbWljcm90YXNrICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19taWNyb3Rhc2sgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21pY3JvdGFzay5qc1wiKSgpXHJcbiAgLCBPQlNFUlZBQkxFICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpKCdvYnNlcnZhYmxlJylcclxuICAsIGFGdW5jdGlvbiAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYS1mdW5jdGlvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qc1wiKVxyXG4gICwgYW5PYmplY3QgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKVxyXG4gICwgYW5JbnN0YW5jZSAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1pbnN0YW5jZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanNcIilcclxuICAsIHJlZGVmaW5lQWxsID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcmVkZWZpbmUtYWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanNcIilcclxuICAsIGhpZGUgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9faGlkZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qc1wiKVxyXG4gICwgZm9yT2YgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19mb3Itb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qc1wiKVxyXG4gICwgUkVUVVJOICAgICAgPSBmb3JPZi5SRVRVUk47XHJcblxyXG52YXIgZ2V0TWV0aG9kID0gZnVuY3Rpb24oZm4pe1xyXG4gIHJldHVybiBmbiA9PSBudWxsID8gdW5kZWZpbmVkIDogYUZ1bmN0aW9uKGZuKTtcclxufTtcclxuXHJcbnZhciBjbGVhbnVwU3Vic2NyaXB0aW9uID0gZnVuY3Rpb24oc3Vic2NyaXB0aW9uKXtcclxuICB2YXIgY2xlYW51cCA9IHN1YnNjcmlwdGlvbi5fYztcclxuICBpZihjbGVhbnVwKXtcclxuICAgIHN1YnNjcmlwdGlvbi5fYyA9IHVuZGVmaW5lZDtcclxuICAgIGNsZWFudXAoKTtcclxuICB9XHJcbn07XHJcblxyXG52YXIgc3Vic2NyaXB0aW9uQ2xvc2VkID0gZnVuY3Rpb24oc3Vic2NyaXB0aW9uKXtcclxuICByZXR1cm4gc3Vic2NyaXB0aW9uLl9vID09PSB1bmRlZmluZWQ7XHJcbn07XHJcblxyXG52YXIgY2xvc2VTdWJzY3JpcHRpb24gPSBmdW5jdGlvbihzdWJzY3JpcHRpb24pe1xyXG4gIGlmKCFzdWJzY3JpcHRpb25DbG9zZWQoc3Vic2NyaXB0aW9uKSl7XHJcbiAgICBzdWJzY3JpcHRpb24uX28gPSB1bmRlZmluZWQ7XHJcbiAgICBjbGVhbnVwU3Vic2NyaXB0aW9uKHN1YnNjcmlwdGlvbik7XHJcbiAgfVxyXG59O1xyXG5cclxudmFyIFN1YnNjcmlwdGlvbiA9IGZ1bmN0aW9uKG9ic2VydmVyLCBzdWJzY3JpYmVyKXtcclxuICBhbk9iamVjdChvYnNlcnZlcik7XHJcbiAgdGhpcy5fYyA9IHVuZGVmaW5lZDtcclxuICB0aGlzLl9vID0gb2JzZXJ2ZXI7XHJcbiAgb2JzZXJ2ZXIgPSBuZXcgU3Vic2NyaXB0aW9uT2JzZXJ2ZXIodGhpcyk7XHJcbiAgdHJ5IHtcclxuICAgIHZhciBjbGVhbnVwICAgICAgPSBzdWJzY3JpYmVyKG9ic2VydmVyKVxyXG4gICAgICAsIHN1YnNjcmlwdGlvbiA9IGNsZWFudXA7XHJcbiAgICBpZihjbGVhbnVwICE9IG51bGwpe1xyXG4gICAgICBpZih0eXBlb2YgY2xlYW51cC51bnN1YnNjcmliZSA9PT0gJ2Z1bmN0aW9uJyljbGVhbnVwID0gZnVuY3Rpb24oKXsgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7IH07XHJcbiAgICAgIGVsc2UgYUZ1bmN0aW9uKGNsZWFudXApO1xyXG4gICAgICB0aGlzLl9jID0gY2xlYW51cDtcclxuICAgIH1cclxuICB9IGNhdGNoKGUpe1xyXG4gICAgb2JzZXJ2ZXIuZXJyb3IoZSk7XHJcbiAgICByZXR1cm47XHJcbiAgfSBpZihzdWJzY3JpcHRpb25DbG9zZWQodGhpcykpY2xlYW51cFN1YnNjcmlwdGlvbih0aGlzKTtcclxufTtcclxuXHJcblN1YnNjcmlwdGlvbi5wcm90b3R5cGUgPSByZWRlZmluZUFsbCh7fSwge1xyXG4gIHVuc3Vic2NyaWJlOiBmdW5jdGlvbiB1bnN1YnNjcmliZSgpeyBjbG9zZVN1YnNjcmlwdGlvbih0aGlzKTsgfVxyXG59KTtcclxuXHJcbnZhciBTdWJzY3JpcHRpb25PYnNlcnZlciA9IGZ1bmN0aW9uKHN1YnNjcmlwdGlvbil7XHJcbiAgdGhpcy5fcyA9IHN1YnNjcmlwdGlvbjtcclxufTtcclxuXHJcblN1YnNjcmlwdGlvbk9ic2VydmVyLnByb3RvdHlwZSA9IHJlZGVmaW5lQWxsKHt9LCB7XHJcbiAgbmV4dDogZnVuY3Rpb24gbmV4dCh2YWx1ZSl7XHJcbiAgICB2YXIgc3Vic2NyaXB0aW9uID0gdGhpcy5fcztcclxuICAgIGlmKCFzdWJzY3JpcHRpb25DbG9zZWQoc3Vic2NyaXB0aW9uKSl7XHJcbiAgICAgIHZhciBvYnNlcnZlciA9IHN1YnNjcmlwdGlvbi5fbztcclxuICAgICAgdHJ5IHtcclxuICAgICAgICB2YXIgbSA9IGdldE1ldGhvZChvYnNlcnZlci5uZXh0KTtcclxuICAgICAgICBpZihtKXJldHVybiBtLmNhbGwob2JzZXJ2ZXIsIHZhbHVlKTtcclxuICAgICAgfSBjYXRjaChlKXtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgY2xvc2VTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcclxuICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9LFxyXG4gIGVycm9yOiBmdW5jdGlvbiBlcnJvcih2YWx1ZSl7XHJcbiAgICB2YXIgc3Vic2NyaXB0aW9uID0gdGhpcy5fcztcclxuICAgIGlmKHN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKXRocm93IHZhbHVlO1xyXG4gICAgdmFyIG9ic2VydmVyID0gc3Vic2NyaXB0aW9uLl9vO1xyXG4gICAgc3Vic2NyaXB0aW9uLl9vID0gdW5kZWZpbmVkO1xyXG4gICAgdHJ5IHtcclxuICAgICAgdmFyIG0gPSBnZXRNZXRob2Qob2JzZXJ2ZXIuZXJyb3IpO1xyXG4gICAgICBpZighbSl0aHJvdyB2YWx1ZTtcclxuICAgICAgdmFsdWUgPSBtLmNhbGwob2JzZXJ2ZXIsIHZhbHVlKTtcclxuICAgIH0gY2F0Y2goZSl7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xyXG4gICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgIHRocm93IGU7XHJcbiAgICAgIH1cclxuICAgIH0gY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG4gIH0sXHJcbiAgY29tcGxldGU6IGZ1bmN0aW9uIGNvbXBsZXRlKHZhbHVlKXtcclxuICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGlzLl9zO1xyXG4gICAgaWYoIXN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKXtcclxuICAgICAgdmFyIG9ic2VydmVyID0gc3Vic2NyaXB0aW9uLl9vO1xyXG4gICAgICBzdWJzY3JpcHRpb24uX28gPSB1bmRlZmluZWQ7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIG0gPSBnZXRNZXRob2Qob2JzZXJ2ZXIuY29tcGxldGUpO1xyXG4gICAgICAgIHZhbHVlID0gbSA/IG0uY2FsbChvYnNlcnZlciwgdmFsdWUpIDogdW5kZWZpbmVkO1xyXG4gICAgICB9IGNhdGNoKGUpe1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBjbGVhbnVwU3Vic2NyaXB0aW9uKHN1YnNjcmlwdGlvbik7XHJcbiAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgIHRocm93IGU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNsZWFudXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxufSk7XHJcblxyXG52YXIgJE9ic2VydmFibGUgPSBmdW5jdGlvbiBPYnNlcnZhYmxlKHN1YnNjcmliZXIpe1xyXG4gIGFuSW5zdGFuY2UodGhpcywgJE9ic2VydmFibGUsICdPYnNlcnZhYmxlJywgJ19mJykuX2YgPSBhRnVuY3Rpb24oc3Vic2NyaWJlcik7XHJcbn07XHJcblxyXG5yZWRlZmluZUFsbCgkT2JzZXJ2YWJsZS5wcm90b3R5cGUsIHtcclxuICBzdWJzY3JpYmU6IGZ1bmN0aW9uIHN1YnNjcmliZShvYnNlcnZlcil7XHJcbiAgICByZXR1cm4gbmV3IFN1YnNjcmlwdGlvbihvYnNlcnZlciwgdGhpcy5fZik7XHJcbiAgfSxcclxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGZuKXtcclxuICAgIHZhciB0aGF0ID0gdGhpcztcclxuICAgIHJldHVybiBuZXcgKGNvcmUuUHJvbWlzZSB8fCBnbG9iYWwuUHJvbWlzZSkoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcclxuICAgICAgYUZ1bmN0aW9uKGZuKTtcclxuICAgICAgdmFyIHN1YnNjcmlwdGlvbiA9IHRoYXQuc3Vic2NyaWJlKHtcclxuICAgICAgICBuZXh0IDogZnVuY3Rpb24odmFsdWUpe1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmV0dXJuIGZuKHZhbHVlKTtcclxuICAgICAgICAgIH0gY2F0Y2goZSl7XHJcbiAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvcjogcmVqZWN0LFxyXG4gICAgICAgIGNvbXBsZXRlOiByZXNvbHZlXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbnJlZGVmaW5lQWxsKCRPYnNlcnZhYmxlLCB7XHJcbiAgZnJvbTogZnVuY3Rpb24gZnJvbSh4KXtcclxuICAgIHZhciBDID0gdHlwZW9mIHRoaXMgPT09ICdmdW5jdGlvbicgPyB0aGlzIDogJE9ic2VydmFibGU7XHJcbiAgICB2YXIgbWV0aG9kID0gZ2V0TWV0aG9kKGFuT2JqZWN0KHgpW09CU0VSVkFCTEVdKTtcclxuICAgIGlmKG1ldGhvZCl7XHJcbiAgICAgIHZhciBvYnNlcnZhYmxlID0gYW5PYmplY3QobWV0aG9kLmNhbGwoeCkpO1xyXG4gICAgICByZXR1cm4gb2JzZXJ2YWJsZS5jb25zdHJ1Y3RvciA9PT0gQyA/IG9ic2VydmFibGUgOiBuZXcgQyhmdW5jdGlvbihvYnNlcnZlcil7XHJcbiAgICAgICAgcmV0dXJuIG9ic2VydmFibGUuc3Vic2NyaWJlKG9ic2VydmVyKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV3IEMoZnVuY3Rpb24ob2JzZXJ2ZXIpe1xyXG4gICAgICB2YXIgZG9uZSA9IGZhbHNlO1xyXG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24oKXtcclxuICAgICAgICBpZighZG9uZSl7XHJcbiAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZihmb3JPZih4LCBmYWxzZSwgZnVuY3Rpb24oaXQpe1xyXG4gICAgICAgICAgICAgIG9ic2VydmVyLm5leHQoaXQpO1xyXG4gICAgICAgICAgICAgIGlmKGRvbmUpcmV0dXJuIFJFVFVSTjtcclxuICAgICAgICAgICAgfSkgPT09IFJFVFVSTilyZXR1cm47XHJcbiAgICAgICAgICB9IGNhdGNoKGUpe1xyXG4gICAgICAgICAgICBpZihkb25lKXRocm93IGU7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGUpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9IG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCl7IGRvbmUgPSB0cnVlOyB9O1xyXG4gICAgfSk7XHJcbiAgfSxcclxuICBvZjogZnVuY3Rpb24gb2YoKXtcclxuICAgIGZvcih2YXIgaSA9IDAsIGwgPSBhcmd1bWVudHMubGVuZ3RoLCBpdGVtcyA9IEFycmF5KGwpOyBpIDwgbDspaXRlbXNbaV0gPSBhcmd1bWVudHNbaSsrXTtcclxuICAgIHJldHVybiBuZXcgKHR5cGVvZiB0aGlzID09PSAnZnVuY3Rpb24nID8gdGhpcyA6ICRPYnNlcnZhYmxlKShmdW5jdGlvbihvYnNlcnZlcil7XHJcbiAgICAgIHZhciBkb25lID0gZmFsc2U7XHJcbiAgICAgIG1pY3JvdGFzayhmdW5jdGlvbigpe1xyXG4gICAgICAgIGlmKCFkb25lKXtcclxuICAgICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7ICsraSl7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm5leHQoaXRlbXNbaV0pO1xyXG4gICAgICAgICAgICBpZihkb25lKXJldHVybjtcclxuICAgICAgICAgIH0gb2JzZXJ2ZXIuY29tcGxldGUoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gZnVuY3Rpb24oKXsgZG9uZSA9IHRydWU7IH07XHJcbiAgICB9KTtcclxuICB9XHJcbn0pO1xyXG5cclxuaGlkZSgkT2JzZXJ2YWJsZS5wcm90b3R5cGUsIE9CU0VSVkFCTEUsIGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9KTtcclxuXHJcbiRleHBvcnQoJGV4cG9ydC5HLCB7T2JzZXJ2YWJsZTogJE9ic2VydmFibGV9KTtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3NldC1zcGVjaWVzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qc1wiKSgnT2JzZXJ2YWJsZScpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5kZWZpbmUtbWV0YWRhdGEuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlZmluZS1tZXRhZGF0YS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgbWV0YWRhdGEgICAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21ldGFkYXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhZGF0YS5qc1wiKVxyXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCB0b01ldGFLZXkgICAgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5XHJcbiAgLCBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhID0gbWV0YWRhdGEuc2V0O1xyXG5cclxubWV0YWRhdGEuZXhwKHtkZWZpbmVNZXRhZGF0YTogZnVuY3Rpb24gZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgdGFyZ2V0S2V5KXtcclxuICBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlLCBhbk9iamVjdCh0YXJnZXQpLCB0b01ldGFLZXkodGFyZ2V0S2V5KSk7XHJcbn19KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZGVsZXRlLW1ldGFkYXRhLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5kZWxldGUtbWV0YWRhdGEuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIG1ldGFkYXRhICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tZXRhZGF0YSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWV0YWRhdGEuanNcIilcclxuICAsIGFuT2JqZWN0ICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKVxyXG4gICwgdG9NZXRhS2V5ICAgICAgICAgICAgICA9IG1ldGFkYXRhLmtleVxyXG4gICwgZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcCA9IG1ldGFkYXRhLm1hcFxyXG4gICwgc3RvcmUgICAgICAgICAgICAgICAgICA9IG1ldGFkYXRhLnN0b3JlO1xyXG5cclxubWV0YWRhdGEuZXhwKHtkZWxldGVNZXRhZGF0YTogZnVuY3Rpb24gZGVsZXRlTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiwgdGFyZ2V0S2V5ICovKXtcclxuICB2YXIgdGFyZ2V0S2V5ICAgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMl0pXHJcbiAgICAsIG1ldGFkYXRhTWFwID0gZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChhbk9iamVjdCh0YXJnZXQpLCB0YXJnZXRLZXksIGZhbHNlKTtcclxuICBpZihtZXRhZGF0YU1hcCA9PT0gdW5kZWZpbmVkIHx8ICFtZXRhZGF0YU1hcFsnZGVsZXRlJ10obWV0YWRhdGFLZXkpKXJldHVybiBmYWxzZTtcclxuICBpZihtZXRhZGF0YU1hcC5zaXplKXJldHVybiB0cnVlO1xyXG4gIHZhciB0YXJnZXRNZXRhZGF0YSA9IHN0b3JlLmdldCh0YXJnZXQpO1xyXG4gIHRhcmdldE1ldGFkYXRhWydkZWxldGUnXSh0YXJnZXRLZXkpO1xyXG4gIHJldHVybiAhIXRhcmdldE1ldGFkYXRhLnNpemUgfHwgc3RvcmVbJ2RlbGV0ZSddKHRhcmdldCk7XHJcbn19KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLWtleXMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLWtleXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgU2V0ICAgICAgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2VzNi5zZXQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnNldC5qc1wiKVxyXG4gICwgZnJvbSAgICAgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hcnJheS1mcm9tLWl0ZXJhYmxlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1mcm9tLWl0ZXJhYmxlLmpzXCIpXHJcbiAgLCBtZXRhZGF0YSAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21ldGFkYXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhZGF0YS5qc1wiKVxyXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKVxyXG4gICwgZ2V0UHJvdG90eXBlT2YgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ3BvICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzXCIpXHJcbiAgLCBvcmRpbmFyeU93bk1ldGFkYXRhS2V5cyA9IG1ldGFkYXRhLmtleXNcclxuICAsIHRvTWV0YUtleSAgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xyXG5cclxudmFyIG9yZGluYXJ5TWV0YWRhdGFLZXlzID0gZnVuY3Rpb24oTywgUCl7XHJcbiAgdmFyIG9LZXlzICA9IG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApXHJcbiAgICAsIHBhcmVudCA9IGdldFByb3RvdHlwZU9mKE8pO1xyXG4gIGlmKHBhcmVudCA9PT0gbnVsbClyZXR1cm4gb0tleXM7XHJcbiAgdmFyIHBLZXlzICA9IG9yZGluYXJ5TWV0YWRhdGFLZXlzKHBhcmVudCwgUCk7XHJcbiAgcmV0dXJuIHBLZXlzLmxlbmd0aCA/IG9LZXlzLmxlbmd0aCA/IGZyb20obmV3IFNldChvS2V5cy5jb25jYXQocEtleXMpKSkgOiBwS2V5cyA6IG9LZXlzO1xyXG59O1xyXG5cclxubWV0YWRhdGEuZXhwKHtnZXRNZXRhZGF0YUtleXM6IGZ1bmN0aW9uIGdldE1ldGFkYXRhS2V5cyh0YXJnZXQgLyosIHRhcmdldEtleSAqLyl7XHJcbiAgcmV0dXJuIG9yZGluYXJ5TWV0YWRhdGFLZXlzKGFuT2JqZWN0KHRhcmdldCksIGFyZ3VtZW50cy5sZW5ndGggPCAyID8gdW5kZWZpbmVkIDogdG9NZXRhS2V5KGFyZ3VtZW50c1sxXSkpO1xyXG59fSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1tZXRhZGF0YS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbnZhciBtZXRhZGF0YSAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fbWV0YWRhdGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGFkYXRhLmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYW4tb2JqZWN0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanNcIilcclxuICAsIGdldFByb3RvdHlwZU9mICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19vYmplY3QtZ3BvICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzXCIpXHJcbiAgLCBvcmRpbmFyeUhhc093bk1ldGFkYXRhID0gbWV0YWRhdGEuaGFzXHJcbiAgLCBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gbWV0YWRhdGEuZ2V0XHJcbiAgLCB0b01ldGFLZXkgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xyXG5cclxudmFyIG9yZGluYXJ5R2V0TWV0YWRhdGEgPSBmdW5jdGlvbihNZXRhZGF0YUtleSwgTywgUCl7XHJcbiAgdmFyIGhhc093biA9IG9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xyXG4gIGlmKGhhc093bilyZXR1cm4gb3JkaW5hcnlHZXRPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XHJcbiAgdmFyIHBhcmVudCA9IGdldFByb3RvdHlwZU9mKE8pO1xyXG4gIHJldHVybiBwYXJlbnQgIT09IG51bGwgPyBvcmRpbmFyeUdldE1ldGFkYXRhKE1ldGFkYXRhS2V5LCBwYXJlbnQsIFApIDogdW5kZWZpbmVkO1xyXG59O1xyXG5cclxubWV0YWRhdGEuZXhwKHtnZXRNZXRhZGF0YTogZnVuY3Rpb24gZ2V0TWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiwgdGFyZ2V0S2V5ICovKXtcclxuICByZXR1cm4gb3JkaW5hcnlHZXRNZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XHJcbn19KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW93bi1tZXRhZGF0YS1rZXlzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhLWtleXMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIG1ldGFkYXRhICAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fbWV0YWRhdGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGFkYXRhLmpzXCIpXHJcbiAgLCBhbk9iamVjdCAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCBvcmRpbmFyeU93bk1ldGFkYXRhS2V5cyA9IG1ldGFkYXRhLmtleXNcclxuICAsIHRvTWV0YUtleSAgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xyXG5cclxubWV0YWRhdGEuZXhwKHtnZXRPd25NZXRhZGF0YUtleXM6IGZ1bmN0aW9uIGdldE93bk1ldGFkYXRhS2V5cyh0YXJnZXQgLyosIHRhcmdldEtleSAqLyl7XHJcbiAgcmV0dXJuIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKGFuT2JqZWN0KHRhcmdldCksIGFyZ3VtZW50cy5sZW5ndGggPCAyID8gdW5kZWZpbmVkIDogdG9NZXRhS2V5KGFyZ3VtZW50c1sxXSkpO1xyXG59fSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1vd24tbWV0YWRhdGEuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgbWV0YWRhdGEgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21ldGFkYXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhZGF0YS5qc1wiKVxyXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gbWV0YWRhdGEuZ2V0XHJcbiAgLCB0b01ldGFLZXkgICAgICAgICAgICAgID0gbWV0YWRhdGEua2V5O1xyXG5cclxubWV0YWRhdGEuZXhwKHtnZXRPd25NZXRhZGF0YTogZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiwgdGFyZ2V0S2V5ICovKXtcclxuICByZXR1cm4gb3JkaW5hcnlHZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KVxyXG4gICAgLCBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMl0pKTtcclxufX0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5oYXMtbWV0YWRhdGEuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0Lmhhcy1tZXRhZGF0YS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgbWV0YWRhdGEgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21ldGFkYXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhZGF0YS5qc1wiKVxyXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCBnZXRQcm90b3R5cGVPZiAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fb2JqZWN0LWdwbyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdwby5qc1wiKVxyXG4gICwgb3JkaW5hcnlIYXNPd25NZXRhZGF0YSA9IG1ldGFkYXRhLmhhc1xyXG4gICwgdG9NZXRhS2V5ICAgICAgICAgICAgICA9IG1ldGFkYXRhLmtleTtcclxuXHJcbnZhciBvcmRpbmFyeUhhc01ldGFkYXRhID0gZnVuY3Rpb24oTWV0YWRhdGFLZXksIE8sIFApe1xyXG4gIHZhciBoYXNPd24gPSBvcmRpbmFyeUhhc093bk1ldGFkYXRhKE1ldGFkYXRhS2V5LCBPLCBQKTtcclxuICBpZihoYXNPd24pcmV0dXJuIHRydWU7XHJcbiAgdmFyIHBhcmVudCA9IGdldFByb3RvdHlwZU9mKE8pO1xyXG4gIHJldHVybiBwYXJlbnQgIT09IG51bGwgPyBvcmRpbmFyeUhhc01ldGFkYXRhKE1ldGFkYXRhS2V5LCBwYXJlbnQsIFApIDogZmFsc2U7XHJcbn07XHJcblxyXG5tZXRhZGF0YS5leHAoe2hhc01ldGFkYXRhOiBmdW5jdGlvbiBoYXNNZXRhZGF0YShtZXRhZGF0YUtleSwgdGFyZ2V0IC8qLCB0YXJnZXRLZXkgKi8pe1xyXG4gIHJldHVybiBvcmRpbmFyeUhhc01ldGFkYXRhKG1ldGFkYXRhS2V5LCBhbk9iamVjdCh0YXJnZXQpLCBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMl0pKTtcclxufX0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5oYXMtb3duLW1ldGFkYXRhLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuaGFzLW93bi1tZXRhZGF0YS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyIG1ldGFkYXRhICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19tZXRhZGF0YSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWV0YWRhdGEuanNcIilcclxuICAsIGFuT2JqZWN0ICAgICAgICAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19hbi1vYmplY3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qc1wiKVxyXG4gICwgb3JkaW5hcnlIYXNPd25NZXRhZGF0YSA9IG1ldGFkYXRhLmhhc1xyXG4gICwgdG9NZXRhS2V5ICAgICAgICAgICAgICA9IG1ldGFkYXRhLmtleTtcclxuXHJcbm1ldGFkYXRhLmV4cCh7aGFzT3duTWV0YWRhdGE6IGZ1bmN0aW9uIGhhc093bk1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQgLyosIHRhcmdldEtleSAqLyl7XHJcbiAgcmV0dXJuIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIGFuT2JqZWN0KHRhcmdldClcclxuICAgICwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XHJcbn19KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QubWV0YWRhdGEuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QubWV0YWRhdGEuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG52YXIgbWV0YWRhdGEgICAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX21ldGFkYXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhZGF0YS5qc1wiKVxyXG4gICwgYW5PYmplY3QgICAgICAgICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2FuLW9iamVjdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzXCIpXHJcbiAgLCBhRnVuY3Rpb24gICAgICAgICAgICAgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fYS1mdW5jdGlvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qc1wiKVxyXG4gICwgdG9NZXRhS2V5ICAgICAgICAgICAgICAgICA9IG1ldGFkYXRhLmtleVxyXG4gICwgb3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YSA9IG1ldGFkYXRhLnNldDtcclxuXHJcbm1ldGFkYXRhLmV4cCh7bWV0YWRhdGE6IGZ1bmN0aW9uIG1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKXtcclxuICByZXR1cm4gZnVuY3Rpb24gZGVjb3JhdG9yKHRhcmdldCwgdGFyZ2V0S2V5KXtcclxuICAgIG9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEoXHJcbiAgICAgIG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlLFxyXG4gICAgICAodGFyZ2V0S2V5ICE9PSB1bmRlZmluZWQgPyBhbk9iamVjdCA6IGFGdW5jdGlvbikodGFyZ2V0KSxcclxuICAgICAgdG9NZXRhS2V5KHRhcmdldEtleSlcclxuICAgICk7XHJcbiAgfTtcclxufX0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc2V0LnRvLWpzb24uanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zZXQudG8tanNvbi5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXHJcbnZhciAkZXhwb3J0ICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdTZXQnLCB7dG9KU09OOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19jb2xsZWN0aW9uLXRvLWpzb24gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24tdG8tanNvbi5qc1wiKSgnU2V0Jyl9KTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN0cmluZy5hdC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcuYXQuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gaHR0cHM6Ly9naXRodWIuY29tL21hdGhpYXNieW5lbnMvU3RyaW5nLnByb3RvdHlwZS5hdFxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpXHJcbiAgLCAkYXQgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLWF0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctYXQuanNcIikodHJ1ZSk7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcclxuICBhdDogZnVuY3Rpb24gYXQocG9zKXtcclxuICAgIHJldHVybiAkYXQodGhpcywgcG9zKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLm1hdGNoLWFsbC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLm1hdGNoLWFsbC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9TdHJpbmcucHJvdG90eXBlLm1hdGNoQWxsL1xyXG52YXIgJGV4cG9ydCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgZGVmaW5lZCAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19kZWZpbmVkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzXCIpXHJcbiAgLCB0b0xlbmd0aCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3RvLWxlbmd0aCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzXCIpXHJcbiAgLCBpc1JlZ0V4cCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2lzLXJlZ2V4cCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtcmVnZXhwLmpzXCIpXHJcbiAgLCBnZXRGbGFncyAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ZsYWdzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mbGFncy5qc1wiKVxyXG4gICwgUmVnRXhwUHJvdG8gPSBSZWdFeHAucHJvdG90eXBlO1xyXG5cclxudmFyICRSZWdFeHBTdHJpbmdJdGVyYXRvciA9IGZ1bmN0aW9uKHJlZ2V4cCwgc3RyaW5nKXtcclxuICB0aGlzLl9yID0gcmVnZXhwO1xyXG4gIHRoaXMuX3MgPSBzdHJpbmc7XHJcbn07XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyLWNyZWF0ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jcmVhdGUuanNcIikoJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yLCAnUmVnRXhwIFN0cmluZycsIGZ1bmN0aW9uIG5leHQoKXtcclxuICB2YXIgbWF0Y2ggPSB0aGlzLl9yLmV4ZWModGhpcy5fcyk7XHJcbiAgcmV0dXJuIHt2YWx1ZTogbWF0Y2gsIGRvbmU6IG1hdGNoID09PSBudWxsfTtcclxufSk7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcclxuICBtYXRjaEFsbDogZnVuY3Rpb24gbWF0Y2hBbGwocmVnZXhwKXtcclxuICAgIGRlZmluZWQodGhpcyk7XHJcbiAgICBpZighaXNSZWdFeHAocmVnZXhwKSl0aHJvdyBUeXBlRXJyb3IocmVnZXhwICsgJyBpcyBub3QgYSByZWdleHAhJyk7XHJcbiAgICB2YXIgUyAgICAgPSBTdHJpbmcodGhpcylcclxuICAgICAgLCBmbGFncyA9ICdmbGFncycgaW4gUmVnRXhwUHJvdG8gPyBTdHJpbmcocmVnZXhwLmZsYWdzKSA6IGdldEZsYWdzLmNhbGwocmVnZXhwKVxyXG4gICAgICAsIHJ4ICAgID0gbmV3IFJlZ0V4cChyZWdleHAuc291cmNlLCB+ZmxhZ3MuaW5kZXhPZignZycpID8gZmxhZ3MgOiAnZycgKyBmbGFncyk7XHJcbiAgICByeC5sYXN0SW5kZXggPSB0b0xlbmd0aChyZWdleHAubGFzdEluZGV4KTtcclxuICAgIHJldHVybiBuZXcgJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKHJ4LCBTKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1lbmQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXN0cmluZy1wYWQtc3RhcnQtZW5kXHJcbnZhciAkZXhwb3J0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZXhwb3J0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanNcIilcclxuICAsICRwYWQgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJpbmctcGFkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctcGFkLmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlAsICdTdHJpbmcnLCB7XHJcbiAgcGFkRW5kOiBmdW5jdGlvbiBwYWRFbmQobWF4TGVuZ3RoIC8qLCBmaWxsU3RyaW5nID0gJyAnICovKXtcclxuICAgIHJldHVybiAkcGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIGZhbHNlKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLXBhZC1zdGFydC1lbmRcclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgJHBhZCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy1wYWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1wYWQuanNcIik7XHJcblxyXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcclxuICBwYWRTdGFydDogZnVuY3Rpb24gcGFkU3RhcnQobWF4TGVuZ3RoIC8qLCBmaWxsU3RyaW5nID0gJyAnICovKXtcclxuICAgIHJldHVybiAkcGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIHRydWUpO1xyXG4gIH1cclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1sZWZ0LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1sZWZ0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vc2VibWFya2JhZ2UvZWNtYXNjcmlwdC1zdHJpbmctbGVmdC1yaWdodC10cmltXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmluZy10cmltICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctdHJpbS5qc1wiKSgndHJpbUxlZnQnLCBmdW5jdGlvbigkdHJpbSl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIHRyaW1MZWZ0KCl7XHJcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMSk7XHJcbiAgfTtcclxufSwgJ3RyaW1TdGFydCcpO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tcmlnaHQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1yaWdodC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zZWJtYXJrYmFnZS9lY21hc2NyaXB0LXN0cmluZy1sZWZ0LXJpZ2h0LXRyaW1cclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyaW5nLXRyaW0gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy10cmltLmpzXCIpKCd0cmltUmlnaHQnLCBmdW5jdGlvbigkdHJpbSl7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uIHRyaW1SaWdodCgpe1xyXG4gICAgcmV0dXJuICR0cmltKHRoaXMsIDIpO1xyXG4gIH07XHJcbn0sICd0cmltRW5kJyk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zeW1ib2wuYXN5bmMtaXRlcmF0b3IuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL193a3MtZGVmaW5lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MtZGVmaW5lLmpzXCIpKCdhc3luY0l0ZXJhdG9yJyk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zeW1ib2wub2JzZXJ2YWJsZS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5bWJvbC5vYnNlcnZhYmxlLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcy1kZWZpbmUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy1kZWZpbmUuanNcIikoJ29ic2VydmFibGUnKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL3Byb3Bvc2FsLWdsb2JhbFxyXG52YXIgJGV4cG9ydCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2V4cG9ydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzXCIpO1xyXG5cclxuJGV4cG9ydCgkZXhwb3J0LlMsICdTeXN0ZW0nLCB7Z2xvYmFsOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKX0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRpdGVyYXRvcnMgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2VzNi5hcnJheS5pdGVyYXRvciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaXRlcmF0b3IuanNcIilcclxuICAsIHJlZGVmaW5lICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19yZWRlZmluZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanNcIilcclxuICAsIGdsb2JhbCAgICAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qc1wiKVxyXG4gICwgaGlkZSAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2hpZGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hpZGUuanNcIilcclxuICAsIEl0ZXJhdG9ycyAgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19pdGVyYXRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXJhdG9ycy5qc1wiKVxyXG4gICwgd2tzICAgICAgICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3drcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzXCIpXHJcbiAgLCBJVEVSQVRPUiAgICAgID0gd2tzKCdpdGVyYXRvcicpXHJcbiAgLCBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpXHJcbiAgLCBBcnJheVZhbHVlcyAgID0gSXRlcmF0b3JzLkFycmF5O1xyXG5cclxuZm9yKHZhciBjb2xsZWN0aW9ucyA9IFsnTm9kZUxpc3QnLCAnRE9NVG9rZW5MaXN0JywgJ01lZGlhTGlzdCcsICdTdHlsZVNoZWV0TGlzdCcsICdDU1NSdWxlTGlzdCddLCBpID0gMDsgaSA8IDU7IGkrKyl7XHJcbiAgdmFyIE5BTUUgICAgICAgPSBjb2xsZWN0aW9uc1tpXVxyXG4gICAgLCBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdXHJcbiAgICAsIHByb3RvICAgICAgPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlXHJcbiAgICAsIGtleTtcclxuICBpZihwcm90byl7XHJcbiAgICBpZighcHJvdG9bSVRFUkFUT1JdKWhpZGUocHJvdG8sIElURVJBVE9SLCBBcnJheVZhbHVlcyk7XHJcbiAgICBpZighcHJvdG9bVE9fU1RSSU5HX1RBR10paGlkZShwcm90bywgVE9fU1RSSU5HX1RBRywgTkFNRSk7XHJcbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBBcnJheVZhbHVlcztcclxuICAgIGZvcihrZXkgaW4gJGl0ZXJhdG9ycylpZighcHJvdG9ba2V5XSlyZWRlZmluZShwcm90bywga2V5LCAkaXRlcmF0b3JzW2tleV0sIHRydWUpO1xyXG4gIH1cclxufVxyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuaW1tZWRpYXRlLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLmltbWVkaWF0ZS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxudmFyICRleHBvcnQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgJHRhc2sgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3Rhc2sgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanNcIik7XHJcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5CLCB7XHJcbiAgc2V0SW1tZWRpYXRlOiAgICR0YXNrLnNldCxcclxuICBjbGVhckltbWVkaWF0ZTogJHRhc2suY2xlYXJcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL3dlYi50aW1lcnMuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIudGltZXJzLmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG4vLyBpZTktIHNldFRpbWVvdXQgJiBzZXRJbnRlcnZhbCBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgZml4XHJcbnZhciBnbG9iYWwgICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fZ2xvYmFsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanNcIilcclxuICAsICRleHBvcnQgICAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19leHBvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qc1wiKVxyXG4gICwgaW52b2tlICAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX2ludm9rZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW52b2tlLmpzXCIpXHJcbiAgLCBwYXJ0aWFsICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fcGFydGlhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGFydGlhbC5qc1wiKVxyXG4gICwgbmF2aWdhdG9yICA9IGdsb2JhbC5uYXZpZ2F0b3JcclxuICAsIE1TSUUgICAgICAgPSAhIW5hdmlnYXRvciAmJiAvTVNJRSAuXFwuLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpOyAvLyA8LSBkaXJ0eSBpZTktIGNoZWNrXHJcbnZhciB3cmFwID0gZnVuY3Rpb24oc2V0KXtcclxuICByZXR1cm4gTVNJRSA/IGZ1bmN0aW9uKGZuLCB0aW1lIC8qLCAuLi5hcmdzICovKXtcclxuICAgIHJldHVybiBzZXQoaW52b2tlKFxyXG4gICAgICBwYXJ0aWFsLFxyXG4gICAgICBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMiksXHJcbiAgICAgIHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbilcclxuICAgICksIHRpbWUpO1xyXG4gIH0gOiBzZXQ7XHJcbn07XHJcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5CICsgJGV4cG9ydC5GICogTVNJRSwge1xyXG4gIHNldFRpbWVvdXQ6ICB3cmFwKGdsb2JhbC5zZXRUaW1lb3V0KSxcclxuICBzZXRJbnRlcnZhbDogd3JhcChnbG9iYWwuc2V0SW50ZXJ2YWwpXHJcbn0pO1xyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvc2hpbS5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2NvcmUtanMvc2hpbS5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuc3ltYm9sICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYub2JqZWN0LmNyZWF0ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmNyZWF0ZS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnR5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnR5LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm9iamVjdC5kZWZpbmUtcHJvcGVydGllcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0aWVzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYub2JqZWN0LmdldC1wcm90b3R5cGUtb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtcHJvdG90eXBlLW9mLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm9iamVjdC5rZXlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cy5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1uYW1lcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktbmFtZXMuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYub2JqZWN0LmZyZWV6ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmZyZWV6ZS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5vYmplY3Quc2VhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnNlYWwuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYub2JqZWN0LnByZXZlbnQtZXh0ZW5zaW9ucyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnByZXZlbnQtZXh0ZW5zaW9ucy5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZnJvemVuICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZnJvemVuLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1zZWFsZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1zZWFsZWQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYub2JqZWN0LmlzLWV4dGVuc2libGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1leHRlbnNpYmxlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYub2JqZWN0LmlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYub2JqZWN0LnNldC1wcm90b3R5cGUtb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmhhcy1pbnN0YW5jZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZnVuY3Rpb24uaGFzLWluc3RhbmNlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnBhcnNlLWludCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtaW50LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnBhcnNlLWZsb2F0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5wYXJzZS1mbG9hdC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5udW1iZXIuY29uc3RydWN0b3IgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5jb25zdHJ1Y3Rvci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5udW1iZXIudG8tZml4ZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci50by1maXhlZC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5udW1iZXIudG8tcHJlY2lzaW9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIudG8tcHJlY2lzaW9uLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm51bWJlci5lcHNpbG9uICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuZXBzaWxvbi5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtZmluaXRlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtZmluaXRlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm51bWJlci5pcy1pbnRlZ2VyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtaW50ZWdlci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtbmFuICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtbmFuLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm51bWJlci5pcy1zYWZlLWludGVnZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1zYWZlLWludGVnZXIuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubnVtYmVyLm1heC1zYWZlLWludGVnZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5tYXgtc2FmZS1pbnRlZ2VyLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm51bWJlci5taW4tc2FmZS1pbnRlZ2VyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIubWluLXNhZmUtaW50ZWdlci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtZmxvYXQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm1hdGguYWNvc2ggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYWNvc2guanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC5hc2luaCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hc2luaC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5tYXRoLmF0YW5oICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmF0YW5oLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm1hdGguY2JydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jYnJ0LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm1hdGguY2x6MzIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguY2x6MzIuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC5jb3NoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNvc2guanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC5leHBtMSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5leHBtMS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5tYXRoLmZyb3VuZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5mcm91bmQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC5oeXBvdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5oeXBvdC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5tYXRoLmltdWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguaW11bC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzEwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzEwLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2Lm1hdGgubG9nMXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMXAuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC5sb2cyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzIuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC5zaWduICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnNpZ24uanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC5zaW5oICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnNpbmguanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC50YW5oICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnRhbmguanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWF0aC50cnVuYyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC50cnVuYy5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5zdHJpbmcuZnJvbS1jb2RlLXBvaW50ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZnJvbS1jb2RlLXBvaW50LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5yYXcgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5yYXcuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy50cmltLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5jb2RlLXBvaW50LWF0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuY29kZS1wb2ludC1hdC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5zdHJpbmcuZW5kcy13aXRoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZW5kcy13aXRoLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5pbmNsdWRlcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmluY2x1ZGVzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5yZXBlYXQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5yZXBlYXQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuc3RyaW5nLnN0YXJ0cy13aXRoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3RhcnRzLXdpdGguanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmlnICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuYmlnLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5ibGluayAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJsaW5rLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5ib2xkICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuYm9sZC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5maXhlZC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5zdHJpbmcuZm9udGNvbG9yICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZm9udGNvbG9yLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5mb250c2l6ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRzaXplLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5pdGFsaWNzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRhbGljcy5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5zdHJpbmcubGluayAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmxpbmsuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuc3RyaW5nLnNtYWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc21hbGwuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuc3RyaW5nLnN0cmlrZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN0cmlrZS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3ViICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3ViLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnN0cmluZy5zdXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdXAuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuZGF0ZS5ub3cgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUubm93LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmRhdGUudG8tanNvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1qc29uLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmRhdGUudG8taXNvLXN0cmluZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1pc28tc3RyaW5nLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmRhdGUudG8tc3RyaW5nICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLXN0cmluZy5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5kYXRlLnRvLXByaW1pdGl2ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1wcmltaXRpdmUuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmlzLWFycmF5LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LmZyb20gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZyb20uanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuYXJyYXkub2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lm9mLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LmpvaW4gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmpvaW4uanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuYXJyYXkuc2xpY2UgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNsaWNlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LnNvcnQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvcnQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuYXJyYXkuZm9yLWVhY2ggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZvci1lYWNoLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5Lm1hcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubWFwLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LmZpbHRlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsdGVyLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LnNvbWUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvbWUuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuYXJyYXkuZXZlcnkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmV2ZXJ5LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS1yaWdodCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlLXJpZ2h0LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LmluZGV4LW9mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pbmRleC1vZi5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5hcnJheS5sYXN0LWluZGV4LW9mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5sYXN0LWluZGV4LW9mLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LmNvcHktd2l0aGluICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5jb3B5LXdpdGhpbi5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5hcnJheS5maWxsICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maWxsLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5LmZpbmQgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbmQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuYXJyYXkuZmluZC1pbmRleCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmluZC1pbmRleC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5yZWdleHAuY29uc3RydWN0b3IgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5jb25zdHJ1Y3Rvci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5yZWdleHAudG8tc3RyaW5nICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAudG8tc3RyaW5nLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZ2V4cC5mbGFncyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLmZsYWdzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZ2V4cC5tYXRjaCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLm1hdGNoLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZ2V4cC5yZXBsYWNlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAucmVwbGFjZS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5yZWdleHAuc2VhcmNoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuc2VhcmNoLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZ2V4cC5zcGxpdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnNwbGl0LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnByb21pc2UgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnByb21pc2UuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYubWFwICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXAuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYuc2V0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zZXQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYud2Vhay1tYXAgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LndlYWstbWFwLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LndlYWstc2V0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi53ZWFrLXNldC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi50eXBlZC5hcnJheS1idWZmZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmFycmF5LWJ1ZmZlci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi50eXBlZC5kYXRhLXZpZXcgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmRhdGEtdmlldy5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQ4LWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQ4LWFycmF5LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQ4LWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1hcnJheS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnR5cGVkLmludDE2LWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi50eXBlZC51aW50MTYtYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQxNi1hcnJheS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQzMi1hcnJheSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50MzItYXJyYXkuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYudHlwZWQudWludDMyLWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50MzItYXJyYXkuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYudHlwZWQuZmxvYXQzMi1hcnJheSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZmxvYXQzMi1hcnJheS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDY0LWFycmF5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDY0LWFycmF5LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZmxlY3QuYXBwbHkgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuYXBwbHkuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYucmVmbGVjdC5jb25zdHJ1Y3QgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuY29uc3RydWN0LmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVmaW5lLXByb3BlcnR5ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlZmluZS1wcm9wZXJ0eS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlbGV0ZS1wcm9wZXJ0eSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5kZWxldGUtcHJvcGVydHkuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYucmVmbGVjdC5lbnVtZXJhdGUgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZW51bWVyYXRlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtcHJvdG90eXBlLW9mICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYucmVmbGVjdC5oYXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuaGFzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZmxlY3QuaXMtZXh0ZW5zaWJsZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5pcy1leHRlbnNpYmxlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczYucmVmbGVjdC5wcmV2ZW50LWV4dGVuc2lvbnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QucHJldmVudC1leHRlbnNpb25zLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC1wcm90b3R5cGUtb2YgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0LXByb3RvdHlwZS1vZi5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuYXJyYXkuaW5jbHVkZXMuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcuc3RyaW5nLmF0ICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcuYXQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1lbmQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tbGVmdCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tbGVmdC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1yaWdodCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tcmlnaHQuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcuc3RyaW5nLm1hdGNoLWFsbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLm1hdGNoLWFsbC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5zeW1ib2wuYXN5bmMtaXRlcmF0b3IgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5bWJvbC5hc3luYy1pdGVyYXRvci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5zeW1ib2wub2JzZXJ2YWJsZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3ltYm9sLm9ic2VydmFibGUuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcnMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3Lm9iamVjdC52YWx1ZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC52YWx1ZXMuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5lbnRyaWVzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3Lm9iamVjdC5kZWZpbmUtZ2V0dGVyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QuZGVmaW5lLWdldHRlci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5vYmplY3QuZGVmaW5lLXNldHRlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXIuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5sb29rdXAtZ2V0dGVyLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3Lm9iamVjdC5sb29rdXAtc2V0dGVyICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QubG9va3VwLXNldHRlci5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5tYXAudG8tanNvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWFwLnRvLWpzb24uanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcuc2V0LnRvLWpzb24gKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnNldC50by1qc29uLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcuZXJyb3IuaXMtZXJyb3IgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LmVycm9yLmlzLWVycm9yLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3Lm1hdGguaWFkZGggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaWFkZGguanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcubWF0aC5pc3ViaCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5pc3ViaC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5tYXRoLmltdWxoICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXRoLmltdWxoLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3Lm1hdGgudW11bGggKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGgudW11bGguanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcucmVmbGVjdC5kZWZpbmUtbWV0YWRhdGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZGVmaW5lLW1ldGFkYXRhLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3LnJlZmxlY3QuZGVsZXRlLW1ldGFkYXRhICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlbGV0ZS1tZXRhZGF0YS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1tZXRhZGF0YSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtbWV0YWRhdGEuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtbWV0YWRhdGEta2V5cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtbWV0YWRhdGEta2V5cy5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1vd24tbWV0YWRhdGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW93bi1tZXRhZGF0YS5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1vd24tbWV0YWRhdGEta2V5cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhLWtleXMuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcucmVmbGVjdC5oYXMtbWV0YWRhdGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuaGFzLW1ldGFkYXRhLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3LnJlZmxlY3QuaGFzLW93bi1tZXRhZGF0YSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5oYXMtb3duLW1ldGFkYXRhLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvZXM3LnJlZmxlY3QubWV0YWRhdGEgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QubWV0YWRhdGEuanNcIik7XHJcbl9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9lczcuYXNhcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuYXNhcC5qc1wiKTtcclxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9tb2R1bGVzL2VzNy5vYnNlcnZhYmxlICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYnNlcnZhYmxlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvd2ViLnRpbWVycyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIudGltZXJzLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvd2ViLmltbWVkaWF0ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuaW1tZWRpYXRlLmpzXCIpO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbW9kdWxlcy9fY29yZSAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29yZS5qc1wiKTtcclxuXHJcbi8qKiovIH0pLFxyXG5cclxuLyoqKi8gXCIuL3NyYy9Db21tb24vTGlicmFyaWVzL1dlYnNvY2tldHMvQ2xvdWRTaGFyZVdlYlNvY2tldHMvY2xvdWRzaGFyZS13ZWJzb2NrZXRzLmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vc3JjL0NvbW1vbi9MaWJyYXJpZXMvV2Vic29ja2V0cy9DbG91ZFNoYXJlV2ViU29ja2V0cy9jbG91ZHNoYXJlLXdlYnNvY2tldHMuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgZXhwb3J0cyBwcm92aWRlZDogZGVmYXVsdCAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBfX3dlYnBhY2tfZXhwb3J0c19fLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuX193ZWJwYWNrX3JlcXVpcmVfXy5yKF9fd2VicGFja19leHBvcnRzX18pO1xyXG4vKiBoYXJtb255IGV4cG9ydCAoYmluZGluZykgKi8gX193ZWJwYWNrX3JlcXVpcmVfXy5kKF9fd2VicGFja19leHBvcnRzX18sIFwiZGVmYXVsdFwiLCBmdW5jdGlvbigpIHsgcmV0dXJuIENsb3VkU2hhcmVXZWJTb2NrZXRzOyB9KTtcclxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cclxuXHJcbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cclxuXHJcbmZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XHJcblxyXG52YXIgQ2xvdWRTaGFyZVdlYlNvY2tldHMgPVxyXG4vKiNfX1BVUkVfXyovXHJcbmZ1bmN0aW9uICgpIHtcclxuICBmdW5jdGlvbiBDbG91ZFNoYXJlV2ViU29ja2V0cyhXZWJTb2NrZXRDbGllbnQpIHtcclxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDbG91ZFNoYXJlV2ViU29ja2V0cyk7XHJcblxyXG4gICAgdGhpcy5fV2ViU29ja2V0Q2xpZW50ID0gV2ViU29ja2V0Q2xpZW50O1xyXG4gIH1cclxuXHJcbiAgX2NyZWF0ZUNsYXNzKENsb3VkU2hhcmVXZWJTb2NrZXRzLCBbe1xyXG4gICAga2V5OiBcImxpc3RlblwiLFxyXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGxpc3RlbihvcHRpb25zKSB7XHJcbiAgICAgIHZhciBnZXRPcHRpb25zT25SZWNvbm5lY3QgPSBudWxsO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnRva2VuUmVmcmVzaGVyID09PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICBnZXRPcHRpb25zT25SZWNvbm5lY3QgPSB0aGlzLl9jcmVhdGVHZXRPcHRpb25zT25SZWNvbm5lY3Qob3B0aW9ucy50b2tlblJlZnJlc2hlcik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBuZXcgdGhpcy5fV2ViU29ja2V0Q2xpZW50KHtcclxuICAgICAgICBwcm90b2NvbEFuZEhvc3Q6IG9wdGlvbnMucHJvdG9jb2xBbmRIb3N0LFxyXG4gICAgICAgIHBhdGg6IFwiL3dlYnNvY2tldHMvXCIuY29uY2F0KG9wdGlvbnMuZGlzcGF0Y2hlck5hbWUpLFxyXG4gICAgICAgIHF1ZXJ5OiB7XHJcbiAgICAgICAgICB0b2tlbjogb3B0aW9ucy50b2tlblxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgb25vcGVuOiBvcHRpb25zLm9ub3BlbixcclxuICAgICAgICBvbmNsb3NlOiBvcHRpb25zLm9uY2xvc2UsXHJcbiAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yLFxyXG4gICAgICAgIG9ubWVzc2FnZTogdGhpcy5fY3JlYXRlT25tZXNzYWdlTGlzdGVuZXIob3B0aW9ucy5vbm1lc3NhZ2UsIG9wdGlvbnMub250b3BpY0xpc3RlbmVycyksXHJcbiAgICAgICAgbm9SZXRyeTogb3B0aW9ucy5ub1JldHJ5LFxyXG4gICAgICAgIHJldHJ5SW50ZXJ2YWxNczogb3B0aW9ucy5yZXRyeUludGVydmFsTXMsXHJcbiAgICAgICAgZ2V0T3B0aW9uc09uUmVjb25uZWN0OiBnZXRPcHRpb25zT25SZWNvbm5lY3RcclxuICAgICAgfSkuY29ubmVjdCgpO1xyXG4gICAgfVxyXG4gIH0sIHtcclxuICAgIGtleTogXCJfY3JlYXRlT25tZXNzYWdlTGlzdGVuZXJcIixcclxuICAgIHZhbHVlOiBmdW5jdGlvbiBfY3JlYXRlT25tZXNzYWdlTGlzdGVuZXIob25tZXNzYWdlLCBvbnRvcGljTGlzdGVuZXJzKSB7XHJcbiAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcblxyXG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBpZiAob25tZXNzYWdlKSB7XHJcbiAgICAgICAgICBvbm1lc3NhZ2UoZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIW9udG9waWNMaXN0ZW5lcnMpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBtZXNzYWdlID0gX3RoaXMuX3RyeUpzb25QYXJzZShlLmRhdGEpO1xyXG5cclxuICAgICAgICBpZiAoIW1lc3NhZ2UpIHtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJXZWJzb2NrZXRzQ3N3czogSW52YWxpZCBtZXNzYWdlOiAnXCIuY29uY2F0KGUuZGF0YSwgXCInXCIpKTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSBPYmplY3Qua2V5cyhvbnRvcGljTGlzdGVuZXJzKS5maWx0ZXIoZnVuY3Rpb24gKHRvcGljKSB7XHJcbiAgICAgICAgICByZXR1cm4gdG9waWMgPT09IG1lc3NhZ2UudG9waWM7XHJcbiAgICAgICAgfSkubWFwKGZ1bmN0aW9uICh0b3BpYykge1xyXG4gICAgICAgICAgcmV0dXJuIG9udG9waWNMaXN0ZW5lcnNbdG9waWNdO1xyXG4gICAgICAgIH0pWzBdO1xyXG5cclxuICAgICAgICBpZiAoIWxpc3RlbmVycykge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICAgICAgbGlzdGVuZXJzKG1lc3NhZ2UpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBsaXN0ZW5lcnMuZm9yRWFjaChmdW5jdGlvbiAobGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGxpc3RlbmVyKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH0sIHtcclxuICAgIGtleTogXCJfY3JlYXRlR2V0T3B0aW9uc09uUmVjb25uZWN0XCIsXHJcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2NyZWF0ZUdldE9wdGlvbnNPblJlY29ubmVjdCh0b2tlbkZ1bmN0aW9uKSB7XHJcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRva2VuRnVuY3Rpb24oKS50aGVuKGZ1bmN0aW9uICh0b2tlbikge1xyXG4gICAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgIHF1ZXJ5OiB7XHJcbiAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdG9rZW47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgfSwge1xyXG4gICAga2V5OiBcIl90cnlKc29uUGFyc2VcIixcclxuICAgIHZhbHVlOiBmdW5jdGlvbiBfdHJ5SnNvblBhcnNlKGpzb24pIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uKTtcclxuICAgICAgfSBjYXRjaCAoXykge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfV0pO1xyXG5cclxuICByZXR1cm4gQ2xvdWRTaGFyZVdlYlNvY2tldHM7XHJcbn0oKTtcclxuXHJcblxyXG5cclxuLyoqKi8gfSksXHJcblxyXG4vKioqLyBcIi4vc3JjL0NvbW1vbi9MaWJyYXJpZXMvV2Vic29ja2V0cy9DbG91ZFNoYXJlV2ViU29ja2V0cy9pbmRleC5qc1wiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vc3JjL0NvbW1vbi9MaWJyYXJpZXMvV2Vic29ja2V0cy9DbG91ZFNoYXJlV2ViU29ja2V0cy9pbmRleC5qcyAqKiohXHJcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGNzd3MgKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgX193ZWJwYWNrX2V4cG9ydHNfXywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcbl9fd2VicGFja19yZXF1aXJlX18ucihfX3dlYnBhY2tfZXhwb3J0c19fKTtcclxuLyogaGFybW9ueSBleHBvcnQgKGJpbmRpbmcpICovIF9fd2VicGFja19yZXF1aXJlX18uZChfX3dlYnBhY2tfZXhwb3J0c19fLCBcImNzd3NcIiwgZnVuY3Rpb24oKSB7IHJldHVybiBjc3dzOyB9KTtcclxuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGNvcmVfanNfc2hpbV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgY29yZS1qcy9zaGltICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS1qcy9zaGltLmpzXCIpO1xyXG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgY29yZV9qc19zaGltX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oY29yZV9qc19zaGltX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX18pO1xyXG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX3dlYnNvY2tldF9jbGllbnRfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzFfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vd2Vic29ja2V0LWNsaWVudCAqLyBcIi4vc3JjL0NvbW1vbi9MaWJyYXJpZXMvV2Vic29ja2V0cy9DbG91ZFNoYXJlV2ViU29ja2V0cy93ZWJzb2NrZXQtY2xpZW50LmpzXCIpO1xyXG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2Nsb3Vkc2hhcmVfd2Vic29ja2V0c19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMl9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9jbG91ZHNoYXJlLXdlYnNvY2tldHMgKi8gXCIuL3NyYy9Db21tb24vTGlicmFyaWVzL1dlYnNvY2tldHMvQ2xvdWRTaGFyZVdlYlNvY2tldHMvY2xvdWRzaGFyZS13ZWJzb2NrZXRzLmpzXCIpO1xyXG5cclxuXHJcblxyXG52YXIgY3N3cyA9IG5ldyBfY2xvdWRzaGFyZV93ZWJzb2NrZXRzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yX19bXCJkZWZhdWx0XCJdKF93ZWJzb2NrZXRfY2xpZW50X19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xX19bXCJkZWZhdWx0XCJdKTtcclxuXHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9zcmMvQ29tbW9uL0xpYnJhcmllcy9XZWJzb2NrZXRzL0Nsb3VkU2hhcmVXZWJTb2NrZXRzL3JlcXVlc3QuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vc3JjL0NvbW1vbi9MaWJyYXJpZXMvV2Vic29ja2V0cy9DbG91ZFNoYXJlV2ViU29ja2V0cy9yZXF1ZXN0LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBleHBvcnRzIHByb3ZpZGVkOiBkZWZhdWx0LCBjcmVhdGVRdWVyeVN0cmluZyAqL1xyXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBfX3dlYnBhY2tfZXhwb3J0c19fLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XHJcblxyXG5cInVzZSBzdHJpY3RcIjtcclxuX193ZWJwYWNrX3JlcXVpcmVfXy5yKF9fd2VicGFja19leHBvcnRzX18pO1xyXG4vKiBoYXJtb255IGV4cG9ydCAoYmluZGluZykgKi8gX193ZWJwYWNrX3JlcXVpcmVfXy5kKF9fd2VicGFja19leHBvcnRzX18sIFwiZGVmYXVsdFwiLCBmdW5jdGlvbigpIHsgcmV0dXJuIHJlcXVlc3Q7IH0pO1xyXG4vKiBoYXJtb255IGV4cG9ydCAoYmluZGluZykgKi8gX193ZWJwYWNrX3JlcXVpcmVfXy5kKF9fd2VicGFja19leHBvcnRzX18sIFwiY3JlYXRlUXVlcnlTdHJpbmdcIiwgZnVuY3Rpb24oKSB7IHJldHVybiBjcmVhdGVRdWVyeVN0cmluZzsgfSk7XHJcbmZ1bmN0aW9uIHJlcXVlc3Qob3B0aW9ucykge1xyXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xyXG4gICAgdmFyIHVybCA9IG9wdGlvbnMuaG9zdCA/IFwiaHR0cHM6Ly9cIiArIG9wdGlvbnMuaG9zdCA6IFwiXCI7XHJcbiAgICB2YXIgcGF0aCA9IG9wdGlvbnMucGF0aCB8fCBcIlwiO1xyXG5cclxuICAgIGlmIChwYXRoWzBdICE9PSBcIi9cIikge1xyXG4gICAgICB1cmwgKz0gXCIvXCIgKyBwYXRoO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdXJsICs9IHBhdGg7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGJvZHkgPSBvcHRpb25zLmJvZHk7XHJcblxyXG4gICAgaWYgKGJvZHkgJiYgdHlwZW9mIGJvZHkgIT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChvcHRpb25zLnF1ZXJ5KSB7XHJcbiAgICAgIHVybCArPSBjcmVhdGVRdWVyeVN0cmluZyhvcHRpb25zLnF1ZXJ5KTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcCA9IHhocih7XHJcbiAgICAgIG1ldGhvZDogb3B0aW9ucy5tZXRob2QgfHwgXCJHRVRcIixcclxuICAgICAgdXJsOiB1cmwsXHJcbiAgICAgIGJvZHk6IGJvZHkgfHwgbnVsbFxyXG4gICAgfSkudGhlbihmdW5jdGlvbiAoeGhyKSB7XHJcbiAgICAgIGlmIChNYXRoLmZsb29yKHhoci5zdGF0dXMgLyAxMDApID4gMikge1xyXG4gICAgICAgIHRocm93IHtcclxuICAgICAgICAgIGVycm9yOiBuZXcgRXJyb3IoXCJYSFIgd2l0aCBzdGF0dXMgY29kZTogXCIgKyB4aHIuc3RhdHVzKSxcclxuICAgICAgICAgIHhocjogeGhyXHJcbiAgICAgICAgfTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGpzb25PYmplY3QgPSBqc29uUGFyc2VPck51bGwoeGhyLnJlc3BvbnNlVGV4dCk7XHJcblxyXG4gICAgICBpZiAoanNvbk9iamVjdCkge1xyXG4gICAgICAgIHJldHVybiBqc29uT2JqZWN0O1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4geGhyLnJlc3BvbnNlVGV4dDtcclxuICAgIH0pO1xyXG4gICAgcmVzb2x2ZShwKTtcclxuICB9KTtcclxufVxyXG5mdW5jdGlvbiBjcmVhdGVRdWVyeVN0cmluZyhvYmopIHtcclxuICB2YXIgcXVlcnlTdHJpbmcgPSBcIlwiO1xyXG5cclxuICBpZiAoIW9iaikge1xyXG4gICAgcmV0dXJuIHF1ZXJ5U3RyaW5nO1xyXG4gIH1cclxuXHJcbiAgcXVlcnlTdHJpbmcgKz0gT2JqZWN0LmtleXMob2JqKS5tYXAoZnVuY3Rpb24gKHBhcmFtS2V5KSB7XHJcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtS2V5KSwgXCI9XCIpLmNvbmNhdChlbmNvZGVVUklDb21wb25lbnQob2JqW3BhcmFtS2V5XSkpO1xyXG4gIH0pLmpvaW4oXCImXCIpO1xyXG5cclxuICBpZiAocXVlcnlTdHJpbmcubGVuZ3RoID4gMCkge1xyXG4gICAgcXVlcnlTdHJpbmcgPSBcIj9cIiArIHF1ZXJ5U3RyaW5nO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHF1ZXJ5U3RyaW5nO1xyXG59XHJcblxyXG5mdW5jdGlvbiBqc29uUGFyc2VPck51bGwoanNvbikge1xyXG4gIHRyeSB7XHJcbiAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uKTtcclxuICB9IGNhdGNoIChlKSB7XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHhocihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XHJcbiAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcclxuXHJcbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0geGhyLkRPTkUpIHtcclxuICAgICAgICByZXNvbHZlKHhocik7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgeGhyLm9wZW4ob3B0aW9ucy5tZXRob2QsIG9wdGlvbnMudXJsKTtcclxuXHJcbiAgICBpZiAob3B0aW9ucy5ib2R5KSB7XHJcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsIFwiYXBwbGljYXRpb24vanNvblwiKTtcclxuICAgIH1cclxuXHJcbiAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIkFjY2VwdFwiLCBcImFwcGxpY2F0aW9uL2pzb25cIik7XHJcbiAgICB4aHIuc2VuZChvcHRpb25zLmJvZHkpO1xyXG4gIH0pO1xyXG59XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9zcmMvQ29tbW9uL0xpYnJhcmllcy9XZWJzb2NrZXRzL0Nsb3VkU2hhcmVXZWJTb2NrZXRzL3dlYnNvY2tldC1jbGllbnQuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcclxuICAhKioqIC4vc3JjL0NvbW1vbi9MaWJyYXJpZXMvV2Vic29ja2V0cy9DbG91ZFNoYXJlV2ViU29ja2V0cy93ZWJzb2NrZXQtY2xpZW50LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBleHBvcnRzIHByb3ZpZGVkOiBkZWZhdWx0ICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XHJcbi8qIGhhcm1vbnkgZXhwb3J0IChiaW5kaW5nKSAqLyBfX3dlYnBhY2tfcmVxdWlyZV9fLmQoX193ZWJwYWNrX2V4cG9ydHNfXywgXCJkZWZhdWx0XCIsIGZ1bmN0aW9uKCkgeyByZXR1cm4gV2ViU29ja2V0Q2xpZW50OyB9KTtcclxuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9yZXF1ZXN0X19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL3JlcXVlc3QgKi8gXCIuL3NyYy9Db21tb24vTGlicmFyaWVzL1dlYnNvY2tldHMvQ2xvdWRTaGFyZVdlYlNvY2tldHMvcmVxdWVzdC5qc1wiKTtcclxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cclxuXHJcbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cclxuXHJcbmZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XHJcblxyXG5cclxudmFyIEJBU0VfUkVUUllfSU5URVJWQUxfTVMgPSA3NTA7XHJcbnZhciBSRVRSWV9NQVhfRVhQT05FTlQgPSAxMDtcclxuXHJcbnZhciBXZWJTb2NrZXRDbGllbnQgPVxyXG4vKiNfX1BVUkVfXyovXHJcbmZ1bmN0aW9uICgpIHtcclxuICBmdW5jdGlvbiBXZWJTb2NrZXRDbGllbnQob3B0aW9ucykge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgV2ViU29ja2V0Q2xpZW50KTtcclxuXHJcbiAgICB0aGlzLl9zb2NrZXQgPSBudWxsO1xyXG4gICAgdGhpcy5fY29ubmVjdGluZyA9IGZhbHNlO1xyXG4gICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2U7XHJcbiAgICB0aGlzLl9yZXRyeVRpbWVvdXRJZCA9IG51bGw7XHJcbiAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcclxuICAgIHRoaXMuX2dldE9wdGlvbnNPblJlY29ubmVjdCA9IG9wdGlvbnMuZ2V0T3B0aW9uc09uUmVjb25uZWN0O1xyXG4gICAgdGhpcy5fbm9SZXRyeSA9IG9wdGlvbnMubm9SZXRyeTtcclxuICAgIHRoaXMuX3JldHJ5QXR0ZW1wdENvdW50ID0gMDtcclxuICAgIHRoaXMuX25leHRSZXRyeUludGVydmFsTXMgPSB0aGlzLl9nZXRFeHBvbmVudGlhbEJhY2tvZmYoKTtcclxuICAgIHRoaXMuX2Rpc2Nvbm5lY3RSZXNvbHZlID0gbnVsbDtcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiYmVmb3JldW5sb2FkXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgX3RoaXMuZGlzY29ubmVjdCgpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBfY3JlYXRlQ2xhc3MoV2ViU29ja2V0Q2xpZW50LCBbe1xyXG4gICAga2V5OiBcImNvbm5lY3RcIixcclxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb25uZWN0KCkge1xyXG4gICAgICB2YXIgX3RoaXMyID0gdGhpcztcclxuXHJcbiAgICAgIGlmICh0aGlzLl9jb25uZWN0aW5nIHx8IHRoaXMuX2Nvbm5lY3RlZCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xyXG4gICAgICAgICAgcmV0dXJuIHJlc29sdmUoX3RoaXMyKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5fY29ubmVjdGluZyA9IHRydWU7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jb25uZWN0VG9XZWJTb2NrZXQoKTtcclxuICAgIH1cclxuICB9LCB7XHJcbiAgICBrZXk6IFwiZGlzY29ubmVjdFwiLFxyXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGRpc2Nvbm5lY3QoKSB7XHJcbiAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xyXG5cclxuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XHJcbiAgICAgICAgaWYgKCFfdGhpczMuX3NvY2tldCB8fCBfdGhpczMuX3NvY2tldC5yZWFkeVN0YXRlID09PSBfdGhpczMuX3NvY2tldC5DTE9TRUQpIHtcclxuICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgX3RoaXMzLl9kaXNjb25uZWN0UmVzb2x2ZSA9IHJlc29sdmU7XHJcbiAgICAgICAgICBfdGhpczMuX25vUmV0cnkgPSB0cnVlO1xyXG5cclxuICAgICAgICAgIF90aGlzMy5fc29ja2V0LmNsb3NlKCk7XHJcblxyXG4gICAgICAgICAgX3RoaXMzLl9zb2NrZXQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfSwge1xyXG4gICAga2V5OiBcInNlbmRUZXh0XCIsXHJcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2VuZFRleHQodGV4dCkge1xyXG4gICAgICBpZiAoIXRoaXMuX3NvY2tldCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5fc29ja2V0LnNlbmQodGV4dCk7XHJcbiAgICB9XHJcbiAgfSwge1xyXG4gICAga2V5OiBcImlzQ29ubmVjdGVkXCIsXHJcbiAgICB2YWx1ZTogZnVuY3Rpb24gaXNDb25uZWN0ZWQoKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jb25uZWN0ZWQ7XHJcbiAgICB9XHJcbiAgfSwge1xyXG4gICAga2V5OiBcIl9jb25uZWN0VG9XZWJTb2NrZXRcIixcclxuICAgIHZhbHVlOiBmdW5jdGlvbiBfY29ubmVjdFRvV2ViU29ja2V0KCkge1xyXG4gICAgICB2YXIgX3RoaXM0ID0gdGhpcztcclxuXHJcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgdmFyIHVybCA9IF90aGlzNC5fb3B0aW9uc1RvV2ViU29ja2V0c1VybChfdGhpczQuX29wdGlvbnMpO1xyXG5cclxuICAgICAgICBfdGhpczQuX2xvZyhcIkNvbm5lY3RpbmcgdG86IFwiLCB1cmwpO1xyXG5cclxuICAgICAgICBfdGhpczQuX3NvY2tldCA9IG5ldyB3aW5kb3cuV2ViU29ja2V0KHVybCk7XHJcblxyXG4gICAgICAgIF90aGlzNC5fc29ja2V0Lm9ub3BlbiA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICBfdGhpczQuX2xvZyhcIkNvbm5lY3RlZCB0bzogXCIsIHVybCk7XHJcblxyXG4gICAgICAgICAgX3RoaXM0Ll9jb25uZWN0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgICBfdGhpczQuX2Nvbm5lY3RlZCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgaWYgKF90aGlzNC5fb3B0aW9ucy5vbm9wZW4pIHtcclxuICAgICAgICAgICAgX3RoaXM0Ll9vcHRpb25zLm9ub3Blbi5jYWxsKF90aGlzNC5fc29ja2V0LCBlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICByZXNvbHZlKF90aGlzNCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgX3RoaXM0Ll9zb2NrZXQub25jbG9zZSA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICByZXR1cm4gX3RoaXM0Ll9vbmNsb3NlKGUsIHVybCwgcmVqZWN0KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBfdGhpczQuX3NvY2tldC5vbmVycm9yID0gZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgIHJldHVybiBfdGhpczQuX29uZXJyb3IoZSwgdXJsLCByZWplY3QpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIF90aGlzNC5fc29ja2V0Lm9ubWVzc2FnZSA9IF90aGlzNC5fb3B0aW9ucy5vbm1lc3NhZ2U7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH0sIHtcclxuICAgIGtleTogXCJfb25jbG9zZVwiLFxyXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9vbmNsb3NlKGNsb3NlRXZlbnQsIHVybCwgcmVqZWN0KSB7XHJcbiAgICAgIHRoaXMuX2Nvbm5lY3RpbmcgPSBmYWxzZTtcclxuICAgICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgICBpZiAoIXRoaXMuX25vUmV0cnkpIHtcclxuICAgICAgICB0aGlzLl9yZXRyeSgpO1xyXG5cclxuICAgICAgICBpZiAoIWNsb3NlRXZlbnQud2FzQ2xlYW4pIHtcclxuICAgICAgICAgIHRoaXMuX2xvZyhcIkNvbm5lY3Rpb24gZmFpbGVkIHRvOiAnXCIuY29uY2F0KHVybCwgXCInLCByZXRyeSBpbiBcIikuY29uY2F0KHRoaXMuX25leHRSZXRyeUludGVydmFsTXMsIFwiIG1zXCIpLCBjbG9zZUV2ZW50KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5fbG9nKFwiQ29ubmVjdGlvbiBjbG9zZWQgdG86ICdcIi5jb25jYXQodXJsLCBcIicsIHJldHJ5IGluIFwiKS5jb25jYXQodGhpcy5fbmV4dFJldHJ5SW50ZXJ2YWxNcywgXCIgbXNcIiksIGNsb3NlRXZlbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLl9sb2coXCJDb25uZWN0aW9uIGNsb3NlZCB0bzogJ1wiLmNvbmNhdCh1cmwsIFwiJ1wiKSwgY2xvc2VFdmVudCk7XHJcblxyXG4gICAgICAgIHJlamVjdCh0aGlzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHRoaXMuX29wdGlvbnMub25jbG9zZSkge1xyXG4gICAgICAgIHRoaXMuX29wdGlvbnMub25jbG9zZS5jYWxsKHRoaXMuX3NvY2tldCwgY2xvc2VFdmVudCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0aGlzLl9kaXNjb25uZWN0UmVzb2x2ZSkge1xyXG4gICAgICAgIHRoaXMuX2Rpc2Nvbm5lY3RSZXNvbHZlKCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2Rpc2Nvbm5lY3RSZXNvbHZlID0gbnVsbDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0sIHtcclxuICAgIGtleTogXCJfb25lcnJvclwiLFxyXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9vbmVycm9yKGVycm9yRXZlbnQsIHVybCwgcmVqZWN0KSB7XHJcbiAgICAgIHRoaXMuX2Nvbm5lY3RpbmcgPSBmYWxzZTtcclxuICAgICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgICBpZiAoIXRoaXMuX25vUmV0cnkpIHtcclxuICAgICAgICB0aGlzLl9yZXRyeSgpO1xyXG5cclxuICAgICAgICB0aGlzLl9sb2coXCJDb25uZWN0aW9uIGZhaWxlZCB0bzogJ1wiLmNvbmNhdCh1cmwsIFwiJywgcmV0cnkgaW4gXCIpLmNvbmNhdCh0aGlzLl9uZXh0UmV0cnlJbnRlcnZhbE1zLCBcIiBtc1wiKSwgZXJyb3JFdmVudCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fbG9nKFwiQ29ubmVjdGlvbiBmYWlsZWQgdG86ICdcIi5jb25jYXQodXJsLCBcIidcIiksIGVycm9yRXZlbnQpO1xyXG5cclxuICAgICAgICByZWplY3QodGhpcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0aGlzLl9vcHRpb25zLm9uZXJyb3IpIHtcclxuICAgICAgICB0aGlzLl9vcHRpb25zLm9uZXJyb3IuY2FsbCh0aGlzLl9zb2NrZXQsIGVycm9yRXZlbnQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5fZGlzY29ubmVjdFJlc29sdmUpIHtcclxuICAgICAgICB0aGlzLl9kaXNjb25uZWN0UmVzb2x2ZSgpO1xyXG5cclxuICAgICAgICB0aGlzLl9kaXNjb25uZWN0UmVzb2x2ZSA9IG51bGw7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9LCB7XHJcbiAgICBrZXk6IFwiX3JldHJ5XCIsXHJcbiAgICB2YWx1ZTogZnVuY3Rpb24gX3JldHJ5KCkge1xyXG4gICAgICB2YXIgX3RoaXM1ID0gdGhpcztcclxuXHJcbiAgICAgIGlmICghdGhpcy5fc29ja2V0IHx8IHRoaXMuX3JldHJ5VGltZW91dElkKSB7XHJcbiAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLl9yZXRyeUF0dGVtcHRDb3VudCArPSAxO1xyXG4gICAgICB0aGlzLl9uZXh0UmV0cnlJbnRlcnZhbE1zID0gdGhpcy5fZ2V0RXhwb25lbnRpYWxCYWNrb2ZmKCk7XHJcbiAgICAgIHRoaXMuX3JldHJ5VGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgX3RoaXM1Ll9yZXRyeVRpbWVvdXRJZCA9IG51bGw7XHJcbiAgICAgICAgX3RoaXM1Ll9zb2NrZXQgPSBudWxsO1xyXG5cclxuICAgICAgICBpZiAoX3RoaXM1Ll9nZXRPcHRpb25zT25SZWNvbm5lY3QpIHtcclxuICAgICAgICAgIF90aGlzNS5fZ2V0T3B0aW9uc09uUmVjb25uZWN0KCkudGhlbihmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICBfdGhpczUuX29wdGlvbnMucHJvdG9jb2xBbmRIb3N0ID0gb3B0aW9ucy5wcm90b2NvbEFuZEhvc3QgfHwgX3RoaXM1Ll9vcHRpb25zLnByb3RvY29sQW5kSG9zdDtcclxuICAgICAgICAgICAgX3RoaXM1Ll9vcHRpb25zLnBhdGggPSBvcHRpb25zLnBhdGggfHwgX3RoaXM1Ll9vcHRpb25zLnBhdGg7XHJcbiAgICAgICAgICAgIF90aGlzNS5fb3B0aW9ucy5xdWVyeSA9IG9wdGlvbnMucXVlcnkgfHwgX3RoaXM1Ll9vcHRpb25zLnF1ZXJ5O1xyXG5cclxuICAgICAgICAgICAgX3RoaXM1LmNvbm5lY3QoKTtcclxuICAgICAgICAgIH0sIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIF90aGlzNS5fcmV0cnkoKTtcclxuXHJcbiAgICAgICAgICAgIF90aGlzNS5fbG9nKFwiRmFpbGVkIHRvIGdldCBjb25uZWN0aW9uIG9wdGlvbnMgYmVmb3JlIHJlY29ubmVjdCwgcmV0cnlpbmcgaW4gXCIuY29uY2F0KF90aGlzNS5fbmV4dFJldHJ5SW50ZXJ2YWxNcywgXCIgbXNcIiksIGUpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIF90aGlzNS5jb25uZWN0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCB0aGlzLl9uZXh0UmV0cnlJbnRlcnZhbE1zKTtcclxuICAgICAgcmV0dXJuIHRoaXMuX25leHRSZXRyeUludGVydmFsTXM7XHJcbiAgICB9XHJcbiAgfSwge1xyXG4gICAga2V5OiBcIl9nZXRFeHBvbmVudGlhbEJhY2tvZmZcIixcclxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0RXhwb25lbnRpYWxCYWNrb2ZmKCkge1xyXG4gICAgICB2YXIgYyA9IE1hdGgubWluKHRoaXMuX3JldHJ5QXR0ZW1wdENvdW50LCBSRVRSWV9NQVhfRVhQT05FTlQpO1xyXG4gICAgICB2YXIgciA9IE1hdGgucmFuZG9tKCkgKiAoTWF0aC5wb3coMiwgYykgLSAxKTtcclxuICAgICAgcmV0dXJuIE1hdGgucm91bmQociAqIEJBU0VfUkVUUllfSU5URVJWQUxfTVMpO1xyXG4gICAgfVxyXG4gIH0sIHtcclxuICAgIGtleTogXCJfb3B0aW9uc1RvV2ViU29ja2V0c1VybFwiLFxyXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9vcHRpb25zVG9XZWJTb2NrZXRzVXJsKG9wdGlvbnMpIHtcclxuICAgICAgdmFyIHVybCA9IG9wdGlvbnMucHJvdG9jb2xBbmRIb3N0O1xyXG5cclxuICAgICAgaWYgKG9wdGlvbnMucGF0aCkge1xyXG4gICAgICAgIHVybCArPSBvcHRpb25zLnBhdGhbMF0gPT09IFwiL1wiID8gb3B0aW9ucy5wYXRoIDogXCIvXCIgKyBvcHRpb25zLnBhdGg7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLnF1ZXJ5KSB7XHJcbiAgICAgICAgdXJsICs9IE9iamVjdChfcmVxdWVzdF9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fW1wiY3JlYXRlUXVlcnlTdHJpbmdcIl0pKG9wdGlvbnMucXVlcnkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdXJsO1xyXG4gICAgfVxyXG4gIH0sIHtcclxuICAgIGtleTogXCJfbG9nXCIsXHJcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2xvZygpIHtcclxuICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xyXG4gICAgICBhcmdzLnVuc2hpZnQoXCJXZWJTb2NrZXRzOiBcIik7XHJcblxyXG4gICAgICBpZiAoY29uc29sZS5pbmZvKSB7XHJcbiAgICAgICAgY29uc29sZS5pbmZvLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfV0pO1xyXG5cclxuICByZXR1cm4gV2ViU29ja2V0Q2xpZW50O1xyXG59KCk7XHJcblxyXG5cclxuXHJcbi8qKiovIH0pXHJcblxyXG4vKioqKioqLyB9KTtcclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3N3cy5qcy5tYXBcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jc3dzLmpzXG4vLyBtb2R1bGUgaWQgPSAyNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBUaGlzIG9iamVjdCB3aWxsIGJlIHVzZWQgYXMgdGhlIHByb3RvdHlwZSBmb3IgTm9kZXMgd2hlbiBjcmVhdGluZyBhXG4vLyBET00tTGV2ZWwtMS1jb21wbGlhbnQgc3RydWN0dXJlLlxudmFyIE5vZGVQcm90b3R5cGUgPSBtb2R1bGUuZXhwb3J0cyA9IHtcblx0Z2V0IGZpcnN0Q2hpbGQoKSB7XG5cdFx0dmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbjtcblx0XHRyZXR1cm4gY2hpbGRyZW4gJiYgY2hpbGRyZW5bMF0gfHwgbnVsbDtcblx0fSxcblx0Z2V0IGxhc3RDaGlsZCgpIHtcblx0XHR2YXIgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuO1xuXHRcdHJldHVybiBjaGlsZHJlbiAmJiBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXSB8fCBudWxsO1xuXHR9LFxuXHRnZXQgbm9kZVR5cGUoKSB7XG5cdFx0cmV0dXJuIG5vZGVUeXBlc1t0aGlzLnR5cGVdIHx8IG5vZGVUeXBlcy5lbGVtZW50O1xuXHR9XG59O1xuXG52YXIgZG9tTHZsMSA9IHtcblx0dGFnTmFtZTogXCJuYW1lXCIsXG5cdGNoaWxkTm9kZXM6IFwiY2hpbGRyZW5cIixcblx0cGFyZW50Tm9kZTogXCJwYXJlbnRcIixcblx0cHJldmlvdXNTaWJsaW5nOiBcInByZXZcIixcblx0bmV4dFNpYmxpbmc6IFwibmV4dFwiLFxuXHRub2RlVmFsdWU6IFwiZGF0YVwiXG59O1xuXG52YXIgbm9kZVR5cGVzID0ge1xuXHRlbGVtZW50OiAxLFxuXHR0ZXh0OiAzLFxuXHRjZGF0YTogNCxcblx0Y29tbWVudDogOFxufTtcblxuT2JqZWN0LmtleXMoZG9tTHZsMSkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcblx0dmFyIHNob3J0aGFuZCA9IGRvbUx2bDFba2V5XTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KE5vZGVQcm90b3R5cGUsIGtleSwge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gdGhpc1tzaG9ydGhhbmRdIHx8IG51bGw7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uKHZhbCkge1xuXHRcdFx0dGhpc1tzaG9ydGhhbmRdID0gdmFsO1xuXHRcdFx0cmV0dXJuIHZhbDtcblx0XHR9XG5cdH0pO1xufSk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZG9taGFuZGxlci9saWIvbm9kZS5qc1xuLy8gbW9kdWxlIGlkID0gMjZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGRlY29kZU1hcCA9IHJlcXVpcmUoXCIuLi9tYXBzL2RlY29kZS5qc29uXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlY29kZUNvZGVQb2ludDtcblxuLy8gbW9kaWZpZWQgdmVyc2lvbiBvZiBodHRwczovL2dpdGh1Yi5jb20vbWF0aGlhc2J5bmVucy9oZS9ibG9iL21hc3Rlci9zcmMvaGUuanMjTDk0LUwxMTlcbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludChjb2RlUG9pbnQpe1xuXG5cdGlmKChjb2RlUG9pbnQgPj0gMHhEODAwICYmIGNvZGVQb2ludCA8PSAweERGRkYpIHx8IGNvZGVQb2ludCA+IDB4MTBGRkZGKXtcblx0XHRyZXR1cm4gXCJcXHVGRkZEXCI7XG5cdH1cblxuXHRpZihjb2RlUG9pbnQgaW4gZGVjb2RlTWFwKXtcblx0XHRjb2RlUG9pbnQgPSBkZWNvZGVNYXBbY29kZVBvaW50XTtcblx0fVxuXG5cdHZhciBvdXRwdXQgPSBcIlwiO1xuXG5cdGlmKGNvZGVQb2ludCA+IDB4RkZGRil7XG5cdFx0Y29kZVBvaW50IC09IDB4MTAwMDA7XG5cdFx0b3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKTtcblx0XHRjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRjtcblx0fVxuXG5cdG91dHB1dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVQb2ludCk7XG5cdHJldHVybiBvdXRwdXQ7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZW50aXRpZXMvbGliL2RlY29kZV9jb2RlcG9pbnQuanNcbi8vIG1vZHVsZSBpZCA9IDI3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0ge1xuXHRcIkFhY3V0ZVwiOiBcIsOBXCIsXG5cdFwiYWFjdXRlXCI6IFwiw6FcIixcblx0XCJBY2lyY1wiOiBcIsOCXCIsXG5cdFwiYWNpcmNcIjogXCLDolwiLFxuXHRcImFjdXRlXCI6IFwiwrRcIixcblx0XCJBRWxpZ1wiOiBcIsOGXCIsXG5cdFwiYWVsaWdcIjogXCLDplwiLFxuXHRcIkFncmF2ZVwiOiBcIsOAXCIsXG5cdFwiYWdyYXZlXCI6IFwiw6BcIixcblx0XCJhbXBcIjogXCImXCIsXG5cdFwiQU1QXCI6IFwiJlwiLFxuXHRcIkFyaW5nXCI6IFwiw4VcIixcblx0XCJhcmluZ1wiOiBcIsOlXCIsXG5cdFwiQXRpbGRlXCI6IFwiw4NcIixcblx0XCJhdGlsZGVcIjogXCLDo1wiLFxuXHRcIkF1bWxcIjogXCLDhFwiLFxuXHRcImF1bWxcIjogXCLDpFwiLFxuXHRcImJydmJhclwiOiBcIsKmXCIsXG5cdFwiQ2NlZGlsXCI6IFwiw4dcIixcblx0XCJjY2VkaWxcIjogXCLDp1wiLFxuXHRcImNlZGlsXCI6IFwiwrhcIixcblx0XCJjZW50XCI6IFwiwqJcIixcblx0XCJjb3B5XCI6IFwiwqlcIixcblx0XCJDT1BZXCI6IFwiwqlcIixcblx0XCJjdXJyZW5cIjogXCLCpFwiLFxuXHRcImRlZ1wiOiBcIsKwXCIsXG5cdFwiZGl2aWRlXCI6IFwiw7dcIixcblx0XCJFYWN1dGVcIjogXCLDiVwiLFxuXHRcImVhY3V0ZVwiOiBcIsOpXCIsXG5cdFwiRWNpcmNcIjogXCLDilwiLFxuXHRcImVjaXJjXCI6IFwiw6pcIixcblx0XCJFZ3JhdmVcIjogXCLDiFwiLFxuXHRcImVncmF2ZVwiOiBcIsOoXCIsXG5cdFwiRVRIXCI6IFwiw5BcIixcblx0XCJldGhcIjogXCLDsFwiLFxuXHRcIkV1bWxcIjogXCLDi1wiLFxuXHRcImV1bWxcIjogXCLDq1wiLFxuXHRcImZyYWMxMlwiOiBcIsK9XCIsXG5cdFwiZnJhYzE0XCI6IFwiwrxcIixcblx0XCJmcmFjMzRcIjogXCLCvlwiLFxuXHRcImd0XCI6IFwiPlwiLFxuXHRcIkdUXCI6IFwiPlwiLFxuXHRcIklhY3V0ZVwiOiBcIsONXCIsXG5cdFwiaWFjdXRlXCI6IFwiw61cIixcblx0XCJJY2lyY1wiOiBcIsOOXCIsXG5cdFwiaWNpcmNcIjogXCLDrlwiLFxuXHRcImlleGNsXCI6IFwiwqFcIixcblx0XCJJZ3JhdmVcIjogXCLDjFwiLFxuXHRcImlncmF2ZVwiOiBcIsOsXCIsXG5cdFwiaXF1ZXN0XCI6IFwiwr9cIixcblx0XCJJdW1sXCI6IFwiw49cIixcblx0XCJpdW1sXCI6IFwiw69cIixcblx0XCJsYXF1b1wiOiBcIsKrXCIsXG5cdFwibHRcIjogXCI8XCIsXG5cdFwiTFRcIjogXCI8XCIsXG5cdFwibWFjclwiOiBcIsKvXCIsXG5cdFwibWljcm9cIjogXCLCtVwiLFxuXHRcIm1pZGRvdFwiOiBcIsK3XCIsXG5cdFwibmJzcFwiOiBcIsKgXCIsXG5cdFwibm90XCI6IFwiwqxcIixcblx0XCJOdGlsZGVcIjogXCLDkVwiLFxuXHRcIm50aWxkZVwiOiBcIsOxXCIsXG5cdFwiT2FjdXRlXCI6IFwiw5NcIixcblx0XCJvYWN1dGVcIjogXCLDs1wiLFxuXHRcIk9jaXJjXCI6IFwiw5RcIixcblx0XCJvY2lyY1wiOiBcIsO0XCIsXG5cdFwiT2dyYXZlXCI6IFwiw5JcIixcblx0XCJvZ3JhdmVcIjogXCLDslwiLFxuXHRcIm9yZGZcIjogXCLCqlwiLFxuXHRcIm9yZG1cIjogXCLCulwiLFxuXHRcIk9zbGFzaFwiOiBcIsOYXCIsXG5cdFwib3NsYXNoXCI6IFwiw7hcIixcblx0XCJPdGlsZGVcIjogXCLDlVwiLFxuXHRcIm90aWxkZVwiOiBcIsO1XCIsXG5cdFwiT3VtbFwiOiBcIsOWXCIsXG5cdFwib3VtbFwiOiBcIsO2XCIsXG5cdFwicGFyYVwiOiBcIsK2XCIsXG5cdFwicGx1c21uXCI6IFwiwrFcIixcblx0XCJwb3VuZFwiOiBcIsKjXCIsXG5cdFwicXVvdFwiOiBcIlxcXCJcIixcblx0XCJRVU9UXCI6IFwiXFxcIlwiLFxuXHRcInJhcXVvXCI6IFwiwrtcIixcblx0XCJyZWdcIjogXCLCrlwiLFxuXHRcIlJFR1wiOiBcIsKuXCIsXG5cdFwic2VjdFwiOiBcIsKnXCIsXG5cdFwic2h5XCI6IFwiwq1cIixcblx0XCJzdXAxXCI6IFwiwrlcIixcblx0XCJzdXAyXCI6IFwiwrJcIixcblx0XCJzdXAzXCI6IFwiwrNcIixcblx0XCJzemxpZ1wiOiBcIsOfXCIsXG5cdFwiVEhPUk5cIjogXCLDnlwiLFxuXHRcInRob3JuXCI6IFwiw75cIixcblx0XCJ0aW1lc1wiOiBcIsOXXCIsXG5cdFwiVWFjdXRlXCI6IFwiw5pcIixcblx0XCJ1YWN1dGVcIjogXCLDulwiLFxuXHRcIlVjaXJjXCI6IFwiw5tcIixcblx0XCJ1Y2lyY1wiOiBcIsO7XCIsXG5cdFwiVWdyYXZlXCI6IFwiw5lcIixcblx0XCJ1Z3JhdmVcIjogXCLDuVwiLFxuXHRcInVtbFwiOiBcIsKoXCIsXG5cdFwiVXVtbFwiOiBcIsOcXCIsXG5cdFwidXVtbFwiOiBcIsO8XCIsXG5cdFwiWWFjdXRlXCI6IFwiw51cIixcblx0XCJ5YWN1dGVcIjogXCLDvVwiLFxuXHRcInllblwiOiBcIsKlXCIsXG5cdFwieXVtbFwiOiBcIsO/XCJcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2VudGl0aWVzL21hcHMvbGVnYWN5Lmpzb25cbi8vIG1vZHVsZSBpZCA9IDI4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIHJlYWRlciB3aGljaCBhdXRvbWF0aWNhbGx5IGhhbmRsZXMgdGhlIGdpdmVuIGlucHV0IHN0cmVhbSwgcmV0dXJuaW5nXHJcbiAqIHN0cmljdGx5IHJlY2VpdmVkIHBhY2tldHMgYXMgYXJyYXkgYnVmZmVycy4gTm90ZSB0aGF0IHRoaXMgb2JqZWN0IHdpbGxcclxuICogb3ZlcndyaXRlIGFueSBpbnN0YWxsZWQgZXZlbnQgaGFuZGxlcnMgb24gdGhlIGdpdmVuIEd1YWNhbW9sZS5JbnB1dFN0cmVhbS5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAcGFyYW0ge0d1YWNhbW9sZS5JbnB1dFN0cmVhbX0gc3RyZWFtIFRoZSBzdHJlYW0gdGhhdCBkYXRhIHdpbGwgYmUgcmVhZFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20uXHJcbiAqL1xyXG5HdWFjYW1vbGUuQXJyYXlCdWZmZXJSZWFkZXIgPSBmdW5jdGlvbihzdHJlYW0pIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5JbnB1dFN0cmVhbS5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBndWFjX3JlYWRlciA9IHRoaXM7XHJcblxyXG4gICAgLy8gUmVjZWl2ZSBibG9icyBhcyBhcnJheSBidWZmZXJzXHJcbiAgICBzdHJlYW0ub25ibG9iID0gZnVuY3Rpb24oZGF0YSkge1xyXG5cclxuICAgICAgICAvLyBDb252ZXJ0IHRvIEFycmF5QnVmZmVyXHJcbiAgICAgICAgdmFyIGJpbmFyeSA9IHdpbmRvdy5hdG9iKGRhdGEpO1xyXG4gICAgICAgIHZhciBhcnJheUJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihiaW5hcnkubGVuZ3RoKTtcclxuICAgICAgICB2YXIgYnVmZmVyVmlldyA9IG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKTtcclxuXHJcbiAgICAgICAgZm9yICh2YXIgaT0wOyBpPGJpbmFyeS5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgYnVmZmVyVmlld1tpXSA9IGJpbmFyeS5jaGFyQ29kZUF0KGkpO1xyXG5cclxuICAgICAgICAvLyBDYWxsIGhhbmRsZXIsIGlmIHByZXNlbnRcclxuICAgICAgICBpZiAoZ3VhY19yZWFkZXIub25kYXRhKVxyXG4gICAgICAgICAgICBndWFjX3JlYWRlci5vbmRhdGEoYXJyYXlCdWZmZXIpO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLy8gU2ltcGx5IGNhbGwgb25lbmQgd2hlbiBlbmQgcmVjZWl2ZWRcclxuICAgIHN0cmVhbS5vbmVuZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGlmIChndWFjX3JlYWRlci5vbmVuZClcclxuICAgICAgICAgICAgZ3VhY19yZWFkZXIub25lbmQoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCBvbmNlIGZvciBldmVyeSBibG9iIG9mIGRhdGEgcmVjZWl2ZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYnVmZmVyIFRoZSBkYXRhIHBhY2tldCByZWNlaXZlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmRhdGEgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgb25jZSB0aGlzIHN0cmVhbSBpcyBmaW5pc2hlZCBhbmQgbm8gZnVydGhlciBkYXRhIHdpbGwgYmUgd3JpdHRlbi5cclxuICAgICAqIEBldmVudFxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uZW5kID0gbnVsbDtcclxuXHJcbn07LypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIHdyaXRlciB3aGljaCBhdXRvbWF0aWNhbGx5IHdyaXRlcyB0byB0aGUgZ2l2ZW4gb3V0cHV0IHN0cmVhbSB3aXRoIGFyYml0cmFyeVxyXG4gKiBiaW5hcnkgZGF0YSwgc3VwcGxpZWQgYXMgQXJyYXlCdWZmZXJzLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLk91dHB1dFN0cmVhbX0gc3RyZWFtIFRoZSBzdHJlYW0gdGhhdCBkYXRhIHdpbGwgYmUgd3JpdHRlblxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0by5cclxuICovXHJcbkd1YWNhbW9sZS5BcnJheUJ1ZmZlcldyaXRlciA9IGZ1bmN0aW9uKHN0cmVhbSkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVmZXJlbmNlIHRvIHRoaXMgR3VhY2Ftb2xlLlN0cmluZ1dyaXRlci5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBndWFjX3dyaXRlciA9IHRoaXM7XHJcblxyXG4gICAgLy8gU2ltcGx5IGNhbGwgb25hY2sgZm9yIGFja25vd2xlZGdlbWVudHNcclxuICAgIHN0cmVhbS5vbmFjayA9IGZ1bmN0aW9uKHN0YXR1cykge1xyXG4gICAgICAgIGlmIChndWFjX3dyaXRlci5vbmFjaylcclxuICAgICAgICAgICAgZ3VhY193cml0ZXIub25hY2soc3RhdHVzKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoZSBnaXZlbiBkYXRhIGFzIGJhc2U2NCwgc2VuZGluZyBpdCBhcyBhIGJsb2IuIFRoZSBkYXRhIG11c3RcclxuICAgICAqIGJlIHNtYWxsIGVub3VnaCB0byBmaXQgaW50byBhIHNpbmdsZSBibG9iIGluc3RydWN0aW9uLlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBieXRlcyBUaGUgZGF0YSB0byBzZW5kLlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBfX3NlbmRfYmxvYihieXRlcykge1xyXG5cclxuICAgICAgICB2YXIgYmluYXJ5ID0gXCJcIjtcclxuXHJcbiAgICAgICAgLy8gUHJvZHVjZSBiaW5hcnkgc3RyaW5nIGZyb20gYnl0ZXMgaW4gYnVmZmVyXHJcbiAgICAgICAgZm9yICh2YXIgaT0wOyBpPGJ5dGVzLmJ5dGVMZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgYmluYXJ5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pO1xyXG5cclxuICAgICAgICAvLyBTZW5kIGFzIGJhc2U2NFxyXG4gICAgICAgIHN0cmVhbS5zZW5kQmxvYih3aW5kb3cuYnRvYShiaW5hcnkpKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGJsb2Igc2VudCBieSB0aGlzIEd1YWNhbW9sZS5BcnJheUJ1ZmZlcldyaXRlcixcclxuICAgICAqIGluIGJ5dGVzLiBEYXRhIHNlbnQgdmlhXHJcbiAgICAgKiBbc2VuZERhdGEoKV17QGxpbmsgR3VhY2Ftb2xlLkFycmF5QnVmZmVyV3JpdGVyI3NlbmREYXRhfSB3aGljaCBleGNlZWRzXHJcbiAgICAgKiB0aGlzIGxlbmd0aCB3aWxsIGJlIHNwbGl0IGludG8gbXVsdGlwbGUgYmxvYnMuIEFzIHRoZSBHdWFjYW1vbGUgcHJvdG9jb2xcclxuICAgICAqIGxpbWl0cyB0aGUgbWF4aW11bSBzaXplIG9mIGFueSBpbnN0cnVjdGlvbiBvciBpbnN0cnVjdGlvbiBlbGVtZW50IHRvXHJcbiAgICAgKiA4MTkyIGJ5dGVzLCBhbmQgdGhlIGNvbnRlbnRzIG9mIGJsb2JzIHdpbGwgYmUgYmFzZTY0LWVuY29kZWQsIHRoaXMgdmFsdWVcclxuICAgICAqIHNob3VsZCBvbmx5IGJlIGluY3JlYXNlZCB3aXRoIGV4dHJlbWUgY2F1dGlvbi5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICogQGRlZmF1bHQge0BsaW5rIEd1YWNhbW9sZS5BcnJheUJ1ZmZlcldyaXRlci5ERUZBVUxUX0JMT0JfTEVOR1RIfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmJsb2JMZW5ndGggPSBHdWFjYW1vbGUuQXJyYXlCdWZmZXJXcml0ZXIuREVGQVVMVF9CTE9CX0xFTkdUSDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlbmRzIHRoZSBnaXZlbiBkYXRhLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfFR5cGVkQXJyYXl9IGRhdGEgVGhlIGRhdGEgdG8gc2VuZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZW5kRGF0YSA9IGZ1bmN0aW9uKGRhdGEpIHtcclxuXHJcbiAgICAgICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XHJcblxyXG4gICAgICAgIC8vIElmIHNtYWxsIGVub3VnaCB0byBmaXQgaW50byBzaW5nbGUgaW5zdHJ1Y3Rpb24sIHNlbmQgYXMtaXNcclxuICAgICAgICBpZiAoYnl0ZXMubGVuZ3RoIDw9IGd1YWNfd3JpdGVyLmJsb2JMZW5ndGgpXHJcbiAgICAgICAgICAgIF9fc2VuZF9ibG9iKGJ5dGVzKTtcclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBzZW5kIGFzIG11bHRpcGxlIGluc3RydWN0aW9uc1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBvZmZzZXQ9MDsgb2Zmc2V0PGJ5dGVzLmxlbmd0aDsgb2Zmc2V0ICs9IGd1YWNfd3JpdGVyLmJsb2JMZW5ndGgpXHJcbiAgICAgICAgICAgICAgICBfX3NlbmRfYmxvYihieXRlcy5zdWJhcnJheShvZmZzZXQsIG9mZnNldCArIGd1YWNfd3JpdGVyLmJsb2JMZW5ndGgpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNpZ25hbHMgdGhhdCBubyBmdXJ0aGVyIHRleHQgd2lsbCBiZSBzZW50LCBlZmZlY3RpdmVseSBjbG9zaW5nIHRoZVxyXG4gICAgICogc3RyZWFtLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnNlbmRFbmQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBzdHJlYW0uc2VuZEVuZCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIGZvciByZWNlaXZlZCBkYXRhLCBpZiBhY2tub3dsZWRnZWQgYnkgdGhlIHNlcnZlci5cclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuU3RhdHVzfSBzdGF0dXMgVGhlIHN0YXR1cyBvZiB0aGUgb3BlcmF0aW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uYWNrID0gbnVsbDtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogVGhlIGRlZmF1bHQgbWF4aW11bSBibG9iIGxlbmd0aCBmb3IgbmV3IEd1YWNhbW9sZS5BcnJheUJ1ZmZlcldyaXRlclxyXG4gKiBpbnN0YW5jZXMuXHJcbiAqXHJcbiAqIEBjb25zdGFudFxyXG4gKiBAdHlwZSB7TnVtYmVyfVxyXG4gKi9cclxuR3VhY2Ftb2xlLkFycmF5QnVmZmVyV3JpdGVyLkRFRkFVTFRfQkxPQl9MRU5HVEggPSA2MDQ4O1xyXG4vKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIE1haW50YWlucyBhIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGUgV2ViIEF1ZGlvIEFQSSBBdWRpb0NvbnRleHQgY2xhc3MsXHJcbiAqIGluc3RhbnRpYXRpbmcgdGhlIEF1ZGlvQ29udGV4dCBvbmx5IGluIHJlc3BvbnNlIHRvIHRoZSBmaXJzdCBjYWxsIHRvXHJcbiAqIGdldEF1ZGlvQ29udGV4dCgpLCBhbmQgb25seSBpZiBubyBleGlzdGluZyBBdWRpb0NvbnRleHQgaW5zdGFuY2UgaGFzIGJlZW5cclxuICogcHJvdmlkZWQgdmlhIHRoZSBzaW5nbGV0b24gcHJvcGVydHkuIFN1YnNlcXVlbnQgY2FsbHMgdG8gZ2V0QXVkaW9Db250ZXh0KClcclxuICogd2lsbCByZXR1cm4gdGhlIHNhbWUgaW5zdGFuY2UuXHJcbiAqXHJcbiAqIEBuYW1lc3BhY2VcclxuICovXHJcbkd1YWNhbW9sZS5BdWRpb0NvbnRleHRGYWN0b3J5ID0ge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgYSBXZWIgQXVkaW8gQVBJIEF1ZGlvQ29udGV4dCBvYmplY3QsIG9yIG51bGwgaWZcclxuICAgICAqIG5vIGluc3RhbmNlIGhhcyB5ZXMgYmVlbiBjcmVhdGVkLiBUaGlzIHByb3BlcnR5IG1heSBiZSBtYW51YWxseSBzZXQgaWZcclxuICAgICAqIHlvdSB3aXNoIHRvIHN1cHBseSB5b3VyIG93biBBdWRpb0NvbnRleHQgaW5zdGFuY2UsIGJ1dCBjYXJlIG11c3QgYmVcclxuICAgICAqIHRha2VuIHRvIGRvIHNvIGFzIGVhcmx5IGFzIHBvc3NpYmxlLiBBc3NpZ25tZW50cyB0byB0aGlzIHByb3BlcnR5IHdpbGxcclxuICAgICAqIG5vdCByZXRyb2FjdGl2ZWx5IGFmZmVjdCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgcHJldmlvdXMgY2FsbHMgdG9cclxuICAgICAqIGdldEF1ZGlvQ29udGV4dCgpLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtBdWRpb0NvbnRleHR9XHJcbiAgICAgKi9cclxuICAgICdzaW5nbGV0b24nIDogbnVsbCxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgYSBXZWIgQXVkaW8gQVBJIEF1ZGlvQ29udGV4dCBvYmplY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybiB7QXVkaW9Db250ZXh0fVxyXG4gICAgICogICAgIEEgc2luZ2xldG9uIGluc3RhbmNlIG9mIGEgV2ViIEF1ZGlvIEFQSSBBdWRpb0NvbnRleHQgb2JqZWN0LCBvciBudWxsXHJcbiAgICAgKiAgICAgaWYgdGhlIFdlYiBBdWRpbyBBUEkgaXMgbm90IHN1cHBvcnRlZC5cclxuICAgICAqL1xyXG4gICAgJ2dldEF1ZGlvQ29udGV4dCcgOiBmdW5jdGlvbiBnZXRBdWRpb0NvbnRleHQoKSB7XHJcblxyXG4gICAgICAgIC8vIEZhbGxiYWNrIHRvIFdlYmtpdC1zcGVjaWZpYyBBdWRpb0NvbnRleHQgaW1wbGVtZW50YXRpb25cclxuICAgICAgICB2YXIgQXVkaW9Db250ZXh0ID0gd2luZG93LkF1ZGlvQ29udGV4dCB8fCB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0O1xyXG5cclxuICAgICAgICAvLyBHZXQgbmV3IEF1ZGlvQ29udGV4dCBpbnN0YW5jZSBpZiBXZWIgQXVkaW8gQVBJIGlzIHN1cHBvcnRlZFxyXG4gICAgICAgIGlmIChBdWRpb0NvbnRleHQpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbmV3IGluc3RhbmNlIGlmIG5vbmUgeWV0IGV4aXN0c1xyXG4gICAgICAgICAgICAgICAgaWYgKCFHdWFjYW1vbGUuQXVkaW9Db250ZXh0RmFjdG9yeS5zaW5nbGV0b24pXHJcbiAgICAgICAgICAgICAgICAgICAgR3VhY2Ftb2xlLkF1ZGlvQ29udGV4dEZhY3Rvcnkuc2luZ2xldG9uID0gbmV3IEF1ZGlvQ29udGV4dCgpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJldHVybiBzaW5nbGV0b24gaW5zdGFuY2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBHdWFjYW1vbGUuQXVkaW9Db250ZXh0RmFjdG9yeS5zaW5nbGV0b247XHJcblxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgdXNlIFdlYiBBdWRpbyBBUEkgaWYgbm90IGFsbG93ZWQgYnkgYnJvd3NlclxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBXZWIgQXVkaW8gQVBJIG5vdCBzdXBwb3J0ZWRcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICB9XHJcblxyXG59O1xyXG4vKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIEFic3RyYWN0IGF1ZGlvIHBsYXllciB3aGljaCBhY2NlcHRzLCBxdWV1ZXMgYW5kIHBsYXlzIGJhY2sgYXJiaXRyYXJ5IGF1ZGlvXHJcbiAqIGRhdGEuIEl0IGlzIHVwIHRvIGltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGNsYXNzIHRvIHByb3ZpZGUgc29tZSBtZWFucyBvZlxyXG4gKiBoYW5kbGluZyBhIHByb3ZpZGVkIEd1YWNhbW9sZS5JbnB1dFN0cmVhbS4gRGF0YSByZWNlaXZlZCBhbG9uZyB0aGUgcHJvdmlkZWRcclxuICogc3RyZWFtIGlzIHRvIGJlIHBsYXllZCBiYWNrIGltbWVkaWF0ZWx5LlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbkd1YWNhbW9sZS5BdWRpb1BsYXllciA9IGZ1bmN0aW9uIEF1ZGlvUGxheWVyKCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTm90aWZpZXMgdGhpcyBHdWFjYW1vbGUuQXVkaW9QbGF5ZXIgdGhhdCBhbGwgYXVkaW8gdXAgdG8gdGhlIGN1cnJlbnRcclxuICAgICAqIHBvaW50IGluIHRpbWUgaGFzIGJlZW4gZ2l2ZW4gdmlhIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSwgYW5kIHRoYXQgYW55XHJcbiAgICAgKiBkaWZmZXJlbmNlIGluIHRpbWUgYmV0d2VlbiBxdWV1ZWQgYXVkaW8gZGF0YSBhbmQgdGhlIGN1cnJlbnQgdGltZSBjYW4gYmVcclxuICAgICAqIGNvbnNpZGVyZWQgbGF0ZW5jeS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zeW5jID0gZnVuY3Rpb24gc3luYygpIHtcclxuICAgICAgICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIC0gZG8gbm90aGluZ1xyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiBtaW1ldHlwZSBpcyBzdXBwb3J0ZWQgYnkgYW55IGJ1aWx0LWluXHJcbiAqIGltcGxlbWVudGF0aW9uIG9mIEd1YWNhbW9sZS5BdWRpb1BsYXllciwgYW5kIHRodXMgd2lsbCBiZSBwcm9wZXJseSBoYW5kbGVkXHJcbiAqIGJ5IEd1YWNhbW9sZS5BdWRpb1BsYXllci5nZXRJbnN0YW5jZSgpLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbWltZXR5cGVcclxuICogICAgIFRoZSBtaW1ldHlwZSB0byBjaGVjay5cclxuICpcclxuICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAqICAgICB0cnVlIGlmIHRoZSBnaXZlbiBtaW1ldHlwZSBpcyBzdXBwb3J0ZWQgYnkgYW55IGJ1aWx0LWluXHJcbiAqICAgICBHdWFjYW1vbGUuQXVkaW9QbGF5ZXIsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXHJcbkd1YWNhbW9sZS5BdWRpb1BsYXllci5pc1N1cHBvcnRlZFR5cGUgPSBmdW5jdGlvbiBpc1N1cHBvcnRlZFR5cGUobWltZXR5cGUpIHtcclxuXHJcbiAgICByZXR1cm4gR3VhY2Ftb2xlLlJhd0F1ZGlvUGxheWVyLmlzU3VwcG9ydGVkVHlwZShtaW1ldHlwZSk7XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBsaXN0IG9mIGFsbCBtaW1ldHlwZXMgc3VwcG9ydGVkIGJ5IGFueSBidWlsdC1pblxyXG4gKiBHdWFjYW1vbGUuQXVkaW9QbGF5ZXIsIGluIHJvdWdoIG9yZGVyIG9mIHByaW9yaXR5LiBCZXdhcmUgdGhhdCBvbmx5IHRoZSBjb3JlXHJcbiAqIG1pbWV0eXBlcyB0aGVtc2VsdmVzIHdpbGwgYmUgbGlzdGVkLiBBbnkgbWltZXR5cGUgcGFyYW1ldGVycywgZXZlbiByZXF1aXJlZFxyXG4gKiBvbmVzLCB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgbGlzdC4gRm9yIGV4YW1wbGUsIFwiYXVkaW8vTDhcIiBpcyBhXHJcbiAqIHN1cHBvcnRlZCByYXcgYXVkaW8gbWltZXR5cGUgdGhhdCBpcyBzdXBwb3J0ZWQsIGJ1dCBpdCBpcyBpbnZhbGlkIHdpdGhvdXRcclxuICogYWRkaXRpb25hbCBwYXJhbWV0ZXJzLiBTb21ldGhpbmcgbGlrZSBcImF1ZGlvL0w4O3JhdGU9NDQxMDBcIiB3b3VsZCBiZSB2YWxpZCxcclxuICogaG93ZXZlciAoc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODU2KS5cclxuICpcclxuICogQHJldHVybnMge1N0cmluZ1tdfVxyXG4gKiAgICAgQSBsaXN0IG9mIGFsbCBtaW1ldHlwZXMgc3VwcG9ydGVkIGJ5IGFueSBidWlsdC1pbiBHdWFjYW1vbGUuQXVkaW9QbGF5ZXIsXHJcbiAqICAgICBleGNsdWRpbmcgYW55IHBhcmFtZXRlcnMuXHJcbiAqL1xyXG5HdWFjYW1vbGUuQXVkaW9QbGF5ZXIuZ2V0U3VwcG9ydGVkVHlwZXMgPSBmdW5jdGlvbiBnZXRTdXBwb3J0ZWRUeXBlcygpIHtcclxuXHJcbiAgICByZXR1cm4gR3VhY2Ftb2xlLlJhd0F1ZGlvUGxheWVyLmdldFN1cHBvcnRlZFR5cGVzKCk7XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgR3VhY2Ftb2xlLkF1ZGlvUGxheWVyIHByb3ZpZGluZyBzdXBwb3J0IGZvciB0aGUgZ2l2ZW5cclxuICogYXVkaW8gZm9ybWF0LiBJZiBzdXBwb3J0IGZvciB0aGUgZ2l2ZW4gYXVkaW8gZm9ybWF0IGlzIG5vdCBhdmFpbGFibGUsIG51bGxcclxuICogaXMgcmV0dXJuZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLklucHV0U3RyZWFtfSBzdHJlYW1cclxuICogICAgIFRoZSBHdWFjYW1vbGUuSW5wdXRTdHJlYW0gdG8gcmVhZCBhdWRpbyBkYXRhIGZyb20uXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZVxyXG4gKiAgICAgVGhlIG1pbWV0eXBlIG9mIHRoZSBhdWRpbyBkYXRhIGluIHRoZSBwcm92aWRlZCBzdHJlYW0uXHJcbiAqXHJcbiAqIEByZXR1cm4ge0d1YWNhbW9sZS5BdWRpb1BsYXllcn1cclxuICogICAgIEEgR3VhY2Ftb2xlLkF1ZGlvUGxheWVyIGluc3RhbmNlIHN1cHBvcnRpbmcgdGhlIGdpdmVuIG1pbWV0eXBlIGFuZFxyXG4gKiAgICAgcmVhZGluZyBmcm9tIHRoZSBnaXZlbiBzdHJlYW0sIG9yIG51bGwgaWYgc3VwcG9ydCBmb3IgdGhlIGdpdmVuIG1pbWV0eXBlXHJcbiAqICAgICBpcyBhYnNlbnQuXHJcbiAqL1xyXG5HdWFjYW1vbGUuQXVkaW9QbGF5ZXIuZ2V0SW5zdGFuY2UgPSBmdW5jdGlvbiBnZXRJbnN0YW5jZShzdHJlYW0sIG1pbWV0eXBlKSB7XHJcblxyXG4gICAgLy8gVXNlIHJhdyBhdWRpbyBwbGF5ZXIgaWYgcG9zc2libGVcclxuICAgIGlmIChHdWFjYW1vbGUuUmF3QXVkaW9QbGF5ZXIuaXNTdXBwb3J0ZWRUeXBlKG1pbWV0eXBlKSlcclxuICAgICAgICByZXR1cm4gbmV3IEd1YWNhbW9sZS5SYXdBdWRpb1BsYXllcihzdHJlYW0sIG1pbWV0eXBlKTtcclxuXHJcbiAgICAvLyBObyBzdXBwb3J0IGZvciBnaXZlbiBtaW1ldHlwZVxyXG4gICAgcmV0dXJuIG51bGw7XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEltcGxlbWVudGF0aW9uIG9mIEd1YWNhbW9sZS5BdWRpb1BsYXllciBwcm92aWRpbmcgc3VwcG9ydCBmb3IgcmF3IFBDTSBmb3JtYXRcclxuICogYXVkaW8uIFRoaXMgcGxheWVyIHJlbGllcyBvbmx5IG9uIHRoZSBXZWIgQXVkaW8gQVBJIGFuZCBkb2VzIG5vdCByZXF1aXJlIGFueVxyXG4gKiBicm93c2VyLWxldmVsIHN1cHBvcnQgZm9yIGl0cyBhdWRpbyBmb3JtYXRzLlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQGF1Z21lbnRzIEd1YWNhbW9sZS5BdWRpb1BsYXllclxyXG4gKiBAcGFyYW0ge0d1YWNhbW9sZS5JbnB1dFN0cmVhbX0gc3RyZWFtXHJcbiAqICAgICBUaGUgR3VhY2Ftb2xlLklucHV0U3RyZWFtIHRvIHJlYWQgYXVkaW8gZGF0YSBmcm9tLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbWltZXR5cGVcclxuICogICAgIFRoZSBtaW1ldHlwZSBvZiB0aGUgYXVkaW8gZGF0YSBpbiB0aGUgcHJvdmlkZWQgc3RyZWFtLCB3aGljaCBtdXN0IGJlIGFcclxuICogICAgIFwiYXVkaW8vTDhcIiBvciBcImF1ZGlvL0wxNlwiIG1pbWV0eXBlIHdpdGggbmVjZXNzYXJ5IHBhcmFtZXRlcnMsIHN1Y2ggYXM6XHJcbiAqICAgICBcImF1ZGlvL0wxNjtyYXRlPTQ0MTAwLGNoYW5uZWxzPTJcIi5cclxuICovXHJcbkd1YWNhbW9sZS5SYXdBdWRpb1BsYXllciA9IGZ1bmN0aW9uIFJhd0F1ZGlvUGxheWVyKHN0cmVhbSwgbWltZXR5cGUpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBmb3JtYXQgb2YgYXVkaW8gdGhpcyBwbGF5ZXIgd2lsbCBkZWNvZGUuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXR9XHJcbiAgICAgKi9cclxuICAgIHZhciBmb3JtYXQgPSBHdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXQucGFyc2UobWltZXR5cGUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gaW5zdGFuY2Ugb2YgYSBXZWIgQXVkaW8gQVBJIEF1ZGlvQ29udGV4dCBvYmplY3QsIG9yIG51bGwgaWYgdGhlXHJcbiAgICAgKiBXZWIgQXVkaW8gQVBJIGlzIG5vdCBzdXBwb3J0ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtBdWRpb0NvbnRleHR9XHJcbiAgICAgKi9cclxuICAgIHZhciBjb250ZXh0ID0gR3VhY2Ftb2xlLkF1ZGlvQ29udGV4dEZhY3RvcnkuZ2V0QXVkaW9Db250ZXh0KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZWFybGllc3QgcG9zc2libGUgdGltZSB0aGF0IHRoZSBuZXh0IHBhY2tldCBjb3VsZCBwbGF5IHdpdGhvdXRcclxuICAgICAqIG92ZXJsYXBwaW5nIGFuIGFscmVhZHktcGxheWluZyBwYWNrZXQsIGluIHNlY29uZHMuIE5vdGUgdGhhdCB3aGlsZSB0aGlzXHJcbiAgICAgKiB2YWx1ZSBpcyBpbiBzZWNvbmRzLCBpdCBpcyBub3QgYW4gaW50ZWdlciB2YWx1ZSBhbmQgaGFzIG1pY3Jvc2Vjb25kXHJcbiAgICAgKiByZXNvbHV0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgbmV4dFBhY2tldFRpbWUgPSBjb250ZXh0LmN1cnJlbnRUaW1lO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR3VhY2Ftb2xlLkFycmF5QnVmZmVyUmVhZGVyIHdyYXBwZWQgYXJvdW5kIHRoZSBhdWRpbyBpbnB1dCBzdHJlYW1cclxuICAgICAqIHByb3ZpZGVkIHdpdGggdGhpcyBHdWFjYW1vbGUuUmF3QXVkaW9QbGF5ZXIgd2FzIGNyZWF0ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuQXJyYXlCdWZmZXJSZWFkZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciByZWFkZXIgPSBuZXcgR3VhY2Ftb2xlLkFycmF5QnVmZmVyUmVhZGVyKHN0cmVhbSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWluaW11bSBzaXplIG9mIGFuIGF1ZGlvIHBhY2tldCBzcGxpdCBieSBzcGxpdEF1ZGlvUGFja2V0KCksIGluXHJcbiAgICAgKiBzZWNvbmRzLiBBdWRpbyBwYWNrZXRzIHNtYWxsZXIgdGhhbiB0aGlzIHdpbGwgbm90IGJlIHNwbGl0LCBub3Igd2lsbCB0aGVcclxuICAgICAqIHNwbGl0IHJlc3VsdCBvZiBhIGxhcmdlciBwYWNrZXQgZXZlciBiZSBzbWFsbGVyIGluIHNpemUgdGhhbiB0aGlzXHJcbiAgICAgKiBtaW5pbXVtLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAY29uc3RhbnRcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBNSU5fU1BMSVRfU0laRSA9IDAuMDI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWF4aW11bSBhbW91bnQgb2YgbGF0ZW5jeSB0byBhbGxvdyBiZXR3ZWVuIHRoZSBidWZmZXJlZCBkYXRhIHN0cmVhbVxyXG4gICAgICogYW5kIHRoZSBwbGF5YmFjayBwb3NpdGlvbiwgaW4gc2Vjb25kcy4gSW5pdGlhbGx5LCB0aGlzIGlzIHNldCB0b1xyXG4gICAgICogcm91Z2hseSBvbmUgdGhpcmQgb2YgYSBzZWNvbmQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBtYXhMYXRlbmN5ID0gMC4zO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHR5cGUgb2YgdHlwZWQgYXJyYXkgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVwcmVzZW50IGVhY2ggYXVkaW8gcGFja2V0XHJcbiAgICAgKiBpbnRlcm5hbGx5LiBUaGlzIHdpbGwgYmUgZWl0aGVyIEludDhBcnJheSBvciBJbnQxNkFycmF5LCBkZXBlbmRpbmcgb25cclxuICAgICAqIHdoZXRoZXIgdGhlIHJhdyBhdWRpbyBmb3JtYXQgaXMgOC1iaXQgb3IgMTYtYml0LlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqL1xyXG4gICAgdmFyIFNhbXBsZUFycmF5ID0gKGZvcm1hdC5ieXRlc1BlclNhbXBsZSA9PT0gMSkgPyB3aW5kb3cuSW50OEFycmF5IDogd2luZG93LkludDE2QXJyYXk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWF4aW11bSBhYnNvbHV0ZSB2YWx1ZSBvZiBhbnkgc2FtcGxlIHdpdGhpbiBhIHJhdyBhdWRpbyBwYWNrZXRcclxuICAgICAqIHJlY2VpdmVkIGJ5IHRoaXMgYXVkaW8gcGxheWVyLiBUaGlzIGRlcGVuZHMgb25seSBvbiB0aGUgc2l6ZSBvZiBlYWNoXHJcbiAgICAgKiBzYW1wbGUsIGFuZCB3aWxsIGJlIDEyOCBmb3IgOC1iaXQgYXVkaW8gYW5kIDMyNzY4IGZvciAxNi1iaXQgYXVkaW8uXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBtYXhTYW1wbGVWYWx1ZSA9IChmb3JtYXQuYnl0ZXNQZXJTYW1wbGUgPT09IDEpID8gMTI4IDogMzI3Njg7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcXVldWUgb2YgYWxsIHBlbmRpbmcgYXVkaW8gcGFja2V0cywgYXMgYW4gYXJyYXkgb2Ygc2FtcGxlIGFycmF5cy5cclxuICAgICAqIEF1ZGlvIHBhY2tldHMgd2hpY2ggYXJlIHBlbmRpbmcgcGxheWJhY2sgd2lsbCBiZSBhZGRlZCB0byB0aGlzIHF1ZXVlIGZvclxyXG4gICAgICogZnVydGhlciBtYW5pcHVsYXRpb24gcHJpb3IgdG8gc2NoZWR1bGluZyB2aWEgdGhlIFdlYiBBdWRpbyBBUEkuIE9uY2UgYW5cclxuICAgICAqIGF1ZGlvIHBhY2tldCBsZWF2ZXMgdGhpcyBxdWV1ZSBhbmQgaXMgc2NoZWR1bGVkIHZpYSB0aGUgV2ViIEF1ZGlvIEFQSSxcclxuICAgICAqIG5vIGZ1cnRoZXIgbW9kaWZpY2F0aW9ucyBjYW4gYmUgbWFkZSB0byB0aGF0IHBhY2tldC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge1NhbXBsZUFycmF5W119XHJcbiAgICAgKi9cclxuICAgIHZhciBwYWNrZXRRdWV1ZSA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2l2ZW4gYW4gYXJyYXkgb2YgYXVkaW8gcGFja2V0cywgcmV0dXJucyBhIHNpbmdsZSBhdWRpbyBwYWNrZXRcclxuICAgICAqIGNvbnRhaW5pbmcgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhvc2UgcGFja2V0cy5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtTYW1wbGVBcnJheVtdfSBwYWNrZXRzXHJcbiAgICAgKiAgICAgVGhlIGFycmF5IG9mIGF1ZGlvIHBhY2tldHMgdG8gY29uY2F0ZW5hdGUuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge1NhbXBsZUFycmF5fVxyXG4gICAgICogICAgIEEgc2luZ2xlIGF1ZGlvIHBhY2tldCBjb250YWluaW5nIHRoZSBjb25jYXRlbmF0aW9uIG9mIGFsbCBnaXZlblxyXG4gICAgICogICAgIGF1ZGlvIHBhY2tldHMuIElmIG5vIHBhY2tldHMgYXJlIHByb3ZpZGVkLCB0aGlzIHdpbGwgYmUgdW5kZWZpbmVkLlxyXG4gICAgICovXHJcbiAgICB2YXIgam9pbkF1ZGlvUGFja2V0cyA9IGZ1bmN0aW9uIGpvaW5BdWRpb1BhY2tldHMocGFja2V0cykge1xyXG5cclxuICAgICAgICAvLyBEbyBub3QgYm90aGVyIGpvaW5pbmcgaWYgb25lIG9yIGZld2VyIHBhY2tldHMgYXJlIGluIHRoZSBxdWV1ZVxyXG4gICAgICAgIGlmIChwYWNrZXRzLmxlbmd0aCA8PSAxKVxyXG4gICAgICAgICAgICByZXR1cm4gcGFja2V0c1swXTtcclxuXHJcbiAgICAgICAgLy8gRGV0ZXJtaW5lIHRvdGFsIHNhbXBsZSBsZW5ndGggb2YgdGhlIGVudGlyZSBxdWV1ZVxyXG4gICAgICAgIHZhciB0b3RhbExlbmd0aCA9IDA7XHJcbiAgICAgICAgcGFja2V0cy5mb3JFYWNoKGZ1bmN0aW9uIGFkZFBhY2tldExlbmd0aHMocGFja2V0KSB7XHJcbiAgICAgICAgICAgIHRvdGFsTGVuZ3RoICs9IHBhY2tldC5sZW5ndGg7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIEFwcGVuZCBlYWNoIHBhY2tldCB3aXRoaW4gcXVldWVcclxuICAgICAgICB2YXIgb2Zmc2V0ID0gMDtcclxuICAgICAgICB2YXIgam9pbmVkID0gbmV3IFNhbXBsZUFycmF5KHRvdGFsTGVuZ3RoKTtcclxuICAgICAgICBwYWNrZXRzLmZvckVhY2goZnVuY3Rpb24gYXBwZW5kUGFja2V0KHBhY2tldCkge1xyXG4gICAgICAgICAgICBqb2luZWQuc2V0KHBhY2tldCwgb2Zmc2V0KTtcclxuICAgICAgICAgICAgb2Zmc2V0ICs9IHBhY2tldC5sZW5ndGg7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBqb2luZWQ7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdpdmVuIGEgc2luZ2xlIHBhY2tldCBvZiBhdWRpbyBkYXRhLCBzcGxpdHMgb2ZmIGFuIGFyYml0cmFyeSBsZW5ndGggb2ZcclxuICAgICAqIGF1ZGlvIGRhdGEgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoYXQgcGFja2V0LCByZXR1cm5pbmcgdGhlIHNwbGl0IHJlc3VsdFxyXG4gICAgICogYXMgYW4gYXJyYXkgb2YgdHdvIHBhY2tldHMuIFRoZSBzcGxpdCBsb2NhdGlvbiBpcyBkZXRlcm1pbmVkIHRocm91Z2ggYW5cclxuICAgICAqIGFsZ29yaXRobSBpbnRlbmRlZCB0byBtaW5pbWl6ZSB0aGUgbGlrbGlob29kIG9mIGF1ZGlibGUgY2xpY2tpbmcgYmV0d2VlblxyXG4gICAgICogcGFja2V0cy4gSWYgbm8gc3VjaCBzcGxpdCBsb2NhdGlvbiBpcyBwb3NzaWJsZSwgYW4gYXJyYXkgY29udGFpbmluZyBvbmx5XHJcbiAgICAgKiB0aGUgb3JpZ2luYWxseS1wcm92aWRlZCBhdWRpbyBwYWNrZXQgaXMgcmV0dXJuZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7U2FtcGxlQXJyYXl9IGRhdGFcclxuICAgICAqICAgICBUaGUgYXVkaW8gcGFja2V0IHRvIHNwbGl0LlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtTYW1wbGVBcnJheVtdfVxyXG4gICAgICogICAgIEFuIGFycmF5IG9mIGF1ZGlvIHBhY2tldHMgY29udGFpbmluZyB0aGUgcmVzdWx0IG9mIHNwbGl0dGluZyB0aGVcclxuICAgICAqICAgICBwcm92aWRlZCBhdWRpbyBwYWNrZXQuIElmIHNwbGl0dGluZyBpcyBwb3NzaWJsZSwgdGhpcyBhcnJheSB3aWxsXHJcbiAgICAgKiAgICAgY29udGFpbiB0d28gcGFja2V0cy4gSWYgc3BsaXR0aW5nIGlzIG5vdCBwb3NzaWJsZSwgdGhpcyBhcnJheSB3aWxsXHJcbiAgICAgKiAgICAgY29udGFpbiBvbmx5IHRoZSBvcmlnaW5hbGx5LXByb3ZpZGVkIHBhY2tldC5cclxuICAgICAqL1xyXG4gICAgdmFyIHNwbGl0QXVkaW9QYWNrZXQgPSBmdW5jdGlvbiBzcGxpdEF1ZGlvUGFja2V0KGRhdGEpIHtcclxuXHJcbiAgICAgICAgdmFyIG1pblZhbHVlID0gTnVtYmVyLk1BWF9WQUxVRTtcclxuICAgICAgICB2YXIgb3B0aW1hbFNwbGl0TGVuZ3RoID0gZGF0YS5sZW5ndGg7XHJcblxyXG4gICAgICAgIC8vIENhbGN1bGF0ZSBudW1iZXIgb2Ygd2hvbGUgc2FtcGxlcyBpbiB0aGUgcHJvdmlkZWQgYXVkaW8gcGFja2V0IEFORFxyXG4gICAgICAgIC8vIGluIHRoZSBtaW5pbXVtIHBvc3NpYmxlIHNwbGl0IHBhY2tldFxyXG4gICAgICAgIHZhciBzYW1wbGVzID0gTWF0aC5mbG9vcihkYXRhLmxlbmd0aCAvIGZvcm1hdC5jaGFubmVscyk7XHJcbiAgICAgICAgdmFyIG1pblNwbGl0U2FtcGxlcyA9IE1hdGguZmxvb3IoZm9ybWF0LnJhdGUgKiBNSU5fU1BMSVRfU0laRSk7XHJcblxyXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBcImVuZFwiIG9mIHRoZSBhdWRpbyBwYWNrZXRcclxuICAgICAgICB2YXIgc3RhcnQgPSBNYXRoLm1heChcclxuICAgICAgICAgICAgZm9ybWF0LmNoYW5uZWxzICogbWluU3BsaXRTYW1wbGVzLFxyXG4gICAgICAgICAgICBmb3JtYXQuY2hhbm5lbHMgKiAoc2FtcGxlcyAtIG1pblNwbGl0U2FtcGxlcylcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICAvLyBGb3IgYWxsIHNhbXBsZXMgYXQgdGhlIGVuZCBvZiB0aGUgZ2l2ZW4gcGFja2V0LCBmaW5kIGEgcG9pbnQgd2hlcmVcclxuICAgICAgICAvLyB0aGUgcGVyY2VwdGlibGUgdm9sdW1lIGFjcm9zcyBhbGwgY2hhbm5lbHMgaXMgbG93ZXN0IChhbmQgdGh1cyBpc1xyXG4gICAgICAgIC8vIHRoZSBvcHRpbWFsIHBvaW50IHRvIHNwbGl0KVxyXG4gICAgICAgIGZvciAodmFyIG9mZnNldCA9IHN0YXJ0OyBvZmZzZXQgPCBkYXRhLmxlbmd0aDsgb2Zmc2V0ICs9IGZvcm1hdC5jaGFubmVscykge1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBzdW0gb2YgYWxsIHZhbHVlcyBhY3Jvc3MgYWxsIGNoYW5uZWxzICh0aGUgcmVzdWx0XHJcbiAgICAgICAgICAgIC8vIHdpbGwgYmUgcHJvcG9ydGlvbmFsIHRvIHRoZSBhdmVyYWdlIHZvbHVtZSBvZiBhIHNhbXBsZSlcclxuICAgICAgICAgICAgdmFyIHRvdGFsVmFsdWUgPSAwO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IGZvcm1hdC5jaGFubmVsczsgY2hhbm5lbCsrKSB7XHJcbiAgICAgICAgICAgICAgICB0b3RhbFZhbHVlICs9IE1hdGguYWJzKGRhdGFbb2Zmc2V0ICsgY2hhbm5lbF0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSBzbWFsbGVzdCBhdmVyYWdlIHZhbHVlIHRodXMgZmFyLCBzZXQgdGhlIHNwbGl0XHJcbiAgICAgICAgICAgIC8vIGxlbmd0aCBzdWNoIHRoYXQgdGhlIGZpcnN0IHBhY2tldCBlbmRzIHdpdGggdGhlIGN1cnJlbnQgc2FtcGxlXHJcbiAgICAgICAgICAgIGlmICh0b3RhbFZhbHVlIDw9IG1pblZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpbWFsU3BsaXRMZW5ndGggPSBvZmZzZXQgKyBmb3JtYXQuY2hhbm5lbHM7XHJcbiAgICAgICAgICAgICAgICBtaW5WYWx1ZSA9IHRvdGFsVmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiBwYWNrZXQgaXMgbm90IHNwbGl0LCByZXR1cm4gdGhlIHN1cHBsaWVkIHBhY2tldCB1bnRvdWNoZWRcclxuICAgICAgICBpZiAob3B0aW1hbFNwbGl0TGVuZ3RoID09PSBkYXRhLmxlbmd0aClcclxuICAgICAgICAgICAgcmV0dXJuIFtkYXRhXTtcclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBzcGxpdCB0aGUgcGFja2V0IGludG8gdHdvIG5ldyBwYWNrZXRzIGFjY29yZGluZyB0byB0aGVcclxuICAgICAgICAvLyBjYWxjdWxhdGVkIG9wdGltYWwgc3BsaXQgbGVuZ3RoXHJcbiAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgbmV3IFNhbXBsZUFycmF5KGRhdGEuYnVmZmVyLnNsaWNlKDAsIG9wdGltYWxTcGxpdExlbmd0aCAqIGZvcm1hdC5ieXRlc1BlclNhbXBsZSkpLFxyXG4gICAgICAgICAgICBuZXcgU2FtcGxlQXJyYXkoZGF0YS5idWZmZXIuc2xpY2Uob3B0aW1hbFNwbGl0TGVuZ3RoICogZm9ybWF0LmJ5dGVzUGVyU2FtcGxlKSlcclxuICAgICAgICBdO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQdXNoZXMgdGhlIGdpdmVuIHBhY2tldCBvZiBhdWRpbyBkYXRhIG9udG8gdGhlIHBsYXliYWNrIHF1ZXVlLiBVbmxpa2VcclxuICAgICAqIG90aGVyIHByaXZhdGUgZnVuY3Rpb25zIHdpdGhpbiBHdWFjYW1vbGUuUmF3QXVkaW9QbGF5ZXIsIHRoZSB0eXBlIG9mIHRoZVxyXG4gICAgICogQXJyYXlCdWZmZXIgcGFja2V0IG9mIGF1ZGlvIGRhdGEgaGVyZSBuZWVkIG5vdCBiZSBzcGVjaWZpYyB0byB0aGUgdHlwZVxyXG4gICAgICogb2YgYXVkaW8gKGFzIHdpdGggU2FtcGxlQXJyYXkpLiBUaGUgQXJyYXlCdWZmZXIgdHlwZSBwcm92aWRlZCBieSBhXHJcbiAgICAgKiBHdWFjYW1vbGUuQXJyYXlCdWZmZXJSZWFkZXIsIGZvciBleGFtcGxlLCBpcyBzdWZmaWNpZW50LiBBbnkgbmVjZXNzYXJ5XHJcbiAgICAgKiBjb252ZXJzaW9ucyB3aWxsIGJlIHBlcmZvcm1lZCBhdXRvbWF0aWNhbGx5IGludGVybmFsbHkuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGRhdGFcclxuICAgICAqICAgICBBIHJhdyBwYWNrZXQgb2YgYXVkaW8gZGF0YSB0aGF0IHNob3VsZCBiZSBwdXNoZWQgb250byB0aGUgYXVkaW9cclxuICAgICAqICAgICBwbGF5YmFjayBxdWV1ZS5cclxuICAgICAqL1xyXG4gICAgdmFyIHB1c2hBdWRpb1BhY2tldCA9IGZ1bmN0aW9uIHB1c2hBdWRpb1BhY2tldChkYXRhKSB7XHJcbiAgICAgICAgcGFja2V0UXVldWUucHVzaChuZXcgU2FtcGxlQXJyYXkoZGF0YSkpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNoaWZ0cyBvZmYgYW5kIHJldHVybnMgYSBwYWNrZXQgb2YgYXVkaW8gZGF0YSBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlXHJcbiAgICAgKiBwbGF5YmFjayBxdWV1ZS4gVGhlIGxlbmd0aCBvZiB0aGlzIGF1ZGlvIHBhY2tldCBpcyBkZXRlcm1pbmVkXHJcbiAgICAgKiBkeW5hbWljYWxseSBhY2NvcmRpbmcgdG8gdGhlIGNsaWNrLXJlZHVjdGlvbiBhbGdvcml0aG0gaW1wbGVtZW50ZWQgYnlcclxuICAgICAqIHNwbGl0QXVkaW9QYWNrZXQoKS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHJldHVybnMge1NhbXBsZUFycmF5fVxyXG4gICAgICogICAgIEEgcGFja2V0IG9mIGF1ZGlvIGRhdGEgcHVsbGVkIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgcGxheWJhY2tcclxuICAgICAqICAgICBxdWV1ZS5cclxuICAgICAqL1xyXG4gICAgdmFyIHNoaWZ0QXVkaW9QYWNrZXQgPSBmdW5jdGlvbiBzaGlmdEF1ZGlvUGFja2V0KCkge1xyXG5cclxuICAgICAgICAvLyBGbGF0dGVuIGRhdGEgaW4gcGFja2V0IHF1ZXVlXHJcbiAgICAgICAgdmFyIGRhdGEgPSBqb2luQXVkaW9QYWNrZXRzKHBhY2tldFF1ZXVlKTtcclxuICAgICAgICBpZiAoIWRhdGEpXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICAvLyBQdWxsIGFuIGFwcHJvcHJpYXRlIGFtb3VudCBvZiBkYXRhIGZyb20gdGhlIGZyb250IG9mIHRoZSBxdWV1ZVxyXG4gICAgICAgIHBhY2tldFF1ZXVlID0gc3BsaXRBdWRpb1BhY2tldChkYXRhKTtcclxuICAgICAgICBkYXRhID0gcGFja2V0UXVldWUuc2hpZnQoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGRhdGE7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBnaXZlbiBhdWRpbyBwYWNrZXQgaW50byBhbiBBdWRpb0J1ZmZlciwgcmVhZHkgZm9yIHBsYXliYWNrXHJcbiAgICAgKiBieSB0aGUgV2ViIEF1ZGlvIEFQSS4gVW5saWtlIHRoZSByYXcgYXVkaW8gcGFja2V0cyByZWNlaXZlZCBieSB0aGlzXHJcbiAgICAgKiBhdWRpbyBwbGF5ZXIsIEF1ZGlvQnVmZmVycyByZXF1aXJlIGZsb2F0aW5nIHBvaW50IHNhbXBsZXMgYW5kIGFyZSBzcGxpdFxyXG4gICAgICogaW50byBpc29sYXRlZCBwbGFuZXMgb2YgY2hhbm5lbC1zcGVjaWZpYyBkYXRhLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge1NhbXBsZUFycmF5fSBkYXRhXHJcbiAgICAgKiAgICAgVGhlIHJhdyBhdWRpbyBwYWNrZXQgdGhhdCBzaG91bGQgYmUgY29udmVydGVkIGludG8gYSBXZWIgQXVkaW8gQVBJXHJcbiAgICAgKiAgICAgQXVkaW9CdWZmZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0F1ZGlvQnVmZmVyfVxyXG4gICAgICogICAgIEEgbmV3IFdlYiBBdWRpbyBBUEkgQXVkaW9CdWZmZXIgY29udGFpbmluZyB0aGUgcHJvdmlkZWQgYXVkaW8gZGF0YSxcclxuICAgICAqICAgICBjb252ZXJ0ZWQgdG8gdGhlIGZvcm1hdCB1c2VkIGJ5IHRoZSBXZWIgQXVkaW8gQVBJLlxyXG4gICAgICovXHJcbiAgICB2YXIgdG9BdWRpb0J1ZmZlciA9IGZ1bmN0aW9uIHRvQXVkaW9CdWZmZXIoZGF0YSkge1xyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgdG90YWwgbnVtYmVyIG9mIHNhbXBsZXNcclxuICAgICAgICB2YXIgc2FtcGxlcyA9IGRhdGEubGVuZ3RoIC8gZm9ybWF0LmNoYW5uZWxzO1xyXG5cclxuICAgICAgICAvLyBEZXRlcm1pbmUgZXhhY3RseSB3aGVuIHBhY2tldCBDQU4gcGxheVxyXG4gICAgICAgIHZhciBwYWNrZXRUaW1lID0gY29udGV4dC5jdXJyZW50VGltZTtcclxuICAgICAgICBpZiAobmV4dFBhY2tldFRpbWUgPCBwYWNrZXRUaW1lKVxyXG4gICAgICAgICAgICBuZXh0UGFja2V0VGltZSA9IHBhY2tldFRpbWU7XHJcblxyXG4gICAgICAgIC8vIEdldCBhdWRpbyBidWZmZXIgZm9yIHNwZWNpZmllZCBmb3JtYXRcclxuICAgICAgICB2YXIgYXVkaW9CdWZmZXIgPSBjb250ZXh0LmNyZWF0ZUJ1ZmZlcihmb3JtYXQuY2hhbm5lbHMsIHNhbXBsZXMsIGZvcm1hdC5yYXRlKTtcclxuXHJcbiAgICAgICAgLy8gQ29udmVydCBlYWNoIGNoYW5uZWxcclxuICAgICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IGZvcm1hdC5jaGFubmVsczsgY2hhbm5lbCsrKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgYXVkaW9EYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCk7XHJcblxyXG4gICAgICAgICAgICAvLyBGaWxsIGF1ZGlvIGJ1ZmZlciB3aXRoIGRhdGEgZm9yIGNoYW5uZWxcclxuICAgICAgICAgICAgdmFyIG9mZnNldCA9IGNoYW5uZWw7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2FtcGxlczsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBhdWRpb0RhdGFbaV0gPSBkYXRhW29mZnNldF0gLyBtYXhTYW1wbGVWYWx1ZTtcclxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBmb3JtYXQuY2hhbm5lbHM7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBEZWZlciBwbGF5YmFjayBvZiByZWNlaXZlZCBhdWRpbyBwYWNrZXRzIHNsaWdodGx5XHJcbiAgICByZWFkZXIub25kYXRhID0gZnVuY3Rpb24gcGxheVJlY2VpdmVkQXVkaW8oZGF0YSkge1xyXG5cclxuICAgICAgICAvLyBQdXNoIHJlY2VpdmVkIHNhbXBsZXMgb250byBxdWV1ZVxyXG4gICAgICAgIHB1c2hBdWRpb1BhY2tldChuZXcgU2FtcGxlQXJyYXkoZGF0YSkpO1xyXG5cclxuICAgICAgICAvLyBTaGlmdCBvZmYgYW4gYXJiaXRyYXJ5IHBhY2tldCBvZiBhdWRpbyBkYXRhIGZyb20gdGhlIHF1ZXVlICh0aGlzIG1heVxyXG4gICAgICAgIC8vIGJlIGRpZmZlcmVudCBpbiBzaXplIGZyb20gdGhlIHBhY2tldCBqdXN0IHB1c2hlZClcclxuICAgICAgICB2YXIgcGFja2V0ID0gc2hpZnRBdWRpb1BhY2tldCgpO1xyXG4gICAgICAgIGlmICghcGFja2V0KVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIERldGVybWluZSBleGFjdGx5IHdoZW4gcGFja2V0IENBTiBwbGF5XHJcbiAgICAgICAgdmFyIHBhY2tldFRpbWUgPSBjb250ZXh0LmN1cnJlbnRUaW1lO1xyXG4gICAgICAgIGlmIChuZXh0UGFja2V0VGltZSA8IHBhY2tldFRpbWUpXHJcbiAgICAgICAgICAgIG5leHRQYWNrZXRUaW1lID0gcGFja2V0VGltZTtcclxuXHJcbiAgICAgICAgLy8gU2V0IHVwIGJ1ZmZlciBzb3VyY2VcclxuICAgICAgICB2YXIgc291cmNlID0gY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcclxuICAgICAgICBzb3VyY2UuY29ubmVjdChjb250ZXh0LmRlc3RpbmF0aW9uKTtcclxuXHJcbiAgICAgICAgLy8gVXNlIG5vdGVPbigpIGluc3RlYWQgb2Ygc3RhcnQoKSBpZiBuZWNlc3NhcnlcclxuICAgICAgICBpZiAoIXNvdXJjZS5zdGFydClcclxuICAgICAgICAgICAgc291cmNlLnN0YXJ0ID0gc291cmNlLm5vdGVPbjtcclxuXHJcbiAgICAgICAgLy8gU2NoZWR1bGUgcGFja2V0XHJcbiAgICAgICAgc291cmNlLmJ1ZmZlciA9IHRvQXVkaW9CdWZmZXIocGFja2V0KTtcclxuICAgICAgICBzb3VyY2Uuc3RhcnQobmV4dFBhY2tldFRpbWUpO1xyXG5cclxuICAgICAgICAvLyBVcGRhdGUgdGltZWxpbmUgYnkgZHVyYXRpb24gb2Ygc2NoZWR1bGVkIHBhY2tldFxyXG4gICAgICAgIG5leHRQYWNrZXRUaW1lICs9IHBhY2tldC5sZW5ndGggLyBmb3JtYXQuY2hhbm5lbHMgLyBmb3JtYXQucmF0ZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKiBAb3ZlcnJpZGUgKi9cclxuICAgIHRoaXMuc3luYyA9IGZ1bmN0aW9uIHN5bmMoKSB7XHJcblxyXG4gICAgICAgIC8vIENhbGN1bGF0ZSBlbGFwc2VkIHRpbWUgc2luY2UgbGFzdCBzeW5jXHJcbiAgICAgICAgdmFyIG5vdyA9IGNvbnRleHQuY3VycmVudFRpbWU7XHJcblxyXG4gICAgICAgIC8vIFJlc2NoZWR1bGUgZnV0dXJlIHBsYXliYWNrIHRpbWUgc3VjaCB0aGF0IHBsYXliYWNrIGxhdGVuY3kgaXNcclxuICAgICAgICAvLyBib3VuZGVkIHdpdGhpbiBhIHJlYXNvbmFibGUgbGF0ZW5jeSB0aHJlc2hvbGRcclxuICAgICAgICBuZXh0UGFja2V0VGltZSA9IE1hdGgubWluKG5leHRQYWNrZXRUaW1lLCBub3cgKyBtYXhMYXRlbmN5KTtcclxuXHJcbiAgICB9O1xyXG5cclxufTtcclxuXHJcbkd1YWNhbW9sZS5SYXdBdWRpb1BsYXllci5wcm90b3R5cGUgPSBuZXcgR3VhY2Ftb2xlLkF1ZGlvUGxheWVyKCk7XHJcblxyXG4vKipcclxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiBtaW1ldHlwZSBpcyBzdXBwb3J0ZWQgYnlcclxuICogR3VhY2Ftb2xlLlJhd0F1ZGlvUGxheWVyLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbWltZXR5cGVcclxuICogICAgIFRoZSBtaW1ldHlwZSB0byBjaGVjay5cclxuICpcclxuICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAqICAgICB0cnVlIGlmIHRoZSBnaXZlbiBtaW1ldHlwZSBpcyBzdXBwb3J0ZWQgYnkgR3VhY2Ftb2xlLlJhd0F1ZGlvUGxheWVyLFxyXG4gKiAgICAgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cclxuR3VhY2Ftb2xlLlJhd0F1ZGlvUGxheWVyLmlzU3VwcG9ydGVkVHlwZSA9IGZ1bmN0aW9uIGlzU3VwcG9ydGVkVHlwZShtaW1ldHlwZSkge1xyXG5cclxuICAgIC8vIE5vIHN1cHBvcnRlZCB0eXBlcyBpZiBubyBXZWIgQXVkaW8gQVBJXHJcbiAgICBpZiAoIUd1YWNhbW9sZS5BdWRpb0NvbnRleHRGYWN0b3J5LmdldEF1ZGlvQ29udGV4dCgpKVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICByZXR1cm4gR3VhY2Ftb2xlLlJhd0F1ZGlvRm9ybWF0LnBhcnNlKG1pbWV0eXBlKSAhPT0gbnVsbDtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIG1pbWV0eXBlcyBzdXBwb3J0ZWQgYnkgR3VhY2Ftb2xlLlJhd0F1ZGlvUGxheWVyLiBPbmx5XHJcbiAqIHRoZSBjb3JlIG1pbWV0eXBlcyB0aGVtc2VsdmVzIHdpbGwgYmUgbGlzdGVkLiBBbnkgbWltZXR5cGUgcGFyYW1ldGVycywgZXZlblxyXG4gKiByZXF1aXJlZCBvbmVzLCB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgbGlzdC4gRm9yIGV4YW1wbGUsIFwiYXVkaW8vTDhcIiBpc1xyXG4gKiBhIHJhdyBhdWRpbyBtaW1ldHlwZSB0aGF0IG1heSBiZSBzdXBwb3J0ZWQsIGJ1dCBpdCBpcyBpbnZhbGlkIHdpdGhvdXRcclxuICogYWRkaXRpb25hbCBwYXJhbWV0ZXJzLiBTb21ldGhpbmcgbGlrZSBcImF1ZGlvL0w4O3JhdGU9NDQxMDBcIiB3b3VsZCBiZSB2YWxpZCxcclxuICogaG93ZXZlciAoc2VlIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM0ODU2KS5cclxuICpcclxuICogQHJldHVybnMge1N0cmluZ1tdfVxyXG4gKiAgICAgQSBsaXN0IG9mIGFsbCBtaW1ldHlwZXMgc3VwcG9ydGVkIGJ5IEd1YWNhbW9sZS5SYXdBdWRpb1BsYXllciwgZXhjbHVkaW5nXHJcbiAqICAgICBhbnkgcGFyYW1ldGVycy4gSWYgdGhlIG5lY2Vzc2FyeSBKYXZhU2NyaXB0IEFQSXMgZm9yIHBsYXlpbmcgcmF3IGF1ZGlvXHJcbiAqICAgICBhcmUgYWJzZW50LCB0aGlzIGxpc3Qgd2lsbCBiZSBlbXB0eS5cclxuICovXHJcbkd1YWNhbW9sZS5SYXdBdWRpb1BsYXllci5nZXRTdXBwb3J0ZWRUeXBlcyA9IGZ1bmN0aW9uIGdldFN1cHBvcnRlZFR5cGVzKCkge1xyXG5cclxuICAgIC8vIE5vIHN1cHBvcnRlZCB0eXBlcyBpZiBubyBXZWIgQXVkaW8gQVBJXHJcbiAgICBpZiAoIUd1YWNhbW9sZS5BdWRpb0NvbnRleHRGYWN0b3J5LmdldEF1ZGlvQ29udGV4dCgpKVxyXG4gICAgICAgIHJldHVybiBbXTtcclxuXHJcbiAgICAvLyBXZSBzdXBwb3J0IDgtYml0IGFuZCAxNi1iaXQgcmF3IFBDTVxyXG4gICAgcmV0dXJuIFtcclxuICAgICAgICAnYXVkaW8vTDgnLFxyXG4gICAgICAgICdhdWRpby9MMTYnXHJcbiAgICBdO1xyXG5cclxufTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBYnN0cmFjdCBhdWRpbyByZWNvcmRlciB3aGljaCBzdHJlYW1zIGFyYml0cmFyeSBhdWRpbyBkYXRhIHRvIGFuIHVuZGVybHlpbmdcclxuICogR3VhY2Ftb2xlLk91dHB1dFN0cmVhbS4gSXQgaXMgdXAgdG8gaW1wbGVtZW50YXRpb25zIG9mIHRoaXMgY2xhc3MgdG8gcHJvdmlkZVxyXG4gKiBzb21lIG1lYW5zIG9mIGhhbmRsaW5nIHRoaXMgR3VhY2Ftb2xlLk91dHB1dFN0cmVhbS4gRGF0YSBwcm9kdWNlZCBieSB0aGVcclxuICogcmVjb3JkZXIgaXMgdG8gYmUgc2VudCBhbG9uZyB0aGUgcHJvdmlkZWQgc3RyZWFtIGltbWVkaWF0ZWx5LlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbkd1YWNhbW9sZS5BdWRpb1JlY29yZGVyID0gZnVuY3Rpb24gQXVkaW9SZWNvcmRlcigpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIHdoaWNoIGlzIGludm9rZWQgd2hlbiB0aGUgYXVkaW8gcmVjb3JkaW5nIHByb2Nlc3MgaGFzIHN0b3BwZWRcclxuICAgICAqIGFuZCB0aGUgdW5kZXJseWluZyBHdWFjYW1vbGUgc3RyZWFtIGhhcyBiZWVuIGNsb3NlZCBub3JtYWxseS4gQXVkaW8gd2lsbFxyXG4gICAgICogb25seSByZXN1bWUgcmVjb3JkaW5nIGlmIGEgbmV3IEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyIGlzIHN0YXJ0ZWQuIFRoaXNcclxuICAgICAqIEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyIGluc3RhbmNlIE1BWSBOT1QgYmUgcmV1c2VkLlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uY2xvc2UgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCB3aGVuIHRoZSBhdWRpbyByZWNvcmRpbmcgcHJvY2VzcyBjYW5ub3RcclxuICAgICAqIGNvbnRpbnVlIGR1ZSB0byBhbiBlcnJvciwgaWYgaXQgaGFzIHN0YXJ0ZWQgYXQgYWxsLiBUaGUgdW5kZXJseWluZ1xyXG4gICAgICogR3VhY2Ftb2xlIHN0cmVhbSBpcyBhdXRvbWF0aWNhbGx5IGNsb3NlZC4gRnV0dXJlIGF0dGVtcHRzIHRvIHJlY29yZFxyXG4gICAgICogYXVkaW8gc2hvdWxkIG5vdCBiZSBtYWRlLCBhbmQgdGhpcyBHdWFjYW1vbGUuQXVkaW9SZWNvcmRlciBpbnN0YW5jZVxyXG4gICAgICogTUFZIE5PVCBiZSByZXVzZWQuXHJcbiAgICAgKlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKi9cclxuICAgIHRoaXMub25lcnJvciA9IG51bGw7XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIERldGVybWluZXMgd2hldGhlciB0aGUgZ2l2ZW4gbWltZXR5cGUgaXMgc3VwcG9ydGVkIGJ5IGFueSBidWlsdC1pblxyXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBHdWFjYW1vbGUuQXVkaW9SZWNvcmRlciwgYW5kIHRodXMgd2lsbCBiZSBwcm9wZXJseSBoYW5kbGVkXHJcbiAqIGJ5IEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyLmdldEluc3RhbmNlKCkuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZVxyXG4gKiAgICAgVGhlIG1pbWV0eXBlIHRvIGNoZWNrLlxyXG4gKlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICogICAgIHRydWUgaWYgdGhlIGdpdmVuIG1pbWV0eXBlIGlzIHN1cHBvcnRlZCBieSBhbnkgYnVpbHQtaW5cclxuICogICAgIEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAqL1xyXG5HdWFjYW1vbGUuQXVkaW9SZWNvcmRlci5pc1N1cHBvcnRlZFR5cGUgPSBmdW5jdGlvbiBpc1N1cHBvcnRlZFR5cGUobWltZXR5cGUpIHtcclxuXHJcbiAgICByZXR1cm4gR3VhY2Ftb2xlLlJhd0F1ZGlvUmVjb3JkZXIuaXNTdXBwb3J0ZWRUeXBlKG1pbWV0eXBlKTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIG1pbWV0eXBlcyBzdXBwb3J0ZWQgYnkgYW55IGJ1aWx0LWluXHJcbiAqIEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyLCBpbiByb3VnaCBvcmRlciBvZiBwcmlvcml0eS4gQmV3YXJlIHRoYXQgb25seSB0aGVcclxuICogY29yZSBtaW1ldHlwZXMgdGhlbXNlbHZlcyB3aWxsIGJlIGxpc3RlZC4gQW55IG1pbWV0eXBlIHBhcmFtZXRlcnMsIGV2ZW5cclxuICogcmVxdWlyZWQgb25lcywgd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIGxpc3QuIEZvciBleGFtcGxlLCBcImF1ZGlvL0w4XCIgaXNcclxuICogYSBzdXBwb3J0ZWQgcmF3IGF1ZGlvIG1pbWV0eXBlIHRoYXQgaXMgc3VwcG9ydGVkLCBidXQgaXQgaXMgaW52YWxpZCB3aXRob3V0XHJcbiAqIGFkZGl0aW9uYWwgcGFyYW1ldGVycy4gU29tZXRoaW5nIGxpa2UgXCJhdWRpby9MODtyYXRlPTQ0MTAwXCIgd291bGQgYmUgdmFsaWQsXHJcbiAqIGhvd2V2ZXIgKHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNDg1NikuXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtTdHJpbmdbXX1cclxuICogICAgIEEgbGlzdCBvZiBhbGwgbWltZXR5cGVzIHN1cHBvcnRlZCBieSBhbnkgYnVpbHQtaW5cclxuICogICAgIEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyLCBleGNsdWRpbmcgYW55IHBhcmFtZXRlcnMuXHJcbiAqL1xyXG5HdWFjYW1vbGUuQXVkaW9SZWNvcmRlci5nZXRTdXBwb3J0ZWRUeXBlcyA9IGZ1bmN0aW9uIGdldFN1cHBvcnRlZFR5cGVzKCkge1xyXG5cclxuICAgIHJldHVybiBHdWFjYW1vbGUuUmF3QXVkaW9SZWNvcmRlci5nZXRTdXBwb3J0ZWRUeXBlcygpO1xyXG5cclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyIHByb3ZpZGluZyBzdXBwb3J0IGZvciB0aGVcclxuICogZ2l2ZW4gYXVkaW8gZm9ybWF0LiBJZiBzdXBwb3J0IGZvciB0aGUgZ2l2ZW4gYXVkaW8gZm9ybWF0IGlzIG5vdCBhdmFpbGFibGUsXHJcbiAqIG51bGwgaXMgcmV0dXJuZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLk91dHB1dFN0cmVhbX0gc3RyZWFtXHJcbiAqICAgICBUaGUgR3VhY2Ftb2xlLk91dHB1dFN0cmVhbSB0byBzZW5kIGF1ZGlvIGRhdGEgdGhyb3VnaC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlXHJcbiAqICAgICBUaGUgbWltZXR5cGUgb2YgdGhlIGF1ZGlvIGRhdGEgdG8gYmUgc2VudCBhbG9uZyB0aGUgcHJvdmlkZWQgc3RyZWFtLlxyXG4gKlxyXG4gKiBAcmV0dXJuIHtHdWFjYW1vbGUuQXVkaW9SZWNvcmRlcn1cclxuICogICAgIEEgR3VhY2Ftb2xlLkF1ZGlvUmVjb3JkZXIgaW5zdGFuY2Ugc3VwcG9ydGluZyB0aGUgZ2l2ZW4gbWltZXR5cGUgYW5kXHJcbiAqICAgICB3cml0aW5nIHRvIHRoZSBnaXZlbiBzdHJlYW0sIG9yIG51bGwgaWYgc3VwcG9ydCBmb3IgdGhlIGdpdmVuIG1pbWV0eXBlXHJcbiAqICAgICBpcyBhYnNlbnQuXHJcbiAqL1xyXG5HdWFjYW1vbGUuQXVkaW9SZWNvcmRlci5nZXRJbnN0YW5jZSA9IGZ1bmN0aW9uIGdldEluc3RhbmNlKHN0cmVhbSwgbWltZXR5cGUpIHtcclxuXHJcbiAgICAvLyBVc2UgcmF3IGF1ZGlvIHJlY29yZGVyIGlmIHBvc3NpYmxlXHJcbiAgICBpZiAoR3VhY2Ftb2xlLlJhd0F1ZGlvUmVjb3JkZXIuaXNTdXBwb3J0ZWRUeXBlKG1pbWV0eXBlKSlcclxuICAgICAgICByZXR1cm4gbmV3IEd1YWNhbW9sZS5SYXdBdWRpb1JlY29yZGVyKHN0cmVhbSwgbWltZXR5cGUpO1xyXG5cclxuICAgIC8vIE5vIHN1cHBvcnQgZm9yIGdpdmVuIG1pbWV0eXBlXHJcbiAgICByZXR1cm4gbnVsbDtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogSW1wbGVtZW50YXRpb24gb2YgR3VhY2Ftb2xlLkF1ZGlvUmVjb3JkZXIgcHJvdmlkaW5nIHN1cHBvcnQgZm9yIHJhdyBQQ01cclxuICogZm9ybWF0IGF1ZGlvLiBUaGlzIHJlY29yZGVyIHJlbGllcyBvbmx5IG9uIHRoZSBXZWIgQXVkaW8gQVBJIGFuZCBkb2VzIG5vdFxyXG4gKiByZXF1aXJlIGFueSBicm93c2VyLWxldmVsIHN1cHBvcnQgZm9yIGl0cyBhdWRpbyBmb3JtYXRzLlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQGF1Z21lbnRzIEd1YWNhbW9sZS5BdWRpb1JlY29yZGVyXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLk91dHB1dFN0cmVhbX0gc3RyZWFtXHJcbiAqICAgICBUaGUgR3VhY2Ftb2xlLk91dHB1dFN0cmVhbSB0byB3cml0ZSBhdWRpbyBkYXRhIHRvLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbWltZXR5cGVcclxuICogICAgIFRoZSBtaW1ldHlwZSBvZiB0aGUgYXVkaW8gZGF0YSB0byBzZW5kIGFsb25nIHRoZSBwcm92aWRlZCBzdHJlYW0sIHdoaWNoXHJcbiAqICAgICBtdXN0IGJlIGEgXCJhdWRpby9MOFwiIG9yIFwiYXVkaW8vTDE2XCIgbWltZXR5cGUgd2l0aCBuZWNlc3NhcnkgcGFyYW1ldGVycyxcclxuICogICAgIHN1Y2ggYXM6IFwiYXVkaW8vTDE2O3JhdGU9NDQxMDAsY2hhbm5lbHM9MlwiLlxyXG4gKi9cclxuR3VhY2Ftb2xlLlJhd0F1ZGlvUmVjb3JkZXIgPSBmdW5jdGlvbiBSYXdBdWRpb1JlY29yZGVyKHN0cmVhbSwgbWltZXR5cGUpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIFJhd0F1ZGlvUmVjb3JkZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuUmF3QXVkaW9SZWNvcmRlcn1cclxuICAgICAqL1xyXG4gICAgdmFyIHJlY29yZGVyID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzaXplIG9mIGF1ZGlvIGJ1ZmZlciB0byByZXF1ZXN0IGZyb20gdGhlIFdlYiBBdWRpbyBBUEkgd2hlblxyXG4gICAgICogcmVjb3JkaW5nIG9yIHByb2Nlc3NpbmcgYXVkaW8sIGluIHNhbXBsZS1mcmFtZXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mXHJcbiAgICAgKiB0d28gYmV0d2VlbiAyNTYgYW5kIDE2Mzg0IGluY2x1c2l2ZSwgYXMgcmVxdWlyZWQgYnlcclxuICAgICAqIEF1ZGlvQ29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoKS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQGNvbnN0YW50XHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgQlVGRkVSX1NJWkUgPSAyMDQ4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHdpbmRvdyBzaXplIHRvIHVzZSB3aGVuIGFwcGx5aW5nIExhbmN6b3MgaW50ZXJwb2xhdGlvbiwgY29tbW9ubHlcclxuICAgICAqIGRlbm90ZWQgYnkgdGhlIHZhcmlhYmxlIFwiYVwiLlxyXG4gICAgICogU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYW5jem9zX3Jlc2FtcGxpbmdcclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQGNvbnRhbnRcclxuICAgICAqIEB0eXBlIE51bWJlclxyXG4gICAgICovXHJcbiAgICB2YXIgTEFOQ1pPU19XSU5ET1dfU0laRSA9IDM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZm9ybWF0IG9mIGF1ZGlvIHRoaXMgcmVjb3JkZXIgd2lsbCBlbmNvZGUuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXR9XHJcbiAgICAgKi9cclxuICAgIHZhciBmb3JtYXQgPSBHdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXQucGFyc2UobWltZXR5cGUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gaW5zdGFuY2Ugb2YgYSBXZWIgQXVkaW8gQVBJIEF1ZGlvQ29udGV4dCBvYmplY3QsIG9yIG51bGwgaWYgdGhlXHJcbiAgICAgKiBXZWIgQXVkaW8gQVBJIGlzIG5vdCBzdXBwb3J0ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtBdWRpb0NvbnRleHR9XHJcbiAgICAgKi9cclxuICAgIHZhciBjb250ZXh0ID0gR3VhY2Ftb2xlLkF1ZGlvQ29udGV4dEZhY3RvcnkuZ2V0QXVkaW9Db250ZXh0KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIGZ1bmN0aW9uIHdoaWNoIGRpcmVjdGx5IGludm9rZXMgdGhlIGJyb3dzZXIncyBpbXBsZW1lbnRhdGlvbiBvZlxyXG4gICAgICogbmF2aWdhdG9yLmdldFVzZXJNZWRpYSgpIHdpdGggYWxsIHByb3ZpZGVkIHBhcmFtZXRlcnMuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUgRnVuY3Rpb25cclxuICAgICAqL1xyXG4gICAgdmFyIGdldFVzZXJNZWRpYSA9IChuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhXHJcbiAgICAgICAgICAgIHx8IG5hdmlnYXRvci53ZWJraXRHZXRVc2VyTWVkaWFcclxuICAgICAgICAgICAgfHwgbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYVxyXG4gICAgICAgICAgICB8fCBuYXZpZ2F0b3IubXNHZXRVc2VyTWVkaWEpLmJpbmQobmF2aWdhdG9yKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEd1YWNhbW9sZS5BcnJheUJ1ZmZlcldyaXRlciB3cmFwcGVkIGFyb3VuZCB0aGUgYXVkaW8gb3V0cHV0IHN0cmVhbVxyXG4gICAgICogcHJvdmlkZWQgd2hlbiB0aGlzIEd1YWNhbW9sZS5SYXdBdWRpb1JlY29yZGVyIHdhcyBjcmVhdGVkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLkFycmF5QnVmZmVyV3JpdGVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgd3JpdGVyID0gbmV3IEd1YWNhbW9sZS5BcnJheUJ1ZmZlcldyaXRlcihzdHJlYW0pO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHR5cGUgb2YgdHlwZWQgYXJyYXkgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVwcmVzZW50IGVhY2ggYXVkaW8gcGFja2V0XHJcbiAgICAgKiBpbnRlcm5hbGx5LiBUaGlzIHdpbGwgYmUgZWl0aGVyIEludDhBcnJheSBvciBJbnQxNkFycmF5LCBkZXBlbmRpbmcgb25cclxuICAgICAqIHdoZXRoZXIgdGhlIHJhdyBhdWRpbyBmb3JtYXQgaXMgOC1iaXQgb3IgMTYtYml0LlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqL1xyXG4gICAgdmFyIFNhbXBsZUFycmF5ID0gKGZvcm1hdC5ieXRlc1BlclNhbXBsZSA9PT0gMSkgPyB3aW5kb3cuSW50OEFycmF5IDogd2luZG93LkludDE2QXJyYXk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWF4aW11bSBhYnNvbHV0ZSB2YWx1ZSBvZiBhbnkgc2FtcGxlIHdpdGhpbiBhIHJhdyBhdWRpbyBwYWNrZXQgc2VudFxyXG4gICAgICogYnkgdGhpcyBhdWRpbyByZWNvcmRlci4gVGhpcyBkZXBlbmRzIG9ubHkgb24gdGhlIHNpemUgb2YgZWFjaCBzYW1wbGUsXHJcbiAgICAgKiBhbmQgd2lsbCBiZSAxMjggZm9yIDgtYml0IGF1ZGlvIGFuZCAzMjc2OCBmb3IgMTYtYml0IGF1ZGlvLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgbWF4U2FtcGxlVmFsdWUgPSAoZm9ybWF0LmJ5dGVzUGVyU2FtcGxlID09PSAxKSA/IDEyOCA6IDMyNzY4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHRvdGFsIG51bWJlciBvZiBhdWRpbyBzYW1wbGVzIHJlYWQgZnJvbSB0aGUgbG9jYWwgYXVkaW8gaW5wdXQgZGV2aWNlXHJcbiAgICAgKiBvdmVyIHRoZSBsaWZlIG9mIHRoaXMgYXVkaW8gcmVjb3JkZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciByZWFkU2FtcGxlcyA9IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdG90YWwgbnVtYmVyIG9mIGF1ZGlvIHNhbXBsZXMgd3JpdHRlbiB0byB0aGUgdW5kZXJseWluZyBHdWFjYW1vbGVcclxuICAgICAqIGNvbm5lY3Rpb24gb3ZlciB0aGUgbGlmZSBvZiB0aGlzIGF1ZGlvIHJlY29yZGVyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgd3JpdHRlblNhbXBsZXMgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGF1ZGlvIHN0cmVhbSBwcm92aWRlZCBieSB0aGUgYnJvd3NlciwgaWYgYWxsb3dlZC4gSWYgbm8gc3RyZWFtIGhhc1xyXG4gICAgICogeWV0IGJlZW4gcmVjZWl2ZWQsIHRoaXMgd2lsbCBiZSBudWxsLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIE1lZGlhU3RyZWFtXHJcbiAgICAgKi9cclxuICAgIHZhciBtZWRpYVN0cmVhbSA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgc291cmNlIG5vZGUgcHJvdmlkaW5nIGFjY2VzcyB0byB0aGUgbG9jYWwgYXVkaW8gaW5wdXQgZGV2aWNlLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGV9XHJcbiAgICAgKi9cclxuICAgIHZhciBzb3VyY2UgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHNjcmlwdCBwcm9jZXNzaW5nIG5vZGUgd2hpY2ggcmVjZWl2ZXMgYXVkaW8gaW5wdXQgZnJvbSB0aGUgbWVkaWFcclxuICAgICAqIHN0cmVhbSBzb3VyY2Ugbm9kZSBhcyBpbmRpdmlkdWFsIGF1ZGlvIGJ1ZmZlcnMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtTY3JpcHRQcm9jZXNzb3JOb2RlfVxyXG4gICAgICovXHJcbiAgICB2YXIgcHJvY2Vzc29yID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBub3JtYWxpemVkIHNpbmMgZnVuY3Rpb24uIFRoZSBub3JtYWxpemVkIHNpbmMgZnVuY3Rpb24gaXMgZGVmaW5lZCBhc1xyXG4gICAgICogMSBmb3IgeD0wIGFuZCBzaW4oUEkgKiB4KSAvIChQSSAqIHgpIGZvciBhbGwgb3RoZXIgdmFsdWVzIG9mIHguXHJcbiAgICAgKlxyXG4gICAgICogU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TaW5jX2Z1bmN0aW9uXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4XHJcbiAgICAgKiAgICAgVGhlIHBvaW50IGF0IHdoaWNoIHRoZSBub3JtYWxpemVkIHNpbmMgZnVuY3Rpb24gc2hvdWxkIGJlIGNvbXB1dGVkLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKiAgICAgVGhlIHZhbHVlIG9mIHRoZSBub3JtYWxpemVkIHNpbmMgZnVuY3Rpb24gYXQgeC5cclxuICAgICAqL1xyXG4gICAgdmFyIHNpbmMgPSBmdW5jdGlvbiBzaW5jKHgpIHtcclxuXHJcbiAgICAgICAgLy8gVGhlIHZhbHVlIG9mIHNpbmMoMCkgaXMgZGVmaW5lZCBhcyAxXHJcbiAgICAgICAgaWYgKHggPT09IDApXHJcbiAgICAgICAgICAgIHJldHVybiAxO1xyXG5cclxuICAgICAgICAvLyBPdGhlcndpc2UsIG5vcm1saXplZCBzaW5jKHgpIGlzIHNpbihQSSAqIHgpIC8gKFBJICogeClcclxuICAgICAgICB2YXIgcGlYID0gTWF0aC5QSSAqIHg7XHJcbiAgICAgICAgcmV0dXJuIE1hdGguc2luKHBpWCkgLyBwaVg7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHZhbHVlIG9mIHRoZSBMYW5jem9zIGtlcm5hbCBhdCBwb2ludCB4IGZvciBhIGdpdmVuIHdpbmRvd1xyXG4gICAgICogc2l6ZS4gU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYW5jem9zX3Jlc2FtcGxpbmdcclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHhcclxuICAgICAqICAgICBUaGUgcG9pbnQgYXQgd2hpY2ggdGhlIHZhbHVlIG9mIHRoZSBMYW5jem9zIGtlcm5lbCBzaG91bGQgYmVcclxuICAgICAqICAgICBjb21wdXRlZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYVxyXG4gICAgICogICAgIFRoZSB3aW5kb3cgc2l6ZSB0byB1c2UgZm9yIHRoZSBMYW5jem9zIGtlcm5lbC5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxyXG4gICAgICogICAgIFRoZSB2YWx1ZSBvZiB0aGUgTGFuY3pvcyBrZXJuZWwgYXQgdGhlIGdpdmVuIHBvaW50IGZvciB0aGUgZ2l2ZW5cclxuICAgICAqICAgICB3aW5kb3cgc2l6ZS5cclxuICAgICAqL1xyXG4gICAgdmFyIGxhbmN6b3MgPSBmdW5jdGlvbiBsYW5jem9zKHgsIGEpIHtcclxuXHJcbiAgICAgICAgLy8gTGFuY3pvcyBpcyBzaW5jKHgpICogc2luYyh4IC8gYSkgZm9yIC1hIDwgeCA8IGEgLi4uXHJcbiAgICAgICAgaWYgKC1hIDwgeCAmJiB4IDwgYSlcclxuICAgICAgICAgICAgcmV0dXJuIHNpbmMoeCkgKiBzaW5jKHggLyBhKTtcclxuXHJcbiAgICAgICAgLy8gLi4uIGFuZCAwIG90aGVyd2lzZVxyXG4gICAgICAgIHJldHVybiAwO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmVzIHRoZSB2YWx1ZSBvZiB0aGUgd2F2ZWZvcm0gcmVwcmVzZW50ZWQgYnkgdGhlIGF1ZGlvIGRhdGEgYXRcclxuICAgICAqIHRoZSBnaXZlbiBsb2NhdGlvbi4gSWYgdGhlIHZhbHVlIGNhbm5vdCBiZSBkZXRlcm1pbmVkIGV4YWN0bHkgYXMgaXQgZG9lc1xyXG4gICAgICogbm90IGNvcnJlc3BvbmQgdG8gYW4gZXhhY3Qgc2FtcGxlIHdpdGhpbiB0aGUgYXVkaW8gZGF0YSwgdGhlIHZhbHVlIHdpbGxcclxuICAgICAqIGJlIGRlcml2ZWQgdGhyb3VnaCBpbnRlcnBvbGF0aW5nIG5lYXJieSBzYW1wbGVzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge0Zsb2F0MzJBcnJheX0gYXVkaW9EYXRhXHJcbiAgICAgKiAgICAgQW4gYXJyYXkgb2YgYXVkaW8gZGF0YSwgYXMgcmV0dXJuZWQgYnkgQXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoKS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdFxyXG4gICAgICogICAgIFRoZSByZWxhdGl2ZSBsb2NhdGlvbiB3aXRoaW4gdGhlIHdhdmVmb3JtIGZyb20gd2hpY2ggdGhlIHZhbHVlXHJcbiAgICAgKiAgICAgc2hvdWxkIGJlIHJldHJpZXZlZCwgcmVwcmVzZW50ZWQgYXMgYSBmbG9hdGluZyBwb2ludCBudW1iZXIgYmV0d2VlblxyXG4gICAgICogICAgIDAgYW5kIDEgaW5jbHVzaXZlLCB3aGVyZSAwIHJlcHJlc2VudHMgdGhlIGVhcmxpZXN0IHBvaW50IGluIHRpbWUgYW5kXHJcbiAgICAgKiAgICAgMSByZXByZXNlbnRzIHRoZSBsYXRlc3QuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge051bWJlcn1cclxuICAgICAqICAgICBUaGUgdmFsdWUgb2YgdGhlIHdhdmVmb3JtIGF0IHRoZSBnaXZlbiBsb2NhdGlvbi5cclxuICAgICAqL1xyXG4gICAgdmFyIGludGVycG9sYXRlU2FtcGxlID0gZnVuY3Rpb24gZ2V0VmFsdWVBdChhdWRpb0RhdGEsIHQpIHtcclxuXHJcbiAgICAgICAgLy8gQ29udmVydCBbMCwgMV0gcmFuZ2UgdG8gWzAsIGF1ZGlvRGF0YS5sZW5ndGggLSAxXVxyXG4gICAgICAgIHZhciBpbmRleCA9IChhdWRpb0RhdGEubGVuZ3RoIC0gMSkgKiB0O1xyXG5cclxuICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGZvciB0aGUgc3VtbWF0aW9uIHVzZWQgYnkgdGhlXHJcbiAgICAgICAgLy8gTGFuY3pvcyBpbnRlcnBvbGF0aW9uIGFsZ29yaXRobSAoc2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYW5jem9zX3Jlc2FtcGxpbmcpXHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gTWF0aC5mbG9vcihpbmRleCkgLSBMQU5DWk9TX1dJTkRPV19TSVpFICsgMTtcclxuICAgICAgICB2YXIgZW5kID0gTWF0aC5mbG9vcihpbmRleCkgKyBMQU5DWk9TX1dJTkRPV19TSVpFO1xyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIHZhbHVlIG9mIHRoZSBMYW5jem9zIGludGVycG9sYXRpb24gZnVuY3Rpb24gZm9yIHRoZVxyXG4gICAgICAgIC8vIHJlcXVpcmVkIHJhbmdlXHJcbiAgICAgICAgdmFyIHN1bSA9IDA7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHN1bSArPSAoYXVkaW9EYXRhW2ldIHx8IDApICogbGFuY3pvcyhpbmRleCAtIGksIExBTkNaT1NfV0lORE9XX1NJWkUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHN1bTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIGdpdmVuIEF1ZGlvQnVmZmVyIGludG8gYW4gYXVkaW8gcGFja2V0LCByZWFkeSBmb3Igc3RyZWFtaW5nXHJcbiAgICAgKiBhbG9uZyB0aGUgdW5kZXJseWluZyBvdXRwdXQgc3RyZWFtLiBVbmxpa2UgdGhlIHJhdyBhdWRpbyBwYWNrZXRzIHVzZWQgYnlcclxuICAgICAqIHRoaXMgYXVkaW8gcmVjb3JkZXIsIEF1ZGlvQnVmZmVycyByZXF1aXJlIGZsb2F0aW5nIHBvaW50IHNhbXBsZXMgYW5kIGFyZVxyXG4gICAgICogc3BsaXQgaW50byBpc29sYXRlZCBwbGFuZXMgb2YgY2hhbm5lbC1zcGVjaWZpYyBkYXRhLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge0F1ZGlvQnVmZmVyfSBhdWRpb0J1ZmZlclxyXG4gICAgICogICAgIFRoZSBXZWIgQXVkaW8gQVBJIEF1ZGlvQnVmZmVyIHRoYXQgc2hvdWxkIGJlIGNvbnZlcnRlZCB0byBhIHJhd1xyXG4gICAgICogICAgIGF1ZGlvIHBhY2tldC5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7U2FtcGxlQXJyYXl9XHJcbiAgICAgKiAgICAgQSBuZXcgcmF3IGF1ZGlvIHBhY2tldCBjb250YWluaW5nIHRoZSBhdWRpbyBkYXRhIGZyb20gdGhlIHByb3ZpZGVkXHJcbiAgICAgKiAgICAgQXVkaW9CdWZmZXIuXHJcbiAgICAgKi9cclxuICAgIHZhciB0b1NhbXBsZUFycmF5ID0gZnVuY3Rpb24gdG9TYW1wbGVBcnJheShhdWRpb0J1ZmZlcikge1xyXG5cclxuICAgICAgICAvLyBUcmFjayBvdmVyYWxsIGFtb3VudCBvZiBkYXRhIHJlYWRcclxuICAgICAgICB2YXIgaW5TYW1wbGVzID0gYXVkaW9CdWZmZXIubGVuZ3RoO1xyXG4gICAgICAgIHJlYWRTYW1wbGVzICs9IGluU2FtcGxlcztcclxuXHJcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSB0b3RhbCBudW1iZXIgb2Ygc2FtcGxlcyB0aGF0IHNob3VsZCBiZSB3cml0dGVuIGFzIG9mXHJcbiAgICAgICAgLy8gdGhlIGF1ZGlvIGRhdGEganVzdCByZWNlaXZlZCBhbmQgYWRqdXN0IHRoZSBzaXplIG9mIHRoZSBvdXRwdXRcclxuICAgICAgICAvLyBwYWNrZXQgYWNjb3JkaW5nbHlcclxuICAgICAgICB2YXIgZXhwZWN0ZWRXcml0dGVuU2FtcGxlcyA9IE1hdGgucm91bmQocmVhZFNhbXBsZXMgKiBmb3JtYXQucmF0ZSAvIGF1ZGlvQnVmZmVyLnNhbXBsZVJhdGUpO1xyXG4gICAgICAgIHZhciBvdXRTYW1wbGVzID0gZXhwZWN0ZWRXcml0dGVuU2FtcGxlcyAtIHdyaXR0ZW5TYW1wbGVzO1xyXG5cclxuICAgICAgICAvLyBVcGRhdGUgbnVtYmVyIG9mIHNhbXBsZXMgd3JpdHRlblxyXG4gICAgICAgIHdyaXR0ZW5TYW1wbGVzICs9IG91dFNhbXBsZXM7XHJcblxyXG4gICAgICAgIC8vIEdldCBhcnJheSBmb3IgcmF3IFBDTSBzdG9yYWdlXHJcbiAgICAgICAgdmFyIGRhdGEgPSBuZXcgU2FtcGxlQXJyYXkob3V0U2FtcGxlcyAqIGZvcm1hdC5jaGFubmVscyk7XHJcblxyXG4gICAgICAgIC8vIENvbnZlcnQgZWFjaCBjaGFubmVsXHJcbiAgICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBmb3JtYXQuY2hhbm5lbHM7IGNoYW5uZWwrKykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGF1ZGlvRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpO1xyXG5cclxuICAgICAgICAgICAgLy8gRmlsbCBhcnJheSB3aXRoIGRhdGEgZnJvbSBhdWRpbyBidWZmZXIgY2hhbm5lbFxyXG4gICAgICAgICAgICB2YXIgb2Zmc2V0ID0gY2hhbm5lbDtcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXRTYW1wbGVzOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGRhdGFbb2Zmc2V0XSA9IGludGVycG9sYXRlU2FtcGxlKGF1ZGlvRGF0YSwgaSAvIChvdXRTYW1wbGVzIC0gMSkpICogbWF4U2FtcGxlVmFsdWU7XHJcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gZm9ybWF0LmNoYW5uZWxzO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGRhdGE7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlcXVlc3RzIGFjY2VzcyB0byB0aGUgdXNlcidzIG1pY3JvcGhvbmUgYW5kIGJlZ2lucyBjYXB0dXJpbmcgYXVkaW8uIEFsbFxyXG4gICAgICogcmVjZWl2ZWQgYXVkaW8gZGF0YSBpcyByZXNhbXBsZWQgYXMgbmVjZXNzYXJ5IGFuZCBmb3J3YXJkZWQgdG8gdGhlXHJcbiAgICAgKiBHdWFjYW1vbGUgc3RyZWFtIHVuZGVybHlpbmcgdGhpcyBHdWFjYW1vbGUuUmF3QXVkaW9SZWNvcmRlci4gVGhpc1xyXG4gICAgICogZnVuY3Rpb24gbXVzdCBiZSBpbnZva2VkIE9OTFkgT05DRSBwZXIgaW5zdGFuY2Ugb2ZcclxuICAgICAqIEd1YWNhbW9sZS5SYXdBdWRpb1JlY29yZGVyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBiZWdpbkF1ZGlvQ2FwdHVyZSA9IGZ1bmN0aW9uIGJlZ2luQXVkaW9DYXB0dXJlKCkge1xyXG5cclxuICAgICAgICAvLyBBdHRlbXB0IHRvIHJldHJpZXZlIGFuIGF1ZGlvIGlucHV0IHN0cmVhbSBmcm9tIHRoZSBicm93c2VyXHJcbiAgICAgICAgZ2V0VXNlck1lZGlhKHsgJ2F1ZGlvJyA6IHRydWUgfSwgZnVuY3Rpb24gc3RyZWFtUmVjZWl2ZWQoc3RyZWFtKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGUgcHJvY2Vzc2luZyBub2RlIHdoaWNoIHJlY2VpdmVzIGFwcHJvcHJpYXRlbHktc2l6ZWQgYXVkaW8gYnVmZmVyc1xyXG4gICAgICAgICAgICBwcm9jZXNzb3IgPSBjb250ZXh0LmNyZWF0ZVNjcmlwdFByb2Nlc3NvcihCVUZGRVJfU0laRSwgZm9ybWF0LmNoYW5uZWxzLCBmb3JtYXQuY2hhbm5lbHMpO1xyXG4gICAgICAgICAgICBwcm9jZXNzb3IuY29ubmVjdChjb250ZXh0LmRlc3RpbmF0aW9uKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlbmQgYmxvYnMgd2hlbiBhdWRpbyBidWZmZXJzIGFyZSByZWNlaXZlZFxyXG4gICAgICAgICAgICBwcm9jZXNzb3Iub25hdWRpb3Byb2Nlc3MgPSBmdW5jdGlvbiBwcm9jZXNzQXVkaW8oZSkge1xyXG4gICAgICAgICAgICAgICAgd3JpdGVyLnNlbmREYXRhKHRvU2FtcGxlQXJyYXkoZS5pbnB1dEJ1ZmZlcikuYnVmZmVyKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8vIENvbm5lY3QgcHJvY2Vzc2luZyBub2RlIHRvIHVzZXIncyBhdWRpbyBpbnB1dCBzb3VyY2VcclxuICAgICAgICAgICAgc291cmNlID0gY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xyXG4gICAgICAgICAgICBzb3VyY2UuY29ubmVjdChwcm9jZXNzb3IpO1xyXG5cclxuICAgICAgICAgICAgLy8gU2F2ZSBzdHJlYW0gZm9yIGxhdGVyIGNsZWFudXBcclxuICAgICAgICAgICAgbWVkaWFTdHJlYW0gPSBzdHJlYW07XHJcblxyXG4gICAgICAgIH0sIGZ1bmN0aW9uIHN0cmVhbURlbmllZCgpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFNpbXBseSBlbmQgc3RyZWFtIGlmIGF1ZGlvIGFjY2VzcyBpcyBub3QgYWxsb3dlZFxyXG4gICAgICAgICAgICB3cml0ZXIuc2VuZEVuZCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gTm90aWZ5IG9mIGNsb3N1cmVcclxuICAgICAgICAgICAgaWYgKHJlY29yZGVyLm9uZXJyb3IpXHJcbiAgICAgICAgICAgICAgICByZWNvcmRlci5vbmVycm9yKCk7XHJcblxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdG9wcyBjYXB0dXJpbmcgYXVkaW8sIGlmIHRoZSBjYXB0dXJlIGhhcyBzdGFydGVkLCBmcmVlaW5nIGFsbCBhc3NvY2lhdGVkXHJcbiAgICAgKiByZXNvdXJjZXMuIElmIHRoZSBjYXB0dXJlIGhhcyBub3Qgc3RhcnRlZCwgdGhpcyBmdW5jdGlvbiBzaW1wbHkgZW5kcyB0aGVcclxuICAgICAqIHVuZGVybHlpbmcgR3VhY2Ftb2xlIHN0cmVhbS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgc3RvcEF1ZGlvQ2FwdHVyZSA9IGZ1bmN0aW9uIHN0b3BBdWRpb0NhcHR1cmUoKSB7XHJcblxyXG4gICAgICAgIC8vIERpc2Nvbm5lY3QgbWVkaWEgc291cmNlIG5vZGUgZnJvbSBzY3JpcHQgcHJvY2Vzc29yXHJcbiAgICAgICAgaWYgKHNvdXJjZSlcclxuICAgICAgICAgICAgc291cmNlLmRpc2Nvbm5lY3QoKTtcclxuXHJcbiAgICAgICAgLy8gRGlzY29ubmVjdCBhc3NvY2lhdGVkIHNjcmlwdCBwcm9jZXNzb3Igbm9kZVxyXG4gICAgICAgIGlmIChwcm9jZXNzb3IpXHJcbiAgICAgICAgICAgIHByb2Nlc3Nvci5kaXNjb25uZWN0KCk7XHJcblxyXG4gICAgICAgIC8vIFN0b3AgY2FwdHVyZVxyXG4gICAgICAgIGlmIChtZWRpYVN0cmVhbSkge1xyXG4gICAgICAgICAgICB2YXIgdHJhY2tzID0gbWVkaWFTdHJlYW0uZ2V0VHJhY2tzKCk7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHJhY2tzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgdHJhY2tzW2ldLnN0b3AoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSByZWZlcmVuY2VzIHRvIG5vdy11bm5lZWRlZCBjb21wb25lbnRzXHJcbiAgICAgICAgcHJvY2Vzc29yID0gbnVsbDtcclxuICAgICAgICBzb3VyY2UgPSBudWxsO1xyXG4gICAgICAgIG1lZGlhU3RyZWFtID0gbnVsbDtcclxuXHJcbiAgICAgICAgLy8gRW5kIHN0cmVhbVxyXG4gICAgICAgIHdyaXRlci5zZW5kRW5kKCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBPbmNlIGF1ZGlvIHN0cmVhbSBpcyBzdWNjZXNzZnVsbHkgb3BlbiwgcmVxdWVzdCBhbmQgYmVnaW4gcmVhZGluZyBhdWRpb1xyXG4gICAgd3JpdGVyLm9uYWNrID0gZnVuY3Rpb24gYXVkaW9TdHJlYW1BY2tub3dsZWRnZWQoc3RhdHVzKSB7XHJcblxyXG4gICAgICAgIC8vIEJlZ2luIGNhcHR1cmUgaWYgc3VjY2Vzc2Z1bCByZXNwb25zZSBhbmQgbm90IHlldCBzdGFydGVkXHJcbiAgICAgICAgaWYgKHN0YXR1cy5jb2RlID09PSBHdWFjYW1vbGUuU3RhdHVzLkNvZGUuU1VDQ0VTUyAmJiAhbWVkaWFTdHJlYW0pXHJcbiAgICAgICAgICAgIGJlZ2luQXVkaW9DYXB0dXJlKCk7XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSBzdG9wIGNhcHR1cmUgYW5kIGNlYXNlIGhhbmRsaW5nIGFueSBmdXJ0aGVyIGFja3NcclxuICAgICAgICBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFN0b3AgY2FwdHVyaW5nIGF1ZGlvXHJcbiAgICAgICAgICAgIHN0b3BBdWRpb0NhcHR1cmUoKTtcclxuICAgICAgICAgICAgd3JpdGVyLm9uYWNrID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIC8vIE5vdGlmeSBpZiBzdHJlYW0gaGFzIGNsb3NlZCBub3JtYWxseVxyXG4gICAgICAgICAgICBpZiAoc3RhdHVzLmNvZGUgPT09IEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5SRVNPVVJDRV9DTE9TRUQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZWNvcmRlci5vbmNsb3NlKVxyXG4gICAgICAgICAgICAgICAgICAgIHJlY29yZGVyLm9uY2xvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIG5vdGlmeSBvZiBjbG9zdXJlIGR1ZSB0byBlcnJvclxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZWNvcmRlci5vbmVycm9yKVxyXG4gICAgICAgICAgICAgICAgICAgIHJlY29yZGVyLm9uZXJyb3IoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG5HdWFjYW1vbGUuUmF3QXVkaW9SZWNvcmRlci5wcm90b3R5cGUgPSBuZXcgR3VhY2Ftb2xlLkF1ZGlvUmVjb3JkZXIoKTtcclxuXHJcbi8qKlxyXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGdpdmVuIG1pbWV0eXBlIGlzIHN1cHBvcnRlZCBieVxyXG4gKiBHdWFjYW1vbGUuUmF3QXVkaW9SZWNvcmRlci5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlXHJcbiAqICAgICBUaGUgbWltZXR5cGUgdG8gY2hlY2suXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gKiAgICAgdHJ1ZSBpZiB0aGUgZ2l2ZW4gbWltZXR5cGUgaXMgc3VwcG9ydGVkIGJ5IEd1YWNhbW9sZS5SYXdBdWRpb1JlY29yZGVyLFxyXG4gKiAgICAgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cclxuR3VhY2Ftb2xlLlJhd0F1ZGlvUmVjb3JkZXIuaXNTdXBwb3J0ZWRUeXBlID0gZnVuY3Rpb24gaXNTdXBwb3J0ZWRUeXBlKG1pbWV0eXBlKSB7XHJcblxyXG4gICAgLy8gTm8gc3VwcG9ydGVkIHR5cGVzIGlmIG5vIFdlYiBBdWRpbyBBUElcclxuICAgIGlmICghR3VhY2Ftb2xlLkF1ZGlvQ29udGV4dEZhY3RvcnkuZ2V0QXVkaW9Db250ZXh0KCkpXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgIHJldHVybiBHdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXQucGFyc2UobWltZXR5cGUpICE9PSBudWxsO1xyXG5cclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgbWltZXR5cGVzIHN1cHBvcnRlZCBieSBHdWFjYW1vbGUuUmF3QXVkaW9SZWNvcmRlci4gT25seVxyXG4gKiB0aGUgY29yZSBtaW1ldHlwZXMgdGhlbXNlbHZlcyB3aWxsIGJlIGxpc3RlZC4gQW55IG1pbWV0eXBlIHBhcmFtZXRlcnMsIGV2ZW5cclxuICogcmVxdWlyZWQgb25lcywgd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIGxpc3QuIEZvciBleGFtcGxlLCBcImF1ZGlvL0w4XCIgaXNcclxuICogYSByYXcgYXVkaW8gbWltZXR5cGUgdGhhdCBtYXkgYmUgc3VwcG9ydGVkLCBidXQgaXQgaXMgaW52YWxpZCB3aXRob3V0XHJcbiAqIGFkZGl0aW9uYWwgcGFyYW1ldGVycy4gU29tZXRoaW5nIGxpa2UgXCJhdWRpby9MODtyYXRlPTQ0MTAwXCIgd291bGQgYmUgdmFsaWQsXHJcbiAqIGhvd2V2ZXIgKHNlZSBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNDg1NikuXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtTdHJpbmdbXX1cclxuICogICAgIEEgbGlzdCBvZiBhbGwgbWltZXR5cGVzIHN1cHBvcnRlZCBieSBHdWFjYW1vbGUuUmF3QXVkaW9SZWNvcmRlcixcclxuICogICAgIGV4Y2x1ZGluZyBhbnkgcGFyYW1ldGVycy4gSWYgdGhlIG5lY2Vzc2FyeSBKYXZhU2NyaXB0IEFQSXMgZm9yIHJlY29yZGluZ1xyXG4gKiAgICAgcmF3IGF1ZGlvIGFyZSBhYnNlbnQsIHRoaXMgbGlzdCB3aWxsIGJlIGVtcHR5LlxyXG4gKi9cclxuR3VhY2Ftb2xlLlJhd0F1ZGlvUmVjb3JkZXIuZ2V0U3VwcG9ydGVkVHlwZXMgPSBmdW5jdGlvbiBnZXRTdXBwb3J0ZWRUeXBlcygpIHtcclxuXHJcbiAgICAvLyBObyBzdXBwb3J0ZWQgdHlwZXMgaWYgbm8gV2ViIEF1ZGlvIEFQSVxyXG4gICAgaWYgKCFHdWFjYW1vbGUuQXVkaW9Db250ZXh0RmFjdG9yeS5nZXRBdWRpb0NvbnRleHQoKSlcclxuICAgICAgICByZXR1cm4gW107XHJcblxyXG4gICAgLy8gV2Ugc3VwcG9ydCA4LWJpdCBhbmQgMTYtYml0IHJhdyBQQ01cclxuICAgIHJldHVybiBbXHJcbiAgICAgICAgJ2F1ZGlvL0w4JyxcclxuICAgICAgICAnYXVkaW8vTDE2J1xyXG4gICAgXTtcclxuXHJcbn07XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogQSByZWFkZXIgd2hpY2ggYXV0b21hdGljYWxseSBoYW5kbGVzIHRoZSBnaXZlbiBpbnB1dCBzdHJlYW0sIGFzc2VtYmxpbmcgYWxsXHJcbiAqIHJlY2VpdmVkIGJsb2JzIGludG8gYSBzaW5nbGUgYmxvYiBieSBhcHBlbmRpbmcgdGhlbSB0byBlYWNoIG90aGVyIGluIG9yZGVyLlxyXG4gKiBOb3RlIHRoYXQgdGhpcyBvYmplY3Qgd2lsbCBvdmVyd3JpdGUgYW55IGluc3RhbGxlZCBldmVudCBoYW5kbGVycyBvbiB0aGVcclxuICogZ2l2ZW4gR3VhY2Ftb2xlLklucHV0U3RyZWFtLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLklucHV0U3RyZWFtfSBzdHJlYW0gVGhlIHN0cmVhbSB0aGF0IGRhdGEgd2lsbCBiZSByZWFkXHJcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbS5cclxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlIFRoZSBtaW1ldHlwZSBvZiB0aGUgYmxvYiBiZWluZyBidWlsdC5cclxuICovXHJcbkd1YWNhbW9sZS5CbG9iUmVhZGVyID0gZnVuY3Rpb24oc3RyZWFtLCBtaW1ldHlwZSkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVmZXJlbmNlIHRvIHRoaXMgR3VhY2Ftb2xlLklucHV0U3RyZWFtLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGd1YWNfcmVhZGVyID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBsZW5ndGggb2YgdGhpcyBHdWFjYW1vbGUuSW5wdXRTdHJlYW0gaW4gYnl0ZXMuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgbGVuZ3RoID0gMDtcclxuXHJcbiAgICAvLyBHZXQgYmxvYiBidWlsZGVyXHJcbiAgICB2YXIgYmxvYl9idWlsZGVyO1xyXG4gICAgaWYgICAgICAod2luZG93LkJsb2JCdWlsZGVyKSAgICAgICBibG9iX2J1aWxkZXIgPSBuZXcgQmxvYkJ1aWxkZXIoKTtcclxuICAgIGVsc2UgaWYgKHdpbmRvdy5XZWJLaXRCbG9iQnVpbGRlcikgYmxvYl9idWlsZGVyID0gbmV3IFdlYktpdEJsb2JCdWlsZGVyKCk7XHJcbiAgICBlbHNlIGlmICh3aW5kb3cuTW96QmxvYkJ1aWxkZXIpICAgIGJsb2JfYnVpbGRlciA9IG5ldyBNb3pCbG9iQnVpbGRlcigpO1xyXG4gICAgZWxzZVxyXG4gICAgICAgIGJsb2JfYnVpbGRlciA9IG5ldyAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgYmxvYnMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIC8qKiBAaWdub3JlICovXHJcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kID0gZnVuY3Rpb24oZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgYmxvYnMucHVzaChuZXcgQmxvYihbZGF0YV0sIHtcInR5cGVcIjogbWltZXR5cGV9KSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKiogQGlnbm9yZSAqL1xyXG4gICAgICAgICAgICB0aGlzLmdldEJsb2IgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmxvYihibG9icywge1widHlwZVwiOiBtaW1ldHlwZX0pO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICB9KSgpO1xyXG5cclxuICAgIC8vIEFwcGVuZCByZWNlaXZlZCBibG9ic1xyXG4gICAgc3RyZWFtLm9uYmxvYiA9IGZ1bmN0aW9uKGRhdGEpIHtcclxuXHJcbiAgICAgICAgLy8gQ29udmVydCB0byBBcnJheUJ1ZmZlclxyXG4gICAgICAgIHZhciBiaW5hcnkgPSB3aW5kb3cuYXRvYihkYXRhKTtcclxuICAgICAgICB2YXIgYXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoYmluYXJ5Lmxlbmd0aCk7XHJcbiAgICAgICAgdmFyIGJ1ZmZlclZpZXcgPSBuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcik7XHJcblxyXG4gICAgICAgIGZvciAodmFyIGk9MDsgaTxiaW5hcnkubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgIGJ1ZmZlclZpZXdbaV0gPSBiaW5hcnkuY2hhckNvZGVBdChpKTtcclxuXHJcbiAgICAgICAgYmxvYl9idWlsZGVyLmFwcGVuZChhcnJheUJ1ZmZlcik7XHJcbiAgICAgICAgbGVuZ3RoICs9IGFycmF5QnVmZmVyLmJ5dGVMZW5ndGg7XHJcblxyXG4gICAgICAgIC8vIENhbGwgaGFuZGxlciwgaWYgcHJlc2VudFxyXG4gICAgICAgIGlmIChndWFjX3JlYWRlci5vbnByb2dyZXNzKVxyXG4gICAgICAgICAgICBndWFjX3JlYWRlci5vbnByb2dyZXNzKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG5cclxuICAgICAgICAvLyBTZW5kIHN1Y2Nlc3MgcmVzcG9uc2VcclxuICAgICAgICBzdHJlYW0uc2VuZEFjayhcIk9LXCIsIDB4MDAwMCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBTaW1wbHkgY2FsbCBvbmVuZCB3aGVuIGVuZCByZWNlaXZlZFxyXG4gICAgc3RyZWFtLm9uZW5kID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgaWYgKGd1YWNfcmVhZGVyLm9uZW5kKVxyXG4gICAgICAgICAgICBndWFjX3JlYWRlci5vbmVuZCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbGVuZ3RoIG9mIHRoaXMgR3VhY2Ftb2xlLklucHV0U3RyZWFtLCBpbiBieXRlcy5cclxuICAgICAqIEByZXR1cm4ge051bWJlcn0gVGhlIGN1cnJlbnQgbGVuZ3RoIG9mIHRoaXMgR3VhY2Ftb2xlLklucHV0U3RyZWFtLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmdldExlbmd0aCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBsZW5ndGg7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgY29udGVudHMgb2YgdGhpcyBHdWFjYW1vbGUuQmxvYlJlYWRlciBhcyBhIEJsb2IuXHJcbiAgICAgKiBAcmV0dXJuIHtCbG9ifSBUaGUgY29udGVudHMgb2YgdGhpcyBHdWFjYW1vbGUuQmxvYlJlYWRlci5cclxuICAgICAqL1xyXG4gICAgdGhpcy5nZXRCbG9iID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIGJsb2JfYnVpbGRlci5nZXRCbG9iKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgb25jZSBmb3IgZXZlcnkgYmxvYiBvZiBkYXRhIHJlY2VpdmVkLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGggVGhlIG51bWJlciBvZiBieXRlcyByZWNlaXZlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbnByb2dyZXNzID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIG9uY2UgdGhpcyBzdHJlYW0gaXMgZmluaXNoZWQgYW5kIG5vIGZ1cnRoZXIgZGF0YSB3aWxsIGJlIHdyaXR0ZW4uXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmVuZCA9IG51bGw7XHJcblxyXG59Oy8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogQSB3cml0ZXIgd2hpY2ggYXV0b21hdGljYWxseSB3cml0ZXMgdG8gdGhlIGdpdmVuIG91dHB1dCBzdHJlYW0gd2l0aCB0aGVcclxuICogY29udGVudHMgb2YgcHJvdmlkZWQgQmxvYiBvYmplY3RzLlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtHdWFjYW1vbGUuT3V0cHV0U3RyZWFtfSBzdHJlYW1cclxuICogICAgIFRoZSBzdHJlYW0gdGhhdCBkYXRhIHdpbGwgYmUgd3JpdHRlbiB0by5cclxuICovXHJcbkd1YWNhbW9sZS5CbG9iV3JpdGVyID0gZnVuY3Rpb24gQmxvYldyaXRlcihzdHJlYW0pIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5CbG9iV3JpdGVyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLkJsb2JXcml0ZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBndWFjV3JpdGVyID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyYXBwZWQgR3VhY2Ftb2xlLkFycmF5QnVmZmVyV3JpdGVyIHdoaWNoIHdpbGwgYmUgdXNlZCB0byBzZW5kIGFueVxyXG4gICAgICogcHJvdmlkZWQgZmlsZSBkYXRhLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLkFycmF5QnVmZmVyV3JpdGVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgYXJyYXlCdWZmZXJXcml0ZXIgPSBuZXcgR3VhY2Ftb2xlLkFycmF5QnVmZmVyV3JpdGVyKHN0cmVhbSk7XHJcblxyXG4gICAgLy8gSW5pdGlhbGx5LCBzaW1wbHkgY2FsbCBvbmFjayBmb3IgYWNrbm93bGVkZ2VtZW50c1xyXG4gICAgYXJyYXlCdWZmZXJXcml0ZXIub25hY2sgPSBmdW5jdGlvbihzdGF0dXMpIHtcclxuICAgICAgICBpZiAoZ3VhY1dyaXRlci5vbmFjaylcclxuICAgICAgICAgICAgZ3VhY1dyaXRlci5vbmFjayhzdGF0dXMpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJyb3dzZXItaW5kZXBlbmRlbnQgaW1wbGVtZW50YXRpb24gb2YgQmxvYi5zbGljZSgpIHdoaWNoIHVzZXMgYW4gZW5kXHJcbiAgICAgKiBvZmZzZXQgdG8gZGV0ZXJtaW5lIHRoZSBzcGFuIG9mIHRoZSByZXN1bHRpbmcgc2xpY2UsIHJhdGhlciB0aGFuIGFcclxuICAgICAqIGxlbmd0aC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtCbG9ifSBibG9iXHJcbiAgICAgKiAgICAgVGhlIEJsb2IgdG8gc2xpY2UuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0XHJcbiAgICAgKiAgICAgVGhlIHN0YXJ0aW5nIG9mZnNldCBvZiB0aGUgc2xpY2UsIGluIGJ5dGVzLCBpbmNsdXNpdmUuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGVuZFxyXG4gICAgICogICAgIFRoZSBlbmRpbmcgb2Zmc2V0IG9mIHRoZSBzbGljZSwgaW4gYnl0ZXMsIGV4Y2x1c2l2ZS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7QmxvYn1cclxuICAgICAqICAgICBBIEJsb2IgY29udGFpbmluZyB0aGUgZGF0YSB3aXRoaW4gdGhlIGdpdmVuIEJsb2Igc3RhcnRpbmcgYXRcclxuICAgICAqICAgICA8Y29kZT5zdGFydDwvY29kZT4gYW5kIGVuZGluZyBhdCA8Y29kZT5lbmQgLSAxPC9jb2RlPi5cclxuICAgICAqL1xyXG4gICAgdmFyIHNsaWNlID0gZnVuY3Rpb24gc2xpY2UoYmxvYiwgc3RhcnQsIGVuZCkge1xyXG5cclxuICAgICAgICAvLyBVc2UgcHJlZml4ZWQgaW1wbGVtZW50YXRpb25zIGlmIG5lY2Vzc2FyeVxyXG4gICAgICAgIHZhciBzbGljZUltcGxlbWVudGF0aW9uID0gKFxyXG4gICAgICAgICAgICAgICAgYmxvYi5zbGljZVxyXG4gICAgICAgICAgICAgfHwgYmxvYi53ZWJraXRTbGljZVxyXG4gICAgICAgICAgICAgfHwgYmxvYi5tb3pTbGljZVxyXG4gICAgICAgICkuYmluZChibG9iKTtcclxuXHJcbiAgICAgICAgdmFyIGxlbmd0aCA9IGVuZCAtIHN0YXJ0O1xyXG5cclxuICAgICAgICAvLyBUaGUgb2xkIEJsb2Iuc2xpY2UoKSB3YXMgbGVuZ3RoLWJhc2VkIChub3QgZW5kLWJhc2VkKS4gVHJ5IHRoZVxyXG4gICAgICAgIC8vIGxlbmd0aCB2ZXJzaW9uIGZpcnN0LCBpZiB0aGUgdHdvIGNhbGxzIGFyZSBub3QgZXF1aXZhbGVudC5cclxuICAgICAgICBpZiAobGVuZ3RoICE9PSBlbmQpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIHRoZSByZXN1bHQgb2YgdGhlIHNsaWNlKCkgY2FsbCBtYXRjaGVzIHRoZSBleHBlY3RlZCBsZW5ndGgsXHJcbiAgICAgICAgICAgIC8vIHRydXN0IHRoYXQgcmVzdWx0LiBJdCBtdXN0IGJlIGNvcnJlY3QuXHJcbiAgICAgICAgICAgIHZhciBzbGljZVJlc3VsdCA9IHNsaWNlSW1wbGVtZW50YXRpb24oc3RhcnQsIGxlbmd0aCk7XHJcbiAgICAgICAgICAgIGlmIChzbGljZVJlc3VsdC5zaXplID09PSBsZW5ndGgpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2xpY2VSZXN1bHQ7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCB1c2UgdGhlIG1vc3QtcmVjZW50IHN0YW5kYXJkOiBlbmQtYmFzZWQgc2xpY2UoKVxyXG4gICAgICAgIHJldHVybiBzbGljZUltcGxlbWVudGF0aW9uKHN0YXJ0LCBlbmQpO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZW5kcyB0aGUgY29udGVudHMgb2YgdGhlIGdpdmVuIGJsb2Igb3ZlciB0aGUgdW5kZXJseWluZyBzdHJlYW0uXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtCbG9ifSBibG9iXHJcbiAgICAgKiAgICAgVGhlIGJsb2IgdG8gc2VuZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZW5kQmxvYiA9IGZ1bmN0aW9uIHNlbmRCbG9iKGJsb2IpIHtcclxuXHJcbiAgICAgICAgdmFyIG9mZnNldCA9IDA7XHJcbiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIHRoZSBuZXh0IGNodW5rIG9mIHRoZSBibG9iIHByb3ZpZGVkIHRvXHJcbiAgICAgICAgICogW3NlbmRCbG9iKClde0BsaW5rIEd1YWNhbW9sZS5CbG9iV3JpdGVyI3NlbmRCbG9ifS4gVGhlIGNodW5rIGl0c2VsZlxyXG4gICAgICAgICAqIGlzIHJlYWQgYXN5bmNocm9ub3VzbHksIGFuZCB3aWxsIG5vdCBiZSBhdmFpbGFibGUgdW50aWxcclxuICAgICAgICAgKiByZWFkZXIub25sb2FkIGZpcmVzLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgcmVhZE5leHRDaHVuayA9IGZ1bmN0aW9uIHJlYWROZXh0Q2h1bmsoKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBJZiBubyBmdXJ0aGVyIGNodW5rcyByZW1haW4sIGluZm9ybSBvZiBjb21wbGV0aW9uIGFuZCBzdG9wXHJcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPj0gYmxvYi5zaXplKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gRmlyZSBjb21wbGV0aW9uIGV2ZW50IGZvciBjb21wbGV0ZWQgYmxvYlxyXG4gICAgICAgICAgICAgICAgaWYgKGd1YWNXcml0ZXIub25jb21wbGV0ZSlcclxuICAgICAgICAgICAgICAgICAgICBndWFjV3JpdGVyLm9uY29tcGxldGUoYmxvYik7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gTm8gZnVydGhlciBjaHVua3MgdG8gcmVhZFxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gT2J0YWluIHJlZmVyZW5jZSB0byBuZXh0IGNodW5rIGFzIGEgbmV3IGJsb2JcclxuICAgICAgICAgICAgdmFyIGNodW5rID0gc2xpY2UoYmxvYiwgb2Zmc2V0LCBvZmZzZXQgKyBhcnJheUJ1ZmZlcldyaXRlci5ibG9iTGVuZ3RoKTtcclxuICAgICAgICAgICAgb2Zmc2V0ICs9IGFycmF5QnVmZmVyV3JpdGVyLmJsb2JMZW5ndGg7XHJcblxyXG4gICAgICAgICAgICAvLyBBdHRlbXB0IHRvIHJlYWQgdGhlIGJsb2IgY29udGVudHMgcmVwcmVzZW50ZWQgYnkgdGhlIGJsb2IgaW50b1xyXG4gICAgICAgICAgICAvLyBhIG5ldyBhcnJheSBidWZmZXJcclxuICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGNodW5rKTtcclxuXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gU2VuZCBlYWNoIGNodW5rIG92ZXIgdGhlIHN0cmVhbSwgY29udGludWUgcmVhZGluZyB0aGUgbmV4dCBjaHVua1xyXG4gICAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiBjaHVua0xvYWRDb21wbGV0ZSgpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlbmQgdGhlIHN1Y2Nlc3NmdWxseS1yZWFkIGNodW5rXHJcbiAgICAgICAgICAgIGFycmF5QnVmZmVyV3JpdGVyLnNlbmREYXRhKHJlYWRlci5yZXN1bHQpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ29udGludWUgc2VuZGluZyBtb3JlIGNodW5rcyBhZnRlciB0aGUgbGF0ZXN0IGNodW5rIGlzXHJcbiAgICAgICAgICAgIC8vIGFja25vd2xlZGdlZFxyXG4gICAgICAgICAgICBhcnJheUJ1ZmZlcldyaXRlci5vbmFjayA9IGZ1bmN0aW9uIHNlbmRNb3JlQ2h1bmtzKHN0YXR1cykge1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChndWFjV3JpdGVyLm9uYWNrKVxyXG4gICAgICAgICAgICAgICAgICAgIGd1YWNXcml0ZXIub25hY2soc3RhdHVzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBYm9ydCB0cmFuc2ZlciBpZiBhbiBlcnJvciBvY2N1cnNcclxuICAgICAgICAgICAgICAgIGlmIChzdGF0dXMuaXNFcnJvcigpKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBJbmZvcm0gb2YgYmxvYiB1cGxvYWQgcHJvZ3Jlc3MgdmlhIHByb2dyZXNzIGV2ZW50c1xyXG4gICAgICAgICAgICAgICAgaWYgKGd1YWNXcml0ZXIub25wcm9ncmVzcylcclxuICAgICAgICAgICAgICAgICAgICBndWFjV3JpdGVyLm9ucHJvZ3Jlc3MoYmxvYiwgb2Zmc2V0IC0gYXJyYXlCdWZmZXJXcml0ZXIuYmxvYkxlbmd0aCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUXVldWUgdGhlIG5leHQgY2h1bmsgZm9yIHJlYWRpbmdcclxuICAgICAgICAgICAgICAgIHJlYWROZXh0Q2h1bmsoKTtcclxuXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIElmIGFuIGVycm9yIHByZXZlbnRzIGZ1cnRoZXIgcmVhZGluZywgaW5mb3JtIG9mIGVycm9yIGFuZCBzdG9wXHJcbiAgICAgICAgcmVhZGVyLm9uZXJyb3IgPSBmdW5jdGlvbiBjaHVua0xvYWRGYWlsZWQoKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBGaXJlIGVycm9yIGV2ZW50LCBpbmNsdWRpbmcgdGhlIGNvbnRleHQgb2YgdGhlIGVycm9yXHJcbiAgICAgICAgICAgIGlmIChndWFjV3JpdGVyLm9uZXJyb3IpXHJcbiAgICAgICAgICAgICAgICBndWFjV3JpdGVyLm9uZXJyb3IoYmxvYiwgb2Zmc2V0LCByZWFkZXIuZXJyb3IpO1xyXG5cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBCZWdpbiByZWFkaW5nIHRoZSBmaXJzdCBjaHVua1xyXG4gICAgICAgIHJlYWROZXh0Q2h1bmsoKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2lnbmFscyB0aGF0IG5vIGZ1cnRoZXIgdGV4dCB3aWxsIGJlIHNlbnQsIGVmZmVjdGl2ZWx5IGNsb3NpbmcgdGhlXHJcbiAgICAgKiBzdHJlYW0uXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2VuZEVuZCA9IGZ1bmN0aW9uIHNlbmRFbmQoKSB7XHJcbiAgICAgICAgYXJyYXlCdWZmZXJXcml0ZXIuc2VuZEVuZCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIGZvciByZWNlaXZlZCBkYXRhLCBpZiBhY2tub3dsZWRnZWQgYnkgdGhlIHNlcnZlci5cclxuICAgICAqXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLlN0YXR1c30gc3RhdHVzXHJcbiAgICAgKiAgICAgVGhlIHN0YXR1cyBvZiB0aGUgb3BlcmF0aW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uYWNrID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW4gYW4gZXJyb3Igb2NjdXJzIHJlYWRpbmcgYSBibG9iIHBhc3NlZCB0b1xyXG4gICAgICogW3NlbmRCbG9iKClde0BsaW5rIEd1YWNhbW9sZS5CbG9iV3JpdGVyI3NlbmRCbG9ifS4gVGhlIHRyYW5zZmVyIGZvciB0aGVcclxuICAgICAqIHRoZSBnaXZlbiBibG9iIHdpbGwgY2Vhc2UsIGJ1dCB0aGUgc3RyZWFtIHdpbGwgcmVtYWluIG9wZW4uXHJcbiAgICAgKlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0Jsb2J9IGJsb2JcclxuICAgICAqICAgICBUaGUgYmxvYiB0aGF0IHdhcyBiZWluZyByZWFkIHdoZW4gdGhlIGVycm9yIG9jY3VycmVkLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBvZmZzZXRcclxuICAgICAqICAgICBUaGUgb2Zmc2V0IG9mIHRoZSBmYWlsZWQgcmVhZCBhdHRlbXB0IHdpdGhpbiB0aGUgYmxvYiwgaW4gYnl0ZXMuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtET01FcnJvcn0gZXJyb3JcclxuICAgICAqICAgICBUaGUgZXJyb3IgdGhhdCBvY2N1cnJlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmVycm9yID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIGZvciBlYWNoIHN1Y2Nlc3NmdWxseS1yZWFkIGNodW5rIG9mIGRhdGEgYXMgYSBibG9iIGlzIGJlaW5nIHNlbnRcclxuICAgICAqIHZpYSBbc2VuZEJsb2IoKV17QGxpbmsgR3VhY2Ftb2xlLkJsb2JXcml0ZXIjc2VuZEJsb2J9LlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtCbG9ifSBibG9iXHJcbiAgICAgKiAgICAgVGhlIGJsb2IgdGhhdCBpcyBiZWluZyByZWFkLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBvZmZzZXRcclxuICAgICAqICAgICBUaGUgb2Zmc2V0IG9mIHRoZSByZWFkIHRoYXQganVzdCBzdWNjZWVkZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25wcm9ncmVzcyA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuIGEgYmxvYiBwYXNzZWQgdG9cclxuICAgICAqIFtzZW5kQmxvYigpXXtAbGluayBHdWFjYW1vbGUuQmxvYldyaXRlciNzZW5kQmxvYn0gaGFzIGZpbmlzaGVkIGJlaW5nXHJcbiAgICAgKiBzZW50LlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtCbG9ifSBibG9iXHJcbiAgICAgKiAgICAgVGhlIGJsb2IgdGhhdCB3YXMgc2VudC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmNvbXBsZXRlID0gbnVsbDtcclxuXHJcbn07XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogR3VhY2Ftb2xlIHByb3RvY29sIGNsaWVudC4gR2l2ZW4gYSB7QGxpbmsgR3VhY2Ftb2xlLlR1bm5lbH0sXHJcbiAqIGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbmNvbWluZyBhbmQgb3V0Z29pbmcgR3VhY2Ftb2xlIGluc3RydWN0aW9ucyB2aWEgdGhlXHJcbiAqIHByb3ZpZGVkIHR1bm5lbCwgdXBkYXRpbmcgaXRzIGRpc3BsYXkgdXNpbmcgb25lIG9yIG1vcmUgY2FudmFzIGVsZW1lbnRzLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLlR1bm5lbH0gdHVubmVsIFRoZSB0dW5uZWwgdG8gdXNlIHRvIHNlbmQgYW5kIHJlY2VpdmVcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR3VhY2Ftb2xlIGluc3RydWN0aW9ucy5cclxuICovXHJcbkd1YWNhbW9sZS5DbGllbnQgPSBmdW5jdGlvbih0dW5uZWwpIHtcclxuXHJcbiAgICB2YXIgZ3VhY19jbGllbnQgPSB0aGlzO1xyXG5cclxuICAgIHZhciBTVEFURV9JRExFICAgICAgICAgID0gMDtcclxuICAgIHZhciBTVEFURV9DT05ORUNUSU5HICAgID0gMTtcclxuICAgIHZhciBTVEFURV9XQUlUSU5HICAgICAgID0gMjtcclxuICAgIHZhciBTVEFURV9DT05ORUNURUQgICAgID0gMztcclxuICAgIHZhciBTVEFURV9ESVNDT05ORUNUSU5HID0gNDtcclxuICAgIHZhciBTVEFURV9ESVNDT05ORUNURUQgID0gNTtcclxuXHJcbiAgICB2YXIgY3VycmVudFN0YXRlID0gU1RBVEVfSURMRTtcclxuICAgIFxyXG4gICAgdmFyIGN1cnJlbnRUaW1lc3RhbXAgPSAwO1xyXG4gICAgdmFyIHBpbmdJbnRlcnZhbCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUcmFuc2xhdGlvbiBmcm9tIEd1YWNhbW9sZSBwcm90b2NvbCBsaW5lIGNhcHMgdG8gTGF5ZXIgbGluZSBjYXBzLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGxpbmVDYXAgPSB7XHJcbiAgICAgICAgMDogXCJidXR0XCIsXHJcbiAgICAgICAgMTogXCJyb3VuZFwiLFxyXG4gICAgICAgIDI6IFwic3F1YXJlXCJcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUcmFuc2xhdGlvbiBmcm9tIEd1YWNhbW9sZSBwcm90b2NvbCBsaW5lIGNhcHMgdG8gTGF5ZXIgbGluZSBjYXBzLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGxpbmVKb2luID0ge1xyXG4gICAgICAgIDA6IFwiYmV2ZWxcIixcclxuICAgICAgICAxOiBcIm1pdGVyXCIsXHJcbiAgICAgICAgMjogXCJyb3VuZFwiXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHVuZGVybHlpbmcgR3VhY2Ftb2xlIGRpc3BsYXkuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuRGlzcGxheX1cclxuICAgICAqL1xyXG4gICAgdmFyIGRpc3BsYXkgPSBuZXcgR3VhY2Ftb2xlLkRpc3BsYXkoKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbCBhdmFpbGFibGUgbGF5ZXJzIGFuZCBidWZmZXJzXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtPYmplY3QuPE51bWJlciwgKEd1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcnxHdWFjYW1vbGUuTGF5ZXIpPn1cclxuICAgICAqL1xyXG4gICAgdmFyIGxheWVycyA9IHt9O1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIEFsbCBhdWRpbyBwbGF5ZXJzIGN1cnJlbnRseSBpbiB1c2UgYnkgdGhlIGNsaWVudC4gSW5pdGlhbGx5LCB0aGlzIHdpbGxcclxuICAgICAqIGJlIGVtcHR5LCBidXQgYXVkaW8gcGxheWVycyBtYXkgYmUgYWxsb2NhdGVkIGJ5IHRoZSBzZXJ2ZXIgdXBvbiByZXF1ZXN0LlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0LjxOdW1iZXIsIEd1YWNhbW9sZS5BdWRpb1BsYXllcj59XHJcbiAgICAgKi9cclxuICAgIHZhciBhdWRpb1BsYXllcnMgPSB7fTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbCB2aWRlbyBwbGF5ZXJzIGN1cnJlbnRseSBpbiB1c2UgYnkgdGhlIGNsaWVudC4gSW5pdGlhbGx5LCB0aGlzIHdpbGxcclxuICAgICAqIGJlIGVtcHR5LCBidXQgdmlkZW8gcGxheWVycyBtYXkgYmUgYWxsb2NhdGVkIGJ5IHRoZSBzZXJ2ZXIgdXBvbiByZXF1ZXN0LlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0LjxOdW1iZXIsIEd1YWNhbW9sZS5WaWRlb1BsYXllcj59XHJcbiAgICAgKi9cclxuICAgIHZhciB2aWRlb1BsYXllcnMgPSB7fTtcclxuXHJcbiAgICAvLyBObyBpbml0aWFsIHBhcnNlcnNcclxuICAgIHZhciBwYXJzZXJzID0gW107XHJcblxyXG4gICAgLy8gTm8gaW5pdGlhbCBzdHJlYW1zIFxyXG4gICAgdmFyIHN0cmVhbXMgPSBbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbCBjdXJyZW50IG9iamVjdHMuIFRoZSBpbmRleCBvZiBlYWNoIG9iamVjdCBpcyBkaWN0YXRlZCBieSB0aGVcclxuICAgICAqIEd1YWNhbW9sZSBzZXJ2ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuT2JqZWN0W119XHJcbiAgICAgKi9cclxuICAgIHZhciBvYmplY3RzID0gW107XHJcblxyXG4gICAgLy8gUG9vbCBvZiBhdmFpbGFibGUgc3RyZWFtIGluZGljZXNcclxuICAgIHZhciBzdHJlYW1faW5kaWNlcyA9IG5ldyBHdWFjYW1vbGUuSW50ZWdlclBvb2woKTtcclxuXHJcbiAgICAvLyBBcnJheSBvZiBhbGxvY2F0ZWQgb3V0cHV0IHN0cmVhbXMgYnkgaW5kZXhcclxuICAgIHZhciBvdXRwdXRfc3RyZWFtcyA9IFtdO1xyXG5cclxuICAgIGZ1bmN0aW9uIHNldFN0YXRlKHN0YXRlKSB7XHJcbiAgICAgICAgaWYgKHN0YXRlICE9IGN1cnJlbnRTdGF0ZSkge1xyXG4gICAgICAgICAgICBjdXJyZW50U3RhdGUgPSBzdGF0ZTtcclxuICAgICAgICAgICAgaWYgKGd1YWNfY2xpZW50Lm9uc3RhdGVjaGFuZ2UpXHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5vbnN0YXRlY2hhbmdlKGN1cnJlbnRTdGF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGlzQ29ubmVjdGVkKCkge1xyXG4gICAgICAgIHJldHVybiBjdXJyZW50U3RhdGUgPT0gU1RBVEVfQ09OTkVDVEVEXHJcbiAgICAgICAgICAgIHx8IGN1cnJlbnRTdGF0ZSA9PSBTVEFURV9XQUlUSU5HO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJvZHVjZXMgYW4gb3BhcXVlIHJlcHJlc2VudGF0aW9uIG9mIEd1YWNhbW9sZS5DbGllbnQgc3RhdGUgd2hpY2ggY2FuIGJlXHJcbiAgICAgKiBsYXRlciBpbXBvcnRlZCB0aHJvdWdoIGEgY2FsbCB0byBpbXBvcnRTdGF0ZSgpLiBUaGlzIG9iamVjdCBpc1xyXG4gICAgICogZWZmZWN0aXZlbHkgYW4gaW5kZXBlbmRlbnQsIGNvbXByZXNzZWQgc25hcHNob3Qgb2YgcHJvdG9jb2wgYW5kIGRpc3BsYXlcclxuICAgICAqIHN0YXRlLiBJbnZva2luZyB0aGlzIGZ1bmN0aW9uIGltcGxpY2l0bHkgZmx1c2hlcyB0aGUgZGlzcGxheS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xyXG4gICAgICogICAgIENhbGxiYWNrIHdoaWNoIHNob3VsZCBiZSBpbnZva2VkIG9uY2UgdGhlIHN0YXRlIG9iamVjdCBpcyByZWFkeS4gVGhlXHJcbiAgICAgKiAgICAgc3RhdGUgb2JqZWN0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBjYWxsYmFjayBhcyB0aGUgc29sZSBwYXJhbWV0ZXIuXHJcbiAgICAgKiAgICAgVGhpcyBjYWxsYmFjayBtYXkgYmUgaW52b2tlZCBpbW1lZGlhdGVseSwgb3IgbGF0ZXIgYXMgdGhlIGRpc3BsYXlcclxuICAgICAqICAgICBmaW5pc2hlcyByZW5kZXJpbmcgYW5kIGJlY29tZXMgcmVhZHkuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZXhwb3J0U3RhdGUgPSBmdW5jdGlvbiBleHBvcnRTdGF0ZShjYWxsYmFjaykge1xyXG5cclxuICAgICAgICAvLyBTdGFydCB3aXRoIGVtcHR5IHN0YXRlXHJcbiAgICAgICAgdmFyIHN0YXRlID0ge1xyXG4gICAgICAgICAgICAnY3VycmVudFN0YXRlJyA6IGN1cnJlbnRTdGF0ZSxcclxuICAgICAgICAgICAgJ2N1cnJlbnRUaW1lc3RhbXAnIDogY3VycmVudFRpbWVzdGFtcCxcclxuICAgICAgICAgICAgJ2xheWVycycgOiB7fVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHZhciBsYXllcnNTbmFwc2hvdCA9IHt9O1xyXG5cclxuICAgICAgICAvLyBNYWtlIGEgY29weSBvZiBhbGwgY3VycmVudCBsYXllcnMgKHByb3RvY29sIHN0YXRlKVxyXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBsYXllcnMpIHtcclxuICAgICAgICAgICAgbGF5ZXJzU25hcHNob3Rba2V5XSA9IGxheWVyc1trZXldO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUG9wdWxhdGUgbGF5ZXJzIG9uY2UgZGF0YSBpcyBhdmFpbGFibGUgKGRpc3BsYXkgc3RhdGUsIHJlcXVpcmVzIGZsdXNoKVxyXG4gICAgICAgIGRpc3BsYXkuZmx1c2goZnVuY3Rpb24gcG9wdWxhdGVMYXllcnMoKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBFeHBvcnQgZWFjaCBkZWZpbmVkIGxheWVyL2J1ZmZlclxyXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gbGF5ZXJzU25hcHNob3QpIHtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBwYXJzZUludChrZXkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGxheWVyID0gbGF5ZXJzU25hcHNob3Rba2V5XTtcclxuICAgICAgICAgICAgICAgIHZhciBjYW52YXMgPSBsYXllci50b0NhbnZhcygpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFN0b3JlIGxheWVyL2J1ZmZlciBkaW1lbnNpb25zXHJcbiAgICAgICAgICAgICAgICB2YXIgZXhwb3J0TGF5ZXIgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgJ3dpZHRoJyAgOiBsYXllci53aWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0JyA6IGxheWVyLmhlaWdodFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTdG9yZSBsYXllci9idWZmZXIgaW1hZ2UgZGF0YSwgaWYgaXQgY2FuIGJlIGdlbmVyYXRlZFxyXG4gICAgICAgICAgICAgICAgaWYgKGxheWVyLndpZHRoICYmIGxheWVyLmhlaWdodClcclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRMYXllci51cmwgPSBjYW52YXMudG9EYXRhVVJMKCdpbWFnZS9wbmcnKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBZGQgbGF5ZXIgcHJvcGVydGllcyBpZiBub3QgYSBidWZmZXIgbm9yIHRoZSBkZWZhdWx0IGxheWVyXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0TGF5ZXIueCA9IGxheWVyLng7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0TGF5ZXIueSA9IGxheWVyLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0TGF5ZXIueiA9IGxheWVyLno7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0TGF5ZXIuYWxwaGEgPSBsYXllci5hbHBoYTtcclxuICAgICAgICAgICAgICAgICAgICBleHBvcnRMYXllci5tYXRyaXggPSBsYXllci5tYXRyaXg7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhwb3J0TGF5ZXIucGFyZW50ID0gZ2V0TGF5ZXJJbmRleChsYXllci5wYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFN0b3JlIGV4cG9ydGVkIGxheWVyXHJcbiAgICAgICAgICAgICAgICBzdGF0ZS5sYXllcnNba2V5XSA9IGV4cG9ydExheWVyO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gSW52b2tlIGNhbGxiYWNrIG5vdyB0aGF0IHRoZSBzdGF0ZSBpcyByZWFkeVxyXG4gICAgICAgICAgICBjYWxsYmFjayhzdGF0ZSk7XHJcblxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXN0b3JlcyBHdWFjYW1vbGUuQ2xpZW50IHByb3RvY29sIGFuZCBkaXNwbGF5IHN0YXRlIGJhc2VkIG9uIGFuIG9wYXF1ZVxyXG4gICAgICogb2JqZWN0IGZyb20gYSBwcmlvciBjYWxsIHRvIGV4cG9ydFN0YXRlKCkuIFRoZSBHdWFjYW1vbGUuQ2xpZW50IGluc3RhbmNlXHJcbiAgICAgKiB1c2VkIHRvIGV4cG9ydCB0aGF0IHN0YXRlIG5lZWQgbm90IGJlIHRoZSBzYW1lIGFzIHRoaXMgaW5zdGFuY2UuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YXRlXHJcbiAgICAgKiAgICAgQW4gb3BhcXVlIHJlcHJlc2VudGF0aW9uIG9mIEd1YWNhbW9sZS5DbGllbnQgc3RhdGUgZnJvbSBhIHByaW9yIGNhbGxcclxuICAgICAqICAgICB0byBleHBvcnRTdGF0ZSgpLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtjYWxsYmFja11cclxuICAgICAqICAgICBUaGUgZnVuY3Rpb24gdG8gaW52b2tlIHdoZW4gc3RhdGUgaGFzIGZpbmlzaGVkIGJlaW5nIGltcG9ydGVkLiBUaGlzXHJcbiAgICAgKiAgICAgbWF5IGhhcHBlbiBpbW1lZGlhdGVseSwgb3IgbGF0ZXIgYXMgaW1hZ2VzIHdpdGhpbiB0aGUgcHJvdmlkZWQgc3RhdGVcclxuICAgICAqICAgICBvYmplY3QgYXJlIGxvYWRlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5pbXBvcnRTdGF0ZSA9IGZ1bmN0aW9uIGltcG9ydFN0YXRlKHN0YXRlLCBjYWxsYmFjaykge1xyXG5cclxuICAgICAgICB2YXIga2V5O1xyXG4gICAgICAgIHZhciBpbmRleDtcclxuXHJcbiAgICAgICAgY3VycmVudFN0YXRlID0gc3RhdGUuY3VycmVudFN0YXRlO1xyXG4gICAgICAgIGN1cnJlbnRUaW1lc3RhbXAgPSBzdGF0ZS5jdXJyZW50VGltZXN0YW1wO1xyXG5cclxuICAgICAgICAvLyBEaXNwb3NlIG9mIGFsbCBsYXllcnNcclxuICAgICAgICBmb3IgKGtleSBpbiBsYXllcnMpIHtcclxuICAgICAgICAgICAgaW5kZXggPSBwYXJzZUludChrZXkpO1xyXG4gICAgICAgICAgICBpZiAoaW5kZXggPiAwKVxyXG4gICAgICAgICAgICAgICAgZGlzcGxheS5kaXNwb3NlKGxheWVyc1trZXldKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxheWVycyA9IHt9O1xyXG5cclxuICAgICAgICAvLyBJbXBvcnQgc3RhdGUgb2YgZWFjaCBsYXllci9idWZmZXJcclxuICAgICAgICBmb3IgKGtleSBpbiBzdGF0ZS5sYXllcnMpIHtcclxuXHJcbiAgICAgICAgICAgIGluZGV4ID0gcGFyc2VJbnQoa2V5KTtcclxuXHJcbiAgICAgICAgICAgIHZhciBpbXBvcnRMYXllciA9IHN0YXRlLmxheWVyc1trZXldO1xyXG4gICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihpbmRleCk7XHJcblxyXG4gICAgICAgICAgICAvLyBSZXNldCBsYXllciBzaXplXHJcbiAgICAgICAgICAgIGRpc3BsYXkucmVzaXplKGxheWVyLCBpbXBvcnRMYXllci53aWR0aCwgaW1wb3J0TGF5ZXIuaGVpZ2h0KTtcclxuXHJcbiAgICAgICAgICAgIC8vIEluaXRpYWxpemUgbmV3IGxheWVyIGlmIGl0IGhhcyBhc3NvY2lhdGVkIGRhdGFcclxuICAgICAgICAgICAgaWYgKGltcG9ydExheWVyLnVybCkge1xyXG4gICAgICAgICAgICAgICAgZGlzcGxheS5zZXRDaGFubmVsTWFzayhsYXllciwgR3VhY2Ftb2xlLkxheWVyLlNSQyk7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5LmRyYXcobGF5ZXIsIDAsIDAsIGltcG9ydExheWVyLnVybCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFNldCBsYXllci1zcGVjaWZpYyBwcm9wZXJ0aWVzIGlmIG5vdCBhIGJ1ZmZlciBub3IgdGhlIGRlZmF1bHQgbGF5ZXJcclxuICAgICAgICAgICAgaWYgKGluZGV4ID4gMCAmJiBpbXBvcnRMYXllci5wYXJlbnQgPj0gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIEFwcGx5IGxheWVyIHBvc2l0aW9uIGFuZCBzZXQgcGFyZW50XHJcbiAgICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gZ2V0TGF5ZXIoaW1wb3J0TGF5ZXIucGFyZW50KTtcclxuICAgICAgICAgICAgICAgIGRpc3BsYXkubW92ZShsYXllciwgcGFyZW50LCBpbXBvcnRMYXllci54LCBpbXBvcnRMYXllci55LCBpbXBvcnRMYXllci56KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgbGF5ZXIgdHJhbnNwYXJlbmN5XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5LnNoYWRlKGxheWVyLCBpbXBvcnRMYXllci5hbHBoYSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQXBwbHkgbWF0cml4IHRyYW5zZm9ybVxyXG4gICAgICAgICAgICAgICAgdmFyIG1hdHJpeCA9IGltcG9ydExheWVyLm1hdHJpeDtcclxuICAgICAgICAgICAgICAgIGRpc3BsYXkuZGlzdG9ydChsYXllcixcclxuICAgICAgICAgICAgICAgICAgICBtYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLFxyXG4gICAgICAgICAgICAgICAgICAgIG1hdHJpeFszXSwgbWF0cml4WzRdLCBtYXRyaXhbNV0pO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEZsdXNoIGNoYW5nZXMgdG8gZGlzcGxheVxyXG4gICAgICAgIGRpc3BsYXkuZmx1c2goY2FsbGJhY2spO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSB1bmRlcmx5aW5nIGRpc3BsYXkgb2YgdGhpcyBHdWFjYW1vbGUuQ2xpZW50LiBUaGUgZGlzcGxheVxyXG4gICAgICogY29udGFpbnMgYW4gRWxlbWVudCB3aGljaCBjYW4gYmUgYWRkZWQgdG8gdGhlIERPTSwgY2F1c2luZyB0aGVcclxuICAgICAqIGRpc3BsYXkgdG8gYmVjb21lIHZpc2libGUuXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm4ge0d1YWNhbW9sZS5EaXNwbGF5fSBUaGUgdW5kZXJseWluZyBkaXNwbGF5IG9mIHRoaXNcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHdWFjYW1vbGUuQ2xpZW50LlxyXG4gICAgICovXHJcbiAgICB0aGlzLmdldERpc3BsYXkgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gZGlzcGxheTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZW5kcyB0aGUgY3VycmVudCBzaXplIG9mIHRoZSBzY3JlZW4uXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aCBUaGUgd2lkdGggb2YgdGhlIHNjcmVlbi5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoZWlnaHQgVGhlIGhlaWdodCBvZiB0aGUgc2NyZWVuLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnNlbmRTaXplID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCkge1xyXG5cclxuICAgICAgICAvLyBEbyBub3Qgc2VuZCByZXF1ZXN0cyBpZiBub3QgY29ubmVjdGVkXHJcbiAgICAgICAgaWYgKCFpc0Nvbm5lY3RlZCgpKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHR1bm5lbC5zZW5kTWVzc2FnZShcInNpemVcIiwgd2lkdGgsIGhlaWdodCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlbmRzIGEga2V5IGV2ZW50IGhhdmluZyB0aGUgZ2l2ZW4gcHJvcGVydGllcyBhcyBpZiB0aGUgdXNlclxyXG4gICAgICogcHJlc3NlZCBvciByZWxlYXNlZCBhIGtleS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBwcmVzc2VkIFdoZXRoZXIgdGhlIGtleSBpcyBwcmVzc2VkICh0cnVlKSBvciByZWxlYXNlZFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIChmYWxzZSkuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0ga2V5c3ltIFRoZSBrZXlzeW0gb2YgdGhlIGtleSBiZWluZyBwcmVzc2VkIG9yIHJlbGVhc2VkLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnNlbmRLZXlFdmVudCA9IGZ1bmN0aW9uKHByZXNzZWQsIGtleXN5bSkge1xyXG4gICAgICAgIC8vIERvIG5vdCBzZW5kIHJlcXVlc3RzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwia2V5XCIsIGtleXN5bSwgcHJlc3NlZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2VuZHMgYSBtb3VzZSBldmVudCBoYXZpbmcgdGhlIHByb3BlcnRpZXMgcHJvdmlkZWQgYnkgdGhlIGdpdmVuIG1vdXNlXHJcbiAgICAgKiBzdGF0ZS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTW91c2UuU3RhdGV9IG1vdXNlU3RhdGUgVGhlIHN0YXRlIG9mIHRoZSBtb3VzZSB0byBzZW5kXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbiB0aGUgbW91c2UgZXZlbnQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2VuZE1vdXNlU3RhdGUgPSBmdW5jdGlvbihtb3VzZVN0YXRlKSB7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBzZW5kIHJlcXVlc3RzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gVXBkYXRlIGNsaWVudC1zaWRlIGN1cnNvclxyXG4gICAgICAgIGRpc3BsYXkubW92ZUN1cnNvcihcclxuICAgICAgICAgICAgTWF0aC5mbG9vcihtb3VzZVN0YXRlLngpLFxyXG4gICAgICAgICAgICBNYXRoLmZsb29yKG1vdXNlU3RhdGUueSlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICAvLyBCdWlsZCBtYXNrXHJcbiAgICAgICAgdmFyIGJ1dHRvbk1hc2sgPSAwO1xyXG4gICAgICAgIGlmIChtb3VzZVN0YXRlLmxlZnQpICAgYnV0dG9uTWFzayB8PSAxO1xyXG4gICAgICAgIGlmIChtb3VzZVN0YXRlLm1pZGRsZSkgYnV0dG9uTWFzayB8PSAyO1xyXG4gICAgICAgIGlmIChtb3VzZVN0YXRlLnJpZ2h0KSAgYnV0dG9uTWFzayB8PSA0O1xyXG4gICAgICAgIGlmIChtb3VzZVN0YXRlLnVwKSAgICAgYnV0dG9uTWFzayB8PSA4O1xyXG4gICAgICAgIGlmIChtb3VzZVN0YXRlLmRvd24pICAgYnV0dG9uTWFzayB8PSAxNjtcclxuXHJcbiAgICAgICAgLy8gU2VuZCBtZXNzYWdlXHJcbiAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwibW91c2VcIiwgTWF0aC5mbG9vcihtb3VzZVN0YXRlLngpLCBNYXRoLmZsb29yKG1vdXNlU3RhdGUueSksIGJ1dHRvbk1hc2spO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGNsaXBib2FyZCBvZiB0aGUgcmVtb3RlIGNsaWVudCB0byB0aGUgZ2l2ZW4gdGV4dCBkYXRhLlxyXG4gICAgICpcclxuICAgICAqIEBkZXByZWNhdGVkIFVzZSBjcmVhdGVDbGlwYm9hcmRTdHJlYW0oKSBpbnN0ZWFkLiBcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIHNlbmQgYXMgdGhlIGNsaXBib2FyZCBjb250ZW50cy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZXRDbGlwYm9hcmQgPSBmdW5jdGlvbihkYXRhKSB7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBzZW5kIHJlcXVlc3RzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gT3BlbiBzdHJlYW1cclxuICAgICAgICB2YXIgc3RyZWFtID0gZ3VhY19jbGllbnQuY3JlYXRlQ2xpcGJvYXJkU3RyZWFtKFwidGV4dC9wbGFpblwiKTtcclxuICAgICAgICB2YXIgd3JpdGVyID0gbmV3IEd1YWNhbW9sZS5TdHJpbmdXcml0ZXIoc3RyZWFtKTtcclxuXHJcbiAgICAgICAgLy8gU2VuZCB0ZXh0IGNodW5rc1xyXG4gICAgICAgIGZvciAodmFyIGk9MDsgaTxkYXRhLmxlbmd0aDsgaSArPSA0MDk2KVxyXG4gICAgICAgICAgICB3cml0ZXIuc2VuZFRleHQoZGF0YS5zdWJzdHJpbmcoaSwgaSs0MDk2KSk7XHJcblxyXG4gICAgICAgIC8vIENsb3NlIHN0cmVhbVxyXG4gICAgICAgIHdyaXRlci5zZW5kRW5kKCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbG9jYXRlcyBhbiBhdmFpbGFibGUgc3RyZWFtIGluZGV4IGFuZCBjcmVhdGVzIGEgbmV3XHJcbiAgICAgKiBHdWFjYW1vbGUuT3V0cHV0U3RyZWFtIHVzaW5nIHRoYXQgaW5kZXgsIGFzc29jaWF0aW5nIHRoZSByZXN1bHRpbmdcclxuICAgICAqIHN0cmVhbSB3aXRoIHRoaXMgR3VhY2Ftb2xlLkNsaWVudC4gTm90ZSB0aGF0IHRoaXMgc3RyZWFtIHdpbGwgbm90IHlldFxyXG4gICAgICogZXhpc3QgYXMgZmFyIGFzIHRoZSBvdGhlciBlbmQgb2YgdGhlIEd1YWNhbW9sZSBjb25uZWN0aW9uIGlzIGNvbmNlcm5lZC5cclxuICAgICAqIFN0cmVhbXMgZXhpc3Qgd2l0aGluIHRoZSBHdWFjYW1vbGUgcHJvdG9jb2wgb25seSB3aGVuIHJlZmVyZW5jZWQgYnkgYW5cclxuICAgICAqIGluc3RydWN0aW9uIHdoaWNoIGNyZWF0ZXMgdGhlIHN0cmVhbSwgc3VjaCBhcyBhIFwiY2xpcGJvYXJkXCIsIFwiZmlsZVwiLCBvclxyXG4gICAgICogXCJwaXBlXCIgaW5zdHJ1Y3Rpb24uXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0d1YWNhbW9sZS5PdXRwdXRTdHJlYW19XHJcbiAgICAgKiAgICAgQSBuZXcgR3VhY2Ftb2xlLk91dHB1dFN0cmVhbSB3aXRoIGEgbmV3bHktYWxsb2NhdGVkIGluZGV4IGFuZFxyXG4gICAgICogICAgIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEd1YWNhbW9sZS5DbGllbnQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY3JlYXRlT3V0cHV0U3RyZWFtID0gZnVuY3Rpb24gY3JlYXRlT3V0cHV0U3RyZWFtKCkge1xyXG5cclxuICAgICAgICAvLyBBbGxvY2F0ZSBpbmRleFxyXG4gICAgICAgIHZhciBpbmRleCA9IHN0cmVhbV9pbmRpY2VzLm5leHQoKTtcclxuXHJcbiAgICAgICAgLy8gUmV0dXJuIG5ldyBzdHJlYW1cclxuICAgICAgICB2YXIgc3RyZWFtID0gb3V0cHV0X3N0cmVhbXNbaW5kZXhdID0gbmV3IEd1YWNhbW9sZS5PdXRwdXRTdHJlYW0oZ3VhY19jbGllbnQsIGluZGV4KTtcclxuICAgICAgICByZXR1cm4gc3RyZWFtO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPcGVucyBhIG5ldyBhdWRpbyBzdHJlYW0gZm9yIHdyaXRpbmcsIHdoZXJlIGF1ZGlvIGRhdGEgaGF2aW5nIHRoZSBnaXZlXHJcbiAgICAgKiBtaW1ldHlwZSB3aWxsIGJlIHNlbnQgYWxvbmcgdGhlIHJldHVybmVkIHN0cmVhbS4gVGhlIGluc3RydWN0aW9uXHJcbiAgICAgKiBuZWNlc3NhcnkgdG8gY3JlYXRlIHRoaXMgc3RyZWFtIHdpbGwgYXV0b21hdGljYWxseSBiZSBzZW50LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZVxyXG4gICAgICogICAgIFRoZSBtaW1ldHlwZSBvZiB0aGUgYXVkaW8gZGF0YSB0aGF0IHdpbGwgYmUgc2VudCBhbG9uZyB0aGUgcmV0dXJuZWRcclxuICAgICAqICAgICBzdHJlYW0uXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybiB7R3VhY2Ftb2xlLk91dHB1dFN0cmVhbX1cclxuICAgICAqICAgICBUaGUgY3JlYXRlZCBhdWRpbyBzdHJlYW0uXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY3JlYXRlQXVkaW9TdHJlYW0gPSBmdW5jdGlvbihtaW1ldHlwZSkge1xyXG5cclxuICAgICAgICAvLyBBbGxvY2F0ZSBhbmQgYXNzb2NpYXRlIHN0cmVhbSB3aXRoIGF1ZGlvIG1ldGFkYXRhXHJcbiAgICAgICAgdmFyIHN0cmVhbSA9IGd1YWNfY2xpZW50LmNyZWF0ZU91dHB1dFN0cmVhbSgpO1xyXG4gICAgICAgIHR1bm5lbC5zZW5kTWVzc2FnZShcImF1ZGlvXCIsIHN0cmVhbS5pbmRleCwgbWltZXR5cGUpO1xyXG4gICAgICAgIHJldHVybiBzdHJlYW07XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE9wZW5zIGEgbmV3IGZpbGUgZm9yIHdyaXRpbmcsIGhhdmluZyB0aGUgZ2l2ZW4gaW5kZXgsIG1pbWV0eXBlIGFuZFxyXG4gICAgICogZmlsZW5hbWUuIFRoZSBpbnN0cnVjdGlvbiBuZWNlc3NhcnkgdG8gY3JlYXRlIHRoaXMgc3RyZWFtIHdpbGxcclxuICAgICAqIGF1dG9tYXRpY2FsbHkgYmUgc2VudC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWltZXR5cGUgVGhlIG1pbWV0eXBlIG9mIHRoZSBmaWxlIGJlaW5nIHNlbnQuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWUgVGhlIGZpbGVuYW1lIG9mIHRoZSBmaWxlIGJlaW5nIHNlbnQuXHJcbiAgICAgKiBAcmV0dXJuIHtHdWFjYW1vbGUuT3V0cHV0U3RyZWFtfSBUaGUgY3JlYXRlZCBmaWxlIHN0cmVhbS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5jcmVhdGVGaWxlU3RyZWFtID0gZnVuY3Rpb24obWltZXR5cGUsIGZpbGVuYW1lKSB7XHJcblxyXG4gICAgICAgIC8vIEFsbG9jYXRlIGFuZCBhc3NvY2lhdGUgc3RyZWFtIHdpdGggZmlsZSBtZXRhZGF0YVxyXG4gICAgICAgIHZhciBzdHJlYW0gPSBndWFjX2NsaWVudC5jcmVhdGVPdXRwdXRTdHJlYW0oKTtcclxuICAgICAgICB0dW5uZWwuc2VuZE1lc3NhZ2UoXCJmaWxlXCIsIHN0cmVhbS5pbmRleCwgbWltZXR5cGUsIGZpbGVuYW1lKTtcclxuICAgICAgICByZXR1cm4gc3RyZWFtO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPcGVucyBhIG5ldyBwaXBlIGZvciB3cml0aW5nLCBoYXZpbmcgdGhlIGdpdmVuIG5hbWUgYW5kIG1pbWV0eXBlLiBUaGVcclxuICAgICAqIGluc3RydWN0aW9uIG5lY2Vzc2FyeSB0byBjcmVhdGUgdGhpcyBzdHJlYW0gd2lsbCBhdXRvbWF0aWNhbGx5IGJlIHNlbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlIFRoZSBtaW1ldHlwZSBvZiB0aGUgZGF0YSBiZWluZyBzZW50LlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBpcGUuXHJcbiAgICAgKiBAcmV0dXJuIHtHdWFjYW1vbGUuT3V0cHV0U3RyZWFtfSBUaGUgY3JlYXRlZCBmaWxlIHN0cmVhbS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5jcmVhdGVQaXBlU3RyZWFtID0gZnVuY3Rpb24obWltZXR5cGUsIG5hbWUpIHtcclxuXHJcbiAgICAgICAgLy8gQWxsb2NhdGUgYW5kIGFzc29jaWF0ZSBzdHJlYW0gd2l0aCBwaXBlIG1ldGFkYXRhXHJcbiAgICAgICAgdmFyIHN0cmVhbSA9IGd1YWNfY2xpZW50LmNyZWF0ZU91dHB1dFN0cmVhbSgpO1xyXG4gICAgICAgIHR1bm5lbC5zZW5kTWVzc2FnZShcInBpcGVcIiwgc3RyZWFtLmluZGV4LCBtaW1ldHlwZSwgbmFtZSk7XHJcbiAgICAgICAgcmV0dXJuIHN0cmVhbTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3BlbnMgYSBuZXcgY2xpcGJvYXJkIG9iamVjdCBmb3Igd3JpdGluZywgaGF2aW5nIHRoZSBnaXZlbiBtaW1ldHlwZS4gVGhlXHJcbiAgICAgKiBpbnN0cnVjdGlvbiBuZWNlc3NhcnkgdG8gY3JlYXRlIHRoaXMgc3RyZWFtIHdpbGwgYXV0b21hdGljYWxseSBiZSBzZW50LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZSBUaGUgbWltZXR5cGUgb2YgdGhlIGRhdGEgYmVpbmcgc2VudC5cclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBwaXBlLlxyXG4gICAgICogQHJldHVybiB7R3VhY2Ftb2xlLk91dHB1dFN0cmVhbX0gVGhlIGNyZWF0ZWQgZmlsZSBzdHJlYW0uXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY3JlYXRlQ2xpcGJvYXJkU3RyZWFtID0gZnVuY3Rpb24obWltZXR5cGUpIHtcclxuXHJcbiAgICAgICAgLy8gQWxsb2NhdGUgYW5kIGFzc29jaWF0ZSBzdHJlYW0gd2l0aCBjbGlwYm9hcmQgbWV0YWRhdGFcclxuICAgICAgICB2YXIgc3RyZWFtID0gZ3VhY19jbGllbnQuY3JlYXRlT3V0cHV0U3RyZWFtKCk7XHJcbiAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwiY2xpcGJvYXJkXCIsIHN0cmVhbS5pbmRleCwgbWltZXR5cGUpO1xyXG4gICAgICAgIHJldHVybiBzdHJlYW07XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgb3V0cHV0IHN0cmVhbSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG9iamVjdCBhbmQgaGF2aW5nXHJcbiAgICAgKiB0aGUgZ2l2ZW4gbWltZXR5cGUgYW5kIG5hbWUuIFRoZSBsZWdhbGl0eSBvZiBhIG1pbWV0eXBlIGFuZCBuYW1lIGlzXHJcbiAgICAgKiBkaWN0YXRlZCBieSB0aGUgb2JqZWN0IGl0c2VsZi4gVGhlIGluc3RydWN0aW9uIG5lY2Vzc2FyeSB0byBjcmVhdGUgdGhpc1xyXG4gICAgICogc3RyZWFtIHdpbGwgYXV0b21hdGljYWxseSBiZSBzZW50LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxyXG4gICAgICogICAgIFRoZSBpbmRleCBvZiB0aGUgb2JqZWN0IGZvciB3aGljaCB0aGUgb3V0cHV0IHN0cmVhbSBpcyBiZWluZ1xyXG4gICAgICogICAgIGNyZWF0ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlXHJcbiAgICAgKiAgICAgVGhlIG1pbWV0eXBlIG9mIHRoZSBkYXRhIHdoaWNoIHdpbGwgYmUgc2VudCB0byB0aGUgb3V0cHV0IHN0cmVhbS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gICAgICogICAgIFRoZSBkZWZpbmVkIG5hbWUgb2YgYW4gb3V0cHV0IHN0cmVhbSB3aXRoaW4gdGhlIGdpdmVuIG9iamVjdC5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7R3VhY2Ftb2xlLk91dHB1dFN0cmVhbX1cclxuICAgICAqICAgICBBbiBvdXRwdXQgc3RyZWFtIHdoaWNoIHdpbGwgd3JpdGUgYmxvYnMgdG8gdGhlIG5hbWVkIG91dHB1dCBzdHJlYW1cclxuICAgICAqICAgICBvZiB0aGUgZ2l2ZW4gb2JqZWN0LlxyXG4gICAgICovXHJcbiAgICB0aGlzLmNyZWF0ZU9iamVjdE91dHB1dFN0cmVhbSA9IGZ1bmN0aW9uIGNyZWF0ZU9iamVjdE91dHB1dFN0cmVhbShpbmRleCwgbWltZXR5cGUsIG5hbWUpIHtcclxuXHJcbiAgICAgICAgLy8gQWxsb2NhdGUgYW5kIHNzb2NpYXRlIHN0cmVhbSB3aXRoIG9iamVjdCBtZXRhZGF0YVxyXG4gICAgICAgIHZhciBzdHJlYW0gPSBndWFjX2NsaWVudC5jcmVhdGVPdXRwdXRTdHJlYW0oKTtcclxuICAgICAgICB0dW5uZWwuc2VuZE1lc3NhZ2UoXCJwdXRcIiwgaW5kZXgsIHN0cmVhbS5pbmRleCwgbWltZXR5cGUsIG5hbWUpO1xyXG4gICAgICAgIHJldHVybiBzdHJlYW07XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlcXVlc3RzIHJlYWQgYWNjZXNzIHRvIHRoZSBpbnB1dCBzdHJlYW0gaGF2aW5nIHRoZSBnaXZlbiBuYW1lLiBJZlxyXG4gICAgICogc3VjY2Vzc2Z1bCwgYSBuZXcgaW5wdXQgc3RyZWFtIHdpbGwgYmUgY3JlYXRlZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcclxuICAgICAqICAgICBUaGUgaW5kZXggb2YgdGhlIG9iamVjdCBmcm9tIHdoaWNoIHRoZSBpbnB1dCBzdHJlYW0gaXMgYmVpbmdcclxuICAgICAqICAgICByZXF1ZXN0ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcclxuICAgICAqICAgICBUaGUgbmFtZSBvZiB0aGUgaW5wdXQgc3RyZWFtIHRvIHJlcXVlc3QuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVxdWVzdE9iamVjdElucHV0U3RyZWFtID0gZnVuY3Rpb24gcmVxdWVzdE9iamVjdElucHV0U3RyZWFtKGluZGV4LCBuYW1lKSB7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBzZW5kIHJlcXVlc3RzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwiZ2V0XCIsIGluZGV4LCBuYW1lKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBY2tub3dsZWRnZSByZWNlaXB0IG9mIGEgYmxvYiBvbiB0aGUgc3RyZWFtIHdpdGggdGhlIGdpdmVuIGluZGV4LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBzdHJlYW0gYXNzb2NpYXRlZCB3aXRoIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVkIGJsb2IuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBBIGh1bWFuLXJlYWRhYmxlIG1lc3NhZ2UgZGVzY3JpYmluZyB0aGUgZXJyb3JcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIG9yIHN0YXR1cy5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb2RlIFRoZSBlcnJvciBjb2RlLCBpZiBhbnksIG9yIDAgZm9yIHN1Y2Nlc3MuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2VuZEFjayA9IGZ1bmN0aW9uKGluZGV4LCBtZXNzYWdlLCBjb2RlKSB7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBzZW5kIHJlcXVlc3RzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwiYWNrXCIsIGluZGV4LCBtZXNzYWdlLCBjb2RlKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHaXZlbiB0aGUgaW5kZXggb2YgYSBmaWxlLCB3cml0ZXMgYSBibG9iIG9mIGRhdGEgdG8gdGhhdCBmaWxlLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBmaWxlIHRvIHdyaXRlIHRvLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgQmFzZTY0LWVuY29kZWQgZGF0YSB0byB3cml0ZSB0byB0aGUgZmlsZS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZW5kQmxvYiA9IGZ1bmN0aW9uKGluZGV4LCBkYXRhKSB7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBzZW5kIHJlcXVlc3RzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwiYmxvYlwiLCBpbmRleCwgZGF0YSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFya3MgYSBjdXJyZW50bHktb3BlbiBzdHJlYW0gYXMgY29tcGxldGUuIFRoZSBvdGhlciBlbmQgb2YgdGhlXHJcbiAgICAgKiBHdWFjYW1vbGUgY29ubmVjdGlvbiB3aWxsIGJlIG5vdGlmaWVkIHZpYSBhbiBcImVuZFwiIGluc3RydWN0aW9uIHRoYXQgdGhlXHJcbiAgICAgKiBzdHJlYW0gaXMgY2xvc2VkLCBhbmQgdGhlIGluZGV4IHdpbGwgYmUgbWFkZSBhdmFpbGFibGUgZm9yIHJldXNlIGluXHJcbiAgICAgKiBmdXR1cmUgc3RyZWFtcy5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XHJcbiAgICAgKiAgICAgVGhlIGluZGV4IG9mIHRoZSBzdHJlYW0gdG8gZW5kLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmVuZFN0cmVhbSA9IGZ1bmN0aW9uKGluZGV4KSB7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBzZW5kIHJlcXVlc3RzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAoIWlzQ29ubmVjdGVkKCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gRXhwbGljaXRseSBjbG9zZSBzdHJlYW0gYnkgc2VuZGluZyBcImVuZFwiIGluc3RydWN0aW9uXHJcbiAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwiZW5kXCIsIGluZGV4KTtcclxuXHJcbiAgICAgICAgLy8gRnJlZSBhc3NvY2lhdGVkIGluZGV4IGFuZCBzdHJlYW0gaWYgdGhleSBleGlzdFxyXG4gICAgICAgIGlmIChvdXRwdXRfc3RyZWFtc1tpbmRleF0pIHtcclxuICAgICAgICAgICAgc3RyZWFtX2luZGljZXMuZnJlZShpbmRleCk7XHJcbiAgICAgICAgICAgIGRlbGV0ZSBvdXRwdXRfc3RyZWFtc1tpbmRleF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciB0aGUgc3RhdGUgb2YgdGhpcyBHdWFjYW1vbGUuQ2xpZW50IGNoYW5nZXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXRlIFRoZSBuZXcgc3RhdGUgb2YgdGhlIGNsaWVudC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbnN0YXRlY2hhbmdlID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW4gdGhlIHJlbW90ZSBjbGllbnQgc2VuZHMgYSBuYW1lIHVwZGF0ZS5cclxuICAgICAqIFxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmV3IG5hbWUgb2YgdGhpcyBjbGllbnQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25uYW1lID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW4gYW4gZXJyb3IgaXMgcmVwb3J0ZWQgYnkgdGhlIHJlbW90ZSBjbGllbnQsIGFuZCB0aGUgY29ubmVjdGlvblxyXG4gICAgICogaXMgYmVpbmcgY2xvc2VkLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLlN0YXR1c30gc3RhdHVzIEEgc3RhdHVzIG9iamVjdCB3aGljaCBkZXNjcmliZXMgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmVycm9yID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW4gYSBhdWRpbyBzdHJlYW0gaXMgY3JlYXRlZC4gVGhlIHN0cmVhbSBwcm92aWRlZCB0byB0aGlzIGV2ZW50XHJcbiAgICAgKiBoYW5kbGVyIHdpbGwgY29udGFpbiBpdHMgb3duIGV2ZW50IGhhbmRsZXJzIGZvciByZWNlaXZlZCBkYXRhLlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuSW5wdXRTdHJlYW19IHN0cmVhbVxyXG4gICAgICogICAgIFRoZSBzdHJlYW0gdGhhdCB3aWxsIHJlY2VpdmUgYXVkaW8gZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlXHJcbiAgICAgKiAgICAgVGhlIG1pbWV0eXBlIG9mIHRoZSBhdWRpbyBkYXRhIHdoaWNoIHdpbGwgYmUgcmVjZWl2ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybiB7R3VhY2Ftb2xlLkF1ZGlvUGxheWVyfVxyXG4gICAgICogICAgIEFuIG9iamVjdCB3aGljaCBpbXBsZW1lbnRzIHRoZSBHdWFjYW1vbGUuQXVkaW9QbGF5ZXIgaW50ZXJmYWNlIGFuZFxyXG4gICAgICogICAgIGhhcyBiZWVuIGluaXRpYWxpZWQgdG8gcGxheSB0aGUgZGF0YSBpbiB0aGUgcHJvdmlkZWQgc3RyZWFtLCBvciBudWxsXHJcbiAgICAgKiAgICAgaWYgdGhlIGJ1aWx0LWluIGF1ZGlvIHBsYXllcnMgb2YgdGhlIEd1YWNhbW9sZSBjbGllbnQgc2hvdWxkIGJlXHJcbiAgICAgKiAgICAgdXNlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmF1ZGlvID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW4gYSB2aWRlbyBzdHJlYW0gaXMgY3JlYXRlZC4gVGhlIHN0cmVhbSBwcm92aWRlZCB0byB0aGlzIGV2ZW50XHJcbiAgICAgKiBoYW5kbGVyIHdpbGwgY29udGFpbiBpdHMgb3duIGV2ZW50IGhhbmRsZXJzIGZvciByZWNlaXZlZCBkYXRhLlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuSW5wdXRTdHJlYW19IHN0cmVhbVxyXG4gICAgICogICAgIFRoZSBzdHJlYW0gdGhhdCB3aWxsIHJlY2VpdmUgdmlkZW8gZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuRGlzcGxheS5WaXNpYmxlTGF5ZXJ9IGxheWVyXHJcbiAgICAgKiAgICAgVGhlIGRlc3RpbmF0aW9uIGxheWVyIG9uIHdoaWNoIHRoZSByZWNlaXZlZCB2aWRlbyBkYXRhIHNob3VsZCBiZVxyXG4gICAgICogICAgIHBsYXllZC4gSXQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBHdWFjYW1vbGUuVmlkZW9QbGF5ZXJcclxuICAgICAqICAgICBpbXBsZW1lbnRhdGlvbiB0byBwbGF5IHRoZSByZWNlaXZlZCBkYXRhIHdpdGhpbiB0aGlzIGxheWVyLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZVxyXG4gICAgICogICAgIFRoZSBtaW1ldHlwZSBvZiB0aGUgdmlkZW8gZGF0YSB3aGljaCB3aWxsIGJlIHJlY2VpdmVkLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm4ge0d1YWNhbW9sZS5WaWRlb1BsYXllcn1cclxuICAgICAqICAgICBBbiBvYmplY3Qgd2hpY2ggaW1wbGVtZW50cyB0aGUgR3VhY2Ftb2xlLlZpZGVvUGxheWVyIGludGVyZmFjZSBhbmRcclxuICAgICAqICAgICBoYXMgYmVlbiBpbml0aWFsaWVkIHRvIHBsYXkgdGhlIGRhdGEgaW4gdGhlIHByb3ZpZGVkIHN0cmVhbSwgb3IgbnVsbFxyXG4gICAgICogICAgIGlmIHRoZSBidWlsdC1pbiB2aWRlbyBwbGF5ZXJzIG9mIHRoZSBHdWFjYW1vbGUgY2xpZW50IHNob3VsZCBiZVxyXG4gICAgICogICAgIHVzZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub252aWRlbyA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuIHRoZSBjbGlwYm9hcmQgb2YgdGhlIHJlbW90ZSBjbGllbnQgaXMgY2hhbmdpbmcuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuSW5wdXRTdHJlYW19IHN0cmVhbSBUaGUgc3RyZWFtIHRoYXQgd2lsbCByZWNlaXZlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXBib2FyZCBkYXRhIGZyb20gdGhlIHNlcnZlci5cclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZSBUaGUgbWltZXR5cGUgb2YgdGhlIGRhdGEgd2hpY2ggd2lsbCBiZSByZWNlaXZlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmNsaXBib2FyZCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuIGEgZmlsZSBzdHJlYW0gaXMgY3JlYXRlZC4gVGhlIHN0cmVhbSBwcm92aWRlZCB0byB0aGlzIGV2ZW50XHJcbiAgICAgKiBoYW5kbGVyIHdpbGwgY29udGFpbiBpdHMgb3duIGV2ZW50IGhhbmRsZXJzIGZvciByZWNlaXZlZCBkYXRhLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLklucHV0U3RyZWFtfSBzdHJlYW0gVGhlIHN0cmVhbSB0aGF0IHdpbGwgcmVjZWl2ZSBkYXRhXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gdGhlIHNlcnZlci5cclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZSBUaGUgbWltZXR5cGUgb2YgdGhlIGZpbGUgcmVjZWl2ZWQuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWUgVGhlIG5hbWUgb2YgdGhlIGZpbGUgcmVjZWl2ZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25maWxlID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW4gYSBmaWxlc3lzdGVtIG9iamVjdCBpcyBjcmVhdGVkLiBUaGUgb2JqZWN0IHByb3ZpZGVkIHRvIHRoaXNcclxuICAgICAqIGV2ZW50IGhhbmRsZXIgd2lsbCBjb250YWluIGl0cyBvd24gZXZlbnQgaGFuZGxlcnMgYW5kIGZ1bmN0aW9ucyBmb3JcclxuICAgICAqIHJlcXVlc3RpbmcgYW5kIGhhbmRsaW5nIGRhdGEuXHJcbiAgICAgKlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5PYmplY3R9IG9iamVjdFxyXG4gICAgICogICAgIFRoZSBjcmVhdGVkIGZpbGVzeXN0ZW0gb2JqZWN0LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXHJcbiAgICAgKiAgICAgVGhlIG5hbWUgb2YgdGhlIGZpbGVzeXN0ZW0uXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25maWxlc3lzdGVtID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW4gYSBwaXBlIHN0cmVhbSBpcyBjcmVhdGVkLiBUaGUgc3RyZWFtIHByb3ZpZGVkIHRvIHRoaXMgZXZlbnRcclxuICAgICAqIGhhbmRsZXIgd2lsbCBjb250YWluIGl0cyBvd24gZXZlbnQgaGFuZGxlcnMgZm9yIHJlY2VpdmVkIGRhdGE7XHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuSW5wdXRTdHJlYW19IHN0cmVhbSBUaGUgc3RyZWFtIHRoYXQgd2lsbCByZWNlaXZlIGRhdGFcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSB0aGUgc2VydmVyLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlIFRoZSBtaW1ldHlwZSBvZiB0aGUgZGF0YSB3aGljaCB3aWxsIGJlIHJlY2VpdmVkLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIHBpcGUuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25waXBlID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIGEgc3luYyBpbnN0cnVjdGlvbiBpcyByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXIsIGluZGljYXRpbmdcclxuICAgICAqIHRoYXQgdGhlIHNlcnZlciBpcyBmaW5pc2hlZCBwcm9jZXNzaW5nIGFueSBpbnB1dCBmcm9tIHRoZSBjbGllbnQgYW5kXHJcbiAgICAgKiBoYXMgc2VudCBhbnkgcmVzdWx0cy5cclxuICAgICAqIFxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZXN0YW1wIFRoZSB0aW1lc3RhbXAgYXNzb2NpYXRlZCB3aXRoIHRoZSBzeW5jXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RydWN0aW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uc3luYyA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBsYXllciB3aXRoIHRoZSBnaXZlbiBpbmRleCwgY3JlYXRpbmcgaXQgaWYgbmVjZXNzYXJ5LlxyXG4gICAgICogUG9zaXRpdmUgaW5kaWNlcyByZWZlciB0byB2aXNpYmxlIGxheWVycywgYW4gaW5kZXggb2YgemVybyByZWZlcnMgdG9cclxuICAgICAqIHRoZSBkZWZhdWx0IGxheWVyLCBhbmQgbmVnYXRpdmUgaW5kaWNlcyByZWZlciB0byBidWZmZXJzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcclxuICAgICAqICAgICBUaGUgaW5kZXggb2YgdGhlIGxheWVyIHRvIHJldHJpZXZlLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm4ge0d1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcnxHdWFjYW1vbGUuTGF5ZXJ9XHJcbiAgICAgKiAgICAgVGhlIGxheWVyIGhhdmluZyB0aGUgZ2l2ZW4gaW5kZXguXHJcbiAgICAgKi9cclxuICAgIHZhciBnZXRMYXllciA9IGZ1bmN0aW9uIGdldExheWVyKGluZGV4KSB7XHJcblxyXG4gICAgICAgIC8vIEdldCBsYXllciwgY3JlYXRlIGlmIG5lY2Vzc2FyeVxyXG4gICAgICAgIHZhciBsYXllciA9IGxheWVyc1tpbmRleF07XHJcbiAgICAgICAgaWYgKCFsYXllcikge1xyXG5cclxuICAgICAgICAgICAgLy8gQ3JlYXRlIGxheWVyIGJhc2VkIG9uIGluZGV4XHJcbiAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMClcclxuICAgICAgICAgICAgICAgIGxheWVyID0gZGlzcGxheS5nZXREZWZhdWx0TGF5ZXIoKTtcclxuICAgICAgICAgICAgZWxzZSBpZiAoaW5kZXggPiAwKVxyXG4gICAgICAgICAgICAgICAgbGF5ZXIgPSBkaXNwbGF5LmNyZWF0ZUxheWVyKCk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIGxheWVyID0gZGlzcGxheS5jcmVhdGVCdWZmZXIoKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyBBZGQgbmV3IGxheWVyXHJcbiAgICAgICAgICAgIGxheWVyc1tpbmRleF0gPSBsYXllcjtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbGF5ZXI7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGluZGV4IHBhc3NlZCB0byBnZXRMYXllcigpIHdoZW4gdGhlIGdpdmVuIGxheWVyIHdhcyBjcmVhdGVkLlxyXG4gICAgICogUG9zaXRpdmUgaW5kaWNlcyByZWZlciB0byB2aXNpYmxlIGxheWVycywgYW4gaW5kZXggb2YgemVybyByZWZlcnMgdG8gdGhlXHJcbiAgICAgKiBkZWZhdWx0IGxheWVyLCBhbmQgbmVnYXRpdmUgaW5kaWNlcyByZWZlciB0byBidWZmZXJzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkRpc3BsYXkuVmlzaWJsZUxheWVyfEd1YWNhbW9sZS5MYXllcn0gbGF5ZXJcclxuICAgICAqICAgICBUaGUgbGF5ZXIgd2hvc2UgaW5kZXggc2hvdWxkIGJlIGRldGVybWluZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge051bWJlcn1cclxuICAgICAqICAgICBUaGUgaW5kZXggb2YgdGhlIGdpdmVuIGxheWVyLCBvciBudWxsIGlmIG5vIHN1Y2ggbGF5ZXIgaXMgYXNzb2NpYXRlZFxyXG4gICAgICogICAgIHdpdGggdGhpcyBjbGllbnQuXHJcbiAgICAgKi9cclxuICAgIHZhciBnZXRMYXllckluZGV4ID0gZnVuY3Rpb24gZ2V0TGF5ZXJJbmRleChsYXllcikge1xyXG5cclxuICAgICAgICAvLyBBdm9pZCBzZWFyY2hpbmcgaWYgdGhlcmUgY2xlYXJseSBpcyBubyBzdWNoIGxheWVyXHJcbiAgICAgICAgaWYgKCFsYXllcilcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIC8vIFNlYXJjaCB0aHJvdWdoIGVhY2ggbGF5ZXIsIHJldHVybmluZyB0aGUgaW5kZXggb2YgdGhlIGdpdmVuIGxheWVyXHJcbiAgICAgICAgLy8gb25jZSBmb3VuZFxyXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBsYXllcnMpIHtcclxuICAgICAgICAgICAgaWYgKGxheWVyID09PSBsYXllcnNba2V5XSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludChrZXkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBubyBzdWNoIGluZGV4XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBnZXRQYXJzZXIoaW5kZXgpIHtcclxuXHJcbiAgICAgICAgdmFyIHBhcnNlciA9IHBhcnNlcnNbaW5kZXhdO1xyXG5cclxuICAgICAgICAvLyBJZiBwYXJzZXIgbm90IHlldCBjcmVhdGVkLCBjcmVhdGUgaXQsIGFuZCB0aWUgdG8gdGhlXHJcbiAgICAgICAgLy8gb25pbnN0cnVjdGlvbiBoYW5kbGVyIG9mIHRoZSB0dW5uZWwuXHJcbiAgICAgICAgaWYgKHBhcnNlciA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHBhcnNlciA9IHBhcnNlcnNbaW5kZXhdID0gbmV3IEd1YWNhbW9sZS5QYXJzZXIoKTtcclxuICAgICAgICAgICAgcGFyc2VyLm9uaW5zdHJ1Y3Rpb24gPSB0dW5uZWwub25pbnN0cnVjdGlvbjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBwYXJzZXI7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlcnMgZm9yIGFsbCBkZWZpbmVkIGxheWVyIHByb3BlcnRpZXMuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgbGF5ZXJQcm9wZXJ0eUhhbmRsZXJzID0ge1xyXG5cclxuICAgICAgICBcIm1pdGVyLWxpbWl0XCI6IGZ1bmN0aW9uKGxheWVyLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICBkaXNwbGF5LnNldE1pdGVyTGltaXQobGF5ZXIsIHBhcnNlRmxvYXQodmFsdWUpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuICAgIFxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVycyBmb3IgYWxsIGluc3RydWN0aW9uIG9wY29kZXMgcmVjZWl2YWJsZSBieSBhIEd1YWNhbW9sZSBwcm90b2NvbFxyXG4gICAgICogY2xpZW50LlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGluc3RydWN0aW9uSGFuZGxlcnMgPSB7XHJcblxyXG4gICAgICAgIFwiYWNrXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBzdHJlYW1faW5kZXggPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIHJlYXNvbiA9IHBhcmFtZXRlcnNbMV07XHJcbiAgICAgICAgICAgIHZhciBjb2RlID0gcGFyc2VJbnQocGFyYW1ldGVyc1syXSk7XHJcblxyXG4gICAgICAgICAgICAvLyBHZXQgc3RyZWFtXHJcbiAgICAgICAgICAgIHZhciBzdHJlYW0gPSBvdXRwdXRfc3RyZWFtc1tzdHJlYW1faW5kZXhdO1xyXG4gICAgICAgICAgICBpZiAoc3RyZWFtKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU2lnbmFsIGFjayBpZiBoYW5kbGVyIGRlZmluZWRcclxuICAgICAgICAgICAgICAgIGlmIChzdHJlYW0ub25hY2spXHJcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLm9uYWNrKG5ldyBHdWFjYW1vbGUuU3RhdHVzKGNvZGUsIHJlYXNvbikpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIElmIGNvZGUgaXMgYW4gZXJyb3IsIGludmFsaWRhdGUgc3RyZWFtIGlmIG5vdCBhbHJlYWR5XHJcbiAgICAgICAgICAgICAgICAvLyBpbnZhbGlkYXRlZCBieSBvbmFjayBoYW5kbGVyXHJcbiAgICAgICAgICAgICAgICBpZiAoY29kZSA+PSAweDAxMDAgJiYgb3V0cHV0X3N0cmVhbXNbc3RyZWFtX2luZGV4XSA9PT0gc3RyZWFtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtX2luZGljZXMuZnJlZShzdHJlYW1faW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBvdXRwdXRfc3RyZWFtc1tzdHJlYW1faW5kZXhdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImFyY1wiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihwYXJzZUludChwYXJhbWV0ZXJzWzBdKSk7XHJcbiAgICAgICAgICAgIHZhciB4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcbiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VJbnQocGFyYW1ldGVyc1syXSk7XHJcbiAgICAgICAgICAgIHZhciByYWRpdXMgPSBwYXJzZUludChwYXJhbWV0ZXJzWzNdKTtcclxuICAgICAgICAgICAgdmFyIHN0YXJ0QW5nbGUgPSBwYXJzZUZsb2F0KHBhcmFtZXRlcnNbNF0pO1xyXG4gICAgICAgICAgICB2YXIgZW5kQW5nbGUgPSBwYXJzZUZsb2F0KHBhcmFtZXRlcnNbNV0pO1xyXG4gICAgICAgICAgICB2YXIgbmVnYXRpdmUgPSBwYXJzZUludChwYXJhbWV0ZXJzWzZdKTtcclxuXHJcbiAgICAgICAgICAgIGRpc3BsYXkuYXJjKGxheWVyLCB4LCB5LCByYWRpdXMsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBuZWdhdGl2ZSAhPSAwKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJhdWRpb1wiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RyZWFtX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBtaW1ldHlwZSA9IHBhcmFtZXRlcnNbMV07XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGUgc3RyZWFtIFxyXG4gICAgICAgICAgICB2YXIgc3RyZWFtID0gc3RyZWFtc1tzdHJlYW1faW5kZXhdID1cclxuICAgICAgICAgICAgICAgICAgICBuZXcgR3VhY2Ftb2xlLklucHV0U3RyZWFtKGd1YWNfY2xpZW50LCBzdHJlYW1faW5kZXgpO1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IHBsYXllciBpbnN0YW5jZSB2aWEgY2FsbGJhY2tcclxuICAgICAgICAgICAgdmFyIGF1ZGlvUGxheWVyID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKGd1YWNfY2xpZW50Lm9uYXVkaW8pXHJcbiAgICAgICAgICAgICAgICBhdWRpb1BsYXllciA9IGd1YWNfY2xpZW50Lm9uYXVkaW8oc3RyZWFtLCBtaW1ldHlwZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBJZiB1bnN1Y2Nlc3NmdWwsIHRyeSB0byB1c2UgYSBkZWZhdWx0IGltcGxlbWVudGF0aW9uXHJcbiAgICAgICAgICAgIGlmICghYXVkaW9QbGF5ZXIpXHJcbiAgICAgICAgICAgICAgICBhdWRpb1BsYXllciA9IEd1YWNhbW9sZS5BdWRpb1BsYXllci5nZXRJbnN0YW5jZShzdHJlYW0sIG1pbWV0eXBlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIHdlIGhhdmUgc3VjY2Vzc2Z1bGx5IHJldHJpZXZlZCBhbiBhdWRpbyBwbGF5ZXIsIHNlbmQgc3VjY2VzcyByZXNwb25zZVxyXG4gICAgICAgICAgICBpZiAoYXVkaW9QbGF5ZXIpIHtcclxuICAgICAgICAgICAgICAgIGF1ZGlvUGxheWVyc1tzdHJlYW1faW5kZXhdID0gYXVkaW9QbGF5ZXI7XHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5zZW5kQWNrKHN0cmVhbV9pbmRleCwgXCJPS1wiLCAweDAwMDApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBPdGhlcndpc2UsIG1pbWV0eXBlIG11c3QgYmUgdW5zdXBwb3J0ZWRcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgZ3VhY19jbGllbnQuc2VuZEFjayhzdHJlYW1faW5kZXgsIFwiQkFEIFRZUEVcIiwgMHgwMzBGKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJibG9iXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIEdldCBzdHJlYW0gXHJcbiAgICAgICAgICAgIHZhciBzdHJlYW1faW5kZXggPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIGRhdGEgPSBwYXJhbWV0ZXJzWzFdO1xyXG4gICAgICAgICAgICB2YXIgc3RyZWFtID0gc3RyZWFtc1tzdHJlYW1faW5kZXhdO1xyXG5cclxuICAgICAgICAgICAgLy8gV3JpdGUgZGF0YVxyXG4gICAgICAgICAgICBpZiAoc3RyZWFtICYmIHN0cmVhbS5vbmJsb2IpXHJcbiAgICAgICAgICAgICAgICBzdHJlYW0ub25ibG9iKGRhdGEpO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImJvZHlcIiA6IGZ1bmN0aW9uIGhhbmRsZUJvZHkocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IG9iamVjdFxyXG4gICAgICAgICAgICB2YXIgb2JqZWN0SW5kZXggPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIG9iamVjdCA9IG9iamVjdHNbb2JqZWN0SW5kZXhdO1xyXG5cclxuICAgICAgICAgICAgdmFyIHN0cmVhbUluZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcbiAgICAgICAgICAgIHZhciBtaW1ldHlwZSA9IHBhcmFtZXRlcnNbMl07XHJcbiAgICAgICAgICAgIHZhciBuYW1lID0gcGFyYW1ldGVyc1szXTtcclxuXHJcbiAgICAgICAgICAgIC8vIENyZWF0ZSBzdHJlYW0gaWYgaGFuZGxlciBkZWZpbmVkXHJcbiAgICAgICAgICAgIGlmIChvYmplY3QgJiYgb2JqZWN0Lm9uYm9keSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0cmVhbSA9IHN0cmVhbXNbc3RyZWFtSW5kZXhdID0gbmV3IEd1YWNhbW9sZS5JbnB1dFN0cmVhbShndWFjX2NsaWVudCwgc3RyZWFtSW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9uYm9keShzdHJlYW0sIG1pbWV0eXBlLCBuYW1lKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB1bnN1cHBvcnRlZFxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5zZW5kQWNrKHN0cmVhbUluZGV4LCBcIlJlY2VpcHQgb2YgYm9keSB1bnN1cHBvcnRlZFwiLCAweDAxMDApO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImNmaWxsXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBjaGFubmVsTWFzayA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMF0pO1xyXG4gICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihwYXJzZUludChwYXJhbWV0ZXJzWzFdKSk7XHJcbiAgICAgICAgICAgIHZhciByID0gcGFyc2VJbnQocGFyYW1ldGVyc1syXSk7XHJcbiAgICAgICAgICAgIHZhciBnID0gcGFyc2VJbnQocGFyYW1ldGVyc1szXSk7XHJcbiAgICAgICAgICAgIHZhciBiID0gcGFyc2VJbnQocGFyYW1ldGVyc1s0XSk7XHJcbiAgICAgICAgICAgIHZhciBhID0gcGFyc2VJbnQocGFyYW1ldGVyc1s1XSk7XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LnNldENoYW5uZWxNYXNrKGxheWVyLCBjaGFubmVsTWFzayk7XHJcbiAgICAgICAgICAgIGRpc3BsYXkuZmlsbENvbG9yKGxheWVyLCByLCBnLCBiLCBhKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJjbGlwXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMF0pKTtcclxuXHJcbiAgICAgICAgICAgIGRpc3BsYXkuY2xpcChsYXllcik7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwiY2xpcGJvYXJkXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBzdHJlYW1faW5kZXggPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIG1pbWV0eXBlID0gcGFyYW1ldGVyc1sxXTtcclxuXHJcbiAgICAgICAgICAgIC8vIENyZWF0ZSBzdHJlYW0gXHJcbiAgICAgICAgICAgIGlmIChndWFjX2NsaWVudC5vbmNsaXBib2FyZCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0cmVhbSA9IHN0cmVhbXNbc3RyZWFtX2luZGV4XSA9IG5ldyBHdWFjYW1vbGUuSW5wdXRTdHJlYW0oZ3VhY19jbGllbnQsIHN0cmVhbV9pbmRleCk7XHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5vbmNsaXBib2FyZChzdHJlYW0sIG1pbWV0eXBlKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB1bnN1cHBvcnRlZFxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5zZW5kQWNrKHN0cmVhbV9pbmRleCwgXCJDbGlwYm9hcmQgdW5zdXBwb3J0ZWRcIiwgMHgwMTAwKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJjbG9zZVwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihwYXJzZUludChwYXJhbWV0ZXJzWzBdKSk7XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LmNsb3NlKGxheWVyKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJjb3B5XCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBzcmNMID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG4gICAgICAgICAgICB2YXIgc3JjWCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pO1xyXG4gICAgICAgICAgICB2YXIgc3JjWSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMl0pO1xyXG4gICAgICAgICAgICB2YXIgc3JjV2lkdGggPSBwYXJzZUludChwYXJhbWV0ZXJzWzNdKTtcclxuICAgICAgICAgICAgdmFyIHNyY0hlaWdodCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbNF0pO1xyXG4gICAgICAgICAgICB2YXIgY2hhbm5lbE1hc2sgPSBwYXJzZUludChwYXJhbWV0ZXJzWzVdKTtcclxuICAgICAgICAgICAgdmFyIGRzdEwgPSBnZXRMYXllcihwYXJzZUludChwYXJhbWV0ZXJzWzZdKSk7XHJcbiAgICAgICAgICAgIHZhciBkc3RYID0gcGFyc2VJbnQocGFyYW1ldGVyc1s3XSk7XHJcbiAgICAgICAgICAgIHZhciBkc3RZID0gcGFyc2VJbnQocGFyYW1ldGVyc1s4XSk7XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LnNldENoYW5uZWxNYXNrKGRzdEwsIGNoYW5uZWxNYXNrKTtcclxuICAgICAgICAgICAgZGlzcGxheS5jb3B5KHNyY0wsIHNyY1gsIHNyY1ksIHNyY1dpZHRoLCBzcmNIZWlnaHQsIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgZHN0TCwgZHN0WCwgZHN0WSk7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwiY3N0cm9rZVwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgY2hhbm5lbE1hc2sgPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1sxXSkpO1xyXG4gICAgICAgICAgICB2YXIgY2FwID0gbGluZUNhcFtwYXJzZUludChwYXJhbWV0ZXJzWzJdKV07XHJcbiAgICAgICAgICAgIHZhciBqb2luID0gbGluZUpvaW5bcGFyc2VJbnQocGFyYW1ldGVyc1szXSldO1xyXG4gICAgICAgICAgICB2YXIgdGhpY2tuZXNzID0gcGFyc2VJbnQocGFyYW1ldGVyc1s0XSk7XHJcbiAgICAgICAgICAgIHZhciByID0gcGFyc2VJbnQocGFyYW1ldGVyc1s1XSk7XHJcbiAgICAgICAgICAgIHZhciBnID0gcGFyc2VJbnQocGFyYW1ldGVyc1s2XSk7XHJcbiAgICAgICAgICAgIHZhciBiID0gcGFyc2VJbnQocGFyYW1ldGVyc1s3XSk7XHJcbiAgICAgICAgICAgIHZhciBhID0gcGFyc2VJbnQocGFyYW1ldGVyc1s4XSk7XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LnNldENoYW5uZWxNYXNrKGxheWVyLCBjaGFubmVsTWFzayk7XHJcbiAgICAgICAgICAgIGRpc3BsYXkuc3Ryb2tlQ29sb3IobGF5ZXIsIGNhcCwgam9pbiwgdGhpY2tuZXNzLCByLCBnLCBiLCBhKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJjdXJzb3JcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGN1cnNvckhvdHNwb3RYID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBjdXJzb3JIb3RzcG90WSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pO1xyXG4gICAgICAgICAgICB2YXIgc3JjTCA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMl0pKTtcclxuICAgICAgICAgICAgdmFyIHNyY1ggPSBwYXJzZUludChwYXJhbWV0ZXJzWzNdKTtcclxuICAgICAgICAgICAgdmFyIHNyY1kgPSBwYXJzZUludChwYXJhbWV0ZXJzWzRdKTtcclxuICAgICAgICAgICAgdmFyIHNyY1dpZHRoID0gcGFyc2VJbnQocGFyYW1ldGVyc1s1XSk7XHJcbiAgICAgICAgICAgIHZhciBzcmNIZWlnaHQgPSBwYXJzZUludChwYXJhbWV0ZXJzWzZdKTtcclxuXHJcbiAgICAgICAgICAgIGRpc3BsYXkuc2V0Q3Vyc29yKGN1cnNvckhvdHNwb3RYLCBjdXJzb3JIb3RzcG90WSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjTCwgc3JjWCwgc3JjWSwgc3JjV2lkdGgsIHNyY0hlaWdodCk7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwiY3VydmVcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG4gICAgICAgICAgICB2YXIgY3AxeCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pO1xyXG4gICAgICAgICAgICB2YXIgY3AxeSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMl0pO1xyXG4gICAgICAgICAgICB2YXIgY3AyeCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbM10pO1xyXG4gICAgICAgICAgICB2YXIgY3AyeSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbNF0pO1xyXG4gICAgICAgICAgICB2YXIgeCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbNV0pO1xyXG4gICAgICAgICAgICB2YXIgeSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbNl0pO1xyXG5cclxuICAgICAgICAgICAgZGlzcGxheS5jdXJ2ZVRvKGxheWVyLCBjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJkaXNjb25uZWN0XCIgOiBmdW5jdGlvbiBoYW5kbGVEaXNjb25uZWN0KHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIEV4cGxpY2l0bHkgdGVhciBkb3duIGNvbm5lY3Rpb25cclxuICAgICAgICAgICAgZ3VhY19jbGllbnQuZGlzY29ubmVjdCgpO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImRpc3Bvc2VcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgdmFyIGxheWVyX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcblxyXG4gICAgICAgICAgICAvLyBJZiB2aXNpYmxlIGxheWVyLCByZW1vdmUgZnJvbSBwYXJlbnRcclxuICAgICAgICAgICAgaWYgKGxheWVyX2luZGV4ID4gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIHBhcmVudFxyXG4gICAgICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIobGF5ZXJfaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgZGlzcGxheS5kaXNwb3NlKGxheWVyKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBEZWxldGUgcmVmZXJlbmNlXHJcbiAgICAgICAgICAgICAgICBkZWxldGUgbGF5ZXJzW2xheWVyX2luZGV4XTtcclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIGJ1ZmZlciwganVzdCBkZWxldGUgcmVmZXJlbmNlXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGxheWVyX2luZGV4IDwgMClcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBsYXllcnNbbGF5ZXJfaW5kZXhdO1xyXG5cclxuICAgICAgICAgICAgLy8gQXR0ZW1wdGluZyB0byBkaXNwb3NlIHRoZSByb290IGxheWVyIGN1cnJlbnRseSBoYXMgbm8gZWZmZWN0LlxyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImRpc3RvcnRcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBhID0gcGFyc2VGbG9hdChwYXJhbWV0ZXJzWzFdKTtcclxuICAgICAgICAgICAgdmFyIGIgPSBwYXJzZUZsb2F0KHBhcmFtZXRlcnNbMl0pO1xyXG4gICAgICAgICAgICB2YXIgYyA9IHBhcnNlRmxvYXQocGFyYW1ldGVyc1szXSk7XHJcbiAgICAgICAgICAgIHZhciBkID0gcGFyc2VGbG9hdChwYXJhbWV0ZXJzWzRdKTtcclxuICAgICAgICAgICAgdmFyIGUgPSBwYXJzZUZsb2F0KHBhcmFtZXRlcnNbNV0pO1xyXG4gICAgICAgICAgICB2YXIgZiA9IHBhcnNlRmxvYXQocGFyYW1ldGVyc1s2XSk7XHJcblxyXG4gICAgICAgICAgICAvLyBPbmx5IHZhbGlkIGZvciB2aXNpYmxlIGxheWVycyAobm90IGJ1ZmZlcnMpXHJcbiAgICAgICAgICAgIGlmIChsYXllcl9pbmRleCA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihsYXllcl9pbmRleCk7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5LmRpc3RvcnQobGF5ZXIsIGEsIGIsIGMsIGQsIGUsIGYpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0sXHJcbiBcclxuICAgICAgICBcImVycm9yXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZWFzb24gPSBwYXJhbWV0ZXJzWzBdO1xyXG4gICAgICAgICAgICB2YXIgY29kZSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsbCBoYW5kbGVyIGlmIGRlZmluZWRcclxuICAgICAgICAgICAgaWYgKGd1YWNfY2xpZW50Lm9uZXJyb3IpXHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5vbmVycm9yKG5ldyBHdWFjYW1vbGUuU3RhdHVzKGNvZGUsIHJlYXNvbikpO1xyXG5cclxuICAgICAgICAgICAgZ3VhY19jbGllbnQuZGlzY29ubmVjdCgpO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImVuZFwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RyZWFtX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcblxyXG4gICAgICAgICAgICAvLyBHZXQgc3RyZWFtXHJcbiAgICAgICAgICAgIHZhciBzdHJlYW0gPSBzdHJlYW1zW3N0cmVhbV9pbmRleF07XHJcbiAgICAgICAgICAgIGlmIChzdHJlYW0pIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTaWduYWwgZW5kIG9mIHN0cmVhbSBpZiBoYW5kbGVyIGRlZmluZWRcclxuICAgICAgICAgICAgICAgIGlmIChzdHJlYW0ub25lbmQpXHJcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLm9uZW5kKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSW52YWxpZGF0ZSBzdHJlYW1cclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBzdHJlYW1zW3N0cmVhbV9pbmRleF07XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwiZmlsZVwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RyZWFtX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBtaW1ldHlwZSA9IHBhcmFtZXRlcnNbMV07XHJcbiAgICAgICAgICAgIHZhciBmaWxlbmFtZSA9IHBhcmFtZXRlcnNbMl07XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGUgc3RyZWFtIFxyXG4gICAgICAgICAgICBpZiAoZ3VhY19jbGllbnQub25maWxlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3RyZWFtID0gc3RyZWFtc1tzdHJlYW1faW5kZXhdID0gbmV3IEd1YWNhbW9sZS5JbnB1dFN0cmVhbShndWFjX2NsaWVudCwgc3RyZWFtX2luZGV4KTtcclxuICAgICAgICAgICAgICAgIGd1YWNfY2xpZW50Lm9uZmlsZShzdHJlYW0sIG1pbWV0eXBlLCBmaWxlbmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgdW5zdXBwb3J0ZWRcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgZ3VhY19jbGllbnQuc2VuZEFjayhzdHJlYW1faW5kZXgsIFwiRmlsZSB0cmFuc2ZlciB1bnN1cHBvcnRlZFwiLCAweDAxMDApO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImZpbGVzeXN0ZW1cIiA6IGZ1bmN0aW9uIGhhbmRsZUZpbGVzeXN0ZW0ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIG9iamVjdEluZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBuYW1lID0gcGFyYW1ldGVyc1sxXTtcclxuXHJcbiAgICAgICAgICAgIC8vIENyZWF0ZSBvYmplY3QsIGlmIHN1cHBvcnRlZFxyXG4gICAgICAgICAgICBpZiAoZ3VhY19jbGllbnQub25maWxlc3lzdGVtKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgb2JqZWN0ID0gb2JqZWN0c1tvYmplY3RJbmRleF0gPSBuZXcgR3VhY2Ftb2xlLk9iamVjdChndWFjX2NsaWVudCwgb2JqZWN0SW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgZ3VhY19jbGllbnQub25maWxlc3lzdGVtKG9iamVjdCwgbmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIHVuc3VwcG9ydGVkLCBzaW1wbHkgaWdub3JlIHRoZSBhdmFpbGFiaWxpdHkgb2YgdGhlIGZpbGVzeXN0ZW1cclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJpZGVudGl0eVwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihwYXJzZUludChwYXJhbWV0ZXJzWzBdKSk7XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LnNldFRyYW5zZm9ybShsYXllciwgMSwgMCwgMCwgMSwgMCwgMCk7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwiaW1nXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBzdHJlYW1faW5kZXggPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIGNoYW5uZWxNYXNrID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMl0pKTtcclxuICAgICAgICAgICAgdmFyIG1pbWV0eXBlID0gcGFyYW1ldGVyc1szXTtcclxuICAgICAgICAgICAgdmFyIHggPSBwYXJzZUludChwYXJhbWV0ZXJzWzRdKTtcclxuICAgICAgICAgICAgdmFyIHkgPSBwYXJzZUludChwYXJhbWV0ZXJzWzVdKTtcclxuXHJcbiAgICAgICAgICAgIC8vIENyZWF0ZSBzdHJlYW1cclxuICAgICAgICAgICAgdmFyIHN0cmVhbSA9IHN0cmVhbXNbc3RyZWFtX2luZGV4XSA9IG5ldyBHdWFjYW1vbGUuSW5wdXRTdHJlYW0oZ3VhY19jbGllbnQsIHN0cmVhbV9pbmRleCk7XHJcbiAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgR3VhY2Ftb2xlLkRhdGFVUklSZWFkZXIoc3RyZWFtLCBtaW1ldHlwZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBEcmF3IGltYWdlIHdoZW4gc3RyZWFtIGlzIGNvbXBsZXRlXHJcbiAgICAgICAgICAgIHJlYWRlci5vbmVuZCA9IGZ1bmN0aW9uIGRyYXdJbWFnZUJsb2IoKSB7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5LnNldENoYW5uZWxNYXNrKGxheWVyLCBjaGFubmVsTWFzayk7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5LmRyYXcobGF5ZXIsIHgsIHksIHJlYWRlci5nZXRVUkkoKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwianBlZ1wiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgY2hhbm5lbE1hc2sgPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1sxXSkpO1xyXG4gICAgICAgICAgICB2YXIgeCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMl0pO1xyXG4gICAgICAgICAgICB2YXIgeSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbM10pO1xyXG4gICAgICAgICAgICB2YXIgZGF0YSA9IHBhcmFtZXRlcnNbNF07XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LnNldENoYW5uZWxNYXNrKGxheWVyLCBjaGFubmVsTWFzayk7XHJcbiAgICAgICAgICAgIGRpc3BsYXkuZHJhdyhsYXllciwgeCwgeSwgXCJkYXRhOmltYWdlL2pwZWc7YmFzZTY0LFwiICsgZGF0YSk7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwibGZpbGxcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGNoYW5uZWxNYXNrID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pKTtcclxuICAgICAgICAgICAgdmFyIHNyY0xheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1syXSkpO1xyXG5cclxuICAgICAgICAgICAgZGlzcGxheS5zZXRDaGFubmVsTWFzayhsYXllciwgY2hhbm5lbE1hc2spO1xyXG4gICAgICAgICAgICBkaXNwbGF5LmZpbGxMYXllcihsYXllciwgc3JjTGF5ZXIpO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImxpbmVcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG4gICAgICAgICAgICB2YXIgeCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pO1xyXG4gICAgICAgICAgICB2YXIgeSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMl0pO1xyXG5cclxuICAgICAgICAgICAgZGlzcGxheS5saW5lVG8obGF5ZXIsIHgsIHkpO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcImxzdHJva2VcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGNoYW5uZWxNYXNrID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pKTtcclxuICAgICAgICAgICAgdmFyIHNyY0xheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1syXSkpO1xyXG5cclxuICAgICAgICAgICAgZGlzcGxheS5zZXRDaGFubmVsTWFzayhsYXllciwgY2hhbm5lbE1hc2spO1xyXG4gICAgICAgICAgICBkaXNwbGF5LnN0cm9rZUxheWVyKGxheWVyLCBzcmNMYXllcik7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwibW91c2VcIiA6IGZ1bmN0aW9uIGhhbmRsZU1vdXNlKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciB4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcblxyXG4gICAgICAgICAgICAvLyBEaXNwbGF5IGFuZCBtb3ZlIHNvZnR3YXJlIGN1cnNvciB0byByZWNlaXZlZCBjb29yZGluYXRlc1xyXG4gICAgICAgICAgICBkaXNwbGF5LnNob3dDdXJzb3IodHJ1ZSk7XHJcbiAgICAgICAgICAgIGRpc3BsYXkubW92ZUN1cnNvcih4LCB5KTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJtb3ZlXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHZhciBsYXllcl9pbmRleCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMF0pO1xyXG4gICAgICAgICAgICB2YXIgcGFyZW50X2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcbiAgICAgICAgICAgIHZhciB4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1syXSk7XHJcbiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VJbnQocGFyYW1ldGVyc1szXSk7XHJcbiAgICAgICAgICAgIHZhciB6ID0gcGFyc2VJbnQocGFyYW1ldGVyc1s0XSk7XHJcblxyXG4gICAgICAgICAgICAvLyBPbmx5IHZhbGlkIGZvciBub24tZGVmYXVsdCBsYXllcnNcclxuICAgICAgICAgICAgaWYgKGxheWVyX2luZGV4ID4gMCAmJiBwYXJlbnRfaW5kZXggPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIobGF5ZXJfaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IGdldExheWVyKHBhcmVudF9pbmRleCk7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5Lm1vdmUobGF5ZXIsIHBhcmVudCwgeCwgeSwgeik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJuYW1lXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuICAgICAgICAgICAgaWYgKGd1YWNfY2xpZW50Lm9ubmFtZSkgZ3VhY19jbGllbnQub25uYW1lKHBhcmFtZXRlcnNbMF0pO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwibmVzdFwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcbiAgICAgICAgICAgIHZhciBwYXJzZXIgPSBnZXRQYXJzZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG4gICAgICAgICAgICBwYXJzZXIucmVjZWl2ZShwYXJhbWV0ZXJzWzFdKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcInBpcGVcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIHN0cmVhbV9pbmRleCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMF0pO1xyXG4gICAgICAgICAgICB2YXIgbWltZXR5cGUgPSBwYXJhbWV0ZXJzWzFdO1xyXG4gICAgICAgICAgICB2YXIgbmFtZSA9IHBhcmFtZXRlcnNbMl07XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGUgc3RyZWFtIFxyXG4gICAgICAgICAgICBpZiAoZ3VhY19jbGllbnQub25waXBlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3RyZWFtID0gc3RyZWFtc1tzdHJlYW1faW5kZXhdID0gbmV3IEd1YWNhbW9sZS5JbnB1dFN0cmVhbShndWFjX2NsaWVudCwgc3RyZWFtX2luZGV4KTtcclxuICAgICAgICAgICAgICAgIGd1YWNfY2xpZW50Lm9ucGlwZShzdHJlYW0sIG1pbWV0eXBlLCBuYW1lKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB1bnN1cHBvcnRlZFxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5zZW5kQWNrKHN0cmVhbV9pbmRleCwgXCJOYW1lZCBwaXBlcyB1bnN1cHBvcnRlZFwiLCAweDAxMDApO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcInBuZ1wiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgY2hhbm5lbE1hc2sgPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1sxXSkpO1xyXG4gICAgICAgICAgICB2YXIgeCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbMl0pO1xyXG4gICAgICAgICAgICB2YXIgeSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbM10pO1xyXG4gICAgICAgICAgICB2YXIgZGF0YSA9IHBhcmFtZXRlcnNbNF07XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LnNldENoYW5uZWxNYXNrKGxheWVyLCBjaGFubmVsTWFzayk7XHJcbiAgICAgICAgICAgIGRpc3BsYXkuZHJhdyhsYXllciwgeCwgeSwgXCJkYXRhOmltYWdlL3BuZztiYXNlNjQsXCIgKyBkYXRhKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJwb3BcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG5cclxuICAgICAgICAgICAgZGlzcGxheS5wb3AobGF5ZXIpO1xyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcInB1c2hcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG5cclxuICAgICAgICAgICAgZGlzcGxheS5wdXNoKGxheWVyKTtcclxuXHJcbiAgICAgICAgfSxcclxuIFxyXG4gICAgICAgIFwicmVjdFwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihwYXJzZUludChwYXJhbWV0ZXJzWzBdKSk7XHJcbiAgICAgICAgICAgIHZhciB4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcbiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VJbnQocGFyYW1ldGVyc1syXSk7XHJcbiAgICAgICAgICAgIHZhciB3ID0gcGFyc2VJbnQocGFyYW1ldGVyc1szXSk7XHJcbiAgICAgICAgICAgIHZhciBoID0gcGFyc2VJbnQocGFyYW1ldGVyc1s0XSk7XHJcblxyXG4gICAgICAgICAgICBkaXNwbGF5LnJlY3QobGF5ZXIsIHgsIHksIHcsIGgpO1xyXG5cclxuICAgICAgICB9LFxyXG4gICAgICAgIFxyXG4gICAgICAgIFwicmVzZXRcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG5cclxuICAgICAgICAgICAgZGlzcGxheS5yZXNldChsYXllcik7XHJcblxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgXHJcbiAgICAgICAgXCJzZXRcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1swXSkpO1xyXG4gICAgICAgICAgICB2YXIgbmFtZSA9IHBhcmFtZXRlcnNbMV07XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHBhcmFtZXRlcnNbMl07XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsIHByb3BlcnR5IGhhbmRsZXIgaWYgZGVmaW5lZFxyXG4gICAgICAgICAgICB2YXIgaGFuZGxlciA9IGxheWVyUHJvcGVydHlIYW5kbGVyc1tuYW1lXTtcclxuICAgICAgICAgICAgaWYgKGhhbmRsZXIpXHJcbiAgICAgICAgICAgICAgICBoYW5kbGVyKGxheWVyLCB2YWx1ZSk7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwic2hhZGVcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgdmFyIGxheWVyX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBhID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcblxyXG4gICAgICAgICAgICAvLyBPbmx5IHZhbGlkIGZvciB2aXNpYmxlIGxheWVycyAobm90IGJ1ZmZlcnMpXHJcbiAgICAgICAgICAgIGlmIChsYXllcl9pbmRleCA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbGF5ZXIgPSBnZXRMYXllcihsYXllcl9pbmRleCk7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5LnNoYWRlKGxheWVyLCBhKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBcInNpemVcIjogZnVuY3Rpb24ocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgdmFyIGxheWVyX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKGxheWVyX2luZGV4KTtcclxuICAgICAgICAgICAgdmFyIHdpZHRoID0gcGFyc2VJbnQocGFyYW1ldGVyc1sxXSk7XHJcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSBwYXJzZUludChwYXJhbWV0ZXJzWzJdKTtcclxuXHJcbiAgICAgICAgICAgIGRpc3BsYXkucmVzaXplKGxheWVyLCB3aWR0aCwgaGVpZ2h0KTtcclxuXHJcbiAgICAgICAgfSxcclxuICAgICAgICBcclxuICAgICAgICBcInN0YXJ0XCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMF0pKTtcclxuICAgICAgICAgICAgdmFyIHggPSBwYXJzZUludChwYXJhbWV0ZXJzWzFdKTtcclxuICAgICAgICAgICAgdmFyIHkgPSBwYXJzZUludChwYXJhbWV0ZXJzWzJdKTtcclxuXHJcbiAgICAgICAgICAgIGRpc3BsYXkubW92ZVRvKGxheWVyLCB4LCB5KTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJzeW5jXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciB0aW1lc3RhbXAgPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEZsdXNoIGRpc3BsYXksIHNlbmQgc3luYyB3aGVuIGRvbmVcclxuICAgICAgICAgICAgZGlzcGxheS5mbHVzaChmdW5jdGlvbiBkaXNwbGF5U3luY0NvbXBsZXRlKCkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFN5bmNocm9uaXplIGFsbCBhdWRpbyBwbGF5ZXJzXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpbmRleCBpbiBhdWRpb1BsYXllcnMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXVkaW9QbGF5ZXIgPSBhdWRpb1BsYXllcnNbaW5kZXhdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BsYXllcilcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9QbGF5ZXIuc3luYygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFNlbmQgc3luYyByZXNwb25zZSB0byBzZXJ2ZXJcclxuICAgICAgICAgICAgICAgIGlmICh0aW1lc3RhbXAgIT09IGN1cnJlbnRUaW1lc3RhbXApIHtcclxuICAgICAgICAgICAgICAgICAgICB0dW5uZWwuc2VuZE1lc3NhZ2UoXCJzeW5jXCIsIHRpbWVzdGFtcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFRpbWVzdGFtcCA9IHRpbWVzdGFtcDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gSWYgcmVjZWl2ZWQgZmlyc3QgdXBkYXRlLCBubyBsb25nZXIgd2FpdGluZy5cclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZSA9PT0gU1RBVEVfV0FJVElORylcclxuICAgICAgICAgICAgICAgIHNldFN0YXRlKFNUQVRFX0NPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsIHN5bmMgaGFuZGxlciBpZiBkZWZpbmVkXHJcbiAgICAgICAgICAgIGlmIChndWFjX2NsaWVudC5vbnN5bmMpXHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5vbnN5bmModGltZXN0YW1wKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJ0cmFuc2ZlclwiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3JjTCA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMF0pKTtcclxuICAgICAgICAgICAgdmFyIHNyY1ggPSBwYXJzZUludChwYXJhbWV0ZXJzWzFdKTtcclxuICAgICAgICAgICAgdmFyIHNyY1kgPSBwYXJzZUludChwYXJhbWV0ZXJzWzJdKTtcclxuICAgICAgICAgICAgdmFyIHNyY1dpZHRoID0gcGFyc2VJbnQocGFyYW1ldGVyc1szXSk7XHJcbiAgICAgICAgICAgIHZhciBzcmNIZWlnaHQgPSBwYXJzZUludChwYXJhbWV0ZXJzWzRdKTtcclxuICAgICAgICAgICAgdmFyIGZ1bmN0aW9uX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1s1XSk7XHJcbiAgICAgICAgICAgIHZhciBkc3RMID0gZ2V0TGF5ZXIocGFyc2VJbnQocGFyYW1ldGVyc1s2XSkpO1xyXG4gICAgICAgICAgICB2YXIgZHN0WCA9IHBhcnNlSW50KHBhcmFtZXRlcnNbN10pO1xyXG4gICAgICAgICAgICB2YXIgZHN0WSA9IHBhcnNlSW50KHBhcmFtZXRlcnNbOF0pO1xyXG5cclxuICAgICAgICAgICAgLyogU1JDICovXHJcbiAgICAgICAgICAgIGlmIChmdW5jdGlvbl9pbmRleCA9PT0gMHgzKVxyXG4gICAgICAgICAgICAgICAgZGlzcGxheS5wdXQoc3JjTCwgc3JjWCwgc3JjWSwgc3JjV2lkdGgsIHNyY0hlaWdodCwgXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0TCwgZHN0WCwgZHN0WSk7XHJcblxyXG4gICAgICAgICAgICAvKiBBbnl0aGluZyBlbHNlIHRoYXQgaXNuJ3QgYSBOTy1PUCAqL1xyXG4gICAgICAgICAgICBlbHNlIGlmIChmdW5jdGlvbl9pbmRleCAhPT0gMHg1KVxyXG4gICAgICAgICAgICAgICAgZGlzcGxheS50cmFuc2ZlcihzcmNMLCBzcmNYLCBzcmNZLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LCBcclxuICAgICAgICAgICAgICAgICAgICBkc3RMLCBkc3RYLCBkc3RZLCBHdWFjYW1vbGUuQ2xpZW50LkRlZmF1bHRUcmFuc2ZlckZ1bmN0aW9uW2Z1bmN0aW9uX2luZGV4XSk7XHJcblxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIFwidHJhbnNmb3JtXCI6IGZ1bmN0aW9uKHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMF0pKTtcclxuICAgICAgICAgICAgdmFyIGEgPSBwYXJzZUZsb2F0KHBhcmFtZXRlcnNbMV0pO1xyXG4gICAgICAgICAgICB2YXIgYiA9IHBhcnNlRmxvYXQocGFyYW1ldGVyc1syXSk7XHJcbiAgICAgICAgICAgIHZhciBjID0gcGFyc2VGbG9hdChwYXJhbWV0ZXJzWzNdKTtcclxuICAgICAgICAgICAgdmFyIGQgPSBwYXJzZUZsb2F0KHBhcmFtZXRlcnNbNF0pO1xyXG4gICAgICAgICAgICB2YXIgZSA9IHBhcnNlRmxvYXQocGFyYW1ldGVyc1s1XSk7XHJcbiAgICAgICAgICAgIHZhciBmID0gcGFyc2VGbG9hdChwYXJhbWV0ZXJzWzZdKTtcclxuXHJcbiAgICAgICAgICAgIGRpc3BsYXkudHJhbnNmb3JtKGxheWVyLCBhLCBiLCBjLCBkLCBlLCBmKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJ1bmRlZmluZVwiIDogZnVuY3Rpb24gaGFuZGxlVW5kZWZpbmUocGFyYW1ldGVycykge1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IG9iamVjdFxyXG4gICAgICAgICAgICB2YXIgb2JqZWN0SW5kZXggPSBwYXJzZUludChwYXJhbWV0ZXJzWzBdKTtcclxuICAgICAgICAgICAgdmFyIG9iamVjdCA9IG9iamVjdHNbb2JqZWN0SW5kZXhdO1xyXG5cclxuICAgICAgICAgICAgLy8gU2lnbmFsIGVuZCBvZiBvYmplY3QgZGVmaW5pdGlvblxyXG4gICAgICAgICAgICBpZiAob2JqZWN0ICYmIG9iamVjdC5vbnVuZGVmaW5lKVxyXG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9udW5kZWZpbmUoKTtcclxuXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgXCJ2aWRlb1wiOiBmdW5jdGlvbihwYXJhbWV0ZXJzKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RyZWFtX2luZGV4ID0gcGFyc2VJbnQocGFyYW1ldGVyc1swXSk7XHJcbiAgICAgICAgICAgIHZhciBsYXllciA9IGdldExheWVyKHBhcnNlSW50KHBhcmFtZXRlcnNbMV0pKTtcclxuICAgICAgICAgICAgdmFyIG1pbWV0eXBlID0gcGFyYW1ldGVyc1syXTtcclxuXHJcbiAgICAgICAgICAgIC8vIENyZWF0ZSBzdHJlYW1cclxuICAgICAgICAgICAgdmFyIHN0cmVhbSA9IHN0cmVhbXNbc3RyZWFtX2luZGV4XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IEd1YWNhbW9sZS5JbnB1dFN0cmVhbShndWFjX2NsaWVudCwgc3RyZWFtX2luZGV4KTtcclxuXHJcbiAgICAgICAgICAgIC8vIEdldCBwbGF5ZXIgaW5zdGFuY2UgdmlhIGNhbGxiYWNrXHJcbiAgICAgICAgICAgIHZhciB2aWRlb1BsYXllciA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmIChndWFjX2NsaWVudC5vbnZpZGVvKVxyXG4gICAgICAgICAgICAgICAgdmlkZW9QbGF5ZXIgPSBndWFjX2NsaWVudC5vbnZpZGVvKHN0cmVhbSwgbGF5ZXIsIG1pbWV0eXBlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIHVuc3VjY2Vzc2Z1bCwgdHJ5IHRvIHVzZSBhIGRlZmF1bHQgaW1wbGVtZW50YXRpb25cclxuICAgICAgICAgICAgaWYgKCF2aWRlb1BsYXllcilcclxuICAgICAgICAgICAgICAgIHZpZGVvUGxheWVyID0gR3VhY2Ftb2xlLlZpZGVvUGxheWVyLmdldEluc3RhbmNlKHN0cmVhbSwgbGF5ZXIsIG1pbWV0eXBlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIHdlIGhhdmUgc3VjY2Vzc2Z1bGx5IHJldHJpZXZlZCBhbiB2aWRlbyBwbGF5ZXIsIHNlbmQgc3VjY2VzcyByZXNwb25zZVxyXG4gICAgICAgICAgICBpZiAodmlkZW9QbGF5ZXIpIHtcclxuICAgICAgICAgICAgICAgIHZpZGVvUGxheWVyc1tzdHJlYW1faW5kZXhdID0gdmlkZW9QbGF5ZXI7XHJcbiAgICAgICAgICAgICAgICBndWFjX2NsaWVudC5zZW5kQWNrKHN0cmVhbV9pbmRleCwgXCJPS1wiLCAweDAwMDApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBPdGhlcndpc2UsIG1pbWV0eXBlIG11c3QgYmUgdW5zdXBwb3J0ZWRcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgZ3VhY19jbGllbnQuc2VuZEFjayhzdHJlYW1faW5kZXgsIFwiQkFEIFRZUEVcIiwgMHgwMzBGKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgdHVubmVsLm9uaW5zdHJ1Y3Rpb24gPSBmdW5jdGlvbihvcGNvZGUsIHBhcmFtZXRlcnMpIHtcclxuXHJcbiAgICAgICAgdmFyIGhhbmRsZXIgPSBpbnN0cnVjdGlvbkhhbmRsZXJzW29wY29kZV07XHJcbiAgICAgICAgaWYgKGhhbmRsZXIpXHJcbiAgICAgICAgICAgIGhhbmRsZXIocGFyYW1ldGVycyk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlbmRzIGEgZGlzY29ubmVjdCBpbnN0cnVjdGlvbiB0byB0aGUgc2VydmVyIGFuZCBjbG9zZXMgdGhlIHR1bm5lbC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5kaXNjb25uZWN0ID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIC8vIE9ubHkgYXR0ZW1wdCBkaXNjb25uZWN0aW9uIG5vdCBkaXNjb25uZWN0ZWQuXHJcbiAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZSAhPSBTVEFURV9ESVNDT05ORUNURURcclxuICAgICAgICAgICAgICAgICYmIGN1cnJlbnRTdGF0ZSAhPSBTVEFURV9ESVNDT05ORUNUSU5HKSB7XHJcblxyXG4gICAgICAgICAgICBzZXRTdGF0ZShTVEFURV9ESVNDT05ORUNUSU5HKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFN0b3AgcGluZ1xyXG4gICAgICAgICAgICBpZiAocGluZ0ludGVydmFsKVxyXG4gICAgICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlbmQgZGlzY29ubmVjdCBtZXNzYWdlIGFuZCBkaXNjb25uZWN0XHJcbiAgICAgICAgICAgIHR1bm5lbC5zZW5kTWVzc2FnZShcImRpc2Nvbm5lY3RcIik7XHJcbiAgICAgICAgICAgIHR1bm5lbC5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgIHNldFN0YXRlKFNUQVRFX0RJU0NPTk5FQ1RFRCk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIENvbm5lY3RzIHRoZSB1bmRlcmx5aW5nIHR1bm5lbCBvZiB0aGlzIEd1YWNhbW9sZS5DbGllbnQsIHBhc3NpbmcgdGhlXHJcbiAgICAgKiBnaXZlbiBhcmJpdHJhcnkgZGF0YSB0byB0aGUgdHVubmVsIGR1cmluZyB0aGUgY29ubmVjdGlvbiBwcm9jZXNzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBkYXRhIEFyYml0cmFyeSBjb25uZWN0aW9uIGRhdGEgdG8gYmUgc2VudCB0byB0aGUgdW5kZXJseWluZ1xyXG4gICAgICogICAgICAgICAgICAgdHVubmVsIGR1cmluZyB0aGUgY29ubmVjdGlvbiBwcm9jZXNzLlxyXG4gICAgICogQHRocm93cyB7R3VhY2Ftb2xlLlN0YXR1c30gSWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBjb25uZWN0aW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmNvbm5lY3QgPSBmdW5jdGlvbihkYXRhKSB7XHJcblxyXG4gICAgICAgIHNldFN0YXRlKFNUQVRFX0NPTk5FQ1RJTkcpO1xyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB0dW5uZWwuY29ubmVjdChkYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKHN0YXR1cykge1xyXG4gICAgICAgICAgICBzZXRTdGF0ZShTVEFURV9JRExFKTtcclxuICAgICAgICAgICAgdGhyb3cgc3RhdHVzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUGluZyBldmVyeSA1IHNlY29uZHMgKGVuc3VyZSBjb25uZWN0aW9uIGFsaXZlKVxyXG4gICAgICAgIHBpbmdJbnRlcnZhbCA9IHdpbmRvdy5zZXRJbnRlcnZhbChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdHVubmVsLnNlbmRNZXNzYWdlKFwibm9wXCIpO1xyXG4gICAgICAgIH0sIDUwMDApO1xyXG5cclxuICAgICAgICBzZXRTdGF0ZShTVEFURV9XQUlUSU5HKTtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIE1hcCBvZiBhbGwgR3VhY2Ftb2xlIGJpbmFyeSByYXN0ZXIgb3BlcmF0aW9ucyB0byB0cmFuc2ZlciBmdW5jdGlvbnMuXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5HdWFjYW1vbGUuQ2xpZW50LkRlZmF1bHRUcmFuc2ZlckZ1bmN0aW9uID0ge1xyXG5cclxuICAgIC8qIEJMQUNLICovXHJcbiAgICAweDA6IGZ1bmN0aW9uIChzcmMsIGRzdCkge1xyXG4gICAgICAgIGRzdC5yZWQgPSBkc3QuZ3JlZW4gPSBkc3QuYmx1ZSA9IDB4MDA7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qIFdISVRFICovXHJcbiAgICAweEY6IGZ1bmN0aW9uIChzcmMsIGRzdCkge1xyXG4gICAgICAgIGRzdC5yZWQgPSBkc3QuZ3JlZW4gPSBkc3QuYmx1ZSA9IDB4RkY7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qIFNSQyAqL1xyXG4gICAgMHgzOiBmdW5jdGlvbiAoc3JjLCBkc3QpIHtcclxuICAgICAgICBkc3QucmVkICAgPSBzcmMucmVkO1xyXG4gICAgICAgIGRzdC5ncmVlbiA9IHNyYy5ncmVlbjtcclxuICAgICAgICBkc3QuYmx1ZSAgPSBzcmMuYmx1ZTtcclxuICAgICAgICBkc3QuYWxwaGEgPSBzcmMuYWxwaGE7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qIERFU1QgKG5vLW9wKSAqL1xyXG4gICAgMHg1OiBmdW5jdGlvbiAoc3JjLCBkc3QpIHtcclxuICAgICAgICAvLyBEbyBub3RoaW5nXHJcbiAgICB9LFxyXG5cclxuICAgIC8qIEludmVydCBTUkMgKi9cclxuICAgIDB4QzogZnVuY3Rpb24gKHNyYywgZHN0KSB7XHJcbiAgICAgICAgZHN0LnJlZCAgID0gMHhGRiAmIH5zcmMucmVkO1xyXG4gICAgICAgIGRzdC5ncmVlbiA9IDB4RkYgJiB+c3JjLmdyZWVuO1xyXG4gICAgICAgIGRzdC5ibHVlICA9IDB4RkYgJiB+c3JjLmJsdWU7XHJcbiAgICAgICAgZHN0LmFscGhhID0gIHNyYy5hbHBoYTtcclxuICAgIH0sXHJcbiAgICBcclxuICAgIC8qIEludmVydCBERVNUICovXHJcbiAgICAweEE6IGZ1bmN0aW9uIChzcmMsIGRzdCkge1xyXG4gICAgICAgIGRzdC5yZWQgICA9IDB4RkYgJiB+ZHN0LnJlZDtcclxuICAgICAgICBkc3QuZ3JlZW4gPSAweEZGICYgfmRzdC5ncmVlbjtcclxuICAgICAgICBkc3QuYmx1ZSAgPSAweEZGICYgfmRzdC5ibHVlO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKiBBTkQgKi9cclxuICAgIDB4MTogZnVuY3Rpb24gKHNyYywgZHN0KSB7XHJcbiAgICAgICAgZHN0LnJlZCAgID0gICggc3JjLnJlZCAgICYgIGRzdC5yZWQpO1xyXG4gICAgICAgIGRzdC5ncmVlbiA9ICAoIHNyYy5ncmVlbiAmICBkc3QuZ3JlZW4pO1xyXG4gICAgICAgIGRzdC5ibHVlICA9ICAoIHNyYy5ibHVlICAmICBkc3QuYmx1ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qIE5BTkQgKi9cclxuICAgIDB4RTogZnVuY3Rpb24gKHNyYywgZHN0KSB7XHJcbiAgICAgICAgZHN0LnJlZCAgID0gMHhGRiAmIH4oIHNyYy5yZWQgICAmICBkc3QucmVkKTtcclxuICAgICAgICBkc3QuZ3JlZW4gPSAweEZGICYgfiggc3JjLmdyZWVuICYgIGRzdC5ncmVlbik7XHJcbiAgICAgICAgZHN0LmJsdWUgID0gMHhGRiAmIH4oIHNyYy5ibHVlICAmICBkc3QuYmx1ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qIE9SICovXHJcbiAgICAweDc6IGZ1bmN0aW9uIChzcmMsIGRzdCkge1xyXG4gICAgICAgIGRzdC5yZWQgICA9ICAoIHNyYy5yZWQgICB8ICBkc3QucmVkKTtcclxuICAgICAgICBkc3QuZ3JlZW4gPSAgKCBzcmMuZ3JlZW4gfCAgZHN0LmdyZWVuKTtcclxuICAgICAgICBkc3QuYmx1ZSAgPSAgKCBzcmMuYmx1ZSAgfCAgZHN0LmJsdWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKiBOT1IgKi9cclxuICAgIDB4ODogZnVuY3Rpb24gKHNyYywgZHN0KSB7XHJcbiAgICAgICAgZHN0LnJlZCAgID0gMHhGRiAmIH4oIHNyYy5yZWQgICB8ICBkc3QucmVkKTtcclxuICAgICAgICBkc3QuZ3JlZW4gPSAweEZGICYgfiggc3JjLmdyZWVuIHwgIGRzdC5ncmVlbik7XHJcbiAgICAgICAgZHN0LmJsdWUgID0gMHhGRiAmIH4oIHNyYy5ibHVlICB8ICBkc3QuYmx1ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qIFhPUiAqL1xyXG4gICAgMHg2OiBmdW5jdGlvbiAoc3JjLCBkc3QpIHtcclxuICAgICAgICBkc3QucmVkICAgPSAgKCBzcmMucmVkICAgXiAgZHN0LnJlZCk7XHJcbiAgICAgICAgZHN0LmdyZWVuID0gICggc3JjLmdyZWVuIF4gIGRzdC5ncmVlbik7XHJcbiAgICAgICAgZHN0LmJsdWUgID0gICggc3JjLmJsdWUgIF4gIGRzdC5ibHVlKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyogWE5PUiAqL1xyXG4gICAgMHg5OiBmdW5jdGlvbiAoc3JjLCBkc3QpIHtcclxuICAgICAgICBkc3QucmVkICAgPSAweEZGICYgfiggc3JjLnJlZCAgIF4gIGRzdC5yZWQpO1xyXG4gICAgICAgIGRzdC5ncmVlbiA9IDB4RkYgJiB+KCBzcmMuZ3JlZW4gXiAgZHN0LmdyZWVuKTtcclxuICAgICAgICBkc3QuYmx1ZSAgPSAweEZGICYgfiggc3JjLmJsdWUgIF4gIGRzdC5ibHVlKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyogQU5EIGludmVydGVkIHNvdXJjZSAqL1xyXG4gICAgMHg0OiBmdW5jdGlvbiAoc3JjLCBkc3QpIHtcclxuICAgICAgICBkc3QucmVkICAgPSAgMHhGRiAmICh+c3JjLnJlZCAgICYgIGRzdC5yZWQpO1xyXG4gICAgICAgIGRzdC5ncmVlbiA9ICAweEZGICYgKH5zcmMuZ3JlZW4gJiAgZHN0LmdyZWVuKTtcclxuICAgICAgICBkc3QuYmx1ZSAgPSAgMHhGRiAmICh+c3JjLmJsdWUgICYgIGRzdC5ibHVlKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyogT1IgaW52ZXJ0ZWQgc291cmNlICovXHJcbiAgICAweEQ6IGZ1bmN0aW9uIChzcmMsIGRzdCkge1xyXG4gICAgICAgIGRzdC5yZWQgICA9ICAweEZGICYgKH5zcmMucmVkICAgfCAgZHN0LnJlZCk7XHJcbiAgICAgICAgZHN0LmdyZWVuID0gIDB4RkYgJiAofnNyYy5ncmVlbiB8ICBkc3QuZ3JlZW4pO1xyXG4gICAgICAgIGRzdC5ibHVlICA9ICAweEZGICYgKH5zcmMuYmx1ZSAgfCAgZHN0LmJsdWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKiBBTkQgaW52ZXJ0ZWQgZGVzdGluYXRpb24gKi9cclxuICAgIDB4MjogZnVuY3Rpb24gKHNyYywgZHN0KSB7XHJcbiAgICAgICAgZHN0LnJlZCAgID0gIDB4RkYgJiAoIHNyYy5yZWQgICAmIH5kc3QucmVkKTtcclxuICAgICAgICBkc3QuZ3JlZW4gPSAgMHhGRiAmICggc3JjLmdyZWVuICYgfmRzdC5ncmVlbik7XHJcbiAgICAgICAgZHN0LmJsdWUgID0gIDB4RkYgJiAoIHNyYy5ibHVlICAmIH5kc3QuYmx1ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qIE9SIGludmVydGVkIGRlc3RpbmF0aW9uICovXHJcbiAgICAweEI6IGZ1bmN0aW9uIChzcmMsIGRzdCkge1xyXG4gICAgICAgIGRzdC5yZWQgICA9ICAweEZGICYgKCBzcmMucmVkICAgfCB+ZHN0LnJlZCk7XHJcbiAgICAgICAgZHN0LmdyZWVuID0gIDB4RkYgJiAoIHNyYy5ncmVlbiB8IH5kc3QuZ3JlZW4pO1xyXG4gICAgICAgIGRzdC5ibHVlICA9ICAweEZGICYgKCBzcmMuYmx1ZSAgfCB+ZHN0LmJsdWUpO1xyXG4gICAgfVxyXG5cclxufTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIHJlYWRlciB3aGljaCBhdXRvbWF0aWNhbGx5IGhhbmRsZXMgdGhlIGdpdmVuIGlucHV0IHN0cmVhbSwgcmV0dXJuaW5nXHJcbiAqIHJlY2VpdmVkIGJsb2JzIGFzIGEgc2luZ2xlIGRhdGEgVVJJIGJ1aWx0IG92ZXIgdGhlIGNvdXJzZSBvZiB0aGUgc3RyZWFtLlxyXG4gKiBOb3RlIHRoYXQgdGhpcyBvYmplY3Qgd2lsbCBvdmVyd3JpdGUgYW55IGluc3RhbGxlZCBldmVudCBoYW5kbGVycyBvbiB0aGVcclxuICogZ2l2ZW4gR3VhY2Ftb2xlLklucHV0U3RyZWFtLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLklucHV0U3RyZWFtfSBzdHJlYW1cclxuICogICAgIFRoZSBzdHJlYW0gdGhhdCBkYXRhIHdpbGwgYmUgcmVhZCBmcm9tLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkRhdGFVUklSZWFkZXIgPSBmdW5jdGlvbihzdHJlYW0sIG1pbWV0eXBlKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBHdWFjYW1vbGUuRGF0YVVSSVJlYWRlci5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBndWFjX3JlYWRlciA9IHRoaXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDdXJyZW50IGRhdGEgVVJJLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxyXG4gICAgICovXHJcbiAgICB2YXIgdXJpID0gJ2RhdGE6JyArIG1pbWV0eXBlICsgJztiYXNlNjQsJztcclxuXHJcbiAgICAvLyBSZWNlaXZlIGJsb2JzIGFzIGFycmF5IGJ1ZmZlcnNcclxuICAgIHN0cmVhbS5vbmJsb2IgPSBmdW5jdGlvbiBkYXRhVVJJUmVhZGVyQmxvYihkYXRhKSB7XHJcblxyXG4gICAgICAgIC8vIEN1cnJlbnRseSBhc3N1bWluZyBkYXRhIHdpbGwgQUxXQVlTIGJlIHNhZmUgdG8gc2ltcGx5IGFwcGVuZC4gVGhpc1xyXG4gICAgICAgIC8vIHdpbGwgbm90IGJlIHRydWUgaWYgdGhlIHJlY2VpdmVkIGJhc2U2NCBkYXRhIGVuY29kZXMgYSBudW1iZXIgb2ZcclxuICAgICAgICAvLyBieXRlcyB0aGF0IGlzbid0IGEgbXVsdGlwbGUgb2YgdGhyZWUgKGFzIGJhc2U2NCBleHBhbmRzIGluIGEgcmF0aW9cclxuICAgICAgICAvLyBvZiBleGFjdGx5IDM6NCkuXHJcbiAgICAgICAgdXJpICs9IGRhdGE7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBTaW1wbHkgY2FsbCBvbmVuZCB3aGVuIGVuZCByZWNlaXZlZFxyXG4gICAgc3RyZWFtLm9uZW5kID0gZnVuY3Rpb24gZGF0YVVSSVJlYWRlckVuZCgpIHtcclxuICAgICAgICBpZiAoZ3VhY19yZWFkZXIub25lbmQpXHJcbiAgICAgICAgICAgIGd1YWNfcmVhZGVyLm9uZW5kKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZGF0YSBVUkkgb2YgYWxsIGRhdGEgcmVjZWl2ZWQgdGhyb3VnaCB0aGUgdW5kZXJseWluZyBzdHJlYW1cclxuICAgICAqIHRodXMgZmFyLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAgICAgKiAgICAgVGhlIGRhdGEgVVJJIG9mIGFsbCBkYXRhIHJlY2VpdmVkIHRocm91Z2ggdGhlIHVuZGVybHlpbmcgc3RyZWFtIHRodXNcclxuICAgICAqICAgICBmYXIuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZ2V0VVJJID0gZnVuY3Rpb24gZ2V0VVJJKCkge1xyXG4gICAgICAgIHJldHVybiB1cmk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgb25jZSB0aGlzIHN0cmVhbSBpcyBmaW5pc2hlZCBhbmQgbm8gZnVydGhlciBkYXRhIHdpbGwgYmUgd3JpdHRlbi5cclxuICAgICAqXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmVuZCA9IG51bGw7XHJcblxyXG59Oy8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogVGhlIEd1YWNhbW9sZSBkaXNwbGF5LiBUaGUgZGlzcGxheSBkb2VzIG5vdCBkZWFsIHdpdGggdGhlIEd1YWNhbW9sZVxyXG4gKiBwcm90b2NvbCwgYW5kIGluc3RlYWQgaW1wbGVtZW50cyBhIHNldCBvZiBncmFwaGljYWwgb3BlcmF0aW9ucyB3aGljaFxyXG4gKiBlbWJvZHkgdGhlIHNldCBvZiBvcGVyYXRpb25zIHByZXNlbnQgaW4gdGhlIHByb3RvY29sLiBUaGUgb3JkZXIgb3BlcmF0aW9uc1xyXG4gKiBhcmUgZXhlY3V0ZWQgaXMgZ3VhcmFudGVlZCB0byBiZSBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGVpciBjb3JyZXNwb25kaW5nXHJcbiAqIGZ1bmN0aW9ucyBhcmUgY2FsbGVkLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqL1xyXG5HdWFjYW1vbGUuRGlzcGxheSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVmZXJlbmNlIHRvIHRoaXMgR3VhY2Ftb2xlLkRpc3BsYXkuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgZ3VhY19kaXNwbGF5ID0gdGhpcztcclxuXHJcbiAgICB2YXIgZGlzcGxheVdpZHRoID0gMDtcclxuICAgIHZhciBkaXNwbGF5SGVpZ2h0ID0gMDtcclxuICAgIHZhciBkaXNwbGF5U2NhbGUgPSAxO1xyXG5cclxuICAgIC8vIENyZWF0ZSBkaXNwbGF5XHJcbiAgICB2YXIgZGlzcGxheSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XHJcbiAgICBkaXNwbGF5LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xyXG4gICAgZGlzcGxheS5zdHlsZS53aWR0aCA9IGRpc3BsYXlXaWR0aCArIFwicHhcIjtcclxuICAgIGRpc3BsYXkuc3R5bGUuaGVpZ2h0ID0gZGlzcGxheUhlaWdodCArIFwicHhcIjtcclxuXHJcbiAgICAvLyBFbnN1cmUgdHJhbnNmb3JtYXRpb25zIG9uIGRpc3BsYXkgb3JpZ2luYXRlIGF0IDAsMFxyXG4gICAgZGlzcGxheS5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPVxyXG4gICAgZGlzcGxheS5zdHlsZS53ZWJraXRUcmFuc2Zvcm1PcmlnaW4gPVxyXG4gICAgZGlzcGxheS5zdHlsZS5Nb3pUcmFuc2Zvcm1PcmlnaW4gPVxyXG4gICAgZGlzcGxheS5zdHlsZS5PVHJhbnNmb3JtT3JpZ2luID1cclxuICAgIGRpc3BsYXkuc3R5bGUubXNUcmFuc2Zvcm1PcmlnaW4gPVxyXG4gICAgICAgIFwiMCAwXCI7XHJcblxyXG4gICAgLy8gQ3JlYXRlIGRlZmF1bHQgbGF5ZXJcclxuICAgIHZhciBkZWZhdWx0X2xheWVyID0gbmV3IEd1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcihkaXNwbGF5V2lkdGgsIGRpc3BsYXlIZWlnaHQpO1xyXG5cclxuICAgIC8vIENyZWF0ZSBjdXJzb3IgbGF5ZXJcclxuICAgIHZhciBjdXJzb3IgPSBuZXcgR3VhY2Ftb2xlLkRpc3BsYXkuVmlzaWJsZUxheWVyKDAsIDApO1xyXG4gICAgY3Vyc29yLnNldENoYW5uZWxNYXNrKEd1YWNhbW9sZS5MYXllci5TUkMpO1xyXG5cclxuICAgIC8vIEFkZCBkZWZhdWx0IGxheWVyIGFuZCBjdXJzb3IgdG8gZGlzcGxheVxyXG4gICAgZGlzcGxheS5hcHBlbmRDaGlsZChkZWZhdWx0X2xheWVyLmdldEVsZW1lbnQoKSk7XHJcbiAgICBkaXNwbGF5LmFwcGVuZENoaWxkKGN1cnNvci5nZXRFbGVtZW50KCkpO1xyXG5cclxuICAgIC8vIENyZWF0ZSBib3VuZGluZyBkaXYgXHJcbiAgICB2YXIgYm91bmRzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuICAgIGJvdW5kcy5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcclxuICAgIGJvdW5kcy5zdHlsZS53aWR0aCA9IChkaXNwbGF5V2lkdGgqZGlzcGxheVNjYWxlKSArIFwicHhcIjtcclxuICAgIGJvdW5kcy5zdHlsZS5oZWlnaHQgPSAoZGlzcGxheUhlaWdodCpkaXNwbGF5U2NhbGUpICsgXCJweFwiO1xyXG5cclxuICAgIC8vIEFkZCBkaXNwbGF5IHRvIGJvdW5kc1xyXG4gICAgYm91bmRzLmFwcGVuZENoaWxkKGRpc3BsYXkpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgaG90c3BvdCBvZiB0aGUgbW91c2UgY3Vyc29yLiBUaGUgaG90c3BvdCBpc1xyXG4gICAgICogdGhlIHJlbGF0aXZlIGxvY2F0aW9uIHdpdGhpbiB0aGUgaW1hZ2Ugb2YgdGhlIG1vdXNlIGN1cnNvciBhdCB3aGljaFxyXG4gICAgICogZWFjaCBjbGljayBvY2N1cnMuXHJcbiAgICAgKiBcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuY3Vyc29ySG90c3BvdFggPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgaG90c3BvdCBvZiB0aGUgbW91c2UgY3Vyc29yLiBUaGUgaG90c3BvdCBpc1xyXG4gICAgICogdGhlIHJlbGF0aXZlIGxvY2F0aW9uIHdpdGhpbiB0aGUgaW1hZ2Ugb2YgdGhlIG1vdXNlIGN1cnNvciBhdCB3aGljaFxyXG4gICAgICogZWFjaCBjbGljayBvY2N1cnMuXHJcbiAgICAgKiBcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuY3Vyc29ySG90c3BvdFkgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgWCBjb29yZGluYXRlIG9mIHRoZSBsb2NhbCBtb3VzZSBjdXJzb3IuIFRoaXMgaXMgbm90XHJcbiAgICAgKiBuZWNlc3NhcmlseSB0aGUgbG9jYXRpb24gb2YgdGhlIGFjdHVhbCBtb3VzZSAtIGl0IHJlZmVycyBvbmx5IHRvXHJcbiAgICAgKiB0aGUgbG9jYXRpb24gb2YgdGhlIGN1cnNvciBpbWFnZSB3aXRoaW4gdGhlIEd1YWNhbW9sZSBkaXNwbGF5LCBhc1xyXG4gICAgICogbGFzdCBzZXQgYnkgbW92ZUN1cnNvcigpLlxyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmN1cnNvclggPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgWCBjb29yZGluYXRlIG9mIHRoZSBsb2NhbCBtb3VzZSBjdXJzb3IuIFRoaXMgaXMgbm90XHJcbiAgICAgKiBuZWNlc3NhcmlseSB0aGUgbG9jYXRpb24gb2YgdGhlIGFjdHVhbCBtb3VzZSAtIGl0IHJlZmVycyBvbmx5IHRvXHJcbiAgICAgKiB0aGUgbG9jYXRpb24gb2YgdGhlIGN1cnNvciBpbWFnZSB3aXRoaW4gdGhlIEd1YWNhbW9sZSBkaXNwbGF5LCBhc1xyXG4gICAgICogbGFzdCBzZXQgYnkgbW92ZUN1cnNvcigpLlxyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmN1cnNvclkgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbiB0aGUgZGVmYXVsdCBsYXllciAoYW5kIHRodXMgdGhlIGVudGlyZSBHdWFjYW1vbGUgZGlzcGxheSlcclxuICAgICAqIGlzIHJlc2l6ZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoIFRoZSBuZXcgd2lkdGggb2YgdGhlIEd1YWNhbW9sZSBkaXNwbGF5LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodCBUaGUgbmV3IGhlaWdodCBvZiB0aGUgR3VhY2Ftb2xlIGRpc3BsYXkuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25yZXNpemUgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgdGhlIGxvY2FsIGN1cnNvciBpbWFnZSBpcyBjaGFuZ2VkLiBUaGlzIGNhbiBiZSB1c2VkIHRvXHJcbiAgICAgKiBpbXBsZW1lbnQgc3BlY2lhbCBoYW5kbGluZyBvZiB0aGUgY2xpZW50LXNpZGUgY3Vyc29yLCBvciB0byBvdmVycmlkZVxyXG4gICAgICogdGhlIGRlZmF1bHQgdXNlIG9mIGEgc29mdHdhcmUgY3Vyc29yIGxheWVyLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhcyBUaGUgY3Vyc29yIGltYWdlLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIFgtY29vcmRpbmF0ZSBvZiB0aGUgY3Vyc29yIGhvdHNwb3QuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgWS1jb29yZGluYXRlIG9mIHRoZSBjdXJzb3IgaG90c3BvdC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmN1cnNvciA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcXVldWUgb2YgYWxsIHBlbmRpbmcgVGFza3MuIFRhc2tzIHdpbGwgYmUgcnVuIGluIG9yZGVyLCB3aXRoIG5ld1xyXG4gICAgICogdGFza3MgYWRkZWQgYXQgdGhlIGVuZCBvZiB0aGUgcXVldWUgYW5kIG9sZCB0YXNrcyByZW1vdmVkIGZyb20gdGhlXHJcbiAgICAgKiBmcm9udCBvZiB0aGUgcXVldWUgKEZJRk8pLiBUaGVzZSB0YXNrcyB3aWxsIGV2ZW50dWFsbHkgYmUgZ3JvdXBlZFxyXG4gICAgICogaW50byBhIEZyYW1lLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtUYXNrW119XHJcbiAgICAgKi9cclxuICAgIHZhciB0YXNrcyA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHF1ZXVlIG9mIGFsbCBmcmFtZXMuIEVhY2ggZnJhbWUgaXMgYSBwYWlyaW5nIG9mIGFuIGFycmF5IG9mIHRhc2tzXHJcbiAgICAgKiBhbmQgYSBjYWxsYmFjayB3aGljaCBtdXN0IGJlIGNhbGxlZCB3aGVuIHRoZSBmcmFtZSBpcyByZW5kZXJlZC5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7RnJhbWVbXX1cclxuICAgICAqL1xyXG4gICAgdmFyIGZyYW1lcyA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmx1c2hlcyBhbGwgcGVuZGluZyBmcmFtZXMuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBfX2ZsdXNoX2ZyYW1lcygpIHtcclxuXHJcbiAgICAgICAgdmFyIHJlbmRlcmVkX2ZyYW1lcyA9IDA7XHJcblxyXG4gICAgICAgIC8vIERyYXcgYWxsIHBlbmRpbmcgZnJhbWVzLCBpZiByZWFkeVxyXG4gICAgICAgIHdoaWxlIChyZW5kZXJlZF9mcmFtZXMgPCBmcmFtZXMubGVuZ3RoKSB7XHJcblxyXG4gICAgICAgICAgICB2YXIgZnJhbWUgPSBmcmFtZXNbcmVuZGVyZWRfZnJhbWVzXTtcclxuICAgICAgICAgICAgaWYgKCFmcmFtZS5pc1JlYWR5KCkpXHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgIGZyYW1lLmZsdXNoKCk7XHJcbiAgICAgICAgICAgIHJlbmRlcmVkX2ZyYW1lcysrO1xyXG5cclxuICAgICAgICB9IFxyXG5cclxuICAgICAgICAvLyBSZW1vdmUgcmVuZGVyZWQgZnJhbWVzIGZyb20gYXJyYXlcclxuICAgICAgICBmcmFtZXMuc3BsaWNlKDAsIHJlbmRlcmVkX2ZyYW1lcyk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gb3JkZXJlZCBsaXN0IG9mIHRhc2tzIHdoaWNoIG11c3QgYmUgZXhlY3V0ZWQgYXRvbWljYWxseS4gT25jZVxyXG4gICAgICogZXhlY3V0ZWQsIGFuIGFzc29jaWF0ZWQgKGFuZCBvcHRpb25hbCkgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aGlzIGZyYW1lIGlzXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJlZC5cclxuICAgICAqIEBwYXJhbSB7VGFza1tdfSB0YXNrcyBUaGUgc2V0IG9mIHRhc2tzIHdoaWNoIG11c3QgYmUgZXhlY3V0ZWQgdG8gcmVuZGVyXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgdGhpcyBmcmFtZS5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gRnJhbWUoY2FsbGJhY2ssIHRhc2tzKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJldHVybnMgd2hldGhlciB0aGlzIGZyYW1lIGlzIHJlYWR5IHRvIGJlIHJlbmRlcmVkLiBUaGlzIGZ1bmN0aW9uXHJcbiAgICAgICAgICogcmV0dXJucyB0cnVlIGlmIGFuZCBvbmx5IGlmIEFMTCB1bmRlcmx5aW5nIHRhc2tzIGFyZSB1bmJsb2NrZWQuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgYWxsIHVuZGVybHlpbmcgdGFza3MgYXJlIHVuYmxvY2tlZCxcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuaXNSZWFkeSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAgICAgLy8gU2VhcmNoIGZvciBibG9ja2VkIHRhc2tzXHJcbiAgICAgICAgICAgIGZvciAodmFyIGk9MDsgaSA8IHRhc2tzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGFza3NbaV0uYmxvY2tlZClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIG5vIGJsb2NrZWQgdGFza3MsIHRoZSBmcmFtZSBpcyByZWFkeVxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVuZGVycyB0aGlzIGZyYW1lLCBjYWxsaW5nIHRoZSBhc3NvY2lhdGVkIGNhbGxiYWNrLCBpZiBhbnksIGFmdGVyXHJcbiAgICAgICAgICogdGhlIGZyYW1lIGlzIGNvbXBsZXRlLiBUaGlzIGZ1bmN0aW9uIE1VU1Qgb25seSBiZSBjYWxsZWQgd2hlbiBub1xyXG4gICAgICAgICAqIGJsb2NrZWQgdGFza3MgZXhpc3QuIENhbGxpbmcgdGhpcyBmdW5jdGlvbiB3aXRoIGJsb2NrZWQgdGFza3NcclxuICAgICAgICAgKiB3aWxsIHJlc3VsdCBpbiB1bmRlZmluZWQgYmVoYXZpb3IuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5mbHVzaCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAgICAgLy8gRHJhdyBhbGwgcGVuZGluZyB0YXNrcy5cclxuICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpIDwgdGFza3MubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICB0YXNrc1tpXS5leGVjdXRlKCk7XHJcblxyXG4gICAgICAgICAgICAvLyBDYWxsIGNhbGxiYWNrXHJcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykgY2FsbGJhY2soKTtcclxuXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIGNvbnRhaW5lciBmb3IgYW4gdGFzayBoYW5kbGVyLiBFYWNoIG9wZXJhdGlvbiB3aGljaCBtdXN0IGJlIG9yZGVyZWRcclxuICAgICAqIGlzIGFzc29jaWF0ZWQgd2l0aCBhIFRhc2sgdGhhdCBnb2VzIGludG8gYSB0YXNrIHF1ZXVlLiBUYXNrcyBpbiB0aGlzXHJcbiAgICAgKiBxdWV1ZSBhcmUgZXhlY3V0ZWQgaW4gb3JkZXIgb25jZSB0aGVpciBoYW5kbGVycyBhcmUgc2V0LCB3aGlsZSBUYXNrcyBcclxuICAgICAqIHdpdGhvdXQgaGFuZGxlcnMgYmxvY2sgdGhlbXNlbHZlcyBhbmQgYW55IGZvbGxvd2luZyBUYXNrcyBmcm9tIHJ1bm5pbmcuXHJcbiAgICAgKlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gdGFza0hhbmRsZXIgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aGlzIHRhc2sgXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5zLCBpZiBhbnkuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGJsb2NrZWQgV2hldGhlciB0aGlzIHRhc2sgc2hvdWxkIHN0YXJ0IGJsb2NrZWQuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIFRhc2sodGFza0hhbmRsZXIsIGJsb2NrZWQpIHtcclxuICAgICAgIFxyXG4gICAgICAgIHZhciB0YXNrID0gdGhpcztcclxuICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZXRoZXIgdGhpcyBUYXNrIGlzIGJsb2NrZWQuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5ibG9ja2VkID0gYmxvY2tlZDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVW5ibG9ja3MgdGhpcyBUYXNrLCBhbGxvd2luZyBpdCB0byBydW4uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy51bmJsb2NrID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmICh0YXNrLmJsb2NrZWQpIHtcclxuICAgICAgICAgICAgICAgIHRhc2suYmxvY2tlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgX19mbHVzaF9mcmFtZXMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENhbGxzIHRoZSBoYW5kbGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHRhc2sgSU1NRURJQVRFTFkuIFRoaXNcclxuICAgICAgICAgKiBmdW5jdGlvbiBkb2VzIG5vdCB0cmFjayB3aGV0aGVyIHRoaXMgdGFzayBpcyBtYXJrZWQgYXMgYmxvY2tlZC5cclxuICAgICAgICAgKiBFbmZvcmNpbmcgdGhlIGJsb2NrZWQgc3RhdHVzIG9mIHRhc2tzIGlzIHVwIHRvIHRoZSBjYWxsZXIuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5leGVjdXRlID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmICh0YXNrSGFuZGxlcikgdGFza0hhbmRsZXIoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNjaGVkdWxlcyBhIHRhc2sgZm9yIGZ1dHVyZSBleGVjdXRpb24uIFRoZSBnaXZlbiBoYW5kbGVyIHdpbGwgZXhlY3V0ZVxyXG4gICAgICogaW1tZWRpYXRlbHkgYWZ0ZXIgYWxsIHByZXZpb3VzIHRhc2tzIHVwb24gZnJhbWUgZmx1c2gsIHVubGVzcyB0aGlzXHJcbiAgICAgKiB0YXNrIGlzIGJsb2NrZWQuIElmIGFueSB0YXNrcyBpcyBibG9ja2VkLCB0aGUgZW50aXJlIGZyYW1lIHdpbGwgbm90XHJcbiAgICAgKiByZW5kZXIgKGFuZCBubyB0YXNrcyB3aXRoaW4gd2lsbCBleGVjdXRlKSB1bnRpbCBhbGwgdGFza3MgYXJlIHVuYmxvY2tlZC5cclxuICAgICAqIFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGhhbmRsZXIgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBwb3NzaWJsZSwgaWYgYW55LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBibG9ja2VkIFdoZXRoZXIgdGhlIHRhc2sgc2hvdWxkIHN0YXJ0IGJsb2NrZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7VGFza30gVGhlIFRhc2sgY3JlYXRlZCBhbmQgYWRkZWQgdG8gdGhlIHF1ZXVlIGZvciBmdXR1cmVcclxuICAgICAqICAgICAgICAgICAgICAgICBydW5uaW5nLlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzY2hlZHVsZVRhc2soaGFuZGxlciwgYmxvY2tlZCkge1xyXG4gICAgICAgIHZhciB0YXNrID0gbmV3IFRhc2soaGFuZGxlciwgYmxvY2tlZCk7XHJcbiAgICAgICAgdGFza3MucHVzaCh0YXNrKTtcclxuICAgICAgICByZXR1cm4gdGFzaztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgd2hpY2ggY29udGFpbnMgdGhlIEd1YWNhbW9sZSBkaXNwbGF5LlxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJuIHtFbGVtZW50fSBUaGUgZWxlbWVudCBjb250YWluaW5nIHRoZSBHdWFjYW1vbGUgZGlzcGxheS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5nZXRFbGVtZW50ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIGJvdW5kcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSB3aWR0aCBvZiB0aGlzIGRpc3BsYXkuXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm4ge051bWJlcn0gVGhlIHdpZHRoIG9mIHRoaXMgZGlzcGxheTtcclxuICAgICAqL1xyXG4gICAgdGhpcy5nZXRXaWR0aCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBkaXNwbGF5V2lkdGg7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgaGVpZ2h0IG9mIHRoaXMgZGlzcGxheS5cclxuICAgICAqIFxyXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBUaGUgaGVpZ2h0IG9mIHRoaXMgZGlzcGxheTtcclxuICAgICAqL1xyXG4gICAgdGhpcy5nZXRIZWlnaHQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gZGlzcGxheUhlaWdodDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGxheWVyIG9mIHRoaXMgZGlzcGxheS4gRWFjaCBHdWFjYW1vbGUgZGlzcGxheSBhbHdheXNcclxuICAgICAqIGhhcyBhdCBsZWFzdCBvbmUgbGF5ZXIuIE90aGVyIGxheWVycyBjYW4gb3B0aW9uYWxseSBiZSBjcmVhdGVkIHdpdGhpblxyXG4gICAgICogdGhpcyBsYXllciwgYnV0IHRoZSBkZWZhdWx0IGxheWVyIGNhbm5vdCBiZSByZW1vdmVkIGFuZCBpcyB0aGUgYWJzb2x1dGVcclxuICAgICAqIGFuY2VzdG9yIG9mIGFsbCBvdGhlciBsYXllcnMuXHJcbiAgICAgKiBcclxuICAgICAqIEByZXR1cm4ge0d1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcn0gVGhlIGRlZmF1bHQgbGF5ZXIuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZ2V0RGVmYXVsdExheWVyID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRfbGF5ZXI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgY3Vyc29yIGxheWVyIG9mIHRoaXMgZGlzcGxheS4gRWFjaCBHdWFjYW1vbGUgZGlzcGxheSBjb250YWluc1xyXG4gICAgICogYSBsYXllciBmb3IgdGhlIGltYWdlIG9mIHRoZSBtb3VzZSBjdXJzb3IuIFRoaXMgbGF5ZXIgaXMgYSBzcGVjaWFsIGNhc2VcclxuICAgICAqIGFuZCBleGlzdHMgYWJvdmUgYWxsIG90aGVyIGxheWVycywgc2ltaWxhciB0byB0aGUgaGFyZHdhcmUgbW91c2UgY3Vyc29yLlxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJuIHtHdWFjYW1vbGUuRGlzcGxheS5WaXNpYmxlTGF5ZXJ9IFRoZSBjdXJzb3IgbGF5ZXIuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZ2V0Q3Vyc29yTGF5ZXIgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gY3Vyc29yO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgbGF5ZXIuIFRoZSBuZXcgbGF5ZXIgd2lsbCBiZSBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgZGVmYXVsdFxyXG4gICAgICogbGF5ZXIsIGJ1dCBjYW4gYmUgbW92ZWQgdG8gYmUgYSBjaGlsZCBvZiBhbnkgb3RoZXIgbGF5ZXIuIExheWVycyByZXR1cm5lZFxyXG4gICAgICogYnkgdGhpcyBmdW5jdGlvbiBhcmUgdmlzaWJsZS5cclxuICAgICAqIFxyXG4gICAgICogQHJldHVybiB7R3VhY2Ftb2xlLkRpc3BsYXkuVmlzaWJsZUxheWVyfSBUaGUgbmV3bHktY3JlYXRlZCBsYXllci5cclxuICAgICAqL1xyXG4gICAgdGhpcy5jcmVhdGVMYXllciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZhciBsYXllciA9IG5ldyBHdWFjYW1vbGUuRGlzcGxheS5WaXNpYmxlTGF5ZXIoZGlzcGxheVdpZHRoLCBkaXNwbGF5SGVpZ2h0KTtcclxuICAgICAgICBsYXllci5tb3ZlKGRlZmF1bHRfbGF5ZXIsIDAsIDAsIDApO1xyXG4gICAgICAgIHJldHVybiBsYXllcjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGJ1ZmZlci4gQnVmZmVycyBhcmUgaW52aXNpYmxlLCBvZmYtc2NyZWVuIHN1cmZhY2VzLiBUaGV5XHJcbiAgICAgKiBhcmUgaW1wbGVtZW50ZWQgaW4gdGhlIHNhbWUgbWFubmVyIGFzIGxheWVycywgYnV0IGRvIG5vdCBwcm92aWRlIHRoZVxyXG4gICAgICogc2FtZSBuZXN0aW5nIHNlbWFudGljcy5cclxuICAgICAqIFxyXG4gICAgICogQHJldHVybiB7R3VhY2Ftb2xlLkxheWVyfSBUaGUgbmV3bHktY3JlYXRlZCBidWZmZXIuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY3JlYXRlQnVmZmVyID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdmFyIGJ1ZmZlciA9IG5ldyBHdWFjYW1vbGUuTGF5ZXIoMCwgMCk7XHJcbiAgICAgICAgYnVmZmVyLmF1dG9zaXplID0gMTtcclxuICAgICAgICByZXR1cm4gYnVmZmVyO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZsdXNoIGFsbCBwZW5kaW5nIGRyYXcgdGFza3MsIGlmIHBvc3NpYmxlLCBhcyBhIG5ldyBmcmFtZS4gSWYgdGhlIGVudGlyZVxyXG4gICAgICogZnJhbWUgaXMgbm90IHJlYWR5LCB0aGUgZmx1c2ggd2lsbCB3YWl0IHVudGlsIGFsbCByZXF1aXJlZCB0YXNrcyBhcmVcclxuICAgICAqIHVuYmxvY2tlZC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aGlzIGZyYW1lIGlzXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbHVzaGVkLiBUaGlzIG1heSBoYXBwZW4gaW1tZWRpYXRlbHksIG9yXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRlciB3aGVuIGJsb2NrZWQgdGFza3MgYmVjb21lIHVuYmxvY2tlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5mbHVzaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XHJcblxyXG4gICAgICAgIC8vIEFkZCBmcmFtZSwgcmVzZXQgdGFza3NcclxuICAgICAgICBmcmFtZXMucHVzaChuZXcgRnJhbWUoY2FsbGJhY2ssIHRhc2tzKSk7XHJcbiAgICAgICAgdGFza3MgPSBbXTtcclxuXHJcbiAgICAgICAgLy8gQXR0ZW1wdCBmbHVzaFxyXG4gICAgICAgIF9fZmx1c2hfZnJhbWVzKCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGhvdHNwb3QgYW5kIGltYWdlIG9mIHRoZSBtb3VzZSBjdXJzb3IgZGlzcGxheWVkIHdpdGhpbiB0aGVcclxuICAgICAqIEd1YWNhbW9sZSBkaXNwbGF5LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaG90c3BvdFggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgY3Vyc29yIGhvdHNwb3QuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaG90c3BvdFkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgY3Vyc29yIGhvdHNwb3QuXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gbGF5ZXIgVGhlIHNvdXJjZSBsYXllciBjb250YWluaW5nIHRoZSBkYXRhIHdoaWNoXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkIGJlIHVzZWQgYXMgdGhlIG1vdXNlIGN1cnNvciBpbWFnZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmN4IFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlIGxheWVyJ3MgY29vcmRpbmF0ZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjeSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZSBsYXllcidzIGNvb3JkaW5hdGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY3cgVGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2UgbGF5ZXInc1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZSBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmNoIFRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgbGF5ZXIncyBjb29yZGluYXRlIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZXRDdXJzb3IgPSBmdW5jdGlvbihob3RzcG90WCwgaG90c3BvdFksIGxheWVyLCBzcmN4LCBzcmN5LCBzcmN3LCBzcmNoKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9zZXRfY3Vyc29yKCkge1xyXG5cclxuICAgICAgICAgICAgLy8gU2V0IGhvdHNwb3RcclxuICAgICAgICAgICAgZ3VhY19kaXNwbGF5LmN1cnNvckhvdHNwb3RYID0gaG90c3BvdFg7XHJcbiAgICAgICAgICAgIGd1YWNfZGlzcGxheS5jdXJzb3JIb3RzcG90WSA9IGhvdHNwb3RZO1xyXG5cclxuICAgICAgICAgICAgLy8gUmVzZXQgY3Vyc29yIHNpemVcclxuICAgICAgICAgICAgY3Vyc29yLnJlc2l6ZShzcmN3LCBzcmNoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIERyYXcgY3Vyc29yIHRvIGN1cnNvciBsYXllclxyXG4gICAgICAgICAgICBjdXJzb3IuY29weShsYXllciwgc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCwgMCwgMCk7XHJcbiAgICAgICAgICAgIGd1YWNfZGlzcGxheS5tb3ZlQ3Vyc29yKGd1YWNfZGlzcGxheS5jdXJzb3JYLCBndWFjX2Rpc3BsYXkuY3Vyc29yWSk7XHJcblxyXG4gICAgICAgICAgICAvLyBGaXJlIGN1cnNvciBjaGFuZ2UgZXZlbnRcclxuICAgICAgICAgICAgaWYgKGd1YWNfZGlzcGxheS5vbmN1cnNvcilcclxuICAgICAgICAgICAgICAgIGd1YWNfZGlzcGxheS5vbmN1cnNvcihjdXJzb3IudG9DYW52YXMoKSwgaG90c3BvdFgsIGhvdHNwb3RZKTtcclxuXHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB3aGV0aGVyIHRoZSBzb2Z0d2FyZS1yZW5kZXJlZCBjdXJzb3IgaXMgc2hvd24uIFRoaXMgY3Vyc29yIGRpZmZlcnNcclxuICAgICAqIGZyb20gdGhlIGhhcmR3YXJlIGN1cnNvciBpbiB0aGF0IGl0IGlzIGJ1aWx0IGludG8gdGhlIEd1YWNhbW9sZS5EaXNwbGF5LFxyXG4gICAgICogYW5kIHJlbGllcyBvbiBpdHMgb3duIEd1YWNhbW9sZSBsYXllciB0byByZW5kZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBbc2hvd249dHJ1ZV0gV2hldGhlciB0byBzaG93IHRoZSBzb2Z0d2FyZSBjdXJzb3IuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2hvd0N1cnNvciA9IGZ1bmN0aW9uKHNob3duKSB7XHJcblxyXG4gICAgICAgIHZhciBlbGVtZW50ID0gY3Vyc29yLmdldEVsZW1lbnQoKTtcclxuICAgICAgICB2YXIgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xyXG5cclxuICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gaWYgaGlkZGVuXHJcbiAgICAgICAgaWYgKHNob3duID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBpZiAocGFyZW50KVxyXG4gICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBlbnN1cmUgY3Vyc29yIGlzIGNoaWxkIG9mIGRpc3BsYXlcclxuICAgICAgICBlbHNlIGlmIChwYXJlbnQgIT09IGRpc3BsYXkpXHJcbiAgICAgICAgICAgIGRpc3BsYXkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBsb2NhbCBjdXJzb3IgdG8gdGhlIGdpdmVuIGNvb3JkaW5hdGVzLiBGb3IgdGhlXHJcbiAgICAgKiBzYWtlIG9mIHJlc3BvbnNpdmVuZXNzLCB0aGlzIGZ1bmN0aW9uIHBlcmZvcm1zIGl0cyBhY3Rpb24gaW1tZWRpYXRlbHkuXHJcbiAgICAgKiBDdXJzb3IgbW90aW9uIGlzIG5vdCBtYWludGFpbmVkIHdpdGhpbiBhdG9taWMgZnJhbWVzLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgWCBjb29yZGluYXRlIHRvIG1vdmUgdGhlIGN1cnNvciB0by5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBZIGNvb3JkaW5hdGUgdG8gbW92ZSB0aGUgY3Vyc29yIHRvLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm1vdmVDdXJzb3IgPSBmdW5jdGlvbih4LCB5KSB7XHJcblxyXG4gICAgICAgIC8vIE1vdmUgY3Vyc29yIGxheWVyXHJcbiAgICAgICAgY3Vyc29yLnRyYW5zbGF0ZSh4IC0gZ3VhY19kaXNwbGF5LmN1cnNvckhvdHNwb3RYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgeSAtIGd1YWNfZGlzcGxheS5jdXJzb3JIb3RzcG90WSk7XHJcblxyXG4gICAgICAgIC8vIFVwZGF0ZSBzdG9yZWQgcG9zaXRpb25cclxuICAgICAgICBndWFjX2Rpc3BsYXkuY3Vyc29yWCA9IHg7XHJcbiAgICAgICAgZ3VhY19kaXNwbGF5LmN1cnNvclkgPSB5O1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGFuZ2VzIHRoZSBzaXplIG9mIHRoZSBnaXZlbiBMYXllciB0byB0aGUgZ2l2ZW4gd2lkdGggYW5kIGhlaWdodC5cclxuICAgICAqIFJlc2l6aW5nIGlzIG9ubHkgYXR0ZW1wdGVkIGlmIHRoZSBuZXcgc2l6ZSBwcm92aWRlZCBpcyBhY3R1YWxseSBkaWZmZXJlbnRcclxuICAgICAqIGZyb20gdGhlIGN1cnJlbnQgc2l6ZS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IGxheWVyIFRoZSBsYXllciB0byByZXNpemUuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gd2lkdGggVGhlIG5ldyB3aWR0aC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoZWlnaHQgVGhlIG5ldyBoZWlnaHQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVzaXplID0gZnVuY3Rpb24obGF5ZXIsIHdpZHRoLCBoZWlnaHQpIHtcclxuICAgICAgICBzY2hlZHVsZVRhc2soZnVuY3Rpb24gX19kaXNwbGF5X3Jlc2l6ZSgpIHtcclxuXHJcbiAgICAgICAgICAgIGxheWVyLnJlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcclxuXHJcbiAgICAgICAgICAgIC8vIFJlc2l6ZSBkaXNwbGF5IGlmIGRlZmF1bHQgbGF5ZXIgaXMgcmVzaXplZFxyXG4gICAgICAgICAgICBpZiAobGF5ZXIgPT09IGRlZmF1bHRfbGF5ZXIpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgKHNldCkgZGlzcGxheSBzaXplXHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5V2lkdGggPSB3aWR0aDtcclxuICAgICAgICAgICAgICAgIGRpc3BsYXlIZWlnaHQgPSBoZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5LnN0eWxlLndpZHRoID0gZGlzcGxheVdpZHRoICsgXCJweFwiO1xyXG4gICAgICAgICAgICAgICAgZGlzcGxheS5zdHlsZS5oZWlnaHQgPSBkaXNwbGF5SGVpZ2h0ICsgXCJweFwiO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBib3VuZHMgc2l6ZVxyXG4gICAgICAgICAgICAgICAgYm91bmRzLnN0eWxlLndpZHRoID0gKGRpc3BsYXlXaWR0aCpkaXNwbGF5U2NhbGUpICsgXCJweFwiO1xyXG4gICAgICAgICAgICAgICAgYm91bmRzLnN0eWxlLmhlaWdodCA9IChkaXNwbGF5SGVpZ2h0KmRpc3BsYXlTY2FsZSkgKyBcInB4XCI7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gTm90aWZ5IG9mIHJlc2l6ZVxyXG4gICAgICAgICAgICAgICAgaWYgKGd1YWNfZGlzcGxheS5vbnJlc2l6ZSlcclxuICAgICAgICAgICAgICAgICAgICBndWFjX2Rpc3BsYXkub25yZXNpemUod2lkdGgsIGhlaWdodCk7XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERyYXdzIHRoZSBzcGVjaWZpZWQgaW1hZ2UgYXQgdGhlIGdpdmVuIGNvb3JkaW5hdGVzLiBUaGUgaW1hZ2Ugc3BlY2lmaWVkXHJcbiAgICAgKiBtdXN0IGFscmVhZHkgYmUgbG9hZGVkLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gbGF5ZXIgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBkZXN0aW5hdGlvbiBYIGNvb3JkaW5hdGUuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgZGVzdGluYXRpb24gWSBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaW1hZ2UgVGhlIGltYWdlIHRvIGRyYXcuIE5vdGUgdGhhdCB0aGlzIGlzIGFuIEltYWdlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvYmplY3QgLSBub3QgYSBVUkwuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZHJhd0ltYWdlID0gZnVuY3Rpb24obGF5ZXIsIHgsIHksIGltYWdlKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9kcmF3SW1hZ2UoKSB7XHJcbiAgICAgICAgICAgIGxheWVyLmRyYXdJbWFnZSh4LCB5LCBpbWFnZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRHJhd3MgdGhlIGltYWdlIGNvbnRhaW5lZCB3aXRoaW4gdGhlIHNwZWNpZmllZCBCbG9iIGF0IHRoZSBnaXZlblxyXG4gICAgICogY29vcmRpbmF0ZXMuIFRoZSBCbG9iIHNwZWNpZmllZCBtdXN0IGFscmVhZHkgYmUgcG9wdWxhdGVkIHdpdGggaW1hZ2VcclxuICAgICAqIGRhdGEuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IGxheWVyXHJcbiAgICAgKiAgICAgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geFxyXG4gICAgICogICAgIFRoZSBkZXN0aW5hdGlvbiBYIGNvb3JkaW5hdGUuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHlcclxuICAgICAqICAgICBUaGUgZGVzdGluYXRpb24gWSBjb29yZGluYXRlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QmxvYn0gYmxvYlxyXG4gICAgICogICAgIFRoZSBCbG9iIGNvbnRhaW5pbmcgdGhlIGltYWdlIGRhdGEgdG8gZHJhdy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5kcmF3QmxvYiA9IGZ1bmN0aW9uKGxheWVyLCB4LCB5LCBibG9iKSB7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBVUkwgZm9yIGJsb2JcclxuICAgICAgICB2YXIgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxuXHJcbiAgICAgICAgLy8gRHJhdyBhbmQgZnJlZSBibG9iIFVSTCB3aGVuIHJlYWR5XHJcbiAgICAgICAgdmFyIHRhc2sgPSBzY2hlZHVsZVRhc2soZnVuY3Rpb24gX19kaXNwbGF5X2RyYXdCbG9iKCkge1xyXG5cclxuICAgICAgICAgICAgLy8gRHJhdyB0aGUgaW1hZ2Ugb25seSBpZiBpdCBsb2FkZWQgd2l0aG91dCBlcnJvcnNcclxuICAgICAgICAgICAgaWYgKGltYWdlLndpZHRoICYmIGltYWdlLmhlaWdodClcclxuICAgICAgICAgICAgICAgIGxheWVyLmRyYXdJbWFnZSh4LCB5LCBpbWFnZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBCbG9iIFVSTCBubyBsb25nZXIgbmVlZGVkXHJcbiAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcclxuXHJcbiAgICAgICAgfSwgdHJ1ZSk7XHJcblxyXG4gICAgICAgIC8vIExvYWQgaW1hZ2UgZnJvbSBVUkxcclxuICAgICAgICB2YXIgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcclxuICAgICAgICBpbWFnZS5vbmxvYWQgPSB0YXNrLnVuYmxvY2s7XHJcbiAgICAgICAgaW1hZ2Uub25lcnJvciA9IHRhc2sudW5ibG9jaztcclxuICAgICAgICBpbWFnZS5zcmMgPSB1cmw7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERyYXdzIHRoZSBpbWFnZSBhdCB0aGUgc3BlY2lmaWVkIFVSTCBhdCB0aGUgZ2l2ZW4gY29vcmRpbmF0ZXMuIFRoZSBpbWFnZVxyXG4gICAgICogd2lsbCBiZSBsb2FkZWQgYXV0b21hdGljYWxseSwgYW5kIHRoaXMgYW5kIGFueSBmdXR1cmUgb3BlcmF0aW9ucyB3aWxsXHJcbiAgICAgKiB3YWl0IGZvciB0aGUgaW1hZ2UgdG8gZmluaXNoIGxvYWRpbmcuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGRlc3RpbmF0aW9uIFggY29vcmRpbmF0ZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBkZXN0aW5hdGlvbiBZIGNvb3JkaW5hdGUuXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdXJsIFRoZSBVUkwgb2YgdGhlIGltYWdlIHRvIGRyYXcuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZHJhdyA9IGZ1bmN0aW9uKGxheWVyLCB4LCB5LCB1cmwpIHtcclxuXHJcbiAgICAgICAgdmFyIHRhc2sgPSBzY2hlZHVsZVRhc2soZnVuY3Rpb24gX19kaXNwbGF5X2RyYXcoKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBEcmF3IHRoZSBpbWFnZSBvbmx5IGlmIGl0IGxvYWRlZCB3aXRob3V0IGVycm9yc1xyXG4gICAgICAgICAgICBpZiAoaW1hZ2Uud2lkdGggJiYgaW1hZ2UuaGVpZ2h0KVxyXG4gICAgICAgICAgICAgICAgbGF5ZXIuZHJhd0ltYWdlKHgsIHksIGltYWdlKTtcclxuXHJcbiAgICAgICAgfSwgdHJ1ZSk7XHJcblxyXG4gICAgICAgIHZhciBpbWFnZSA9IG5ldyBJbWFnZSgpO1xyXG4gICAgICAgIGltYWdlLm9ubG9hZCA9IHRhc2sudW5ibG9jaztcclxuICAgICAgICBpbWFnZS5vbmVycm9yID0gdGFzay51bmJsb2NrO1xyXG4gICAgICAgIGltYWdlLnNyYyA9IHVybDtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGxheXMgdGhlIHZpZGVvIGF0IHRoZSBzcGVjaWZpZWQgVVJMIHdpdGhpbiB0aGlzIGxheWVyLiBUaGUgdmlkZW9cclxuICAgICAqIHdpbGwgYmUgbG9hZGVkIGF1dG9tYXRpY2FsbHksIGFuZCB0aGlzIGFuZCBhbnkgZnV0dXJlIG9wZXJhdGlvbnMgd2lsbFxyXG4gICAgICogd2FpdCBmb3IgdGhlIHZpZGVvIHRvIGZpbmlzaCBsb2FkaW5nLiBGdXR1cmUgb3BlcmF0aW9ucyB3aWxsIG5vdCBiZVxyXG4gICAgICogZXhlY3V0ZWQgdW50aWwgdGhlIHZpZGVvIGZpbmlzaGVzIHBsYXlpbmcuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlIFRoZSBtaW1ldHlwZSBvZiB0aGUgdmlkZW8gdG8gcGxheS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdXJhdGlvbiBUaGUgZHVyYXRpb24gb2YgdGhlIHZpZGVvIGluIG1pbGxpc2Vjb25kcy5cclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cmwgVGhlIFVSTCBvZiB0aGUgdmlkZW8gdG8gcGxheS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5wbGF5ID0gZnVuY3Rpb24obGF5ZXIsIG1pbWV0eXBlLCBkdXJhdGlvbiwgdXJsKSB7XHJcblxyXG4gICAgICAgIC8vIFN0YXJ0IGxvYWRpbmcgdGhlIHZpZGVvXHJcbiAgICAgICAgdmFyIHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInZpZGVvXCIpO1xyXG4gICAgICAgIHZpZGVvLnR5cGUgPSBtaW1ldHlwZTtcclxuICAgICAgICB2aWRlby5zcmMgPSB1cmw7XHJcblxyXG4gICAgICAgIC8vIFN0YXJ0IGNvcHlpbmcgZnJhbWVzIHdoZW4gcGxheWluZ1xyXG4gICAgICAgIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoXCJwbGF5XCIsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgZnVuY3Rpb24gcmVuZGVyX2NhbGxiYWNrKCkge1xyXG4gICAgICAgICAgICAgICAgbGF5ZXIuZHJhd0ltYWdlKDAsIDAsIHZpZGVvKTtcclxuICAgICAgICAgICAgICAgIGlmICghdmlkZW8uZW5kZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQocmVuZGVyX2NhbGxiYWNrLCAyMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHJlbmRlcl9jYWxsYmFjaygpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICB9LCBmYWxzZSk7XHJcblxyXG4gICAgICAgIHNjaGVkdWxlVGFzayh2aWRlby5wbGF5KTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHJhbnNmZXIgYSByZWN0YW5nbGUgb2YgaW1hZ2UgZGF0YSBmcm9tIG9uZSBMYXllciB0byB0aGlzIExheWVyIHVzaW5nIHRoZVxyXG4gICAgICogc3BlY2lmaWVkIHRyYW5zZmVyIGZ1bmN0aW9uLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gc3JjTGF5ZXIgVGhlIExheWVyIHRvIGNvcHkgaW1hZ2UgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY3ggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2UgTGF5ZXIncyBjb29yZGluYXRlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmN5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlIExheWVyJ3MgY29vcmRpbmF0ZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjdyBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZSBMYXllcidzXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY2ggVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBMYXllcidzIGNvb3JkaW5hdGUgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gZHN0TGF5ZXIgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBkZXN0aW5hdGlvbiBYIGNvb3JkaW5hdGUuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgZGVzdGluYXRpb24gWSBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNmZXJGdW5jdGlvbiBUaGUgdHJhbnNmZXIgZnVuY3Rpb24gdG8gdXNlIHRvXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZmVyIGRhdGEgZnJvbSBzb3VyY2UgdG9cclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb24uXHJcbiAgICAgKi9cclxuICAgIHRoaXMudHJhbnNmZXIgPSBmdW5jdGlvbihzcmNMYXllciwgc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCwgZHN0TGF5ZXIsIHgsIHksIHRyYW5zZmVyRnVuY3Rpb24pIHtcclxuICAgICAgICBzY2hlZHVsZVRhc2soZnVuY3Rpb24gX19kaXNwbGF5X3RyYW5zZmVyKCkge1xyXG4gICAgICAgICAgICBkc3RMYXllci50cmFuc2ZlcihzcmNMYXllciwgc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCwgeCwgeSwgdHJhbnNmZXJGdW5jdGlvbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHV0IGEgcmVjdGFuZ2xlIG9mIGltYWdlIGRhdGEgZnJvbSBvbmUgTGF5ZXIgdG8gdGhpcyBMYXllciBkaXJlY3RseVxyXG4gICAgICogd2l0aG91dCBwZXJmb3JtaW5nIGFueSBhbHBoYSBibGVuZGluZy4gU2ltcGx5IGNvcHkgdGhlIGRhdGEuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBzcmNMYXllciBUaGUgTGF5ZXIgdG8gY29weSBpbWFnZSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjeCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZSBMYXllcidzIGNvb3JkaW5hdGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY3kgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2UgTGF5ZXIncyBjb29yZGluYXRlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmN3IFRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlIExheWVyJ3NcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGUgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjaCBUaGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2VcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIExheWVyJ3MgY29vcmRpbmF0ZSBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBkc3RMYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGRlc3RpbmF0aW9uIFggY29vcmRpbmF0ZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBkZXN0aW5hdGlvbiBZIGNvb3JkaW5hdGUuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucHV0ID0gZnVuY3Rpb24oc3JjTGF5ZXIsIHNyY3gsIHNyY3ksIHNyY3csIHNyY2gsIGRzdExheWVyLCB4LCB5KSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9wdXQoKSB7XHJcbiAgICAgICAgICAgIGRzdExheWVyLnB1dChzcmNMYXllciwgc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCwgeCwgeSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29weSBhIHJlY3RhbmdsZSBvZiBpbWFnZSBkYXRhIGZyb20gb25lIExheWVyIHRvIHRoaXMgTGF5ZXIuIFRoaXNcclxuICAgICAqIG9wZXJhdGlvbiB3aWxsIGNvcHkgZXhhY3RseSB0aGUgaW1hZ2UgZGF0YSB0aGF0IHdpbGwgYmUgZHJhd24gb25jZSBhbGxcclxuICAgICAqIG9wZXJhdGlvbnMgb2YgdGhlIHNvdXJjZSBMYXllciB0aGF0IHdlcmUgcGVuZGluZyBhdCB0aGUgdGltZSB0aGlzXHJcbiAgICAgKiBmdW5jdGlvbiB3YXMgY2FsbGVkIGFyZSBjb21wbGV0ZS4gVGhpcyBvcGVyYXRpb24gd2lsbCBub3QgYWx0ZXIgdGhlXHJcbiAgICAgKiBzaXplIG9mIHRoZSBzb3VyY2UgTGF5ZXIgZXZlbiBpZiBpdHMgYXV0b3NpemUgcHJvcGVydHkgaXMgc2V0IHRvIHRydWUuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBzcmNMYXllciBUaGUgTGF5ZXIgdG8gY29weSBpbWFnZSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjeCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZSBMYXllcidzIGNvb3JkaW5hdGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY3kgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2UgTGF5ZXIncyBjb29yZGluYXRlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmN3IFRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlIExheWVyJ3NcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGUgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjaCBUaGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2VcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIExheWVyJ3MgY29vcmRpbmF0ZSBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBkc3RMYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGRlc3RpbmF0aW9uIFggY29vcmRpbmF0ZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBkZXN0aW5hdGlvbiBZIGNvb3JkaW5hdGUuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY29weSA9IGZ1bmN0aW9uKHNyY0xheWVyLCBzcmN4LCBzcmN5LCBzcmN3LCBzcmNoLCBkc3RMYXllciwgeCwgeSkge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfY29weSgpIHtcclxuICAgICAgICAgICAgZHN0TGF5ZXIuY29weShzcmNMYXllciwgc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCwgeCwgeSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3RhcnRzIGEgbmV3IHBhdGggYXQgdGhlIHNwZWNpZmllZCBwb2ludC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IGxheWVyIFRoZSBsYXllciB0byBkcmF3IHVwb24uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB0byBkcmF3LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgdG8gZHJhdy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5tb3ZlVG8gPSBmdW5jdGlvbihsYXllciwgeCwgeSkge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfbW92ZVRvKCkge1xyXG4gICAgICAgICAgICBsYXllci5tb3ZlVG8oeCwgeSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkIHRoZSBzcGVjaWZpZWQgbGluZSB0byB0aGUgY3VycmVudCBwYXRoLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gbGF5ZXIgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGVuZHBvaW50IG9mIHRoZSBsaW5lIHRvIGRyYXcuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBlbmRwb2ludCBvZiB0aGUgbGluZSB0byBkcmF3LlxyXG4gICAgICovXHJcbiAgICB0aGlzLmxpbmVUbyA9IGZ1bmN0aW9uKGxheWVyLCB4LCB5KSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9saW5lVG8oKSB7XHJcbiAgICAgICAgICAgIGxheWVyLmxpbmVUbyh4LCB5KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGQgdGhlIHNwZWNpZmllZCBhcmMgdG8gdGhlIGN1cnJlbnQgcGF0aC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IGxheWVyIFRoZSBsYXllciB0byBkcmF3IHVwb24uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBjZW50ZXIgb2YgdGhlIGNpcmNsZSB3aGljaFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgd2lsbCBjb250YWluIHRoZSBhcmMuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBjZW50ZXIgb2YgdGhlIGNpcmNsZSB3aGljaFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgd2lsbCBjb250YWluIHRoZSBhcmMuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcmFkaXVzIFRoZSByYWRpdXMgb2YgdGhlIGNpcmNsZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydEFuZ2xlIFRoZSBzdGFydGluZyBhbmdsZSBvZiB0aGUgYXJjLCBpbiByYWRpYW5zLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGVuZEFuZ2xlIFRoZSBlbmRpbmcgYW5nbGUgb2YgdGhlIGFyYywgaW4gcmFkaWFucy5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbmVnYXRpdmUgV2hldGhlciB0aGUgYXJjIHNob3VsZCBiZSBkcmF3biBpbiBvcmRlciBvZlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzaW5nIGFuZ2xlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmFyYyA9IGZ1bmN0aW9uKGxheWVyLCB4LCB5LCByYWRpdXMsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBuZWdhdGl2ZSkge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfYXJjKCkge1xyXG4gICAgICAgICAgICBsYXllci5hcmMoeCwgeSwgcmFkaXVzLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgbmVnYXRpdmUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0YXJ0cyBhIG5ldyBwYXRoIGF0IHRoZSBzcGVjaWZpZWQgcG9pbnQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNwMXggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgY29udHJvbCBwb2ludC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjcDF5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY3AyeCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjcDJ5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBjb250cm9sIHBvaW50LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZW5kcG9pbnQgb2YgdGhlIGN1cnZlLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgZW5kcG9pbnQgb2YgdGhlIGN1cnZlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmN1cnZlVG8gPSBmdW5jdGlvbihsYXllciwgY3AxeCwgY3AxeSwgY3AyeCwgY3AyeSwgeCwgeSkge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfY3VydmVUbygpIHtcclxuICAgICAgICAgICAgbGF5ZXIuY3VydmVUbyhjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDbG9zZXMgdGhlIGN1cnJlbnQgcGF0aCBieSBjb25uZWN0aW5nIHRoZSBlbmQgcG9pbnQgd2l0aCB0aGUgc3RhcnRcclxuICAgICAqIHBvaW50IChpZiBhbnkpIHdpdGggYSBzdHJhaWdodCBsaW5lLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gbGF5ZXIgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqL1xyXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uKGxheWVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9jbG9zZSgpIHtcclxuICAgICAgICAgICAgbGF5ZXIuY2xvc2UoKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGQgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgdG8gdGhlIGN1cnJlbnQgcGF0aC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IGxheWVyIFRoZSBsYXllciB0byBkcmF3IHVwb24uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSB0byBkcmF3LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgdG8gZHJhdy5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB3IFRoZSB3aWR0aCBvZiB0aGUgcmVjdGFuZ2xlIHRvIGRyYXcuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaCBUaGUgaGVpZ2h0IG9mIHRoZSByZWN0YW5nbGUgdG8gZHJhdy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5yZWN0ID0gZnVuY3Rpb24obGF5ZXIsIHgsIHksIHcsIGgpIHtcclxuICAgICAgICBzY2hlZHVsZVRhc2soZnVuY3Rpb24gX19kaXNwbGF5X3JlY3QoKSB7XHJcbiAgICAgICAgICAgIGxheWVyLnJlY3QoeCwgeSwgdywgaCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xpcCBhbGwgZnV0dXJlIGRyYXdpbmcgb3BlcmF0aW9ucyBieSB0aGUgY3VycmVudCBwYXRoLiBUaGUgY3VycmVudCBwYXRoXHJcbiAgICAgKiBpcyBpbXBsaWNpdGx5IGNsb3NlZC4gVGhlIGN1cnJlbnQgcGF0aCBjYW4gY29udGludWUgdG8gYmUgcmV1c2VkXHJcbiAgICAgKiBmb3Igb3RoZXIgb3BlcmF0aW9ucyAoc3VjaCBhcyBmaWxsQ29sb3IoKSkgYnV0IGEgbmV3IHBhdGggd2lsbCBiZSBzdGFydGVkXHJcbiAgICAgKiBvbmNlIGEgcGF0aCBkcmF3aW5nIG9wZXJhdGlvbiAocGF0aCgpIG9yIHJlY3QoKSkgaXMgdXNlZC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IGxheWVyIFRoZSBsYXllciB0byBhZmZlY3QuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY2xpcCA9IGZ1bmN0aW9uKGxheWVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9jbGlwKCkge1xyXG4gICAgICAgICAgICBsYXllci5jbGlwKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3Ryb2tlIHRoZSBjdXJyZW50IHBhdGggd2l0aCB0aGUgc3BlY2lmaWVkIGNvbG9yLiBUaGUgY3VycmVudCBwYXRoXHJcbiAgICAgKiBpcyBpbXBsaWNpdGx5IGNsb3NlZC4gVGhlIGN1cnJlbnQgcGF0aCBjYW4gY29udGludWUgdG8gYmUgcmV1c2VkXHJcbiAgICAgKiBmb3Igb3RoZXIgb3BlcmF0aW9ucyAoc3VjaCBhcyBjbGlwKCkpIGJ1dCBhIG5ldyBwYXRoIHdpbGwgYmUgc3RhcnRlZFxyXG4gICAgICogb25jZSBhIHBhdGggZHJhd2luZyBvcGVyYXRpb24gKHBhdGgoKSBvciByZWN0KCkpIGlzIHVzZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNhcCBUaGUgbGluZSBjYXAgc3R5bGUuIENhbiBiZSBcInJvdW5kXCIsIFwic3F1YXJlXCIsXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIG9yIFwiYnV0dFwiLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGpvaW4gVGhlIGxpbmUgam9pbiBzdHlsZS4gQ2FuIGJlIFwicm91bmRcIiwgXCJiZXZlbFwiLFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgb3IgXCJtaXRlclwiLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRoaWNrbmVzcyBUaGUgbGluZSB0aGlja25lc3MgaW4gcGl4ZWxzLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHIgVGhlIHJlZCBjb21wb25lbnQgb2YgdGhlIGNvbG9yIHRvIGZpbGwuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZyBUaGUgZ3JlZW4gY29tcG9uZW50IG9mIHRoZSBjb2xvciB0byBmaWxsLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGIgVGhlIGJsdWUgY29tcG9uZW50IG9mIHRoZSBjb2xvciB0byBmaWxsLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGEgVGhlIGFscGhhIGNvbXBvbmVudCBvZiB0aGUgY29sb3IgdG8gZmlsbC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zdHJva2VDb2xvciA9IGZ1bmN0aW9uKGxheWVyLCBjYXAsIGpvaW4sIHRoaWNrbmVzcywgciwgZywgYiwgYSkge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfc3Ryb2tlQ29sb3IoKSB7XHJcbiAgICAgICAgICAgIGxheWVyLnN0cm9rZUNvbG9yKGNhcCwgam9pbiwgdGhpY2tuZXNzLCByLCBnLCBiLCBhKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaWxscyB0aGUgY3VycmVudCBwYXRoIHdpdGggdGhlIHNwZWNpZmllZCBjb2xvci4gVGhlIGN1cnJlbnQgcGF0aFxyXG4gICAgICogaXMgaW1wbGljaXRseSBjbG9zZWQuIFRoZSBjdXJyZW50IHBhdGggY2FuIGNvbnRpbnVlIHRvIGJlIHJldXNlZFxyXG4gICAgICogZm9yIG90aGVyIG9wZXJhdGlvbnMgKHN1Y2ggYXMgY2xpcCgpKSBidXQgYSBuZXcgcGF0aCB3aWxsIGJlIHN0YXJ0ZWRcclxuICAgICAqIG9uY2UgYSBwYXRoIGRyYXdpbmcgb3BlcmF0aW9uIChwYXRoKCkgb3IgcmVjdCgpKSBpcyB1c2VkLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gbGF5ZXIgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSByIFRoZSByZWQgY29tcG9uZW50IG9mIHRoZSBjb2xvciB0byBmaWxsLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGcgVGhlIGdyZWVuIGNvbXBvbmVudCBvZiB0aGUgY29sb3IgdG8gZmlsbC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBibHVlIGNvbXBvbmVudCBvZiB0aGUgY29sb3IgdG8gZmlsbC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBhbHBoYSBjb21wb25lbnQgb2YgdGhlIGNvbG9yIHRvIGZpbGwuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZmlsbENvbG9yID0gZnVuY3Rpb24obGF5ZXIsIHIsIGcsIGIsIGEpIHtcclxuICAgICAgICBzY2hlZHVsZVRhc2soZnVuY3Rpb24gX19kaXNwbGF5X2ZpbGxDb2xvcigpIHtcclxuICAgICAgICAgICAgbGF5ZXIuZmlsbENvbG9yKHIsIGcsIGIsIGEpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0cm9rZSB0aGUgY3VycmVudCBwYXRoIHdpdGggdGhlIGltYWdlIHdpdGhpbiB0aGUgc3BlY2lmaWVkIGxheWVyLiBUaGVcclxuICAgICAqIGltYWdlIGRhdGEgd2lsbCBiZSB0aWxlZCBpbmZpbml0ZWx5IHdpdGhpbiB0aGUgc3Ryb2tlLiBUaGUgY3VycmVudCBwYXRoXHJcbiAgICAgKiBpcyBpbXBsaWNpdGx5IGNsb3NlZC4gVGhlIGN1cnJlbnQgcGF0aCBjYW4gY29udGludWUgdG8gYmUgcmV1c2VkXHJcbiAgICAgKiBmb3Igb3RoZXIgb3BlcmF0aW9ucyAoc3VjaCBhcyBjbGlwKCkpIGJ1dCBhIG5ldyBwYXRoIHdpbGwgYmUgc3RhcnRlZFxyXG4gICAgICogb25jZSBhIHBhdGggZHJhd2luZyBvcGVyYXRpb24gKHBhdGgoKSBvciByZWN0KCkpIGlzIHVzZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNhcCBUaGUgbGluZSBjYXAgc3R5bGUuIENhbiBiZSBcInJvdW5kXCIsIFwic3F1YXJlXCIsXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIG9yIFwiYnV0dFwiLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGpvaW4gVGhlIGxpbmUgam9pbiBzdHlsZS4gQ2FuIGJlIFwicm91bmRcIiwgXCJiZXZlbFwiLFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgb3IgXCJtaXRlclwiLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRoaWNrbmVzcyBUaGUgbGluZSB0aGlja25lc3MgaW4gcGl4ZWxzLlxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IHNyY0xheWVyIFRoZSBsYXllciB0byB1c2UgYXMgYSByZXBlYXRpbmcgcGF0dGVyblxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGhpbiB0aGUgc3Ryb2tlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnN0cm9rZUxheWVyID0gZnVuY3Rpb24obGF5ZXIsIGNhcCwgam9pbiwgdGhpY2tuZXNzLCBzcmNMYXllcikge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfc3Ryb2tlTGF5ZXIoKSB7XHJcbiAgICAgICAgICAgIGxheWVyLnN0cm9rZUxheWVyKGNhcCwgam9pbiwgdGhpY2tuZXNzLCBzcmNMYXllcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlsbHMgdGhlIGN1cnJlbnQgcGF0aCB3aXRoIHRoZSBpbWFnZSB3aXRoaW4gdGhlIHNwZWNpZmllZCBsYXllci4gVGhlXHJcbiAgICAgKiBpbWFnZSBkYXRhIHdpbGwgYmUgdGlsZWQgaW5maW5pdGVseSB3aXRoaW4gdGhlIHN0cm9rZS4gVGhlIGN1cnJlbnQgcGF0aFxyXG4gICAgICogaXMgaW1wbGljaXRseSBjbG9zZWQuIFRoZSBjdXJyZW50IHBhdGggY2FuIGNvbnRpbnVlIHRvIGJlIHJldXNlZFxyXG4gICAgICogZm9yIG90aGVyIG9wZXJhdGlvbnMgKHN1Y2ggYXMgY2xpcCgpKSBidXQgYSBuZXcgcGF0aCB3aWxsIGJlIHN0YXJ0ZWRcclxuICAgICAqIG9uY2UgYSBwYXRoIGRyYXdpbmcgb3BlcmF0aW9uIChwYXRoKCkgb3IgcmVjdCgpKSBpcyB1c2VkLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gbGF5ZXIgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBzcmNMYXllciBUaGUgbGF5ZXIgdG8gdXNlIGFzIGEgcmVwZWF0aW5nIHBhdHRlcm5cclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoaW4gdGhlIGZpbGwuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZmlsbExheWVyID0gZnVuY3Rpb24obGF5ZXIsIHNyY0xheWVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9maWxsTGF5ZXIoKSB7XHJcbiAgICAgICAgICAgIGxheWVyLmZpbGxMYXllcihzcmNMYXllcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHVzaCBjdXJyZW50IGxheWVyIHN0YXRlIG9udG8gc3RhY2suXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnB1c2ggPSBmdW5jdGlvbihsYXllcikge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfcHVzaCgpIHtcclxuICAgICAgICAgICAgbGF5ZXIucHVzaCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFBvcCBsYXllciBzdGF0ZSBvZmYgc3RhY2suXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gZHJhdyB1cG9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnBvcCA9IGZ1bmN0aW9uKGxheWVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9wb3AoKSB7XHJcbiAgICAgICAgICAgIGxheWVyLnBvcCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc2V0IHRoZSBsYXllciwgY2xlYXJpbmcgdGhlIHN0YWNrLCB0aGUgY3VycmVudCBwYXRoLCBhbmQgYW55IHRyYW5zZm9ybVxyXG4gICAgICogbWF0cml4LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gbGF5ZXIgVGhlIGxheWVyIHRvIGRyYXcgdXBvbi5cclxuICAgICAqL1xyXG4gICAgdGhpcy5yZXNldCA9IGZ1bmN0aW9uKGxheWVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9yZXNldCgpIHtcclxuICAgICAgICAgICAgbGF5ZXIucmVzZXQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBnaXZlbiBhZmZpbmUgdHJhbnNmb3JtIChkZWZpbmVkIHdpdGggc2l4IHZhbHVlcyBmcm9tIHRoZVxyXG4gICAgICogdHJhbnNmb3JtJ3MgbWF0cml4KS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IGxheWVyIFRoZSBsYXllciB0byBtb2RpZnkuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgZmlyc3QgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGMgVGhlIHRoaXJkIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGQgVGhlIGZvdXJ0aCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBlIFRoZSBmaWZ0aCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBmIFRoZSBzaXh0aCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZXRUcmFuc2Zvcm0gPSBmdW5jdGlvbihsYXllciwgYSwgYiwgYywgZCwgZSwgZikge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfc2V0VHJhbnNmb3JtKCkge1xyXG4gICAgICAgICAgICBsYXllci5zZXRUcmFuc2Zvcm0oYSwgYiwgYywgZCwgZSwgZik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwbGllcyB0aGUgZ2l2ZW4gYWZmaW5lIHRyYW5zZm9ybSAoZGVmaW5lZCB3aXRoIHNpeCB2YWx1ZXMgZnJvbSB0aGVcclxuICAgICAqIHRyYW5zZm9ybSdzIG1hdHJpeCkuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gbW9kaWZ5LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGEgVGhlIGZpcnN0IHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGIgVGhlIHNlY29uZCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSB0aGlyZCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkIFRoZSBmb3VydGggdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZSBUaGUgZmlmdGggdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZiBUaGUgc2l4dGggdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKi9cclxuICAgIHRoaXMudHJhbnNmb3JtID0gZnVuY3Rpb24obGF5ZXIsIGEsIGIsIGMsIGQsIGUsIGYpIHtcclxuICAgICAgICBzY2hlZHVsZVRhc2soZnVuY3Rpb24gX19kaXNwbGF5X3RyYW5zZm9ybSgpIHtcclxuICAgICAgICAgICAgbGF5ZXIudHJhbnNmb3JtKGEsIGIsIGMsIGQsIGUsIGYpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGNoYW5uZWwgbWFzayBmb3IgZnV0dXJlIG9wZXJhdGlvbnMgb24gdGhpcyBMYXllci5cclxuICAgICAqIFxyXG4gICAgICogVGhlIGNoYW5uZWwgbWFzayBpcyBhIEd1YWNhbW9sZS1zcGVjaWZpYyBjb21wb3NpdGluZyBvcGVyYXRpb24gaWRlbnRpZmllclxyXG4gICAgICogd2l0aCBhIHNpbmdsZSBiaXQgcmVwcmVzZW50aW5nIGVhY2ggb2YgZm91ciBjaGFubmVscyAoaW4gb3JkZXIpOiBzb3VyY2VcclxuICAgICAqIGltYWdlIHdoZXJlIGRlc3RpbmF0aW9uIHRyYW5zcGFyZW50LCBzb3VyY2Ugd2hlcmUgZGVzdGluYXRpb24gb3BhcXVlLFxyXG4gICAgICogZGVzdGluYXRpb24gd2hlcmUgc291cmNlIHRyYW5zcGFyZW50LCBhbmQgZGVzdGluYXRpb24gd2hlcmUgc291cmNlXHJcbiAgICAgKiBvcGFxdWUuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gbW9kaWZ5LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1hc2sgVGhlIGNoYW5uZWwgbWFzayBmb3IgZnV0dXJlIG9wZXJhdGlvbnMgb24gdGhpc1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgTGF5ZXIuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2V0Q2hhbm5lbE1hc2sgPSBmdW5jdGlvbihsYXllciwgbWFzaykge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBfX2Rpc3BsYXlfc2V0Q2hhbm5lbE1hc2soKSB7XHJcbiAgICAgICAgICAgIGxheWVyLnNldENoYW5uZWxNYXNrKG1hc2spO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIG1pdGVyIGxpbWl0IGZvciBzdHJva2Ugb3BlcmF0aW9ucyB1c2luZyB0aGUgbWl0ZXIgam9pbi4gVGhpc1xyXG4gICAgICogbGltaXQgaXMgdGhlIG1heGltdW0gcmF0aW8gb2YgdGhlIHNpemUgb2YgdGhlIG1pdGVyIGpvaW4gdG8gdGhlIHN0cm9rZVxyXG4gICAgICogd2lkdGguIElmIHRoaXMgcmF0aW8gaXMgZXhjZWVkZWQsIHRoZSBtaXRlciB3aWxsIG5vdCBiZSBkcmF3biBmb3IgdGhhdFxyXG4gICAgICogam9pbnQgb2YgdGhlIHBhdGguXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkxheWVyfSBsYXllciBUaGUgbGF5ZXIgdG8gbW9kaWZ5LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxpbWl0IFRoZSBtaXRlciBsaW1pdCBmb3Igc3Ryb2tlIG9wZXJhdGlvbnMgdXNpbmcgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgbWl0ZXIgam9pbi5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZXRNaXRlckxpbWl0ID0gZnVuY3Rpb24obGF5ZXIsIGxpbWl0KSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIF9fZGlzcGxheV9zZXRNaXRlckxpbWl0KCkge1xyXG4gICAgICAgICAgICBsYXllci5zZXRNaXRlckxpbWl0KGxpbWl0KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIHRoZSBnaXZlbiBsYXllciBjb250YWluZXIgZW50aXJlbHksIHN1Y2ggdGhhdCBpdCBpcyBubyBsb25nZXJcclxuICAgICAqIGNvbnRhaW5lZCB3aXRoaW4gaXRzIHBhcmVudCBsYXllciwgaWYgYW55LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLkRpc3BsYXkuVmlzaWJsZUxheWVyfSBsYXllclxyXG4gICAgICogICAgIFRoZSBsYXllciBiZWluZyByZW1vdmVkIGZyb20gaXRzIHBhcmVudC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5kaXNwb3NlID0gZnVuY3Rpb24gZGlzcG9zZShsYXllcikge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBkaXNwb3NlTGF5ZXIoKSB7XHJcbiAgICAgICAgICAgIGxheWVyLmRpc3Bvc2UoKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBsaWVzIHRoZSBnaXZlbiBhZmZpbmUgdHJhbnNmb3JtIChkZWZpbmVkIHdpdGggc2l4IHZhbHVlcyBmcm9tIHRoZVxyXG4gICAgICogdHJhbnNmb3JtJ3MgbWF0cml4KSB0byB0aGUgZ2l2ZW4gbGF5ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuRGlzcGxheS5WaXNpYmxlTGF5ZXJ9IGxheWVyXHJcbiAgICAgKiAgICAgVGhlIGxheWVyIGJlaW5nIGRpc3RvcnRlZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYVxyXG4gICAgICogICAgIFRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYlxyXG4gICAgICogICAgIFRoZSBzZWNvbmQgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNcclxuICAgICAqICAgICBUaGUgdGhpcmQgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGRcclxuICAgICAqICAgICBUaGUgZm91cnRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBlXHJcbiAgICAgKiAgICAgVGhlIGZpZnRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBmXHJcbiAgICAgKiAgICAgVGhlIHNpeHRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICovXHJcbiAgICB0aGlzLmRpc3RvcnQgPSBmdW5jdGlvbiBkaXN0b3J0KGxheWVyLCBhLCBiLCBjLCBkLCBlLCBmKSB7XHJcbiAgICAgICAgc2NoZWR1bGVUYXNrKGZ1bmN0aW9uIGRpc3RvcnRMYXllcigpIHtcclxuICAgICAgICAgICAgbGF5ZXIuZGlzdG9ydChhLCBiLCBjLCBkLCBlLCBmKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNb3ZlcyB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGdpdmVuIGxheWVyIHRvIHRoZSBnaXZlbiBYIGFuZCBZXHJcbiAgICAgKiBjb29yZGluYXRlLCBzZXRzIHRoZSBaIHN0YWNraW5nIG9yZGVyLCBhbmQgcmVwYXJlbnRzIHRoZSBsYXllclxyXG4gICAgICogdG8gdGhlIGdpdmVuIHBhcmVudCBsYXllci5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcn0gbGF5ZXJcclxuICAgICAqICAgICBUaGUgbGF5ZXIgYmVpbmcgbW92ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuRGlzcGxheS5WaXNpYmxlTGF5ZXJ9IHBhcmVudFxyXG4gICAgICogICAgIFRoZSBwYXJlbnQgdG8gc2V0LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4XHJcbiAgICAgKiAgICAgVGhlIFggY29vcmRpbmF0ZSB0byBtb3ZlIHRvLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5XHJcbiAgICAgKiAgICAgVGhlIFkgY29vcmRpbmF0ZSB0byBtb3ZlIHRvLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB6XHJcbiAgICAgKiAgICAgVGhlIFogY29vcmRpbmF0ZSB0byBtb3ZlIHRvLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm1vdmUgPSBmdW5jdGlvbiBtb3ZlKGxheWVyLCBwYXJlbnQsIHgsIHksIHopIHtcclxuICAgICAgICBzY2hlZHVsZVRhc2soZnVuY3Rpb24gbW92ZUxheWVyKCkge1xyXG4gICAgICAgICAgICBsYXllci5tb3ZlKHBhcmVudCwgeCwgeSwgeik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgb3BhY2l0eSBvZiB0aGUgZ2l2ZW4gbGF5ZXIgdG8gdGhlIGdpdmVuIHZhbHVlLCB3aGVyZSAyNTUgaXNcclxuICAgICAqIGZ1bGx5IG9wYXF1ZSBhbmQgMCBpcyBmdWxseSB0cmFuc3BhcmVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcn0gbGF5ZXJcclxuICAgICAqICAgICBUaGUgbGF5ZXIgd2hvc2Ugb3BhY2l0eSBzaG91bGQgYmUgc2V0LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhbHBoYVxyXG4gICAgICogICAgIFRoZSBvcGFjaXR5IHRvIHNldC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zaGFkZSA9IGZ1bmN0aW9uIHNoYWRlKGxheWVyLCBhbHBoYSkge1xyXG4gICAgICAgIHNjaGVkdWxlVGFzayhmdW5jdGlvbiBzaGFkZUxheWVyKCkge1xyXG4gICAgICAgICAgICBsYXllci5zaGFkZShhbHBoYSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgc2NhbGUgb2YgdGhlIGNsaWVudCBkaXNwbGF5IGVsZW1lbnQgc3VjaCB0aGF0IGl0IHJlbmRlcnMgYXRcclxuICAgICAqIGEgcmVsYXRpdmVseSBzbWFsbGVyIG9yIGxhcmdlciBzaXplLCB3aXRob3V0IGFmZmVjdGluZyB0aGUgdHJ1ZVxyXG4gICAgICogcmVzb2x1dGlvbiBvZiB0aGUgZGlzcGxheS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc2NhbGUgVGhlIHNjYWxlIHRvIHJlc2l6ZSB0bywgd2hlcmUgMS4wIGlzIG5vcm1hbFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgIHNpemUgKDE6MSBzY2FsZSkuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2NhbGUgPSBmdW5jdGlvbihzY2FsZSkge1xyXG5cclxuICAgICAgICBkaXNwbGF5LnN0eWxlLnRyYW5zZm9ybSA9XHJcbiAgICAgICAgZGlzcGxheS5zdHlsZS5XZWJraXRUcmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpc3BsYXkuc3R5bGUuTW96VHJhbnNmb3JtID1cclxuICAgICAgICBkaXNwbGF5LnN0eWxlLk9UcmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpc3BsYXkuc3R5bGUubXNUcmFuc2Zvcm0gPVxyXG5cclxuICAgICAgICAgICAgXCJzY2FsZShcIiArIHNjYWxlICsgXCIsXCIgKyBzY2FsZSArIFwiKVwiO1xyXG5cclxuICAgICAgICBkaXNwbGF5U2NhbGUgPSBzY2FsZTtcclxuXHJcbiAgICAgICAgLy8gVXBkYXRlIGJvdW5kcyBzaXplXHJcbiAgICAgICAgYm91bmRzLnN0eWxlLndpZHRoID0gKGRpc3BsYXlXaWR0aCpkaXNwbGF5U2NhbGUpICsgXCJweFwiO1xyXG4gICAgICAgIGJvdW5kcy5zdHlsZS5oZWlnaHQgPSAoZGlzcGxheUhlaWdodCpkaXNwbGF5U2NhbGUpICsgXCJweFwiO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2FsZSBvZiB0aGUgZGlzcGxheS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IFRoZSBzY2FsZSBvZiB0aGUgZGlzcGxheS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5nZXRTY2FsZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBkaXNwbGF5U2NhbGU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIGNhbnZhcyBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGVudGlyZSBkaXNwbGF5LCB3aXRoIGFsbCBjaGlsZFxyXG4gICAgICogbGF5ZXJzIGNvbXBvc2l0ZWQgd2l0aGluLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fSBBIG5ldyBjYW52YXMgZWxlbWVudCBjb250YWluaW5nIGEgY29weSBvZlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBkaXNwbGF5LlxyXG4gICAgICovXHJcbiAgICB0aGlzLmZsYXR0ZW4gPSBmdW5jdGlvbigpIHtcclxuICAgICAgIFxyXG4gICAgICAgIC8vIEdldCBkZXN0aW5hdGlvbiBjYW52YXNcclxuICAgICAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcclxuICAgICAgICBjYW52YXMud2lkdGggPSBkZWZhdWx0X2xheWVyLndpZHRoO1xyXG4gICAgICAgIGNhbnZhcy5oZWlnaHQgPSBkZWZhdWx0X2xheWVyLmhlaWdodDtcclxuXHJcbiAgICAgICAgdmFyIGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG5cclxuICAgICAgICAvLyBSZXR1cm5zIHNvcnRlZCBhcnJheSBvZiBjaGlsZHJlblxyXG4gICAgICAgIGZ1bmN0aW9uIGdldF9jaGlsZHJlbihsYXllcikge1xyXG5cclxuICAgICAgICAgICAgLy8gQnVpbGQgYXJyYXkgb2YgY2hpbGRyZW5cclxuICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gW107XHJcbiAgICAgICAgICAgIGZvciAodmFyIGluZGV4IGluIGxheWVyLmNoaWxkcmVuKVxyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChsYXllci5jaGlsZHJlbltpbmRleF0pO1xyXG5cclxuICAgICAgICAgICAgLy8gU29ydFxyXG4gICAgICAgICAgICBjaGlsZHJlbi5zb3J0KGZ1bmN0aW9uIGNoaWxkcmVuX2NvbXBhcmF0b3IoYSwgYikge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIENvbXBhcmUgYmFzZWQgb24gWiBvcmRlclxyXG4gICAgICAgICAgICAgICAgdmFyIGRpZmYgPSBhLnogLSBiLno7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGlmZiAhPT0gMClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlmZjtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiBaIG9yZGVyIGlkZW50aWNhbCwgdXNlIGRvY3VtZW50IG9yZGVyXHJcbiAgICAgICAgICAgICAgICB2YXIgYV9lbGVtZW50ID0gYS5nZXRFbGVtZW50KCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgYl9lbGVtZW50ID0gYi5nZXRFbGVtZW50KCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgcG9zaXRpb24gPSBiX2VsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYV9lbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX1BSRUNFRElORykgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9GT0xMT1dJTkcpIHJldHVybiAgMTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIGFzc3VtZSBzYW1lXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcclxuXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gRG9uZVxyXG4gICAgICAgICAgICByZXR1cm4gY2hpbGRyZW47XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRHJhd3MgdGhlIGNvbnRlbnRzIG9mIHRoZSBnaXZlbiBsYXllciBhdCB0aGUgZ2l2ZW4gY29vcmRpbmF0ZXNcclxuICAgICAgICBmdW5jdGlvbiBkcmF3X2xheWVyKGxheWVyLCB4LCB5KSB7XHJcblxyXG4gICAgICAgICAgICAvLyBEcmF3IGxheWVyXHJcbiAgICAgICAgICAgIGlmIChsYXllci53aWR0aCA+IDAgJiYgbGF5ZXIuaGVpZ2h0ID4gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFNhdmUgYW5kIHVwZGF0ZSBhbHBoYVxyXG4gICAgICAgICAgICAgICAgdmFyIGluaXRpYWxfYWxwaGEgPSBjb250ZXh0Lmdsb2JhbEFscGhhO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5nbG9iYWxBbHBoYSAqPSBsYXllci5hbHBoYSAvIDI1NS4wO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIENvcHkgZGF0YVxyXG4gICAgICAgICAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UobGF5ZXIuZ2V0Q2FudmFzKCksIHgsIHkpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIERyYXcgYWxsIGNoaWxkcmVuXHJcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBnZXRfY2hpbGRyZW4obGF5ZXIpO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpPGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV07XHJcbiAgICAgICAgICAgICAgICAgICAgZHJhd19sYXllcihjaGlsZCwgeCArIGNoaWxkLngsIHkgKyBjaGlsZC55KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZXN0b3JlIGFscGhhXHJcbiAgICAgICAgICAgICAgICBjb250ZXh0Lmdsb2JhbEFscGhhID0gaW5pdGlhbF9hbHBoYTtcclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEcmF3IGRlZmF1bHQgbGF5ZXIgYW5kIGFsbCBjaGlsZHJlblxyXG4gICAgICAgIGRyYXdfbGF5ZXIoZGVmYXVsdF9sYXllciwgMCwgMCk7XHJcblxyXG4gICAgICAgIC8vIFJldHVybiBuZXcgY2FudmFzIGNvcHlcclxuICAgICAgICByZXR1cm4gY2FudmFzO1xyXG4gICAgICAgIFxyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogU2ltcGxlIGNvbnRhaW5lciBmb3IgR3VhY2Ftb2xlLkxheWVyLCBhbGxvd2luZyBsYXllcnMgdG8gYmUgZWFzaWx5XHJcbiAqIHJlcG9zaXRpb25lZCBhbmQgbmVzdGVkLiBUaGlzIGFsbG93cyBjZXJ0YWluIG9wZXJhdGlvbnMgdG8gYmUgYWNjZWxlcmF0ZWRcclxuICogdGhyb3VnaCBET00gbWFuaXB1bGF0aW9uLCByYXRoZXIgdGhhbiByYXN0ZXIgb3BlcmF0aW9ucy5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAYXVnbWVudHMgR3VhY2Ftb2xlLkxheWVyXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aCBUaGUgd2lkdGggb2YgdGhlIExheWVyLCBpbiBwaXhlbHMuIFRoZSBjYW52YXMgZWxlbWVudFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgYmFja2luZyB0aGlzIExheWVyIHdpbGwgYmUgZ2l2ZW4gdGhpcyB3aWR0aC5cclxuICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodCBUaGUgaGVpZ2h0IG9mIHRoZSBMYXllciwgaW4gcGl4ZWxzLiBUaGUgY2FudmFzIGVsZW1lbnRcclxuICogICAgICAgICAgICAgICAgICAgICAgICBiYWNraW5nIHRoaXMgTGF5ZXIgd2lsbCBiZSBnaXZlbiB0aGlzIGhlaWdodC5cclxuICovXHJcbkd1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllciA9IGZ1bmN0aW9uKHdpZHRoLCBoZWlnaHQpIHtcclxuXHJcbiAgICBHdWFjYW1vbGUuTGF5ZXIuYXBwbHkodGhpcywgW3dpZHRoLCBoZWlnaHRdKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIGxheWVyLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGxheWVyID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIElkZW50aWZpZXIgd2hpY2ggdW5pcXVlbHkgaWRlbnRpZmllcyB0aGlzIGxheWVyLiBUaGlzIGlzIENPTVBMRVRFTFlcclxuICAgICAqIFVOUkVMQVRFRCB0byB0aGUgaW5kZXggb2YgdGhlIHVuZGVybHlpbmcgbGF5ZXIsIHdoaWNoIGlzIHNwZWNpZmljXHJcbiAgICAgKiB0byB0aGUgR3VhY2Ftb2xlIHByb3RvY29sLCBhbmQgbm90IHJlbGV2YW50IGF0IHRoaXMgbGV2ZWwuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLl9fdW5pcXVlX2lkID0gR3VhY2Ftb2xlLkRpc3BsYXkuVmlzaWJsZUxheWVyLl9fbmV4dF9pZCsrO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wYWNpdHkgb2YgdGhlIGxheWVyIGNvbnRhaW5lciwgd2hlcmUgMjU1IGlzIGZ1bGx5IG9wYXF1ZSBhbmQgMCBpc1xyXG4gICAgICogZnVsbHkgdHJhbnNwYXJlbnQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuYWxwaGEgPSAweEZGO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogWCBjb29yZGluYXRlIG9mIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGlzIGxheWVyIGNvbnRhaW5lciB3aXRoaW5cclxuICAgICAqIGl0cyBwYXJlbnQsIGluIHBpeGVscy5cclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMueCA9IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoaXMgbGF5ZXIgY29udGFpbmVyIHdpdGhpblxyXG4gICAgICogaXRzIHBhcmVudCwgaW4gcGl4ZWxzLlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy55ID0gMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFogc3RhY2tpbmcgb3JkZXIgb2YgdGhpcyBsYXllciByZWxhdGl2ZSB0byBvdGhlciBzaWJsaW5nIGxheWVycy5cclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMueiA9IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYWZmaW5lIHRyYW5zZm9ybWF0aW9uIGFwcGxpZWQgdG8gdGhpcyBsYXllciBjb250YWluZXIuIEVhY2ggZWxlbWVudFxyXG4gICAgICogY29ycmVzcG9uZHMgdG8gYSB2YWx1ZSBmcm9tIHRoZSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXgsIHdpdGggdGhlIGZpcnN0XHJcbiAgICAgKiB0aHJlZSB2YWx1ZXMgYmVpbmcgdGhlIGZpcnN0IHJvdywgYW5kIHRoZSBsYXN0IHRocmVlIHZhbHVlcyBiZWluZyB0aGVcclxuICAgICAqIHNlY29uZCByb3cuIFRoZXJlIGFyZSBzaXggdmFsdWVzIHRvdGFsLlxyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyW119XHJcbiAgICAgKi9cclxuICAgIHRoaXMubWF0cml4ID0gWzEsIDAsIDAsIDEsIDAsIDBdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHBhcmVudCBsYXllciBjb250YWluZXIgb2YgdGhpcyBsYXllciwgaWYgYW55LlxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5wYXJlbnQgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0IG9mIGFsbCBjaGlsZHJlbiBvZiB0aGlzIGxheWVyLCBpbmRleGVkIGJ5IGxheWVyIGluZGV4LiBUaGlzIG9iamVjdFxyXG4gICAgICogd2lsbCBoYXZlIG9uZSBwcm9wZXJ0eSBwZXIgY2hpbGQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY2hpbGRyZW4gPSB7fTtcclxuXHJcbiAgICAvLyBTZXQgbGF5ZXIgcG9zaXRpb25cclxuICAgIHZhciBjYW52YXMgPSBsYXllci5nZXRDYW52YXMoKTtcclxuICAgIGNhbnZhcy5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcclxuICAgIGNhbnZhcy5zdHlsZS5sZWZ0ID0gXCIwcHhcIjtcclxuICAgIGNhbnZhcy5zdHlsZS50b3AgPSBcIjBweFwiO1xyXG5cclxuICAgIC8vIENyZWF0ZSBkaXYgd2l0aCBnaXZlbiBzaXplXHJcbiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuICAgIGRpdi5hcHBlbmRDaGlsZChjYW52YXMpO1xyXG4gICAgZGl2LnN0eWxlLndpZHRoID0gd2lkdGggKyBcInB4XCI7XHJcbiAgICBkaXYuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgZGl2LnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xyXG4gICAgZGl2LnN0eWxlLmxlZnQgPSBcIjBweFwiO1xyXG4gICAgZGl2LnN0eWxlLnRvcCA9IFwiMHB4XCI7XHJcbiAgICBkaXYuc3R5bGUub3ZlcmZsb3cgPSBcImhpZGRlblwiO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3VwZXJjbGFzcyByZXNpemUoKSBmdW5jdGlvbi5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBfX3N1cGVyX3Jlc2l6ZSA9IHRoaXMucmVzaXplO1xyXG5cclxuICAgIHRoaXMucmVzaXplID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCkge1xyXG5cclxuICAgICAgICAvLyBSZXNpemUgY29udGFpbmluZyBkaXZcclxuICAgICAgICBkaXYuc3R5bGUud2lkdGggPSB3aWR0aCArIFwicHhcIjtcclxuICAgICAgICBkaXYuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0ICsgXCJweFwiO1xyXG5cclxuICAgICAgICBfX3N1cGVyX3Jlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcclxuXHJcbiAgICB9O1xyXG4gIFxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGNhbnZhcyBhbmQgYW55IG90aGVyIGVsZW1lbnRzXHJcbiAgICAgKiBhc3NvY2lhdGVkIHdpdGggdGhpcyBsYXllci5cclxuICAgICAqIEByZXR1cm5zIHtFbGVtZW50fSBUaGUgZWxlbWVudCBjb250YWluaW5nIHRoaXMgbGF5ZXIncyBjYW52YXMuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZ2V0RWxlbWVudCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBkaXY7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHRyYW5zbGF0aW9uIGNvbXBvbmVudCBvZiB0aGlzIGxheWVyJ3MgdHJhbnNmb3JtLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIHRyYW5zbGF0ZSA9IFwidHJhbnNsYXRlKDBweCwgMHB4KVwiOyAvLyAoMCwgMClcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBhcmJpdHJhcnkgbWF0cml4IGNvbXBvbmVudCBvZiB0aGlzIGxheWVyJ3MgdHJhbnNmb3JtLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIG1hdHJpeCA9IFwibWF0cml4KDEsIDAsIDAsIDEsIDAsIDApXCI7IC8vIElkZW50aXR5XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNb3ZlcyB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhpcyBsYXllciB0byB0aGUgZ2l2ZW4gWCBhbmQgWVxyXG4gICAgICogY29vcmRpbmF0ZS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIFggY29vcmRpbmF0ZSB0byBtb3ZlIHRvLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSB0byBtb3ZlIHRvLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uKHgsIHkpIHtcclxuXHJcbiAgICAgICAgbGF5ZXIueCA9IHg7XHJcbiAgICAgICAgbGF5ZXIueSA9IHk7XHJcblxyXG4gICAgICAgIC8vIEdlbmVyYXRlIHRyYW5zbGF0aW9uXHJcbiAgICAgICAgdHJhbnNsYXRlID0gXCJ0cmFuc2xhdGUoXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKyB4ICsgXCJweCxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICArIHkgKyBcInB4KVwiO1xyXG5cclxuICAgICAgICAvLyBTZXQgbGF5ZXIgdHJhbnNmb3JtIFxyXG4gICAgICAgIGRpdi5zdHlsZS50cmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpdi5zdHlsZS5XZWJraXRUcmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpdi5zdHlsZS5Nb3pUcmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpdi5zdHlsZS5PVHJhbnNmb3JtID1cclxuICAgICAgICBkaXYuc3R5bGUubXNUcmFuc2Zvcm0gPVxyXG5cclxuICAgICAgICAgICAgdHJhbnNsYXRlICsgXCIgXCIgKyBtYXRyaXg7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1vdmVzIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGlzIFZpc2libGVMYXllciB0byB0aGUgZ2l2ZW4gWCBhbmQgWVxyXG4gICAgICogY29vcmRpbmF0ZSwgc2V0cyB0aGUgWiBzdGFja2luZyBvcmRlciwgYW5kIHJlcGFyZW50cyB0aGlzIFZpc2libGVMYXllclxyXG4gICAgICogdG8gdGhlIGdpdmVuIFZpc2libGVMYXllci5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuRGlzcGxheS5WaXNpYmxlTGF5ZXJ9IHBhcmVudCBUaGUgcGFyZW50IHRvIHNldC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBYIGNvb3JkaW5hdGUgdG8gbW92ZSB0by5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBZIGNvb3JkaW5hdGUgdG8gbW92ZSB0by5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSBaIGNvb3JkaW5hdGUgdG8gbW92ZSB0by5cclxuICAgICAqL1xyXG4gICAgdGhpcy5tb3ZlID0gZnVuY3Rpb24ocGFyZW50LCB4LCB5LCB6KSB7XHJcblxyXG4gICAgICAgIC8vIFNldCBwYXJlbnQgaWYgbmVjZXNzYXJ5XHJcbiAgICAgICAgaWYgKGxheWVyLnBhcmVudCAhPT0gcGFyZW50KSB7XHJcblxyXG4gICAgICAgICAgICAvLyBNYWludGFpbiByZWxhdGlvbnNoaXBcclxuICAgICAgICAgICAgaWYgKGxheWVyLnBhcmVudClcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBsYXllci5wYXJlbnQuY2hpbGRyZW5bbGF5ZXIuX191bmlxdWVfaWRdO1xyXG4gICAgICAgICAgICBsYXllci5wYXJlbnQgPSBwYXJlbnQ7XHJcbiAgICAgICAgICAgIHBhcmVudC5jaGlsZHJlbltsYXllci5fX3VuaXF1ZV9pZF0gPSBsYXllcjtcclxuXHJcbiAgICAgICAgICAgIC8vIFJlcGFyZW50IGVsZW1lbnRcclxuICAgICAgICAgICAgdmFyIHBhcmVudF9lbGVtZW50ID0gcGFyZW50LmdldEVsZW1lbnQoKTtcclxuICAgICAgICAgICAgcGFyZW50X2VsZW1lbnQuYXBwZW5kQ2hpbGQoZGl2KTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBTZXQgbG9jYXRpb25cclxuICAgICAgICBsYXllci50cmFuc2xhdGUoeCwgeSk7XHJcbiAgICAgICAgbGF5ZXIueiA9IHo7XHJcbiAgICAgICAgZGl2LnN0eWxlLnpJbmRleCA9IHo7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIG9wYWNpdHkgb2YgdGhpcyBsYXllciB0byB0aGUgZ2l2ZW4gdmFsdWUsIHdoZXJlIDI1NSBpcyBmdWxseVxyXG4gICAgICogb3BhcXVlIGFuZCAwIGlzIGZ1bGx5IHRyYW5zcGFyZW50LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgb3BhY2l0eSB0byBzZXQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2hhZGUgPSBmdW5jdGlvbihhKSB7XHJcbiAgICAgICAgbGF5ZXIuYWxwaGEgPSBhO1xyXG4gICAgICAgIGRpdi5zdHlsZS5vcGFjaXR5ID0gYS8yNTUuMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIHRoaXMgbGF5ZXIgY29udGFpbmVyIGVudGlyZWx5LCBzdWNoIHRoYXQgaXQgaXMgbm8gbG9uZ2VyXHJcbiAgICAgKiBjb250YWluZWQgd2l0aGluIGl0cyBwYXJlbnQgbGF5ZXIsIGlmIGFueS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5kaXNwb3NlID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIHBhcmVudCBjb250YWluZXJcclxuICAgICAgICBpZiAobGF5ZXIucGFyZW50KSB7XHJcbiAgICAgICAgICAgIGRlbGV0ZSBsYXllci5wYXJlbnQuY2hpbGRyZW5bbGF5ZXIuX191bmlxdWVfaWRdO1xyXG4gICAgICAgICAgICBsYXllci5wYXJlbnQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGZyb20gcGFyZW50IGVsZW1lbnRcclxuICAgICAgICBpZiAoZGl2LnBhcmVudE5vZGUpXHJcbiAgICAgICAgICAgIGRpdi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGRpdik7XHJcbiAgICAgICAgXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwbGllcyB0aGUgZ2l2ZW4gYWZmaW5lIHRyYW5zZm9ybSAoZGVmaW5lZCB3aXRoIHNpeCB2YWx1ZXMgZnJvbSB0aGVcclxuICAgICAqIHRyYW5zZm9ybSdzIG1hdHJpeCkuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGUgVGhlIGZpZnRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGYgVGhlIHNpeHRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICovXHJcbiAgICB0aGlzLmRpc3RvcnQgPSBmdW5jdGlvbihhLCBiLCBjLCBkLCBlLCBmKSB7XHJcblxyXG4gICAgICAgIC8vIFN0b3JlIG1hdHJpeFxyXG4gICAgICAgIGxheWVyLm1hdHJpeCA9IFthLCBiLCBjLCBkLCBlLCBmXTtcclxuXHJcbiAgICAgICAgLy8gR2VuZXJhdGUgbWF0cml4IHRyYW5zZm9ybWF0aW9uXHJcbiAgICAgICAgbWF0cml4ID1cclxuXHJcbiAgICAgICAgICAgIC8qIGEgYyBlXHJcbiAgICAgICAgICAgICAqIGIgZCBmXHJcbiAgICAgICAgICAgICAqIDAgMCAxXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgXHJcbiAgICAgICAgICAgIFwibWF0cml4KFwiICsgYSArIFwiLFwiICsgYiArIFwiLFwiICsgYyArIFwiLFwiICsgZCArIFwiLFwiICsgZSArIFwiLFwiICsgZiArIFwiKVwiO1xyXG5cclxuICAgICAgICAvLyBTZXQgbGF5ZXIgdHJhbnNmb3JtIFxyXG4gICAgICAgIGRpdi5zdHlsZS50cmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpdi5zdHlsZS5XZWJraXRUcmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpdi5zdHlsZS5Nb3pUcmFuc2Zvcm0gPVxyXG4gICAgICAgIGRpdi5zdHlsZS5PVHJhbnNmb3JtID1cclxuICAgICAgICBkaXYuc3R5bGUubXNUcmFuc2Zvcm0gPVxyXG5cclxuICAgICAgICAgICAgdHJhbnNsYXRlICsgXCIgXCIgKyBtYXRyaXg7XHJcblxyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogVGhlIG5leHQgaWRlbnRpZmllciB0byBiZSBhc3NpZ25lZCB0byB0aGUgbGF5ZXIgY29udGFpbmVyLiBUaGlzIGlkZW50aWZpZXJcclxuICogdW5pcXVlbHkgaWRlbnRpZmllcyBlYWNoIFZpc2libGVMYXllciwgYnV0IGlzIHVucmVsYXRlZCB0byB0aGUgaW5kZXggb2ZcclxuICogdGhlIGxheWVyLCB3aGljaCBleGlzdHMgYXQgdGhlIHByb3RvY29sL2NsaWVudCBsZXZlbCBvbmx5LlxyXG4gKiBcclxuICogQHByaXZhdGVcclxuICogQHR5cGUge051bWJlcn1cclxuICovXHJcbkd1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllci5fX25leHRfaWQgPSAwO1xyXG4vKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIEFuIGlucHV0IHN0cmVhbSBhYnN0cmFjdGlvbiB1c2VkIGJ5IHRoZSBHdWFjYW1vbGUgY2xpZW50IHRvIGZhY2lsaXRhdGVcclxuICogdHJhbnNmZXIgb2YgZmlsZXMgb3Igb3RoZXIgYmluYXJ5IGRhdGEuXHJcbiAqIFxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtHdWFjYW1vbGUuQ2xpZW50fSBjbGllbnQgVGhlIGNsaWVudCBvd25pbmcgdGhpcyBzdHJlYW0uXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhpcyBzdHJlYW0uXHJcbiAqL1xyXG5HdWFjYW1vbGUuSW5wdXRTdHJlYW0gPSBmdW5jdGlvbihjbGllbnQsIGluZGV4KSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBzdHJlYW0uXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgZ3VhY19zdHJlYW0gPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGluZGV4IG9mIHRoaXMgc3RyZWFtLlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGVkIHdoZW4gYSBibG9iIG9mIGRhdGEgaXMgcmVjZWl2ZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgVGhlIHJlY2VpdmVkIGJhc2U2NCBkYXRhLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uYmxvYiA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsZWQgd2hlbiB0aGlzIHN0cmVhbSBpcyBjbG9zZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uZW5kID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFja25vd2xlZGdlcyB0aGUgcmVjZWlwdCBvZiBhIGJsb2IuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIEEgaHVtYW4tcmVhZGFibGUgbWVzc2FnZSBkZXNjcmliaW5nIHRoZSBlcnJvclxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgb3Igc3RhdHVzLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvZGUgVGhlIGVycm9yIGNvZGUsIGlmIGFueSwgb3IgMCBmb3Igc3VjY2Vzcy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZW5kQWNrID0gZnVuY3Rpb24obWVzc2FnZSwgY29kZSkge1xyXG4gICAgICAgIGNsaWVudC5zZW5kQWNrKGd1YWNfc3RyZWFtLmluZGV4LCBtZXNzYWdlLCBjb2RlKTtcclxuICAgIH07XHJcblxyXG59O1xyXG4vKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIEludGVnZXIgcG9vbCB3aGljaCByZXR1cm5zIGNvbnNpc3RlbnRseSBpbmNyZWFzaW5nIGludGVnZXJzIHdoaWxlIGludGVnZXJzXHJcbiAqIGFyZSBpbiB1c2UsIGFuZCBwcmV2aW91c2x5LXVzZWQgaW50ZWdlcnMgd2hlbiBwb3NzaWJsZS5cclxuICogQGNvbnN0cnVjdG9yIFxyXG4gKi9cclxuR3VhY2Ftb2xlLkludGVnZXJQb29sID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBpbnRlZ2VyIHBvb2wuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGd1YWNfcG9vbCA9IHRoaXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcnJheSBvZiBhdmFpbGFibGUgaW50ZWdlcnMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJbXX1cclxuICAgICAqL1xyXG4gICAgdmFyIHBvb2wgPSBbXTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuZXh0IGludGVnZXIgdG8gcmV0dXJuIGlmIG5vIG1vcmUgaW50ZWdlcnMgcmVtYWluLlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5uZXh0X2ludCA9IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGF2YWlsYWJsZSBpbnRlZ2VyIGluIHRoZSBwb29sLiBJZiBwb3NzaWJsZSwgYSBwcmV2aW91c2x5XHJcbiAgICAgKiB1c2VkIGludGVnZXIgd2lsbCBiZSByZXR1cm5lZC5cclxuICAgICAqIFxyXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBUaGUgbmV4dCBhdmFpbGFibGUgaW50ZWdlci5cclxuICAgICAqL1xyXG4gICAgdGhpcy5uZXh0ID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIC8vIElmIGZyZWUnZCBpbnRlZ2VycyBleGlzdCwgcmV0dXJuIG9uZSBvZiB0aG9zZVxyXG4gICAgICAgIGlmIChwb29sLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgIHJldHVybiBwb29sLnNoaWZ0KCk7XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSwgcmV0dXJuIGEgbmV3IGludGVnZXJcclxuICAgICAgICByZXR1cm4gZ3VhY19wb29sLm5leHRfaW50Kys7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZyZWVzIHRoZSBnaXZlbiBpbnRlZ2VyLCBhbGxvd2luZyBpdCB0byBiZSByZXVzZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbnRlZ2VyIFRoZSBpbnRlZ2VyIHRvIGZyZWUuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZnJlZSA9IGZ1bmN0aW9uKGludGVnZXIpIHtcclxuICAgICAgICBwb29sLnB1c2goaW50ZWdlcik7XHJcbiAgICB9O1xyXG5cclxufTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIHJlYWRlciB3aGljaCBhdXRvbWF0aWNhbGx5IGhhbmRsZXMgdGhlIGdpdmVuIGlucHV0IHN0cmVhbSwgYXNzZW1ibGluZyBhbGxcclxuICogcmVjZWl2ZWQgYmxvYnMgaW50byBhIEphdmFTY3JpcHQgb2JqZWN0IGJ5IGFwcGVuZGluZyB0aGVtIHRvIGVhY2ggb3RoZXIsIGluXHJcbiAqIG9yZGVyLCBhbmQgZGVjb2RpbmcgdGhlIHJlc3VsdCBhcyBKU09OLiBOb3RlIHRoYXQgdGhpcyBvYmplY3Qgd2lsbCBvdmVyd3JpdGVcclxuICogYW55IGluc3RhbGxlZCBldmVudCBoYW5kbGVycyBvbiB0aGUgZ2l2ZW4gR3VhY2Ftb2xlLklucHV0U3RyZWFtLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLklucHV0U3RyZWFtfSBzdHJlYW1cclxuICogICAgIFRoZSBzdHJlYW0gdGhhdCBKU09OIHdpbGwgYmUgcmVhZCBmcm9tLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkpTT05SZWFkZXIgPSBmdW5jdGlvbiBndWFjYW1vbGVKU09OUmVhZGVyKHN0cmVhbSkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVmZXJlbmNlIHRvIHRoaXMgR3VhY2Ftb2xlLkpTT05SZWFkZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuSlNPTlJlYWRlcn1cclxuICAgICAqL1xyXG4gICAgdmFyIGd1YWNSZWFkZXIgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JhcHBlZCBHdWFjYW1vbGUuU3RyaW5nUmVhZGVyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLlN0cmluZ1JlYWRlcn1cclxuICAgICAqL1xyXG4gICAgdmFyIHN0cmluZ1JlYWRlciA9IG5ldyBHdWFjYW1vbGUuU3RyaW5nUmVhZGVyKHN0cmVhbSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwgSlNPTiByZWFkIHRodXMgZmFyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxyXG4gICAgICovXHJcbiAgICB2YXIganNvbiA9ICcnO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCBsZW5ndGggb2YgdGhpcyBHdWFjYW1vbGUuSlNPTlJlYWRlciwgaW4gY2hhcmFjdGVycy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XHJcbiAgICAgKiAgICAgVGhlIGN1cnJlbnQgbGVuZ3RoIG9mIHRoaXMgR3VhY2Ftb2xlLkpTT05SZWFkZXIuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZ2V0TGVuZ3RoID0gZnVuY3Rpb24gZ2V0TGVuZ3RoKCkge1xyXG4gICAgICAgIHJldHVybiBqc29uLmxlbmd0aDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGlzIEd1YWNhbW9sZS5KU09OUmVhZGVyIGFzIGEgSmF2YVNjcmlwdFxyXG4gICAgICogb2JqZWN0LlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm4ge09iamVjdH1cclxuICAgICAqICAgICBUaGUgY29udGVudHMgb2YgdGhpcyBHdWFjYW1vbGUuSlNPTlJlYWRlciwgYXMgcGFyc2VkIGZyb20gdGhlIEpTT05cclxuICAgICAqICAgICBjb250ZW50cyBvZiB0aGUgaW5wdXQgc3RyZWFtLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmdldEpTT04gPSBmdW5jdGlvbiBnZXRKU09OKCkge1xyXG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKGpzb24pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBBcHBlbmQgYWxsIHJlY2VpdmVkIHRleHRcclxuICAgIHN0cmluZ1JlYWRlci5vbnRleHQgPSBmdW5jdGlvbiBvbnRleHQodGV4dCkge1xyXG5cclxuICAgICAgICAvLyBBcHBlbmQgcmVjZWl2ZWQgdGV4dFxyXG4gICAgICAgIGpzb24gKz0gdGV4dDtcclxuXHJcbiAgICAgICAgLy8gQ2FsbCBoYW5kbGVyLCBpZiBwcmVzZW50XHJcbiAgICAgICAgaWYgKGd1YWNSZWFkZXIub25wcm9ncmVzcylcclxuICAgICAgICAgICAgZ3VhY1JlYWRlci5vbnByb2dyZXNzKHRleHQubGVuZ3RoKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIFNpbXBseSBjYWxsIG9uZW5kIHdoZW4gZW5kIHJlY2VpdmVkXHJcbiAgICBzdHJpbmdSZWFkZXIub25lbmQgPSBmdW5jdGlvbiBvbmVuZCgpIHtcclxuICAgICAgICBpZiAoZ3VhY1JlYWRlci5vbmVuZClcclxuICAgICAgICAgICAgZ3VhY1JlYWRlci5vbmVuZCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIG9uY2UgZm9yIGV2ZXJ5IGJsb2Igb2YgZGF0YSByZWNlaXZlZC5cclxuICAgICAqIFxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXHJcbiAgICAgKiAgICAgVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHJlY2VpdmVkLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9ucHJvZ3Jlc3MgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgb25jZSB0aGlzIHN0cmVhbSBpcyBmaW5pc2hlZCBhbmQgbm8gZnVydGhlciBkYXRhIHdpbGwgYmUgd3JpdHRlbi5cclxuICAgICAqXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmVuZCA9IG51bGw7XHJcblxyXG59O1xyXG4vKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVzIGNyb3NzLWJyb3dzZXIgYW5kIGNyb3NzLWtleWJvYXJkIGtleWJvYXJkIGZvciBhIHNwZWNpZmljIGVsZW1lbnQuXHJcbiAqIEJyb3dzZXIgYW5kIGtleWJvYXJkIGxheW91dCB2YXJpYXRpb24gaXMgYWJzdHJhY3RlZCBhd2F5LCBwcm92aWRpbmcgZXZlbnRzXHJcbiAqIHdoaWNoIHJlcHJlc2VudCBrZXlzIGFzIHRoZWlyIGNvcnJlc3BvbmRpbmcgWDExIGtleXN5bS5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGhlIEVsZW1lbnQgdG8gdXNlIHRvIHByb3ZpZGUga2V5Ym9hcmQgZXZlbnRzLlxyXG4gKi9cclxuR3VhY2Ftb2xlLktleWJvYXJkID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVmZXJlbmNlIHRvIHRoaXMgR3VhY2Ftb2xlLktleWJvYXJkLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGd1YWNfa2V5Ym9hcmQgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgdGhlIHVzZXIgcHJlc3NlcyBhIGtleSB3aXRoIHRoZSBlbGVtZW50IGFzc29jaWF0ZWRcclxuICAgICAqIHdpdGggdGhpcyBHdWFjYW1vbGUuS2V5Ym9hcmQgaW4gZm9jdXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGtleXN5bSBUaGUga2V5c3ltIG9mIHRoZSBrZXkgYmVpbmcgcHJlc3NlZC5cclxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgdGhlIGtleSBldmVudCBzaG91bGQgYmUgYWxsb3dlZCB0aHJvdWdoIHRvIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgYnJvd3NlciwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9ua2V5ZG93biA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciB0aGUgdXNlciByZWxlYXNlcyBhIGtleSB3aXRoIHRoZSBlbGVtZW50IGFzc29jaWF0ZWRcclxuICAgICAqIHdpdGggdGhpcyBHdWFjYW1vbGUuS2V5Ym9hcmQgaW4gZm9jdXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGtleXN5bSBUaGUga2V5c3ltIG9mIHRoZSBrZXkgYmVpbmcgcmVsZWFzZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25rZXl1cCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIGtleSBldmVudCBoYXZpbmcgYSBjb3JyZXNwb25kaW5nIHRpbWVzdGFtcC4gVGhpcyBldmVudCBpcyBub24tc3BlY2lmaWMuXHJcbiAgICAgKiBJdHMgc3ViY2xhc3NlcyBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIHdoZW4gcmVjb3JkaW5nIHNwZWNpZmljIGtleVxyXG4gICAgICogZXZlbnRzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqL1xyXG4gICAgdmFyIEtleUV2ZW50ID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIGtleSBldmVudC5cclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIga2V5X2V2ZW50ID0gdGhpcztcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQW4gYXJiaXRyYXJ5IHRpbWVzdGFtcCBpbiBtaWxsaXNlY29uZHMsIGluZGljYXRpbmcgdGhpcyBldmVudCdzXHJcbiAgICAgICAgICogcG9zaXRpb24gaW4gdGltZSByZWxhdGl2ZSB0byBvdGhlciBldmVudHMuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMudGltZXN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYWN0aW9uIG9mIHRoaXMga2V5IGV2ZW50IHNob3VsZCBiZSBwcmV2ZW50ZWQuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIGtleXN5bSBvZiB0aGUga2V5IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGtleSBldmVudCwgYXMgZGV0ZXJtaW5lZFxyXG4gICAgICAgICAqIGJ5IGEgYmVzdC1lZmZvcnQgZ3Vlc3MgdXNpbmcgYXZhaWxhYmxlIGV2ZW50IHByb3BlcnRpZXMgYW5kIGtleWJvYXJkXHJcbiAgICAgICAgICogc3RhdGUuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMua2V5c3ltID0gbnVsbDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV2hldGhlciB0aGUga2V5c3ltIHZhbHVlIG9mIHRoaXMga2V5IGV2ZW50IGlzIGtub3duIHRvIGJlIHJlbGlhYmxlLlxyXG4gICAgICAgICAqIElmIGZhbHNlLCB0aGUga2V5c3ltIG1heSBzdGlsbCBiZSB2YWxpZCwgYnV0IGl0J3Mgb25seSBhIGJlc3QgZ3Vlc3MsXHJcbiAgICAgICAgICogYW5kIGZ1dHVyZSBrZXkgZXZlbnRzIG1heSBiZSBhIGJldHRlciBzb3VyY2Ugb2YgaW5mb3JtYXRpb24uXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLnJlbGlhYmxlID0gZmFsc2U7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgZWxhcHNlZCBzaW5jZSB0aGlzIGV2ZW50IHdhc1xyXG4gICAgICAgICAqIHJlY2VpdmVkLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHJldHVybiB7TnVtYmVyfSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBlbGFwc2VkIHNpbmNlIHRoaXNcclxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgIGV2ZW50IHdhcyByZWNlaXZlZC5cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmdldEFnZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBrZXlfZXZlbnQudGltZXN0YW1wO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gdGhlIHByZXNzaW5nIG9mIGEga2V5LCB3aGljaCBuZWVkIG5vdCBiZSBhIGtleVxyXG4gICAgICogYXNzb2NpYXRlZCB3aXRoIGEgcHJpbnRhYmxlIGNoYXJhY3Rlci4gVGhlIHByZXNlbmNlIG9yIGFic2VuY2Ugb2YgYW55XHJcbiAgICAgKiBpbmZvcm1hdGlvbiB3aXRoaW4gdGhpcyBvYmplY3QgaXMgYnJvd3Nlci1kZXBlbmRlbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQGF1Z21lbnRzIEd1YWNhbW9sZS5LZXlib2FyZC5LZXlFdmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGtleUNvZGUgVGhlIEphdmFTY3JpcHQga2V5IGNvZGUgb2YgdGhlIGtleSBwcmVzc2VkLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleUlkZW50aWZpZXIgVGhlIGxlZ2FjeSBET00zIFwia2V5SWRlbnRpZmllclwiIG9mIHRoZSBrZXlcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXNzZWQsIGFzIGRlZmluZWQgYXQ6XHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA5L1dELURPTS1MZXZlbC0zLUV2ZW50cy0yMDA5MDkwOC8jZXZlbnRzLUV2ZW50cy1LZXlib2FyZEV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IFRoZSBzdGFuZGFyZCBuYW1lIG9mIHRoZSBrZXkgcHJlc3NlZCwgYXMgZGVmaW5lZCBhdDpcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtS2V5Ym9hcmRFdmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGxvY2F0aW9uIFRoZSBsb2NhdGlvbiBvbiB0aGUga2V5Ym9hcmQgY29ycmVzcG9uZGluZyB0b1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBrZXkgcHJlc3NlZCwgYXMgZGVmaW5lZCBhdDpcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50cy1LZXlib2FyZEV2ZW50XHJcbiAgICAgKi9cclxuICAgIHZhciBLZXlkb3duRXZlbnQgPSBmdW5jdGlvbihrZXlDb2RlLCBrZXlJZGVudGlmaWVyLCBrZXksIGxvY2F0aW9uKSB7XHJcblxyXG4gICAgICAgIC8vIFdlIGV4dGVuZCBLZXlFdmVudFxyXG4gICAgICAgIEtleUV2ZW50LmFwcGx5KHRoaXMpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgSmF2YVNjcmlwdCBrZXkgY29kZSBvZiB0aGUga2V5IHByZXNzZWQuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMua2V5Q29kZSA9IGtleUNvZGU7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSBsZWdhY3kgRE9NMyBcImtleUlkZW50aWZpZXJcIiBvZiB0aGUga2V5IHByZXNzZWQsIGFzIGRlZmluZWQgYXQ6XHJcbiAgICAgICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvMjAwOS9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwOTA5MDgvI2V2ZW50cy1FdmVudHMtS2V5Ym9hcmRFdmVudFxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmtleUlkZW50aWZpZXIgPSBrZXlJZGVudGlmaWVyO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgc3RhbmRhcmQgbmFtZSBvZiB0aGUga2V5IHByZXNzZWQsIGFzIGRlZmluZWQgYXQ6XHJcbiAgICAgICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtS2V5Ym9hcmRFdmVudFxyXG4gICAgICAgICAqIFxyXG4gICAgICAgICAqIEB0eXBlIHtTdHJpbmd9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5rZXkgPSBrZXk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSBsb2NhdGlvbiBvbiB0aGUga2V5Ym9hcmQgY29ycmVzcG9uZGluZyB0byB0aGUga2V5IHByZXNzZWQsIGFzXHJcbiAgICAgICAgICogZGVmaW5lZCBhdDpcclxuICAgICAgICAgKiBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50cy1LZXlib2FyZEV2ZW50XHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmxvY2F0aW9uID0gbG9jYXRpb247XHJcblxyXG4gICAgICAgIC8vIElmIGtleSBpcyBrbm93biBmcm9tIGtleUNvZGUgb3IgRE9NMyBhbG9uZSwgdXNlIHRoYXRcclxuICAgICAgICB0aGlzLmtleXN5bSA9ICBrZXlzeW1fZnJvbV9rZXlfaWRlbnRpZmllcihrZXksIGxvY2F0aW9uKVxyXG4gICAgICAgICAgICAgICAgICAgIHx8IGtleXN5bV9mcm9tX2tleWNvZGUoa2V5Q29kZSwgbG9jYXRpb24pO1xyXG5cclxuICAgICAgICAvLyBET00zIGFuZCBrZXlDb2RlIGFyZSByZWxpYWJsZSBzb3VyY2VzIGlmIHRoZSBjb3JyZXNwb25kaW5nIGtleSBpc1xyXG4gICAgICAgIC8vIG5vdCBhIHByaW50YWJsZSBrZXlcclxuICAgICAgICBpZiAodGhpcy5rZXlzeW0gJiYgIWlzUHJpbnRhYmxlKHRoaXMua2V5c3ltKSlcclxuICAgICAgICAgICAgdGhpcy5yZWxpYWJsZSA9IHRydWU7XHJcblxyXG4gICAgICAgIC8vIFVzZSBsZWdhY3kga2V5SWRlbnRpZmllciBhcyBhIGxhc3QgcmVzb3J0LCBpZiBpdCBsb29rcyBzYW5lXHJcbiAgICAgICAgaWYgKCF0aGlzLmtleXN5bSAmJiBrZXlfaWRlbnRpZmllcl9zYW5lKGtleUNvZGUsIGtleUlkZW50aWZpZXIpKVxyXG4gICAgICAgICAgICB0aGlzLmtleXN5bSA9IGtleXN5bV9mcm9tX2tleV9pZGVudGlmaWVyKGtleUlkZW50aWZpZXIsIGxvY2F0aW9uLCBndWFjX2tleWJvYXJkLm1vZGlmaWVycy5zaGlmdCk7XHJcblxyXG4gICAgICAgIC8vIERldGVybWluZSB3aGV0aGVyIGRlZmF1bHQgYWN0aW9uIGZvciBBbHQrY29tYmluYXRpb25zIG11c3QgYmUgcHJldmVudGVkXHJcbiAgICAgICAgdmFyIHByZXZlbnRfYWx0ID0gICFndWFjX2tleWJvYXJkLm1vZGlmaWVycy5jdHJsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICYmICEobmF2aWdhdG9yICYmIG5hdmlnYXRvci5wbGF0Zm9ybSAmJiBuYXZpZ2F0b3IucGxhdGZvcm0ubWF0Y2goL15tYWMvaSkpO1xyXG5cclxuICAgICAgICAvLyBEZXRlcm1pbmUgd2hldGhlciBkZWZhdWx0IGFjdGlvbiBmb3IgQ3RybCtjb21iaW5hdGlvbnMgbXVzdCBiZSBwcmV2ZW50ZWRcclxuICAgICAgICB2YXIgcHJldmVudF9jdHJsID0gIWd1YWNfa2V5Ym9hcmQubW9kaWZpZXJzLmFsdDtcclxuXHJcbiAgICAgICAgLy8gV2UgbXVzdCByZWx5IG9uIHRoZSAocG90ZW50aWFsbHkgYnVnZ3kpIGtleUlkZW50aWZpZXIgaWYgcHJldmVudGluZ1xyXG4gICAgICAgIC8vIHRoZSBkZWZhdWx0IGFjdGlvbiBpcyBpbXBvcnRhbnRcclxuICAgICAgICBpZiAoKHByZXZlbnRfY3RybCAmJiBndWFjX2tleWJvYXJkLm1vZGlmaWVycy5jdHJsKVxyXG4gICAgICAgICB8fCAocHJldmVudF9hbHQgICYmIGd1YWNfa2V5Ym9hcmQubW9kaWZpZXJzLmFsdClcclxuICAgICAgICAgfHwgZ3VhY19rZXlib2FyZC5tb2RpZmllcnMubWV0YVxyXG4gICAgICAgICB8fCBndWFjX2tleWJvYXJkLm1vZGlmaWVycy5oeXBlcilcclxuICAgICAgICAgICAgdGhpcy5yZWxpYWJsZSA9IHRydWU7XHJcblxyXG4gICAgICAgIC8vIFJlY29yZCBtb3N0IHJlY2VudGx5IGtub3duIGtleXN5bSBieSBhc3NvY2lhdGVkIGtleSBjb2RlXHJcbiAgICAgICAgcmVjZW50S2V5c3ltW2tleUNvZGVdID0gdGhpcy5rZXlzeW07XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBLZXlkb3duRXZlbnQucHJvdG90eXBlID0gbmV3IEtleUV2ZW50KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmZvcm1hdGlvbiByZWxhdGVkIHRvIHRoZSBwcmVzc2luZyBvZiBhIGtleSwgd2hpY2ggTVVTVCBiZVxyXG4gICAgICogYXNzb2NpYXRlZCB3aXRoIGEgcHJpbnRhYmxlIGNoYXJhY3Rlci4gVGhlIHByZXNlbmNlIG9yIGFic2VuY2Ugb2YgYW55XHJcbiAgICAgKiBpbmZvcm1hdGlvbiB3aXRoaW4gdGhpcyBvYmplY3QgaXMgYnJvd3Nlci1kZXBlbmRlbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQGF1Z21lbnRzIEd1YWNhbW9sZS5LZXlib2FyZC5LZXlFdmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNoYXJDb2RlIFRoZSBVbmljb2RlIGNvZGVwb2ludCBvZiB0aGUgY2hhcmFjdGVyIHRoYXRcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB3b3VsZCBiZSB0eXBlZCBieSB0aGUga2V5IHByZXNzZWQuXHJcbiAgICAgKi9cclxuICAgIHZhciBLZXlwcmVzc0V2ZW50ID0gZnVuY3Rpb24oY2hhckNvZGUpIHtcclxuXHJcbiAgICAgICAgLy8gV2UgZXh0ZW5kIEtleUV2ZW50XHJcbiAgICAgICAgS2V5RXZlbnQuYXBwbHkodGhpcyk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSBVbmljb2RlIGNvZGVwb2ludCBvZiB0aGUgY2hhcmFjdGVyIHRoYXQgd291bGQgYmUgdHlwZWQgYnkgdGhlXHJcbiAgICAgICAgICoga2V5IHByZXNzZWQuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuY2hhckNvZGUgPSBjaGFyQ29kZTtcclxuXHJcbiAgICAgICAgLy8gUHVsbCBrZXlzeW0gZnJvbSBjaGFyIGNvZGVcclxuICAgICAgICB0aGlzLmtleXN5bSA9IGtleXN5bV9mcm9tX2NoYXJjb2RlKGNoYXJDb2RlKTtcclxuXHJcbiAgICAgICAgLy8gS2V5cHJlc3MgaXMgYWx3YXlzIHJlbGlhYmxlXHJcbiAgICAgICAgdGhpcy5yZWxpYWJsZSA9IHRydWU7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBLZXlwcmVzc0V2ZW50LnByb3RvdHlwZSA9IG5ldyBLZXlFdmVudCgpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5mb3JtYXRpb24gcmVsYXRlZCB0byB0aGUgcHJlc3Npbmcgb2YgYSBrZXksIHdoaWNoIG5lZWQgbm90IGJlIGEga2V5XHJcbiAgICAgKiBhc3NvY2lhdGVkIHdpdGggYSBwcmludGFibGUgY2hhcmFjdGVyLiBUaGUgcHJlc2VuY2Ugb3IgYWJzZW5jZSBvZiBhbnlcclxuICAgICAqIGluZm9ybWF0aW9uIHdpdGhpbiB0aGlzIG9iamVjdCBpcyBicm93c2VyLWRlcGVuZGVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAYXVnbWVudHMgR3VhY2Ftb2xlLktleWJvYXJkLktleUV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0ga2V5Q29kZSBUaGUgSmF2YVNjcmlwdCBrZXkgY29kZSBvZiB0aGUga2V5IHJlbGVhc2VkLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleUlkZW50aWZpZXIgVGhlIGxlZ2FjeSBET00zIFwia2V5SWRlbnRpZmllclwiIG9mIHRoZSBrZXlcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2VkLCBhcyBkZWZpbmVkIGF0OlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy53My5vcmcvVFIvMjAwOS9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwOTA5MDgvI2V2ZW50cy1FdmVudHMtS2V5Ym9hcmRFdmVudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleSBUaGUgc3RhbmRhcmQgbmFtZSBvZiB0aGUga2V5IHJlbGVhc2VkLCBhcyBkZWZpbmVkIGF0OlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50cy1LZXlib2FyZEV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbG9jYXRpb24gVGhlIGxvY2F0aW9uIG9uIHRoZSBrZXlib2FyZCBjb3JyZXNwb25kaW5nIHRvXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGtleSByZWxlYXNlZCwgYXMgZGVmaW5lZCBhdDpcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50cy1LZXlib2FyZEV2ZW50XHJcbiAgICAgKi9cclxuICAgIHZhciBLZXl1cEV2ZW50ID0gZnVuY3Rpb24oa2V5Q29kZSwga2V5SWRlbnRpZmllciwga2V5LCBsb2NhdGlvbikge1xyXG5cclxuICAgICAgICAvLyBXZSBleHRlbmQgS2V5RXZlbnRcclxuICAgICAgICBLZXlFdmVudC5hcHBseSh0aGlzKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIEphdmFTY3JpcHQga2V5IGNvZGUgb2YgdGhlIGtleSByZWxlYXNlZC5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5rZXlDb2RlID0ga2V5Q29kZTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIGxlZ2FjeSBET00zIFwia2V5SWRlbnRpZmllclwiIG9mIHRoZSBrZXkgcmVsZWFzZWQsIGFzIGRlZmluZWQgYXQ6XHJcbiAgICAgICAgICogaHR0cDovL3d3dy53My5vcmcvVFIvMjAwOS9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwOTA5MDgvI2V2ZW50cy1FdmVudHMtS2V5Ym9hcmRFdmVudFxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmtleUlkZW50aWZpZXIgPSBrZXlJZGVudGlmaWVyO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgc3RhbmRhcmQgbmFtZSBvZiB0aGUga2V5IHJlbGVhc2VkLCBhcyBkZWZpbmVkIGF0OlxyXG4gICAgICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8jZXZlbnRzLUtleWJvYXJkRXZlbnRcclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAdHlwZSB7U3RyaW5nfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMua2V5ID0ga2V5O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgbG9jYXRpb24gb24gdGhlIGtleWJvYXJkIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGtleSByZWxlYXNlZCwgYXNcclxuICAgICAgICAgKiBkZWZpbmVkIGF0OlxyXG4gICAgICAgICAqIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8jZXZlbnRzLUtleWJvYXJkRXZlbnRcclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMubG9jYXRpb24gPSBsb2NhdGlvbjtcclxuXHJcbiAgICAgICAgLy8gSWYga2V5IGlzIGtub3duIGZyb20ga2V5Q29kZSBvciBET00zIGFsb25lLCB1c2UgdGhhdFxyXG4gICAgICAgIHRoaXMua2V5c3ltID0gIHJlY2VudEtleXN5bVtrZXlDb2RlXVxyXG4gICAgICAgICAgICAgICAgICAgIHx8IGtleXN5bV9mcm9tX2tleWNvZGUoa2V5Q29kZSwgbG9jYXRpb24pXHJcbiAgICAgICAgICAgICAgICAgICAgfHwga2V5c3ltX2Zyb21fa2V5X2lkZW50aWZpZXIoa2V5LCBsb2NhdGlvbik7IC8vIGtleUNvZGUgaXMgc3RpbGwgbW9yZSByZWxpYWJsZSBmb3Iga2V5dXAgd2hlbiBkZWFkIGtleXMgYXJlIGluIHVzZVxyXG5cclxuICAgICAgICAvLyBLZXl1cCBpcyBhcyByZWxpYWJsZSBhcyBpdCB3aWxsIGV2ZXIgYmVcclxuICAgICAgICB0aGlzLnJlbGlhYmxlID0gdHJ1ZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIEtleXVwRXZlbnQucHJvdG90eXBlID0gbmV3IEtleUV2ZW50KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbiBhcnJheSBvZiByZWNvcmRlZCBldmVudHMsIHdoaWNoIGNhbiBiZSBpbnN0YW5jZXMgb2YgdGhlIHByaXZhdGVcclxuICAgICAqIEtleWRvd25FdmVudCwgS2V5cHJlc3NFdmVudCwgYW5kIEtleXVwRXZlbnQgY2xhc3Nlcy5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0tleUV2ZW50W119XHJcbiAgICAgKi9cclxuICAgIHZhciBldmVudExvZyA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFwIG9mIGtub3duIEphdmFTY3JpcHQga2V5Y29kZXMgd2hpY2ggZG8gbm90IG1hcCB0byB0eXBhYmxlIGNoYXJhY3RlcnNcclxuICAgICAqIHRvIHRoZWlyIFgxMSBrZXlzeW0gZXF1aXZhbGVudHMuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIga2V5Y29kZUtleXN5bXMgPSB7XHJcbiAgICAgICAgODogICBbMHhGRjA4XSwgLy8gYmFja3NwYWNlXHJcbiAgICAgICAgOTogICBbMHhGRjA5XSwgLy8gdGFiXHJcbiAgICAgICAgMTI6ICBbMHhGRjBCLCAweEZGMEIsIDB4RkYwQiwgMHhGRkI1XSwgLy8gY2xlYXIgICAgICAgLyBLUCA1XHJcbiAgICAgICAgMTM6ICBbMHhGRjBEXSwgLy8gZW50ZXJcclxuICAgICAgICAxNjogIFsweEZGRTEsIDB4RkZFMSwgMHhGRkUyXSwgLy8gc2hpZnRcclxuICAgICAgICAxNzogIFsweEZGRTMsIDB4RkZFMywgMHhGRkU0XSwgLy8gY3RybFxyXG4gICAgICAgIDE4OiAgWzB4RkZFOSwgMHhGRkU5LCAweEZFMDNdLCAvLyBhbHRcclxuICAgICAgICAxOTogIFsweEZGMTNdLCAvLyBwYXVzZS9icmVha1xyXG4gICAgICAgIDIwOiAgWzB4RkZFNV0sIC8vIGNhcHMgbG9ja1xyXG4gICAgICAgIDI3OiAgWzB4RkYxQl0sIC8vIGVzY2FwZVxyXG4gICAgICAgIDMyOiAgWzB4MDAyMF0sIC8vIHNwYWNlXHJcbiAgICAgICAgMzM6ICBbMHhGRjU1LCAweEZGNTUsIDB4RkY1NSwgMHhGRkI5XSwgLy8gcGFnZSB1cCAgICAgLyBLUCA5XHJcbiAgICAgICAgMzQ6ICBbMHhGRjU2LCAweEZGNTYsIDB4RkY1NiwgMHhGRkIzXSwgLy8gcGFnZSBkb3duICAgLyBLUCAzXHJcbiAgICAgICAgMzU6ICBbMHhGRjU3LCAweEZGNTcsIDB4RkY1NywgMHhGRkIxXSwgLy8gZW5kICAgICAgICAgLyBLUCAxXHJcbiAgICAgICAgMzY6ICBbMHhGRjUwLCAweEZGNTAsIDB4RkY1MCwgMHhGRkI3XSwgLy8gaG9tZSAgICAgICAgLyBLUCA3XHJcbiAgICAgICAgMzc6ICBbMHhGRjUxLCAweEZGNTEsIDB4RkY1MSwgMHhGRkI0XSwgLy8gbGVmdCBhcnJvdyAgLyBLUCA0XHJcbiAgICAgICAgMzg6ICBbMHhGRjUyLCAweEZGNTIsIDB4RkY1MiwgMHhGRkI4XSwgLy8gdXAgYXJyb3cgICAgLyBLUCA4XHJcbiAgICAgICAgMzk6ICBbMHhGRjUzLCAweEZGNTMsIDB4RkY1MywgMHhGRkI2XSwgLy8gcmlnaHQgYXJyb3cgLyBLUCA2XHJcbiAgICAgICAgNDA6ICBbMHhGRjU0LCAweEZGNTQsIDB4RkY1NCwgMHhGRkIyXSwgLy8gZG93biBhcnJvdyAgLyBLUCAyXHJcbiAgICAgICAgNDU6ICBbMHhGRjYzLCAweEZGNjMsIDB4RkY2MywgMHhGRkIwXSwgLy8gaW5zZXJ0ICAgICAgLyBLUCAwXHJcbiAgICAgICAgNDY6ICBbMHhGRkZGLCAweEZGRkYsIDB4RkZGRiwgMHhGRkFFXSwgLy8gZGVsZXRlICAgICAgLyBLUCBkZWNpbWFsXHJcbiAgICAgICAgOTE6ICBbMHhGRkVCXSwgLy8gbGVmdCB3aW5kb3cga2V5IChoeXBlcl9sKVxyXG4gICAgICAgIDkyOiAgWzB4RkY2N10sIC8vIHJpZ2h0IHdpbmRvdyBrZXkgKG1lbnUga2V5PylcclxuICAgICAgICA5MzogIG51bGwsICAgICAvLyBzZWxlY3Qga2V5XHJcbiAgICAgICAgOTY6ICBbMHhGRkIwXSwgLy8gS1AgMFxyXG4gICAgICAgIDk3OiAgWzB4RkZCMV0sIC8vIEtQIDFcclxuICAgICAgICA5ODogIFsweEZGQjJdLCAvLyBLUCAyXHJcbiAgICAgICAgOTk6ICBbMHhGRkIzXSwgLy8gS1AgM1xyXG4gICAgICAgIDEwMDogWzB4RkZCNF0sIC8vIEtQIDRcclxuICAgICAgICAxMDE6IFsweEZGQjVdLCAvLyBLUCA1XHJcbiAgICAgICAgMTAyOiBbMHhGRkI2XSwgLy8gS1AgNlxyXG4gICAgICAgIDEwMzogWzB4RkZCN10sIC8vIEtQIDdcclxuICAgICAgICAxMDQ6IFsweEZGQjhdLCAvLyBLUCA4XHJcbiAgICAgICAgMTA1OiBbMHhGRkI5XSwgLy8gS1AgOVxyXG4gICAgICAgIDEwNjogWzB4RkZBQV0sIC8vIEtQIG11bHRpcGx5XHJcbiAgICAgICAgMTA3OiBbMHhGRkFCXSwgLy8gS1AgYWRkXHJcbiAgICAgICAgMTA5OiBbMHhGRkFEXSwgLy8gS1Agc3VidHJhY3RcclxuICAgICAgICAxMTA6IFsweEZGQUVdLCAvLyBLUCBkZWNpbWFsXHJcbiAgICAgICAgMTExOiBbMHhGRkFGXSwgLy8gS1AgZGl2aWRlXHJcbiAgICAgICAgMTEyOiBbMHhGRkJFXSwgLy8gZjFcclxuICAgICAgICAxMTM6IFsweEZGQkZdLCAvLyBmMlxyXG4gICAgICAgIDExNDogWzB4RkZDMF0sIC8vIGYzXHJcbiAgICAgICAgMTE1OiBbMHhGRkMxXSwgLy8gZjRcclxuICAgICAgICAxMTY6IFsweEZGQzJdLCAvLyBmNVxyXG4gICAgICAgIDExNzogWzB4RkZDM10sIC8vIGY2XHJcbiAgICAgICAgMTE4OiBbMHhGRkM0XSwgLy8gZjdcclxuICAgICAgICAxMTk6IFsweEZGQzVdLCAvLyBmOFxyXG4gICAgICAgIDEyMDogWzB4RkZDNl0sIC8vIGY5XHJcbiAgICAgICAgMTIxOiBbMHhGRkM3XSwgLy8gZjEwXHJcbiAgICAgICAgMTIyOiBbMHhGRkM4XSwgLy8gZjExXHJcbiAgICAgICAgMTIzOiBbMHhGRkM5XSwgLy8gZjEyXHJcbiAgICAgICAgMTQ0OiBbMHhGRjdGXSwgLy8gbnVtIGxvY2tcclxuICAgICAgICAxNDU6IFsweEZGMTRdLCAvLyBzY3JvbGwgbG9ja1xyXG4gICAgICAgIDIyNTogWzB4RkUwM10gIC8vIGFsdGdyYXBoIChpc29fbGV2ZWwzX3NoaWZ0KVxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1hcCBvZiBrbm93biBKYXZhU2NyaXB0IGtleWlkZW50aWZpZXJzIHdoaWNoIGRvIG5vdCBtYXAgdG8gdHlwYWJsZVxyXG4gICAgICogY2hhcmFjdGVycyB0byB0aGVpciB1bnNoaWZ0ZWQgWDExIGtleXN5bSBlcXVpdmFsZW50cy5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBrZXlpZGVudGlmaWVyX2tleXN5bSA9IHtcclxuICAgICAgICBcIkFnYWluXCI6IFsweEZGNjZdLFxyXG4gICAgICAgIFwiQWxsQ2FuZGlkYXRlc1wiOiBbMHhGRjNEXSxcclxuICAgICAgICBcIkFscGhhbnVtZXJpY1wiOiBbMHhGRjMwXSxcclxuICAgICAgICBcIkFsdFwiOiBbMHhGRkU5LCAweEZGRTksIDB4RkUwM10sXHJcbiAgICAgICAgXCJBdHRuXCI6IFsweEZEMEVdLFxyXG4gICAgICAgIFwiQWx0R3JhcGhcIjogWzB4RkUwM10sXHJcbiAgICAgICAgXCJBcnJvd0Rvd25cIjogWzB4RkY1NF0sXHJcbiAgICAgICAgXCJBcnJvd0xlZnRcIjogWzB4RkY1MV0sXHJcbiAgICAgICAgXCJBcnJvd1JpZ2h0XCI6IFsweEZGNTNdLFxyXG4gICAgICAgIFwiQXJyb3dVcFwiOiBbMHhGRjUyXSxcclxuICAgICAgICBcIkJhY2tzcGFjZVwiOiBbMHhGRjA4XSxcclxuICAgICAgICBcIkNhcHNMb2NrXCI6IFsweEZGRTVdLFxyXG4gICAgICAgIFwiQ2FuY2VsXCI6IFsweEZGNjldLFxyXG4gICAgICAgIFwiQ2xlYXJcIjogWzB4RkYwQl0sXHJcbiAgICAgICAgXCJDb252ZXJ0XCI6IFsweEZGMjFdLFxyXG4gICAgICAgIFwiQ29weVwiOiBbMHhGRDE1XSxcclxuICAgICAgICBcIkNyc2VsXCI6IFsweEZEMUNdLFxyXG4gICAgICAgIFwiQ3JTZWxcIjogWzB4RkQxQ10sXHJcbiAgICAgICAgXCJDb2RlSW5wdXRcIjogWzB4RkYzN10sXHJcbiAgICAgICAgXCJDb21wb3NlXCI6IFsweEZGMjBdLFxyXG4gICAgICAgIFwiQ29udHJvbFwiOiBbMHhGRkUzLCAweEZGRTMsIDB4RkZFNF0sXHJcbiAgICAgICAgXCJDb250ZXh0TWVudVwiOiBbMHhGRjY3XSxcclxuICAgICAgICBcIkRlYWRHcmF2ZVwiOiBbMHhGRTUwXSxcclxuICAgICAgICBcIkRlYWRBY3V0ZVwiOiBbMHhGRTUxXSxcclxuICAgICAgICBcIkRlYWRDaXJjdW1mbGV4XCI6IFsweEZFNTJdLFxyXG4gICAgICAgIFwiRGVhZFRpbGRlXCI6IFsweEZFNTNdLFxyXG4gICAgICAgIFwiRGVhZE1hY3JvblwiOiBbMHhGRTU0XSxcclxuICAgICAgICBcIkRlYWRCcmV2ZVwiOiBbMHhGRTU1XSxcclxuICAgICAgICBcIkRlYWRBYm92ZURvdFwiOiBbMHhGRTU2XSxcclxuICAgICAgICBcIkRlYWRVbWxhdXRcIjogWzB4RkU1N10sXHJcbiAgICAgICAgXCJEZWFkQWJvdmVSaW5nXCI6IFsweEZFNThdLFxyXG4gICAgICAgIFwiRGVhZERvdWJsZWFjdXRlXCI6IFsweEZFNTldLFxyXG4gICAgICAgIFwiRGVhZENhcm9uXCI6IFsweEZFNUFdLFxyXG4gICAgICAgIFwiRGVhZENlZGlsbGFcIjogWzB4RkU1Ql0sXHJcbiAgICAgICAgXCJEZWFkT2dvbmVrXCI6IFsweEZFNUNdLFxyXG4gICAgICAgIFwiRGVhZElvdGFcIjogWzB4RkU1RF0sXHJcbiAgICAgICAgXCJEZWFkVm9pY2VkU291bmRcIjogWzB4RkU1RV0sXHJcbiAgICAgICAgXCJEZWFkU2VtaXZvaWNlZFNvdW5kXCI6IFsweEZFNUZdLFxyXG4gICAgICAgIFwiRGVsZXRlXCI6IFsweEZGRkZdLFxyXG4gICAgICAgIFwiRG93blwiOiBbMHhGRjU0XSxcclxuICAgICAgICBcIkVuZFwiOiBbMHhGRjU3XSxcclxuICAgICAgICBcIkVudGVyXCI6IFsweEZGMERdLFxyXG4gICAgICAgIFwiRXJhc2VFb2ZcIjogWzB4RkQwNl0sXHJcbiAgICAgICAgXCJFc2NhcGVcIjogWzB4RkYxQl0sXHJcbiAgICAgICAgXCJFeGVjdXRlXCI6IFsweEZGNjJdLFxyXG4gICAgICAgIFwiRXhzZWxcIjogWzB4RkQxRF0sXHJcbiAgICAgICAgXCJFeFNlbFwiOiBbMHhGRDFEXSxcclxuICAgICAgICBcIkYxXCI6IFsweEZGQkVdLFxyXG4gICAgICAgIFwiRjJcIjogWzB4RkZCRl0sXHJcbiAgICAgICAgXCJGM1wiOiBbMHhGRkMwXSxcclxuICAgICAgICBcIkY0XCI6IFsweEZGQzFdLFxyXG4gICAgICAgIFwiRjVcIjogWzB4RkZDMl0sXHJcbiAgICAgICAgXCJGNlwiOiBbMHhGRkMzXSxcclxuICAgICAgICBcIkY3XCI6IFsweEZGQzRdLFxyXG4gICAgICAgIFwiRjhcIjogWzB4RkZDNV0sXHJcbiAgICAgICAgXCJGOVwiOiBbMHhGRkM2XSxcclxuICAgICAgICBcIkYxMFwiOiBbMHhGRkM3XSxcclxuICAgICAgICBcIkYxMVwiOiBbMHhGRkM4XSxcclxuICAgICAgICBcIkYxMlwiOiBbMHhGRkM5XSxcclxuICAgICAgICBcIkYxM1wiOiBbMHhGRkNBXSxcclxuICAgICAgICBcIkYxNFwiOiBbMHhGRkNCXSxcclxuICAgICAgICBcIkYxNVwiOiBbMHhGRkNDXSxcclxuICAgICAgICBcIkYxNlwiOiBbMHhGRkNEXSxcclxuICAgICAgICBcIkYxN1wiOiBbMHhGRkNFXSxcclxuICAgICAgICBcIkYxOFwiOiBbMHhGRkNGXSxcclxuICAgICAgICBcIkYxOVwiOiBbMHhGRkQwXSxcclxuICAgICAgICBcIkYyMFwiOiBbMHhGRkQxXSxcclxuICAgICAgICBcIkYyMVwiOiBbMHhGRkQyXSxcclxuICAgICAgICBcIkYyMlwiOiBbMHhGRkQzXSxcclxuICAgICAgICBcIkYyM1wiOiBbMHhGRkQ0XSxcclxuICAgICAgICBcIkYyNFwiOiBbMHhGRkQ1XSxcclxuICAgICAgICBcIkZpbmRcIjogWzB4RkY2OF0sXHJcbiAgICAgICAgXCJHcm91cEZpcnN0XCI6IFsweEZFMENdLFxyXG4gICAgICAgIFwiR3JvdXBMYXN0XCI6IFsweEZFMEVdLFxyXG4gICAgICAgIFwiR3JvdXBOZXh0XCI6IFsweEZFMDhdLFxyXG4gICAgICAgIFwiR3JvdXBQcmV2aW91c1wiOiBbMHhGRTBBXSxcclxuICAgICAgICBcIkZ1bGxXaWR0aFwiOiBudWxsLFxyXG4gICAgICAgIFwiSGFsZldpZHRoXCI6IG51bGwsXHJcbiAgICAgICAgXCJIYW5ndWxNb2RlXCI6IFsweEZGMzFdLFxyXG4gICAgICAgIFwiSGFua2FrdVwiOiBbMHhGRjI5XSxcclxuICAgICAgICBcIkhhbmphTW9kZVwiOiBbMHhGRjM0XSxcclxuICAgICAgICBcIkhlbHBcIjogWzB4RkY2QV0sXHJcbiAgICAgICAgXCJIaXJhZ2FuYVwiOiBbMHhGRjI1XSxcclxuICAgICAgICBcIkhpcmFnYW5hS2F0YWthbmFcIjogWzB4RkYyN10sXHJcbiAgICAgICAgXCJIb21lXCI6IFsweEZGNTBdLFxyXG4gICAgICAgIFwiSHlwZXJcIjogWzB4RkZFRCwgMHhGRkVELCAweEZGRUVdLFxyXG4gICAgICAgIFwiSW5zZXJ0XCI6IFsweEZGNjNdLFxyXG4gICAgICAgIFwiSmFwYW5lc2VIaXJhZ2FuYVwiOiBbMHhGRjI1XSxcclxuICAgICAgICBcIkphcGFuZXNlS2F0YWthbmFcIjogWzB4RkYyNl0sXHJcbiAgICAgICAgXCJKYXBhbmVzZVJvbWFqaVwiOiBbMHhGRjI0XSxcclxuICAgICAgICBcIkp1bmphTW9kZVwiOiBbMHhGRjM4XSxcclxuICAgICAgICBcIkthbmFNb2RlXCI6IFsweEZGMkRdLFxyXG4gICAgICAgIFwiS2FuamlNb2RlXCI6IFsweEZGMjFdLFxyXG4gICAgICAgIFwiS2F0YWthbmFcIjogWzB4RkYyNl0sXHJcbiAgICAgICAgXCJMZWZ0XCI6IFsweEZGNTFdLFxyXG4gICAgICAgIFwiTWV0YVwiOiBbMHhGRkU3LCAweEZGRTcsIDB4RkZFOF0sXHJcbiAgICAgICAgXCJNb2RlQ2hhbmdlXCI6IFsweEZGN0VdLFxyXG4gICAgICAgIFwiTnVtTG9ja1wiOiBbMHhGRjdGXSxcclxuICAgICAgICBcIlBhZ2VEb3duXCI6IFsweEZGNTZdLFxyXG4gICAgICAgIFwiUGFnZVVwXCI6IFsweEZGNTVdLFxyXG4gICAgICAgIFwiUGF1c2VcIjogWzB4RkYxM10sXHJcbiAgICAgICAgXCJQbGF5XCI6IFsweEZEMTZdLFxyXG4gICAgICAgIFwiUHJldmlvdXNDYW5kaWRhdGVcIjogWzB4RkYzRV0sXHJcbiAgICAgICAgXCJQcmludFNjcmVlblwiOiBbMHhGRDFEXSxcclxuICAgICAgICBcIlJlZG9cIjogWzB4RkY2Nl0sXHJcbiAgICAgICAgXCJSaWdodFwiOiBbMHhGRjUzXSxcclxuICAgICAgICBcIlJvbWFuQ2hhcmFjdGVyc1wiOiBudWxsLFxyXG4gICAgICAgIFwiU2Nyb2xsXCI6IFsweEZGMTRdLFxyXG4gICAgICAgIFwiU2VsZWN0XCI6IFsweEZGNjBdLFxyXG4gICAgICAgIFwiU2VwYXJhdG9yXCI6IFsweEZGQUNdLFxyXG4gICAgICAgIFwiU2hpZnRcIjogWzB4RkZFMSwgMHhGRkUxLCAweEZGRTJdLFxyXG4gICAgICAgIFwiU2luZ2xlQ2FuZGlkYXRlXCI6IFsweEZGM0NdLFxyXG4gICAgICAgIFwiU3VwZXJcIjogWzB4RkZFQiwgMHhGRkVCLCAweEZGRUNdLFxyXG4gICAgICAgIFwiVGFiXCI6IFsweEZGMDldLFxyXG4gICAgICAgIFwiVXBcIjogWzB4RkY1Ml0sXHJcbiAgICAgICAgXCJVbmRvXCI6IFsweEZGNjVdLFxyXG4gICAgICAgIFwiV2luXCI6IFsweEZGRUJdLFxyXG4gICAgICAgIFwiWmVua2FrdVwiOiBbMHhGRjI4XSxcclxuICAgICAgICBcIlplbmtha3VIYW5rYWt1XCI6IFsweEZGMkFdXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsIGtleXN5bXMgd2hpY2ggc2hvdWxkIG5vdCByZXBlYXQgd2hlbiBoZWxkIGRvd24uXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgbm9fcmVwZWF0ID0ge1xyXG4gICAgICAgIDB4RkUwMzogdHJ1ZSwgLy8gSVNPIExldmVsIDMgU2hpZnQgKEFsdEdyKVxyXG4gICAgICAgIDB4RkZFMTogdHJ1ZSwgLy8gTGVmdCBzaGlmdFxyXG4gICAgICAgIDB4RkZFMjogdHJ1ZSwgLy8gUmlnaHQgc2hpZnRcclxuICAgICAgICAweEZGRTM6IHRydWUsIC8vIExlZnQgY3RybCBcclxuICAgICAgICAweEZGRTQ6IHRydWUsIC8vIFJpZ2h0IGN0cmwgXHJcbiAgICAgICAgMHhGRkU3OiB0cnVlLCAvLyBMZWZ0IG1ldGEgXHJcbiAgICAgICAgMHhGRkU4OiB0cnVlLCAvLyBSaWdodCBtZXRhIFxyXG4gICAgICAgIDB4RkZFOTogdHJ1ZSwgLy8gTGVmdCBhbHRcclxuICAgICAgICAweEZGRUE6IHRydWUsIC8vIFJpZ2h0IGFsdFxyXG4gICAgICAgIDB4RkZFQjogdHJ1ZSwgLy8gTGVmdCBoeXBlclxyXG4gICAgICAgIDB4RkZFQzogdHJ1ZSAgLy8gUmlnaHQgaHlwZXJcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwgbW9kaWZpZXJzIGFuZCB0aGVpciBzdGF0ZXMuXHJcbiAgICAgKi9cclxuICAgIHRoaXMubW9kaWZpZXJzID0gbmV3IEd1YWNhbW9sZS5LZXlib2FyZC5Nb2RpZmllclN0YXRlKCk7XHJcbiAgICAgICAgXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzdGF0ZSBvZiBldmVyeSBrZXksIGluZGV4ZWQgYnkga2V5c3ltLiBJZiBhIHBhcnRpY3VsYXIga2V5IGlzXHJcbiAgICAgKiBwcmVzc2VkLCB0aGUgdmFsdWUgb2YgcHJlc3NlZCBmb3IgdGhhdCBrZXlzeW0gd2lsbCBiZSB0cnVlLiBJZiBhIGtleVxyXG4gICAgICogaXMgbm90IGN1cnJlbnRseSBwcmVzc2VkLCBpdCB3aWxsIG5vdCBiZSBkZWZpbmVkLiBcclxuICAgICAqL1xyXG4gICAgdGhpcy5wcmVzc2VkID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbGFzdCByZXN1bHQgb2YgY2FsbGluZyB0aGUgb25rZXlkb3duIGhhbmRsZXIgZm9yIGVhY2gga2V5LCBpbmRleGVkXHJcbiAgICAgKiBieSBrZXlzeW0uIFRoaXMgaXMgdXNlZCB0byBwcmV2ZW50L2FsbG93IGRlZmF1bHQgYWN0aW9ucyBmb3Iga2V5IGV2ZW50cyxcclxuICAgICAqIGV2ZW4gd2hlbiB0aGUgb25rZXlkb3duIGhhbmRsZXIgY2Fubm90IGJlIGNhbGxlZCBhZ2FpbiBiZWNhdXNlIHRoZSBrZXlcclxuICAgICAqIGlzICh0aGVvcmV0aWNhbGx5KSBzdGlsbCBwcmVzc2VkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBsYXN0X2tleWRvd25fcmVzdWx0ID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUga2V5c3ltIG1vc3QgcmVjZW50bHkgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4ga2V5Y29kZSB3aGVuIGtleWRvd25cclxuICAgICAqIGZpcmVkLiBUaGlzIG9iamVjdCBtYXBzIGtleWNvZGVzIHRvIGtleXN5bXMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtPYmplY3QuPE51bWJlciwgTnVtYmVyPn1cclxuICAgICAqL1xyXG4gICAgdmFyIHJlY2VudEtleXN5bSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGltZW91dCBiZWZvcmUga2V5IHJlcGVhdCBzdGFydHMuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIga2V5X3JlcGVhdF90aW1lb3V0ID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEludGVydmFsIHdoaWNoIHByZXNzZXMgYW5kIHJlbGVhc2VzIHRoZSBsYXN0IGtleSBwcmVzc2VkIHdoaWxlIHRoYXRcclxuICAgICAqIGtleSBpcyBzdGlsbCBiZWluZyBoZWxkIGRvd24uXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIga2V5X3JlcGVhdF9pbnRlcnZhbCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHaXZlbiBhbiBhcnJheSBvZiBrZXlzeW1zIGluZGV4ZWQgYnkgbG9jYXRpb24sIHJldHVybnMgdGhlIGtleXN5bVxyXG4gICAgICogZm9yIHRoZSBnaXZlbiBsb2NhdGlvbiwgb3IgdGhlIGtleXN5bSBmb3IgdGhlIHN0YW5kYXJkIGxvY2F0aW9uIGlmXHJcbiAgICAgKiB1bmRlZmluZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcltdfSBrZXlzeW1zXHJcbiAgICAgKiAgICAgQW4gYXJyYXkgb2Yga2V5c3ltcywgd2hlcmUgdGhlIGluZGV4IG9mIHRoZSBrZXlzeW0gaW4gdGhlIGFycmF5IGlzXHJcbiAgICAgKiAgICAgdGhlIGxvY2F0aW9uIHZhbHVlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsb2NhdGlvblxyXG4gICAgICogICAgIFRoZSBsb2NhdGlvbiBvbiB0aGUga2V5Ym9hcmQgY29ycmVzcG9uZGluZyB0byB0aGUga2V5IHByZXNzZWQsIGFzXHJcbiAgICAgKiAgICAgZGVmaW5lZCBhdDogaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtS2V5Ym9hcmRFdmVudFxyXG4gICAgICovXHJcbiAgICB2YXIgZ2V0X2tleXN5bSA9IGZ1bmN0aW9uIGdldF9rZXlzeW0oa2V5c3ltcywgbG9jYXRpb24pIHtcclxuXHJcbiAgICAgICAgaWYgKCFrZXlzeW1zKVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICAgICAgcmV0dXJuIGtleXN5bXNbbG9jYXRpb25dIHx8IGtleXN5bXNbMF07XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBrZXlzeW0gY29ycmVzcG9uZHMgdG8gYSBwcmludGFibGUgY2hhcmFjdGVyLFxyXG4gICAgICogZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBrZXlzeW1cclxuICAgICAqICAgICBUaGUga2V5c3ltIHRvIGNoZWNrLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gICAgICogICAgIHRydWUgaWYgdGhlIGdpdmVuIGtleXN5bSBjb3JyZXNwb25kcyB0byBhIHByaW50YWJsZSBjaGFyYWN0ZXIsXHJcbiAgICAgKiAgICAgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICB2YXIgaXNQcmludGFibGUgPSBmdW5jdGlvbiBpc1ByaW50YWJsZShrZXlzeW0pIHtcclxuXHJcbiAgICAgICAgLy8gS2V5c3ltcyB3aXRoIFVuaWNvZGUgZXF1aXZhbGVudHMgYXJlIHByaW50YWJsZVxyXG4gICAgICAgIHJldHVybiAoa2V5c3ltID49IDB4MDAgJiYga2V5c3ltIDw9IDB4RkYpXHJcbiAgICAgICAgICAgIHx8IChrZXlzeW0gJiAweEZGRkYwMDAwKSA9PT0gMHgwMTAwMDAwMDtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIGtleXN5bV9mcm9tX2tleV9pZGVudGlmaWVyKGlkZW50aWZpZXIsIGxvY2F0aW9uLCBzaGlmdGVkKSB7XHJcblxyXG4gICAgICAgIGlmICghaWRlbnRpZmllcilcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIHZhciB0eXBlZENoYXJhY3RlcjtcclxuXHJcbiAgICAgICAgLy8gSWYgaWRlbnRpZmllciBpcyBVK3h4eHgsIGRlY29kZSBVbmljb2RlIGNoYXJhY3RlciBcclxuICAgICAgICB2YXIgdW5pY29kZVByZWZpeExvY2F0aW9uID0gaWRlbnRpZmllci5pbmRleE9mKFwiVStcIik7XHJcbiAgICAgICAgaWYgKHVuaWNvZGVQcmVmaXhMb2NhdGlvbiA+PSAwKSB7XHJcbiAgICAgICAgICAgIHZhciBoZXggPSBpZGVudGlmaWVyLnN1YnN0cmluZyh1bmljb2RlUHJlZml4TG9jYXRpb24rMik7XHJcbiAgICAgICAgICAgIHR5cGVkQ2hhcmFjdGVyID0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXgsIDE2KSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiBzaW5nbGUgY2hhcmFjdGVyIGFuZCBub3Qga2V5cGFkLCB1c2UgdGhhdCBhcyB0eXBlZCBjaGFyYWN0ZXJcclxuICAgICAgICBlbHNlIGlmIChpZGVudGlmaWVyLmxlbmd0aCA9PT0gMSAmJiBsb2NhdGlvbiAhPT0gMylcclxuICAgICAgICAgICAgdHlwZWRDaGFyYWN0ZXIgPSBpZGVudGlmaWVyO1xyXG5cclxuICAgICAgICAvLyBPdGhlcndpc2UsIGxvb2sgdXAgY29ycmVzcG9uZGluZyBrZXlzeW1cclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJldHVybiBnZXRfa2V5c3ltKGtleWlkZW50aWZpZXJfa2V5c3ltW2lkZW50aWZpZXJdLCBsb2NhdGlvbik7XHJcblxyXG4gICAgICAgIC8vIEFsdGVyIGNhc2UgaWYgbmVjZXNzYXJ5XHJcbiAgICAgICAgaWYgKHNoaWZ0ZWQgPT09IHRydWUpXHJcbiAgICAgICAgICAgIHR5cGVkQ2hhcmFjdGVyID0gdHlwZWRDaGFyYWN0ZXIudG9VcHBlckNhc2UoKTtcclxuICAgICAgICBlbHNlIGlmIChzaGlmdGVkID09PSBmYWxzZSlcclxuICAgICAgICAgICAgdHlwZWRDaGFyYWN0ZXIgPSB0eXBlZENoYXJhY3Rlci50b0xvd2VyQ2FzZSgpO1xyXG5cclxuICAgICAgICAvLyBHZXQgY29kZXBvaW50XHJcbiAgICAgICAgdmFyIGNvZGVwb2ludCA9IHR5cGVkQ2hhcmFjdGVyLmNoYXJDb2RlQXQoMCk7XHJcbiAgICAgICAgcmV0dXJuIGtleXN5bV9mcm9tX2NoYXJjb2RlKGNvZGVwb2ludCk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGlzQ29udHJvbENoYXJhY3Rlcihjb2RlcG9pbnQpIHtcclxuICAgICAgICByZXR1cm4gY29kZXBvaW50IDw9IDB4MUYgfHwgKGNvZGVwb2ludCA+PSAweDdGICYmIGNvZGVwb2ludCA8PSAweDlGKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBrZXlzeW1fZnJvbV9jaGFyY29kZShjb2RlcG9pbnQpIHtcclxuXHJcbiAgICAgICAgLy8gS2V5c3ltcyBmb3IgY29udHJvbCBjaGFyYWN0ZXJzXHJcbiAgICAgICAgaWYgKGlzQ29udHJvbENoYXJhY3Rlcihjb2RlcG9pbnQpKSByZXR1cm4gMHhGRjAwIHwgY29kZXBvaW50O1xyXG5cclxuICAgICAgICAvLyBLZXlzeW1zIGZvciBBU0NJSSBjaGFyc1xyXG4gICAgICAgIGlmIChjb2RlcG9pbnQgPj0gMHgwMDAwICYmIGNvZGVwb2ludCA8PSAweDAwRkYpXHJcbiAgICAgICAgICAgIHJldHVybiBjb2RlcG9pbnQ7XHJcblxyXG4gICAgICAgIC8vIEtleXN5bXMgZm9yIFVuaWNvZGVcclxuICAgICAgICBpZiAoY29kZXBvaW50ID49IDB4MDEwMCAmJiBjb2RlcG9pbnQgPD0gMHgxMEZGRkYpXHJcbiAgICAgICAgICAgIHJldHVybiAweDAxMDAwMDAwIHwgY29kZXBvaW50O1xyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24ga2V5c3ltX2Zyb21fa2V5Y29kZShrZXlDb2RlLCBsb2NhdGlvbikge1xyXG4gICAgICAgIHJldHVybiBnZXRfa2V5c3ltKGtleWNvZGVLZXlzeW1zW2tleUNvZGVdLCBsb2NhdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZXVyaXN0aWNhbGx5IGRldGVjdHMgaWYgdGhlIGxlZ2FjeSBrZXlJZGVudGlmaWVyIHByb3BlcnR5IG9mXHJcbiAgICAgKiBhIGtleWRvd24va2V5dXAgZXZlbnQgbG9va3MgaW5jb3JyZWN0bHkgZGVyaXZlZC4gQ2hyb21lLCBhbmRcclxuICAgICAqIHByZXN1bWFibHkgb3RoZXJzLCB3aWxsIHByb2R1Y2UgdGhlIGtleUlkZW50aWZpZXIgYnkgYXNzdW1pbmdcclxuICAgICAqIHRoZSBrZXlDb2RlIGlzIHRoZSBVbmljb2RlIGNvZGVwb2ludCBmb3IgdGhhdCBrZXkuIFRoaXMgaXMgbm90XHJcbiAgICAgKiBjb3JyZWN0IGluIGFsbCBjYXNlcy5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGtleUNvZGVcclxuICAgICAqICAgICBUaGUga2V5Q29kZSBmcm9tIGEgYnJvd3NlciBrZXlkb3duL2tleXVwIGV2ZW50LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlJZGVudGlmaWVyXHJcbiAgICAgKiAgICAgVGhlIGxlZ2FjeSBrZXlJZGVudGlmaWVyIGZyb20gYSBicm93c2VyIGtleWRvd24va2V5dXAgZXZlbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAgICAgKiAgICAgdHJ1ZSBpZiB0aGUga2V5SWRlbnRpZmllciBsb29rcyBzYW5lLCBmYWxzZSBpZiB0aGUga2V5SWRlbnRpZmllclxyXG4gICAgICogICAgIGFwcGVhcnMgaW5jb3JyZWN0bHkgZGVyaXZlZCBvciBpcyBtaXNzaW5nIGVudGlyZWx5LlxyXG4gICAgICovXHJcbiAgICB2YXIga2V5X2lkZW50aWZpZXJfc2FuZSA9IGZ1bmN0aW9uIGtleV9pZGVudGlmaWVyX3NhbmUoa2V5Q29kZSwga2V5SWRlbnRpZmllcikge1xyXG5cclxuICAgICAgICAvLyBNaXNzaW5nIGlkZW50aWZpZXIgaXMgbm90IHNhbmVcclxuICAgICAgICBpZiAoIWtleUlkZW50aWZpZXIpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gQXNzdW1lIG5vbi1Vbmljb2RlIGtleUlkZW50aWZpZXIgdmFsdWVzIGFyZSBzYW5lXHJcbiAgICAgICAgdmFyIHVuaWNvZGVQcmVmaXhMb2NhdGlvbiA9IGtleUlkZW50aWZpZXIuaW5kZXhPZihcIlUrXCIpO1xyXG4gICAgICAgIGlmICh1bmljb2RlUHJlZml4TG9jYXRpb24gPT09IC0xKVxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAgICAgLy8gSWYgdGhlIFVuaWNvZGUgY29kZXBvaW50IGlzbid0IGlkZW50aWNhbCB0byB0aGUga2V5Q29kZSxcclxuICAgICAgICAvLyB0aGVuIHRoZSBpZGVudGlmaWVyIGlzIGxpa2VseSBjb3JyZWN0XHJcbiAgICAgICAgdmFyIGNvZGVwb2ludCA9IHBhcnNlSW50KGtleUlkZW50aWZpZXIuc3Vic3RyaW5nKHVuaWNvZGVQcmVmaXhMb2NhdGlvbisyKSwgMTYpO1xyXG4gICAgICAgIGlmIChrZXlDb2RlICE9PSBjb2RlcG9pbnQpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgICAvLyBUaGUga2V5Q29kZXMgZm9yIEEtWiBhbmQgMC05IGFyZSBhY3R1YWxseSBpZGVudGljYWwgdG8gdGhlaXJcclxuICAgICAgICAvLyBVbmljb2RlIGNvZGVwb2ludHNcclxuICAgICAgICBpZiAoKGtleUNvZGUgPj0gNjUgJiYga2V5Q29kZSA8PSA5MCkgfHwgKGtleUNvZGUgPj0gNDggJiYga2V5Q29kZSA8PSA1NykpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgICAvLyBUaGUga2V5SWRlbnRpZmllciBkb2VzIE5PVCBhcHBlYXIgc2FuZVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFya3MgYSBrZXkgYXMgcHJlc3NlZCwgZmlyaW5nIHRoZSBrZXlkb3duIGV2ZW50IGlmIHJlZ2lzdGVyZWQuIEtleVxyXG4gICAgICogcmVwZWF0IGZvciB0aGUgcHJlc3NlZCBrZXkgd2lsbCBzdGFydCBhZnRlciBhIGRlbGF5IGlmIHRoYXQga2V5IGlzXHJcbiAgICAgKiBub3QgYSBtb2RpZmllci4gVGhlIHJldHVybiB2YWx1ZSBvZiB0aGlzIGZ1bmN0aW9uIGRlcGVuZHMgb24gdGhlXHJcbiAgICAgKiByZXR1cm4gdmFsdWUgb2YgdGhlIGtleWRvd24gZXZlbnQgaGFuZGxlciwgaWYgYW55LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0ga2V5c3ltIFRoZSBrZXlzeW0gb2YgdGhlIGtleSB0byBwcmVzcy5cclxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgZXZlbnQgc2hvdWxkIE5PVCBiZSBjYW5jZWxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnByZXNzID0gZnVuY3Rpb24oa2V5c3ltKSB7XHJcblxyXG4gICAgICAgIC8vIERvbid0IGJvdGhlciB3aXRoIHByZXNzaW5nIHRoZSBrZXkgaWYgdGhlIGtleSBpcyB1bmtub3duXHJcbiAgICAgICAgaWYgKGtleXN5bSA9PT0gbnVsbCkgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBPbmx5IHByZXNzIGlmIHJlbGVhc2VkXHJcbiAgICAgICAgaWYgKCFndWFjX2tleWJvYXJkLnByZXNzZWRba2V5c3ltXSkge1xyXG5cclxuICAgICAgICAgICAgLy8gTWFyayBrZXkgYXMgcHJlc3NlZFxyXG4gICAgICAgICAgICBndWFjX2tleWJvYXJkLnByZXNzZWRba2V5c3ltXSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAvLyBTZW5kIGtleSBldmVudFxyXG4gICAgICAgICAgICBpZiAoZ3VhY19rZXlib2FyZC5vbmtleWRvd24pIHtcclxuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBndWFjX2tleWJvYXJkLm9ua2V5ZG93bihrZXlzeW0pO1xyXG4gICAgICAgICAgICAgICAgbGFzdF9rZXlkb3duX3Jlc3VsdFtrZXlzeW1dID0gcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFN0b3AgYW55IGN1cnJlbnQgcmVwZWF0XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KGtleV9yZXBlYXRfdGltZW91dCk7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbChrZXlfcmVwZWF0X2ludGVydmFsKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZXBlYXQgYWZ0ZXIgYSBkZWxheSBhcyBsb25nIGFzIHByZXNzZWRcclxuICAgICAgICAgICAgICAgIGlmICghbm9fcmVwZWF0W2tleXN5bV0pXHJcbiAgICAgICAgICAgICAgICAgICAga2V5X3JlcGVhdF90aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleV9yZXBlYXRfaW50ZXJ2YWwgPSB3aW5kb3cuc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBndWFjX2tleWJvYXJkLm9ua2V5dXAoa2V5c3ltKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQub25rZXlkb3duKGtleXN5bSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDUwKTtcclxuICAgICAgICAgICAgICAgICAgICB9LCA1MDApO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJldHVybiB0aGUgbGFzdCBrZXlkb3duIHJlc3VsdCBieSBkZWZhdWx0LCByZXNvcnQgdG8gZmFsc2UgaWYgdW5rbm93blxyXG4gICAgICAgIHJldHVybiBsYXN0X2tleWRvd25fcmVzdWx0W2tleXN5bV0gfHwgZmFsc2U7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1hcmtzIGEga2V5IGFzIHJlbGVhc2VkLCBmaXJpbmcgdGhlIGtleXVwIGV2ZW50IGlmIHJlZ2lzdGVyZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBrZXlzeW0gVGhlIGtleXN5bSBvZiB0aGUga2V5IHRvIHJlbGVhc2UuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVsZWFzZSA9IGZ1bmN0aW9uKGtleXN5bSkge1xyXG5cclxuICAgICAgICAvLyBPbmx5IHJlbGVhc2UgaWYgcHJlc3NlZFxyXG4gICAgICAgIGlmIChndWFjX2tleWJvYXJkLnByZXNzZWRba2V5c3ltXSkge1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gTWFyayBrZXkgYXMgcmVsZWFzZWRcclxuICAgICAgICAgICAgZGVsZXRlIGd1YWNfa2V5Ym9hcmQucHJlc3NlZFtrZXlzeW1dO1xyXG5cclxuICAgICAgICAgICAgLy8gU3RvcCByZXBlYXRcclxuICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dChrZXlfcmVwZWF0X3RpbWVvdXQpO1xyXG4gICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbChrZXlfcmVwZWF0X2ludGVydmFsKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFNlbmQga2V5IGV2ZW50XHJcbiAgICAgICAgICAgIGlmIChrZXlzeW0gIT09IG51bGwgJiYgZ3VhY19rZXlib2FyZC5vbmtleXVwKVxyXG4gICAgICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5vbmtleXVwKGtleXN5bSk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoZSBzdGF0ZSBvZiB0aGlzIGtleWJvYXJkLCByZWxlYXNpbmcgYWxsIGtleXMsIGFuZCBmaXJpbmcga2V5dXBcclxuICAgICAqIGV2ZW50cyBmb3IgZWFjaCByZWxlYXNlZCBrZXkuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVzZXQgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgLy8gUmVsZWFzZSBhbGwgcHJlc3NlZCBrZXlzXHJcbiAgICAgICAgZm9yICh2YXIga2V5c3ltIGluIGd1YWNfa2V5Ym9hcmQucHJlc3NlZClcclxuICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5yZWxlYXNlKHBhcnNlSW50KGtleXN5bSkpO1xyXG5cclxuICAgICAgICAvLyBDbGVhciBldmVudCBsb2dcclxuICAgICAgICBldmVudExvZyA9IFtdO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHaXZlbiBhIGtleWJvYXJkIGV2ZW50LCB1cGRhdGVzIHRoZSBsb2NhbCBtb2RpZmllciBzdGF0ZSBhbmQgcmVtb3RlXHJcbiAgICAgKiBrZXkgc3RhdGUgYmFzZWQgb24gdGhlIG1vZGlmaWVyIGZsYWdzIHdpdGhpbiB0aGUgZXZlbnQuIFRoaXMgZnVuY3Rpb25cclxuICAgICAqIHBheXMgbm8gYXR0ZW50aW9uIHRvIGtleWNvZGVzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge0tleWJvYXJkRXZlbnR9IGVcclxuICAgICAqICAgICBUaGUga2V5Ym9hcmQgZXZlbnQgY29udGFpbmluZyB0aGUgZmxhZ3MgdG8gdXBkYXRlLlxyXG4gICAgICovXHJcbiAgICB2YXIgdXBkYXRlX21vZGlmaWVyX3N0YXRlID0gZnVuY3Rpb24gdXBkYXRlX21vZGlmaWVyX3N0YXRlKGUpIHtcclxuXHJcbiAgICAgICAgLy8gR2V0IHN0YXRlXHJcbiAgICAgICAgdmFyIHN0YXRlID0gR3VhY2Ftb2xlLktleWJvYXJkLk1vZGlmaWVyU3RhdGUuZnJvbUtleWJvYXJkRXZlbnQoZSk7XHJcblxyXG4gICAgICAgIC8vIFJlbGVhc2UgYWx0IGlmIGltcGxpY2l0bHkgcmVsZWFzZWRcclxuICAgICAgICBpZiAoZ3VhY19rZXlib2FyZC5tb2RpZmllcnMuYWx0ICYmIHN0YXRlLmFsdCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5yZWxlYXNlKDB4RkZFOSk7IC8vIExlZnQgYWx0XHJcbiAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVsZWFzZSgweEZGRUEpOyAvLyBSaWdodCBhbHRcclxuICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5yZWxlYXNlKDB4RkUwMyk7IC8vIEFsdEdyXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZWxlYXNlIHNoaWZ0IGlmIGltcGxpY2l0bHkgcmVsZWFzZWRcclxuICAgICAgICBpZiAoZ3VhY19rZXlib2FyZC5tb2RpZmllcnMuc2hpZnQgJiYgc3RhdGUuc2hpZnQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVsZWFzZSgweEZGRTEpOyAvLyBMZWZ0IHNoaWZ0XHJcbiAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVsZWFzZSgweEZGRTIpOyAvLyBSaWdodCBzaGlmdFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVsZWFzZSBjdHJsIGlmIGltcGxpY2l0bHkgcmVsZWFzZWRcclxuICAgICAgICBpZiAoZ3VhY19rZXlib2FyZC5tb2RpZmllcnMuY3RybCAmJiBzdGF0ZS5jdHJsID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBndWFjX2tleWJvYXJkLnJlbGVhc2UoMHhGRkUzKTsgLy8gTGVmdCBjdHJsIFxyXG4gICAgICAgICAgICBndWFjX2tleWJvYXJkLnJlbGVhc2UoMHhGRkU0KTsgLy8gUmlnaHQgY3RybCBcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJlbGVhc2UgbWV0YSBpZiBpbXBsaWNpdGx5IHJlbGVhc2VkXHJcbiAgICAgICAgaWYgKGd1YWNfa2V5Ym9hcmQubW9kaWZpZXJzLm1ldGEgJiYgc3RhdGUubWV0YSA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5yZWxlYXNlKDB4RkZFNyk7IC8vIExlZnQgbWV0YSBcclxuICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5yZWxlYXNlKDB4RkZFOCk7IC8vIFJpZ2h0IG1ldGEgXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZWxlYXNlIGh5cGVyIGlmIGltcGxpY2l0bHkgcmVsZWFzZWRcclxuICAgICAgICBpZiAoZ3VhY19rZXlib2FyZC5tb2RpZmllcnMuaHlwZXIgJiYgc3RhdGUuaHlwZXIgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVsZWFzZSgweEZGRUIpOyAvLyBMZWZ0IGh5cGVyXHJcbiAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVsZWFzZSgweEZGRUMpOyAvLyBSaWdodCBoeXBlclxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gVXBkYXRlIHN0YXRlXHJcbiAgICAgICAgZ3VhY19rZXlib2FyZC5tb2RpZmllcnMgPSBzdGF0ZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgdGhyb3VnaCB0aGUgZXZlbnQgbG9nLCByZW1vdmluZyBldmVudHMgZnJvbSB0aGUgaGVhZCBvZiB0aGUgbG9nXHJcbiAgICAgKiB3aGVuIHRoZSBjb3JyZXNwb25kaW5nIHRydWUga2V5IHByZXNzZXMgYXJlIGtub3duIChvciBhcyBrbm93biBhcyB0aGV5XHJcbiAgICAgKiBjYW4gYmUpLlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn0gV2hldGhlciB0aGUgZGVmYXVsdCBhY3Rpb24gb2YgdGhlIGxhdGVzdCBldmVudCBzaG91bGRcclxuICAgICAqICAgICAgICAgICAgICAgICAgIGJlIHByZXZlbnRlZC5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gaW50ZXJwcmV0X2V2ZW50cygpIHtcclxuXHJcbiAgICAgICAgLy8gRG8gbm90IHByZXZlbnQgZGVmYXVsdCBpZiBubyBldmVudCBjb3VsZCBiZSBpbnRlcnByZXRlZFxyXG4gICAgICAgIHZhciBoYW5kbGVkX2V2ZW50ID0gaW50ZXJwcmV0X2V2ZW50KCk7XHJcbiAgICAgICAgaWYgKCFoYW5kbGVkX2V2ZW50KVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgIC8vIEludGVycHJldCBhcyBtdWNoIGFzIHBvc3NpYmxlXHJcbiAgICAgICAgdmFyIGxhc3RfZXZlbnQ7XHJcbiAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICBsYXN0X2V2ZW50ID0gaGFuZGxlZF9ldmVudDtcclxuICAgICAgICAgICAgaGFuZGxlZF9ldmVudCA9IGludGVycHJldF9ldmVudCgpO1xyXG4gICAgICAgIH0gd2hpbGUgKGhhbmRsZWRfZXZlbnQgIT09IG51bGwpO1xyXG5cclxuICAgICAgICByZXR1cm4gbGFzdF9ldmVudC5kZWZhdWx0UHJldmVudGVkO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlbGVhc2VzIEN0cmwrQWx0LCBpZiBib3RoIGFyZSBjdXJyZW50bHkgcHJlc3NlZCBhbmQgdGhlIGdpdmVuIGtleXN5bVxyXG4gICAgICogbG9va3MgbGlrZSBhIGtleSB0aGF0IG1heSByZXF1aXJlIEFsdEdyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0ga2V5c3ltIFRoZSBrZXkgdGhhdCB3YXMganVzdCBwcmVzc2VkLlxyXG4gICAgICovXHJcbiAgICB2YXIgcmVsZWFzZV9zaW11bGF0ZWRfYWx0Z3IgPSBmdW5jdGlvbiByZWxlYXNlX3NpbXVsYXRlZF9hbHRncihrZXlzeW0pIHtcclxuXHJcbiAgICAgICAgLy8gQm90aCBDdHJsK0FsdCBtdXN0IGJlIHByZXNzZWQgaWYgc2ltdWxhdGVkIEFsdEdyIGlzIGluIHVzZVxyXG4gICAgICAgIGlmICghZ3VhY19rZXlib2FyZC5tb2RpZmllcnMuY3RybCB8fCAhZ3VhY19rZXlib2FyZC5tb2RpZmllcnMuYWx0KVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIEFzc3VtZSBbQS1aXSBuZXZlciByZXF1aXJlIEFsdEdyXHJcbiAgICAgICAgaWYgKGtleXN5bSA+PSAweDAwNDEgJiYga2V5c3ltIDw9IDB4MDA1QSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBBc3N1bWUgW2Etel0gbmV2ZXIgcmVxdWlyZSBBbHRHclxyXG4gICAgICAgIGlmIChrZXlzeW0gPj0gMHgwMDYxICYmIGtleXN5bSA8PSAweDAwN0EpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gUmVsZWFzZSBDdHJsK0FsdCBpZiB0aGUga2V5c3ltIGlzIHByaW50YWJsZVxyXG4gICAgICAgIGlmIChrZXlzeW0gPD0gMHhGRiB8fCAoa2V5c3ltICYgMHhGRjAwMDAwMCkgPT09IDB4MDEwMDAwMDApIHtcclxuICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5yZWxlYXNlKDB4RkZFMyk7IC8vIExlZnQgY3RybCBcclxuICAgICAgICAgICAgZ3VhY19rZXlib2FyZC5yZWxlYXNlKDB4RkZFNCk7IC8vIFJpZ2h0IGN0cmwgXHJcbiAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVsZWFzZSgweEZGRTkpOyAvLyBMZWZ0IGFsdFxyXG4gICAgICAgICAgICBndWFjX2tleWJvYXJkLnJlbGVhc2UoMHhGRkVBKTsgLy8gUmlnaHQgYWx0XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyB0aHJvdWdoIHRoZSBldmVudCBsb2csIGludGVycHJldGluZyB0aGUgZmlyc3QgZXZlbnQsIGlmIHBvc3NpYmxlLFxyXG4gICAgICogYW5kIHJldHVybmluZyB0aGF0IGV2ZW50LiBJZiBubyBldmVudHMgY2FuIGJlIGludGVycHJldGVkLCBkdWUgdG8gYVxyXG4gICAgICogdG90YWwgbGFjayBvZiBldmVudHMgb3IgdGhlIG5lZWQgZm9yIG1vcmUgZXZlbnRzLCBudWxsIGlzIHJldHVybmVkLiBBbnlcclxuICAgICAqIGludGVycHJldGVkIGV2ZW50cyBhcmUgYXV0b21hdGljYWxseSByZW1vdmVkIGZyb20gdGhlIGxvZy5cclxuICAgICAqIFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEByZXR1cm4ge0tleUV2ZW50fVxyXG4gICAgICogICAgIFRoZSBmaXJzdCBrZXkgZXZlbnQgaW4gdGhlIGxvZywgaWYgaXQgY2FuIGJlIGludGVycHJldGVkLCBvciBudWxsXHJcbiAgICAgKiAgICAgb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICB2YXIgaW50ZXJwcmV0X2V2ZW50ID0gZnVuY3Rpb24gaW50ZXJwcmV0X2V2ZW50KCkge1xyXG5cclxuICAgICAgICAvLyBQZWVrIGF0IGZpcnN0IGV2ZW50IGluIGxvZ1xyXG4gICAgICAgIHZhciBmaXJzdCA9IGV2ZW50TG9nWzBdO1xyXG4gICAgICAgIGlmICghZmlyc3QpXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICAvLyBLZXlkb3duIGV2ZW50XHJcbiAgICAgICAgaWYgKGZpcnN0IGluc3RhbmNlb2YgS2V5ZG93bkV2ZW50KSB7XHJcblxyXG4gICAgICAgICAgICB2YXIga2V5c3ltID0gbnVsbDtcclxuICAgICAgICAgICAgdmFyIGFjY2VwdGVkX2V2ZW50cyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgLy8gSWYgZXZlbnQgaXRzZWxmIGlzIHJlbGlhYmxlLCBubyBuZWVkIHRvIHdhaXQgZm9yIG90aGVyIGV2ZW50c1xyXG4gICAgICAgICAgICBpZiAoZmlyc3QucmVsaWFibGUpIHtcclxuICAgICAgICAgICAgICAgIGtleXN5bSA9IGZpcnN0LmtleXN5bTtcclxuICAgICAgICAgICAgICAgIGFjY2VwdGVkX2V2ZW50cyA9IGV2ZW50TG9nLnNwbGljZSgwLCAxKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gSWYga2V5ZG93biBpcyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBhIGtleXByZXNzLCB1c2UgdGhlIGluZGljYXRlZCBjaGFyYWN0ZXJcclxuICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnRMb2dbMV0gaW5zdGFuY2VvZiBLZXlwcmVzc0V2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICBrZXlzeW0gPSBldmVudExvZ1sxXS5rZXlzeW07XHJcbiAgICAgICAgICAgICAgICBhY2NlcHRlZF9ldmVudHMgPSBldmVudExvZy5zcGxpY2UoMCwgMik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIGtleWRvd24gaXMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgYW55dGhpbmcgZWxzZSwgdGhlbiBub1xyXG4gICAgICAgICAgICAvLyBrZXlwcmVzcyBjYW4gcG9zc2libHkgb2NjdXIgdG8gY2xhcmlmeSB0aGlzIGV2ZW50LCBhbmQgd2UgbXVzdFxyXG4gICAgICAgICAgICAvLyBoYW5kbGUgaXQgbm93XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50TG9nWzFdKSB7XHJcbiAgICAgICAgICAgICAgICBrZXlzeW0gPSBmaXJzdC5rZXlzeW07XHJcbiAgICAgICAgICAgICAgICBhY2NlcHRlZF9ldmVudHMgPSBldmVudExvZy5zcGxpY2UoMCwgMSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEZpcmUgYSBrZXkgcHJlc3MgaWYgdmFsaWQgZXZlbnRzIHdlcmUgZm91bmRcclxuICAgICAgICAgICAgaWYgKGFjY2VwdGVkX2V2ZW50cy5sZW5ndGggPiAwKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGtleXN5bSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBGaXJlIGV2ZW50XHJcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZV9zaW11bGF0ZWRfYWx0Z3Ioa2V5c3ltKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdFByZXZlbnRlZCA9ICFndWFjX2tleWJvYXJkLnByZXNzKGtleXN5bSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVjZW50S2V5c3ltW2ZpcnN0LmtleUNvZGVdID0ga2V5c3ltO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBhIGtleSBpcyBwcmVzc2VkIHdoaWxlIG1ldGEgaXMgaGVsZCBkb3duLCB0aGUga2V5dXAgd2lsbFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG5ldmVyIGJlIHNlbnQgaW4gQ2hyb21lLCBzbyBzZW5kIGl0IG5vdy4gKGJ1ZyAjMTA4NDA0KVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChndWFjX2tleWJvYXJkLm1vZGlmaWVycy5tZXRhICYmIGtleXN5bSAhPT0gMHhGRkU3ICYmIGtleXN5bSAhPT0gMHhGRkU4KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBndWFjX2tleWJvYXJkLnJlbGVhc2Uoa2V5c3ltKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVjb3JkIHdoZXRoZXIgZGVmYXVsdCB3YXMgcHJldmVudGVkXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpPGFjY2VwdGVkX2V2ZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXB0ZWRfZXZlbnRzW2ldLmRlZmF1bHRQcmV2ZW50ZWQgPSBkZWZhdWx0UHJldmVudGVkO1xyXG5cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlyc3Q7XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0gLy8gZW5kIGlmIGtleWRvd25cclxuXHJcbiAgICAgICAgLy8gS2V5dXAgZXZlbnRcclxuICAgICAgICBlbHNlIGlmIChmaXJzdCBpbnN0YW5jZW9mIEtleXVwRXZlbnQpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFJlbGVhc2Ugc3BlY2lmaWMga2V5IGlmIGtub3duXHJcbiAgICAgICAgICAgIHZhciBrZXlzeW0gPSBmaXJzdC5rZXlzeW07XHJcbiAgICAgICAgICAgIGlmIChrZXlzeW0pIHtcclxuICAgICAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVsZWFzZShrZXlzeW0pO1xyXG4gICAgICAgICAgICAgICAgZmlyc3QuZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgZmFsbCBiYWNrIHRvIHJlbGVhc2luZyBhbGwga2V5c1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGd1YWNfa2V5Ym9hcmQucmVzZXQoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmaXJzdDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGV2ZW50TG9nLnNoaWZ0KCk7XHJcblxyXG4gICAgICAgIH0gLy8gZW5kIGlmIGtleXVwXHJcblxyXG4gICAgICAgIC8vIElnbm9yZSBhbnkgb3RoZXIgdHlwZSBvZiBldmVudCAoa2V5cHJlc3MgYnkgaXRzZWxmIGlzIGludmFsaWQpXHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gZXZlbnRMb2cuc2hpZnQoKTtcclxuXHJcbiAgICAgICAgLy8gTm8gZXZlbnQgaW50ZXJwcmV0ZWRcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUga2V5Ym9hcmQgbG9jYXRpb24gb2YgdGhlIGtleSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuXHJcbiAgICAgKiBrZXlib2FyZCBldmVudC4gVGhlIGxvY2F0aW9uIGRpZmZlcmVudGlhdGVzIGtleSBldmVudHMgd2hpY2ggb3RoZXJ3aXNlXHJcbiAgICAgKiBoYXZlIHRoZSBzYW1lIGtleWNvZGUsIHN1Y2ggYXMgbGVmdCBzaGlmdCB2cy4gcmlnaHQgc2hpZnQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZVxyXG4gICAgICogICAgIEEgSmF2YVNjcmlwdCBrZXlib2FyZCBldmVudCwgYXMgcmVjZWl2ZWQgdGhyb3VnaCB0aGUgRE9NIHZpYSBhXHJcbiAgICAgKiAgICAgXCJrZXlkb3duXCIsIFwia2V5dXBcIiwgb3IgXCJrZXlwcmVzc1wiIGhhbmRsZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge051bWJlcn1cclxuICAgICAqICAgICBUaGUgbG9jYXRpb24gb2YgdGhlIGtleSBldmVudCBvbiB0aGUga2V5Ym9hcmQsIGFzIGRlZmluZWQgYXQ6XHJcbiAgICAgKiAgICAgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtS2V5Ym9hcmRFdmVudFxyXG4gICAgICovXHJcbiAgICB2YXIgZ2V0RXZlbnRMb2NhdGlvbiA9IGZ1bmN0aW9uIGdldEV2ZW50TG9jYXRpb24oZSkge1xyXG5cclxuICAgICAgICAvLyBVc2Ugc3RhbmRhcmQgbG9jYXRpb24sIGlmIHBvc3NpYmxlXHJcbiAgICAgICAgaWYgKCdsb2NhdGlvbicgaW4gZSlcclxuICAgICAgICAgICAgcmV0dXJuIGUubG9jYXRpb247XHJcblxyXG4gICAgICAgIC8vIEZhaWxpbmcgdGhhdCwgYXR0ZW1wdCB0byB1c2UgZGVwcmVjYXRlZCBrZXlMb2NhdGlvblxyXG4gICAgICAgIGlmICgna2V5TG9jYXRpb24nIGluIGUpXHJcbiAgICAgICAgICAgIHJldHVybiBlLmtleUxvY2F0aW9uO1xyXG5cclxuICAgICAgICAvLyBJZiBubyBsb2NhdGlvbiBpcyBhdmFpbGFibGUsIGFzc3VtZSBsZWZ0IHNpZGVcclxuICAgICAgICByZXR1cm4gMDtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIFdoZW4ga2V5IHByZXNzZWRcclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgZnVuY3Rpb24oZSkge1xyXG5cclxuICAgICAgICAvLyBPbmx5IGludGVyY2VwdCBpZiBoYW5kbGVyIHNldFxyXG4gICAgICAgIGlmICghZ3VhY19rZXlib2FyZC5vbmtleWRvd24pIHJldHVybjtcclxuXHJcbiAgICAgICAgdmFyIGtleUNvZGU7XHJcbiAgICAgICAgaWYgKHdpbmRvdy5ldmVudCkga2V5Q29kZSA9IHdpbmRvdy5ldmVudC5rZXlDb2RlO1xyXG4gICAgICAgIGVsc2UgaWYgKGUud2hpY2gpIGtleUNvZGUgPSBlLndoaWNoO1xyXG5cclxuICAgICAgICAvLyBGaXggbW9kaWZpZXIgc3RhdGVzXHJcbiAgICAgICAgdXBkYXRlX21vZGlmaWVyX3N0YXRlKGUpO1xyXG5cclxuICAgICAgICAvLyBJZ25vcmUgKGJ1dCBkbyBub3QgcHJldmVudCkgdGhlIFwiY29tcG9zaXRpb25cIiBrZXljb2RlIHNlbnQgYnkgc29tZVxyXG4gICAgICAgIC8vIGJyb3dzZXJzIHdoZW4gYW4gSU1FIGlzIGluIHVzZSAoc2VlOiBodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3ctZG9tLzIwMTBKdWxTZXAvYXR0LTAxODIva2V5Q29kZS1zcGVjLmh0bWwpXHJcbiAgICAgICAgaWYgKGtleUNvZGUgPT09IDIyOSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBMb2cgZXZlbnRcclxuICAgICAgICB2YXIga2V5ZG93bkV2ZW50ID0gbmV3IEtleWRvd25FdmVudChrZXlDb2RlLCBlLmtleUlkZW50aWZpZXIsIGUua2V5LCBnZXRFdmVudExvY2F0aW9uKGUpKTtcclxuICAgICAgICBldmVudExvZy5wdXNoKGtleWRvd25FdmVudCk7XHJcblxyXG4gICAgICAgIC8vIEludGVycHJldCBhcyBtYW55IGV2ZW50cyBhcyBwb3NzaWJsZSwgcHJldmVudCBkZWZhdWx0IGlmIGluZGljYXRlZFxyXG4gICAgICAgIGlmIChpbnRlcnByZXRfZXZlbnRzKCkpXHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICB9LCB0cnVlKTtcclxuXHJcbiAgICAvLyBXaGVuIGtleSBwcmVzc2VkXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlwcmVzc1wiLCBmdW5jdGlvbihlKSB7XHJcblxyXG4gICAgICAgIC8vIE9ubHkgaW50ZXJjZXB0IGlmIGhhbmRsZXIgc2V0XHJcbiAgICAgICAgaWYgKCFndWFjX2tleWJvYXJkLm9ua2V5ZG93biAmJiAhZ3VhY19rZXlib2FyZC5vbmtleXVwKSByZXR1cm47XHJcblxyXG4gICAgICAgIHZhciBjaGFyQ29kZTtcclxuICAgICAgICBpZiAod2luZG93LmV2ZW50KSBjaGFyQ29kZSA9IHdpbmRvdy5ldmVudC5rZXlDb2RlO1xyXG4gICAgICAgIGVsc2UgaWYgKGUud2hpY2gpIGNoYXJDb2RlID0gZS53aGljaDtcclxuXHJcbiAgICAgICAgLy8gRml4IG1vZGlmaWVyIHN0YXRlc1xyXG4gICAgICAgIHVwZGF0ZV9tb2RpZmllcl9zdGF0ZShlKTtcclxuXHJcbiAgICAgICAgLy8gTG9nIGV2ZW50XHJcbiAgICAgICAgdmFyIGtleXByZXNzRXZlbnQgPSBuZXcgS2V5cHJlc3NFdmVudChjaGFyQ29kZSk7XHJcbiAgICAgICAgZXZlbnRMb2cucHVzaChrZXlwcmVzc0V2ZW50KTtcclxuXHJcbiAgICAgICAgLy8gSW50ZXJwcmV0IGFzIG1hbnkgZXZlbnRzIGFzIHBvc3NpYmxlLCBwcmV2ZW50IGRlZmF1bHQgaWYgaW5kaWNhdGVkXHJcbiAgICAgICAgaWYgKGludGVycHJldF9ldmVudHMoKSlcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgIH0sIHRydWUpO1xyXG5cclxuICAgIC8vIFdoZW4ga2V5IHJlbGVhc2VkXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXl1cFwiLCBmdW5jdGlvbihlKSB7XHJcblxyXG4gICAgICAgIC8vIE9ubHkgaW50ZXJjZXB0IGlmIGhhbmRsZXIgc2V0XHJcbiAgICAgICAgaWYgKCFndWFjX2tleWJvYXJkLm9ua2V5dXApIHJldHVybjtcclxuXHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICB2YXIga2V5Q29kZTtcclxuICAgICAgICBpZiAod2luZG93LmV2ZW50KSBrZXlDb2RlID0gd2luZG93LmV2ZW50LmtleUNvZGU7XHJcbiAgICAgICAgZWxzZSBpZiAoZS53aGljaCkga2V5Q29kZSA9IGUud2hpY2g7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gRml4IG1vZGlmaWVyIHN0YXRlc1xyXG4gICAgICAgIHVwZGF0ZV9tb2RpZmllcl9zdGF0ZShlKTtcclxuXHJcbiAgICAgICAgLy8gTG9nIGV2ZW50LCBjYWxsIGZvciBpbnRlcnByZXRhdGlvblxyXG4gICAgICAgIHZhciBrZXl1cEV2ZW50ID0gbmV3IEtleXVwRXZlbnQoa2V5Q29kZSwgZS5rZXlJZGVudGlmaWVyLCBlLmtleSwgZ2V0RXZlbnRMb2NhdGlvbihlKSk7XHJcbiAgICAgICAgZXZlbnRMb2cucHVzaChrZXl1cEV2ZW50KTtcclxuICAgICAgICBpbnRlcnByZXRfZXZlbnRzKCk7XHJcblxyXG4gICAgfSwgdHJ1ZSk7XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRoZSBzdGF0ZSBvZiBhbGwgc3VwcG9ydGVkIGtleWJvYXJkIG1vZGlmaWVycy5cclxuICogQGNvbnN0cnVjdG9yXHJcbiAqL1xyXG5HdWFjYW1vbGUuS2V5Ym9hcmQuTW9kaWZpZXJTdGF0ZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgc2hpZnQgaXMgY3VycmVudGx5IHByZXNzZWQuXHJcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5zaGlmdCA9IGZhbHNlO1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgY3RybCBpcyBjdXJyZW50bHkgcHJlc3NlZC5cclxuICAgICAqIEB0eXBlIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICB0aGlzLmN0cmwgPSBmYWxzZTtcclxuICAgIFxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIGFsdCBpcyBjdXJyZW50bHkgcHJlc3NlZC5cclxuICAgICAqIEB0eXBlIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICB0aGlzLmFsdCA9IGZhbHNlO1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgbWV0YSAoYXBwbGUga2V5KSBpcyBjdXJyZW50bHkgcHJlc3NlZC5cclxuICAgICAqIEB0eXBlIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICB0aGlzLm1ldGEgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgaHlwZXIgKHdpbmRvd3Mga2V5KSBpcyBjdXJyZW50bHkgcHJlc3NlZC5cclxuICAgICAqIEB0eXBlIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICB0aGlzLmh5cGVyID0gZmFsc2U7XHJcbiAgICBcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBtb2RpZmllciBzdGF0ZSBhcHBsaWNhYmxlIHRvIHRoZSBrZXlib2FyZCBldmVudCBnaXZlbi5cclxuICogXHJcbiAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZSBUaGUga2V5Ym9hcmQgZXZlbnQgdG8gcmVhZC5cclxuICogQHJldHVybnMge0d1YWNhbW9sZS5LZXlib2FyZC5Nb2RpZmllclN0YXRlfSBUaGUgY3VycmVudCBzdGF0ZSBvZiBrZXlib2FyZFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVycy5cclxuICovXHJcbkd1YWNhbW9sZS5LZXlib2FyZC5Nb2RpZmllclN0YXRlLmZyb21LZXlib2FyZEV2ZW50ID0gZnVuY3Rpb24oZSkge1xyXG4gICAgXHJcbiAgICB2YXIgc3RhdGUgPSBuZXcgR3VhY2Ftb2xlLktleWJvYXJkLk1vZGlmaWVyU3RhdGUoKTtcclxuXHJcbiAgICAvLyBBc3NpZ24gc3RhdGVzIGZyb20gb2xkIGZsYWdzXHJcbiAgICBzdGF0ZS5zaGlmdCA9IGUuc2hpZnRLZXk7XHJcbiAgICBzdGF0ZS5jdHJsICA9IGUuY3RybEtleTtcclxuICAgIHN0YXRlLmFsdCAgID0gZS5hbHRLZXk7XHJcbiAgICBzdGF0ZS5tZXRhICA9IGUubWV0YUtleTtcclxuXHJcbiAgICAvLyBVc2UgRE9NMyBnZXRNb2RpZmllclN0YXRlKCkgZm9yIG90aGVyc1xyXG4gICAgaWYgKGUuZ2V0TW9kaWZpZXJTdGF0ZSkge1xyXG4gICAgICAgIHN0YXRlLmh5cGVyID0gZS5nZXRNb2RpZmllclN0YXRlKFwiT1NcIilcclxuICAgICAgICAgICAgICAgICAgIHx8IGUuZ2V0TW9kaWZpZXJTdGF0ZShcIlN1cGVyXCIpXHJcbiAgICAgICAgICAgICAgICAgICB8fCBlLmdldE1vZGlmaWVyU3RhdGUoXCJIeXBlclwiKVxyXG4gICAgICAgICAgICAgICAgICAgfHwgZS5nZXRNb2RpZmllclN0YXRlKFwiV2luXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdGF0ZTtcclxuICAgIFxyXG59O1xyXG4vKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIEFic3RyYWN0IG9yZGVyZWQgZHJhd2luZyBzdXJmYWNlLiBFYWNoIExheWVyIGNvbnRhaW5zIGEgY2FudmFzIGVsZW1lbnQgYW5kXHJcbiAqIHByb3ZpZGVzIHNpbXBsZSBkcmF3aW5nIGluc3RydWN0aW9ucyBmb3IgZHJhd2luZyB0byB0aGF0IGNhbnZhcyBlbGVtZW50LFxyXG4gKiBob3dldmVyIHVubGlrZSB0aGUgY2FudmFzIGVsZW1lbnQgaXRzZWxmLCBkcmF3aW5nIG9wZXJhdGlvbnMgb24gYSBMYXllciBhcmVcclxuICogZ3VhcmFudGVlZCB0byBydW4gaW4gb3JkZXIsIGV2ZW4gaWYgc3VjaCBhbiBvcGVyYXRpb24gbXVzdCB3YWl0IGZvciBhbiBpbWFnZVxyXG4gKiB0byBsb2FkIGJlZm9yZSBjb21wbGV0aW5nLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIFxyXG4gKiBAcGFyYW0ge051bWJlcn0gd2lkdGggVGhlIHdpZHRoIG9mIHRoZSBMYXllciwgaW4gcGl4ZWxzLiBUaGUgY2FudmFzIGVsZW1lbnRcclxuICogICAgICAgICAgICAgICAgICAgICAgIGJhY2tpbmcgdGhpcyBMYXllciB3aWxsIGJlIGdpdmVuIHRoaXMgd2lkdGguXHJcbiAqICAgICAgICAgICAgICAgICAgICAgICBcclxuICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodCBUaGUgaGVpZ2h0IG9mIHRoZSBMYXllciwgaW4gcGl4ZWxzLiBUaGUgY2FudmFzIGVsZW1lbnRcclxuICogICAgICAgICAgICAgICAgICAgICAgICBiYWNraW5nIHRoaXMgTGF5ZXIgd2lsbCBiZSBnaXZlbiB0aGlzIGhlaWdodC5cclxuICovXHJcbkd1YWNhbW9sZS5MYXllciA9IGZ1bmN0aW9uKHdpZHRoLCBoZWlnaHQpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIExheWVyLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGxheWVyID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2YgcGl4ZWxzIHRoZSB3aWR0aCBvciBoZWlnaHQgb2YgYSBsYXllciBtdXN0IGNoYW5nZSBiZWZvcmVcclxuICAgICAqIHRoZSB1bmRlcmx5aW5nIGNhbnZhcyBpcyByZXNpemVkLiBUaGUgdW5kZXJseWluZyBjYW52YXMgd2lsbCBiZSBrZXB0IGF0XHJcbiAgICAgKiBkaW1lbnNpb25zIHdoaWNoIGFyZSBpbnRlZ2VyIG11bHRpcGxlcyBvZiB0aGlzIGZhY3Rvci5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQGNvbnN0YW50XHJcbiAgICAgKiBAdHlwZSBOdW1iZXJcclxuICAgICAqL1xyXG4gICAgdmFyIENBTlZBU19TSVpFX0ZBQ1RPUiA9IDY0O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNhbnZhcyBlbGVtZW50IGJhY2tpbmcgdGhpcyBMYXllci5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIDJEIGRpc3BsYXkgY29udGV4dCBvZiB0aGUgY2FudmFzIGVsZW1lbnQgYmFja2luZyB0aGlzIExheWVyLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xyXG4gICAgY29udGV4dC5zYXZlKCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIHRoZSBsYXllciBoYXMgbm90IHlldCBiZWVuIGRyYXduIHRvLiBPbmNlIGFueSBkcmF3IG9wZXJhdGlvblxyXG4gICAgICogd2hpY2ggYWZmZWN0cyB0aGUgdW5kZXJseWluZyBjYW52YXMgaXMgaW52b2tlZCwgdGhpcyBmbGFnIHdpbGwgYmUgc2V0IHRvXHJcbiAgICAgKiBmYWxzZS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUgQm9vbGVhblxyXG4gICAgICovXHJcbiAgICB2YXIgZW1wdHkgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciBhIG5ldyBwYXRoIHNob3VsZCBiZSBzdGFydGVkIHdpdGggdGhlIG5leHQgcGF0aCBkcmF3aW5nXHJcbiAgICAgKiBvcGVyYXRpb25zLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIHBhdGhDbG9zZWQgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG51bWJlciBvZiBzdGF0ZXMgb24gdGhlIHN0YXRlIHN0YWNrLlxyXG4gICAgICogXHJcbiAgICAgKiBOb3RlIHRoYXQgdGhlcmUgd2lsbCBBTFdBWVMgYmUgb25lIGVsZW1lbnQgb24gdGhlIHN0YWNrLCBidXQgdGhhdFxyXG4gICAgICogZWxlbWVudCBpcyBub3QgZXhwb3NlZC4gSXQgaXMgb25seSB1c2VkIHRvIHJlc2V0IHRoZSBsYXllciB0byBpdHNcclxuICAgICAqIGluaXRpYWwgc3RhdGUuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBzdGFja1NpemUgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFwIG9mIGFsbCBHdWFjYW1vbGUgY2hhbm5lbCBtYXNrcyB0byBIVE1MNSBjYW52YXMgY29tcG9zaXRlIG9wZXJhdGlvblxyXG4gICAgICogbmFtZXMuIE5vdCBhbGwgY2hhbm5lbCBtYXNrIGNvbWJpbmF0aW9ucyBhcmUgY3VycmVudGx5IGltcGxlbWVudGVkLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGNvbXBvc2l0ZU9wZXJhdGlvbiA9IHtcclxuICAgICAvKiAweDAgTk9UIElNUExFTUVOVEVEICovXHJcbiAgICAgICAgMHgxOiBcImRlc3RpbmF0aW9uLWluXCIsXHJcbiAgICAgICAgMHgyOiBcImRlc3RpbmF0aW9uLW91dFwiLFxyXG4gICAgIC8qIDB4MyBOT1QgSU1QTEVNRU5URUQgKi9cclxuICAgICAgICAweDQ6IFwic291cmNlLWluXCIsXHJcbiAgICAgLyogMHg1IE5PVCBJTVBMRU1FTlRFRCAqL1xyXG4gICAgICAgIDB4NjogXCJzb3VyY2UtYXRvcFwiLFxyXG4gICAgIC8qIDB4NyBOT1QgSU1QTEVNRU5URUQgKi9cclxuICAgICAgICAweDg6IFwic291cmNlLW91dFwiLFxyXG4gICAgICAgIDB4OTogXCJkZXN0aW5hdGlvbi1hdG9wXCIsXHJcbiAgICAgICAgMHhBOiBcInhvclwiLFxyXG4gICAgICAgIDB4QjogXCJkZXN0aW5hdGlvbi1vdmVyXCIsXHJcbiAgICAgICAgMHhDOiBcImNvcHlcIixcclxuICAgICAvKiAweEQgTk9UIElNUExFTUVOVEVEICovXHJcbiAgICAgICAgMHhFOiBcInNvdXJjZS1vdmVyXCIsXHJcbiAgICAgICAgMHhGOiBcImxpZ2h0ZXJcIlxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc2l6ZXMgdGhlIGNhbnZhcyBlbGVtZW50IGJhY2tpbmcgdGhpcyBMYXllci4gVGhpcyBmdW5jdGlvbiBzaG91bGQgb25seVxyXG4gICAgICogYmUgdXNlZCBpbnRlcm5hbGx5LlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IFtuZXdXaWR0aD0wXVxyXG4gICAgICogICAgIFRoZSBuZXcgd2lkdGggdG8gYXNzaWduIHRvIHRoaXMgTGF5ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IFtuZXdIZWlnaHQ9MF1cclxuICAgICAqICAgICBUaGUgbmV3IGhlaWdodCB0byBhc3NpZ24gdG8gdGhpcyBMYXllci5cclxuICAgICAqL1xyXG4gICAgdmFyIHJlc2l6ZSA9IGZ1bmN0aW9uIHJlc2l6ZShuZXdXaWR0aCwgbmV3SGVpZ2h0KSB7XHJcblxyXG4gICAgICAgIC8vIERlZmF1bHQgc2l6ZSB0byB6ZXJvXHJcbiAgICAgICAgbmV3V2lkdGggPSBuZXdXaWR0aCB8fCAwO1xyXG4gICAgICAgIG5ld0hlaWdodCA9IG5ld0hlaWdodCB8fCAwO1xyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgbmV3IGRpbWVuc2lvbnMgb2YgaW50ZXJuYWwgY2FudmFzXHJcbiAgICAgICAgdmFyIGNhbnZhc1dpZHRoICA9IE1hdGguY2VpbChuZXdXaWR0aCAgLyBDQU5WQVNfU0laRV9GQUNUT1IpICogQ0FOVkFTX1NJWkVfRkFDVE9SO1xyXG4gICAgICAgIHZhciBjYW52YXNIZWlnaHQgPSBNYXRoLmNlaWwobmV3SGVpZ2h0IC8gQ0FOVkFTX1NJWkVfRkFDVE9SKSAqIENBTlZBU19TSVpFX0ZBQ1RPUjtcclxuXHJcbiAgICAgICAgLy8gUmVzaXplIG9ubHkgaWYgY2FudmFzIGRpbWVuc2lvbnMgYXJlIGFjdHVhbGx5IGNoYW5naW5nXHJcbiAgICAgICAgaWYgKGNhbnZhcy53aWR0aCAhPT0gY2FudmFzV2lkdGggfHwgY2FudmFzLmhlaWdodCAhPT0gY2FudmFzSGVpZ2h0KSB7XHJcblxyXG4gICAgICAgICAgICAvLyBDb3B5IG9sZCBkYXRhIG9ubHkgaWYgcmVsZXZhbnQgYW5kIG5vbi1lbXB0eVxyXG4gICAgICAgICAgICB2YXIgb2xkRGF0YSA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICghZW1wdHkgJiYgY2FudmFzLndpZHRoICE9PSAwICYmIGNhbnZhcy5oZWlnaHQgIT09IDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgY2FudmFzIGFuZCBjb250ZXh0IGZvciBob2xkaW5nIG9sZCBkYXRhXHJcbiAgICAgICAgICAgICAgICBvbGREYXRhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcclxuICAgICAgICAgICAgICAgIG9sZERhdGEud2lkdGggPSBNYXRoLm1pbihsYXllci53aWR0aCwgbmV3V2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgb2xkRGF0YS5oZWlnaHQgPSBNYXRoLm1pbihsYXllci5oZWlnaHQsIG5ld0hlaWdodCk7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIG9sZERhdGFDb250ZXh0ID0gb2xkRGF0YS5nZXRDb250ZXh0KFwiMmRcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQ29weSBpbWFnZSBkYXRhIGZyb20gY3VycmVudFxyXG4gICAgICAgICAgICAgICAgb2xkRGF0YUNvbnRleHQuZHJhd0ltYWdlKGNhbnZhcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgb2xkRGF0YS53aWR0aCwgb2xkRGF0YS5oZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIG9sZERhdGEud2lkdGgsIG9sZERhdGEuaGVpZ2h0KTtcclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFByZXNlcnZlIGNvbXBvc2l0ZSBvcGVyYXRpb25cclxuICAgICAgICAgICAgdmFyIG9sZENvbXBvc2l0ZU9wZXJhdGlvbiA9IGNvbnRleHQuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uO1xyXG5cclxuICAgICAgICAgICAgLy8gUmVzaXplIGNhbnZhc1xyXG4gICAgICAgICAgICBjYW52YXMud2lkdGggPSBjYW52YXNXaWR0aDtcclxuICAgICAgICAgICAgY2FudmFzLmhlaWdodCA9IGNhbnZhc0hlaWdodDtcclxuXHJcbiAgICAgICAgICAgIC8vIFJlZHJhdyBvbGQgZGF0YSwgaWYgYW55XHJcbiAgICAgICAgICAgIGlmIChvbGREYXRhKVxyXG4gICAgICAgICAgICAgICAgY29udGV4dC5kcmF3SW1hZ2Uob2xkRGF0YSxcclxuICAgICAgICAgICAgICAgICAgICAwLCAwLCBvbGREYXRhLndpZHRoLCBvbGREYXRhLmhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAwLCAwLCBvbGREYXRhLndpZHRoLCBvbGREYXRhLmhlaWdodCk7XHJcblxyXG4gICAgICAgICAgICAvLyBSZXN0b3JlIGNvbXBvc2l0ZSBvcGVyYXRpb25cclxuICAgICAgICAgICAgY29udGV4dC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBvbGRDb21wb3NpdGVPcGVyYXRpb247XHJcblxyXG4gICAgICAgICAgICAvLyBBY2tub3dsZWRnZSByZXNldCBvZiBzdGFjayAoaGFwcGVucyBvbiByZXNpemUgb2YgY2FudmFzKVxyXG4gICAgICAgICAgICBzdGFja1NpemUgPSAwO1xyXG4gICAgICAgICAgICBjb250ZXh0LnNhdmUoKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiB0aGUgY2FudmFzIHNpemUgaXMgbm90IGNoYW5naW5nLCBtYW51YWxseSBmb3JjZSBzdGF0ZSByZXNldFxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgbGF5ZXIucmVzZXQoKTtcclxuXHJcbiAgICAgICAgLy8gQXNzaWduIG5ldyBsYXllciBkaW1lbnNpb25zXHJcbiAgICAgICAgbGF5ZXIud2lkdGggPSBuZXdXaWR0aDtcclxuICAgICAgICBsYXllci5oZWlnaHQgPSBuZXdIZWlnaHQ7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdpdmVuIHRoZSBYIGFuZCBZIGNvb3JkaW5hdGVzIG9mIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiBhIHJlY3RhbmdsZVxyXG4gICAgICogYW5kIHRoZSByZWN0YW5nbGUncyB3aWR0aCBhbmQgaGVpZ2h0LCByZXNpemUgdGhlIGJhY2tpbmcgY2FudmFzIGVsZW1lbnRcclxuICAgICAqIGFzIG5lY2Vzc2FyeSB0byBlbnN1cmUgdGhhdCB0aGUgcmVjdGFuZ2xlIGZpdHMgd2l0aGluIHRoZSBjYW52YXNcclxuICAgICAqIGVsZW1lbnQncyBjb29yZGluYXRlIHNwYWNlLiBUaGlzIGZ1bmN0aW9uIHdpbGwgb25seSBtYWtlIHRoZSBjYW52YXNcclxuICAgICAqIGxhcmdlci4gSWYgdGhlIHJlY3RhbmdsZSBhbHJlYWR5IGZpdHMgd2l0aGluIHRoZSBjYW52YXMgZWxlbWVudCdzXHJcbiAgICAgKiBjb29yZGluYXRlIHNwYWNlLCB0aGUgY2FudmFzIGlzIGxlZnQgdW5jaGFuZ2VkLlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgdG8gZml0LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgdG8gZml0LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHcgVGhlIHdpZHRoIG9mIHRoZSB0aGUgcmVjdGFuZ2xlIHRvIGZpdC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBoIFRoZSBoZWlnaHQgb2YgdGhlIHRoZSByZWN0YW5nbGUgdG8gZml0LlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBmaXRSZWN0KHgsIHksIHcsIGgpIHtcclxuICAgICAgICBcclxuICAgICAgICAvLyBDYWxjdWxhdGUgYm91bmRzXHJcbiAgICAgICAgdmFyIG9wQm91bmRYID0gdyArIHg7XHJcbiAgICAgICAgdmFyIG9wQm91bmRZID0gaCArIHk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gRGV0ZXJtaW5lIG1heCB3aWR0aFxyXG4gICAgICAgIHZhciByZXNpemVXaWR0aDtcclxuICAgICAgICBpZiAob3BCb3VuZFggPiBsYXllci53aWR0aClcclxuICAgICAgICAgICAgcmVzaXplV2lkdGggPSBvcEJvdW5kWDtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJlc2l6ZVdpZHRoID0gbGF5ZXIud2lkdGg7XHJcblxyXG4gICAgICAgIC8vIERldGVybWluZSBtYXggaGVpZ2h0XHJcbiAgICAgICAgdmFyIHJlc2l6ZUhlaWdodDtcclxuICAgICAgICBpZiAob3BCb3VuZFkgPiBsYXllci5oZWlnaHQpXHJcbiAgICAgICAgICAgIHJlc2l6ZUhlaWdodCA9IG9wQm91bmRZO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgcmVzaXplSGVpZ2h0ID0gbGF5ZXIuaGVpZ2h0O1xyXG5cclxuICAgICAgICAvLyBSZXNpemUgaWYgbmVjZXNzYXJ5XHJcbiAgICAgICAgbGF5ZXIucmVzaXplKHJlc2l6ZVdpZHRoLCByZXNpemVIZWlnaHQpO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldCB0byB0cnVlIGlmIHRoaXMgTGF5ZXIgc2hvdWxkIHJlc2l6ZSBpdHNlbGYgdG8gYWNjb21vZGF0ZSB0aGVcclxuICAgICAqIGRpbWVuc2lvbnMgb2YgYW55IGRyYXdpbmcgb3BlcmF0aW9uLCBhbmQgZmFsc2UgKHRoZSBkZWZhdWx0KSBvdGhlcndpc2UuXHJcbiAgICAgKiBcclxuICAgICAqIE5vdGUgdGhhdCBzZXR0aW5nIHRoaXMgcHJvcGVydHkgdGFrZXMgZWZmZWN0IGltbWVkaWF0ZWx5LCBhbmQgdGh1cyBtYXlcclxuICAgICAqIHRha2UgZWZmZWN0IG9uIG9wZXJhdGlvbnMgdGhhdCB3ZXJlIHN0YXJ0ZWQgaW4gdGhlIHBhc3QgYnV0IGhhdmUgbm90XHJcbiAgICAgKiB5ZXQgY29tcGxldGVkLiBJZiB5b3Ugd2lzaCB0aGUgc2V0dGluZyBvZiB0aGlzIGZsYWcgdG8gb25seSBtb2RpZnlcclxuICAgICAqIGZ1dHVyZSBvcGVyYXRpb25zLCB5b3Ugd2lsbCBuZWVkIHRvIG1ha2UgdGhlIHNldHRpbmcgb2YgdGhpcyBmbGFnIGFuXHJcbiAgICAgKiBvcGVyYXRpb24gd2l0aCBzeW5jKCkuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAvLyBTZXQgYXV0b3NpemUgdG8gdHJ1ZSBmb3IgYWxsIGZ1dHVyZSBvcGVyYXRpb25zXHJcbiAgICAgKiBsYXllci5zeW5jKGZ1bmN0aW9uKCkge1xyXG4gICAgICogICAgIGxheWVyLmF1dG9zaXplID0gdHJ1ZTtcclxuICAgICAqIH0pO1xyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAqIEBkZWZhdWx0IGZhbHNlXHJcbiAgICAgKi9cclxuICAgIHRoaXMuYXV0b3NpemUgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjdXJyZW50IHdpZHRoIG9mIHRoaXMgbGF5ZXIuXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLndpZHRoID0gd2lkdGg7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY3VycmVudCBoZWlnaHQgb2YgdGhpcyBsYXllci5cclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgY2FudmFzIGVsZW1lbnQgYmFja2luZyB0aGlzIExheWVyLiBOb3RlIHRoYXQgdGhlIGRpbWVuc2lvbnNcclxuICAgICAqIG9mIHRoZSBjYW52YXMgbWF5IG5vdCBleGFjdGx5IG1hdGNoIHRob3NlIG9mIHRoZSBMYXllciwgYXMgcmVzaXppbmcgYVxyXG4gICAgICogY2FudmFzIHdoaWxlIG1haW50YWluaW5nIGl0cyBzdGF0ZSBpcyBhbiBleHBlbnNpdmUgb3BlcmF0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtIVE1MQ2FudmFzRWxlbWVudH1cclxuICAgICAqICAgICBUaGUgY2FudmFzIGVsZW1lbnQgYmFja2luZyB0aGlzIExheWVyLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmdldENhbnZhcyA9IGZ1bmN0aW9uIGdldENhbnZhcygpIHtcclxuICAgICAgICByZXR1cm4gY2FudmFzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBuZXcgY2FudmFzIGVsZW1lbnQgY29udGFpbmluZyB0aGUgc2FtZSBpbWFnZSBhcyB0aGlzIExheWVyLlxyXG4gICAgICogVW5saWtlIGdldENhbnZhcygpLCB0aGUgY2FudmFzIGVsZW1lbnQgcmV0dXJuZWQgaXMgZ3VhcmFudGVlZCB0byBoYXZlXHJcbiAgICAgKiB0aGUgZXhhY3Qgc2FtZSBkaW1lbnNpb25zIGFzIHRoZSBMYXllci5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7SFRNTENhbnZhc0VsZW1lbnR9XHJcbiAgICAgKiAgICAgQSBuZXcgY2FudmFzIGVsZW1lbnQgY29udGFpbmluZyBhIGNvcHkgb2YgdGhlIGltYWdlIGNvbnRlbnQgdGhpc1xyXG4gICAgICogICAgIExheWVyLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnRvQ2FudmFzID0gZnVuY3Rpb24gdG9DYW52YXMoKSB7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBuZXcgY2FudmFzIGhhdmluZyBzYW1lIGRpbWVuc2lvbnNcclxuICAgICAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XHJcbiAgICAgICAgY2FudmFzLndpZHRoID0gbGF5ZXIud2lkdGg7XHJcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IGxheWVyLmhlaWdodDtcclxuXHJcbiAgICAgICAgLy8gQ29weSBpbWFnZSBjb250ZW50cyB0byBuZXcgY2FudmFzXHJcbiAgICAgICAgdmFyIGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgICAgICBjb250ZXh0LmRyYXdJbWFnZShsYXllci5nZXRDYW52YXMoKSwgMCwgMCk7XHJcblxyXG4gICAgICAgIHJldHVybiBjYW52YXM7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENoYW5nZXMgdGhlIHNpemUgb2YgdGhpcyBMYXllciB0byB0aGUgZ2l2ZW4gd2lkdGggYW5kIGhlaWdodC4gUmVzaXppbmdcclxuICAgICAqIGlzIG9ubHkgYXR0ZW1wdGVkIGlmIHRoZSBuZXcgc2l6ZSBwcm92aWRlZCBpcyBhY3R1YWxseSBkaWZmZXJlbnQgZnJvbVxyXG4gICAgICogdGhlIGN1cnJlbnQgc2l6ZS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG5ld1dpZHRoIFRoZSBuZXcgd2lkdGggdG8gYXNzaWduIHRvIHRoaXMgTGF5ZXIuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbmV3SGVpZ2h0IFRoZSBuZXcgaGVpZ2h0IHRvIGFzc2lnbiB0byB0aGlzIExheWVyLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnJlc2l6ZSA9IGZ1bmN0aW9uKG5ld1dpZHRoLCBuZXdIZWlnaHQpIHtcclxuICAgICAgICBpZiAobmV3V2lkdGggIT09IGxheWVyLndpZHRoIHx8IG5ld0hlaWdodCAhPT0gbGF5ZXIuaGVpZ2h0KVxyXG4gICAgICAgICAgICByZXNpemUobmV3V2lkdGgsIG5ld0hlaWdodCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRHJhd3MgdGhlIHNwZWNpZmllZCBpbWFnZSBhdCB0aGUgZ2l2ZW4gY29vcmRpbmF0ZXMuIFRoZSBpbWFnZSBzcGVjaWZpZWRcclxuICAgICAqIG11c3QgYWxyZWFkeSBiZSBsb2FkZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBkZXN0aW5hdGlvbiBYIGNvb3JkaW5hdGUuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgZGVzdGluYXRpb24gWSBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIHtJbWFnZX0gaW1hZ2UgVGhlIGltYWdlIHRvIGRyYXcuIE5vdGUgdGhhdCB0aGlzIGlzIGFuIEltYWdlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvYmplY3QgLSBub3QgYSBVUkwuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZHJhd0ltYWdlID0gZnVuY3Rpb24oeCwgeSwgaW1hZ2UpIHtcclxuICAgICAgICBpZiAobGF5ZXIuYXV0b3NpemUpIGZpdFJlY3QoeCwgeSwgaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCk7XHJcbiAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIHgsIHkpO1xyXG4gICAgICAgIGVtcHR5ID0gZmFsc2U7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHJhbnNmZXIgYSByZWN0YW5nbGUgb2YgaW1hZ2UgZGF0YSBmcm9tIG9uZSBMYXllciB0byB0aGlzIExheWVyIHVzaW5nIHRoZVxyXG4gICAgICogc3BlY2lmaWVkIHRyYW5zZmVyIGZ1bmN0aW9uLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gc3JjTGF5ZXIgVGhlIExheWVyIHRvIGNvcHkgaW1hZ2UgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY3ggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2UgTGF5ZXIncyBjb29yZGluYXRlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmN5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlIExheWVyJ3MgY29vcmRpbmF0ZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjdyBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZSBMYXllcidzXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY2ggVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBMYXllcidzIGNvb3JkaW5hdGUgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZGVzdGluYXRpb24gWCBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIGRlc3RpbmF0aW9uIFkgY29vcmRpbmF0ZS5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZmVyRnVuY3Rpb24gVGhlIHRyYW5zZmVyIGZ1bmN0aW9uIHRvIHVzZSB0b1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2ZlciBkYXRhIGZyb20gc291cmNlIHRvXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnRyYW5zZmVyID0gZnVuY3Rpb24oc3JjTGF5ZXIsIHNyY3gsIHNyY3ksIHNyY3csIHNyY2gsIHgsIHksIHRyYW5zZmVyRnVuY3Rpb24pIHtcclxuXHJcbiAgICAgICAgdmFyIHNyY0NhbnZhcyA9IHNyY0xheWVyLmdldENhbnZhcygpO1xyXG5cclxuICAgICAgICAvLyBJZiBlbnRpcmUgcmVjdGFuZ2xlIG91dHNpZGUgc291cmNlIGNhbnZhcywgc3RvcFxyXG4gICAgICAgIGlmIChzcmN4ID49IHNyY0NhbnZhcy53aWR0aCB8fCBzcmN5ID49IHNyY0NhbnZhcy5oZWlnaHQpIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBjbGlwIHJlY3RhbmdsZSB0byBhcmVhXHJcbiAgICAgICAgaWYgKHNyY3ggKyBzcmN3ID4gc3JjQ2FudmFzLndpZHRoKVxyXG4gICAgICAgICAgICBzcmN3ID0gc3JjQ2FudmFzLndpZHRoIC0gc3JjeDtcclxuXHJcbiAgICAgICAgaWYgKHNyY3kgKyBzcmNoID4gc3JjQ2FudmFzLmhlaWdodClcclxuICAgICAgICAgICAgc3JjaCA9IHNyY0NhbnZhcy5oZWlnaHQgLSBzcmN5O1xyXG5cclxuICAgICAgICAvLyBTdG9wIGlmIG5vdGhpbmcgdG8gZHJhdy5cclxuICAgICAgICBpZiAoc3JjdyA9PT0gMCB8fCBzcmNoID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgICAgIGlmIChsYXllci5hdXRvc2l6ZSkgZml0UmVjdCh4LCB5LCBzcmN3LCBzcmNoKTtcclxuXHJcbiAgICAgICAgLy8gR2V0IGltYWdlIGRhdGEgZnJvbSBzcmMgYW5kIGRzdFxyXG4gICAgICAgIHZhciBzcmMgPSBzcmNMYXllci5nZXRDYW52YXMoKS5nZXRDb250ZXh0KFwiMmRcIikuZ2V0SW1hZ2VEYXRhKHNyY3gsIHNyY3ksIHNyY3csIHNyY2gpO1xyXG4gICAgICAgIHZhciBkc3QgPSBjb250ZXh0LmdldEltYWdlRGF0YSh4ICwgeSwgc3Jjdywgc3JjaCk7XHJcblxyXG4gICAgICAgIC8vIEFwcGx5IHRyYW5zZmVyIGZvciBlYWNoIHBpeGVsXHJcbiAgICAgICAgZm9yICh2YXIgaT0wOyBpPHNyY3cqc3JjaCo0OyBpKz00KSB7XHJcblxyXG4gICAgICAgICAgICAvLyBHZXQgc291cmNlIHBpeGVsIGVudmlyb25tZW50XHJcbiAgICAgICAgICAgIHZhciBzcmNfcGl4ZWwgPSBuZXcgR3VhY2Ftb2xlLkxheWVyLlBpeGVsKFxyXG4gICAgICAgICAgICAgICAgc3JjLmRhdGFbaV0sXHJcbiAgICAgICAgICAgICAgICBzcmMuZGF0YVtpKzFdLFxyXG4gICAgICAgICAgICAgICAgc3JjLmRhdGFbaSsyXSxcclxuICAgICAgICAgICAgICAgIHNyYy5kYXRhW2krM11cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyBHZXQgZGVzdGluYXRpb24gcGl4ZWwgZW52aXJvbm1lbnRcclxuICAgICAgICAgICAgdmFyIGRzdF9waXhlbCA9IG5ldyBHdWFjYW1vbGUuTGF5ZXIuUGl4ZWwoXHJcbiAgICAgICAgICAgICAgICBkc3QuZGF0YVtpXSxcclxuICAgICAgICAgICAgICAgIGRzdC5kYXRhW2krMV0sXHJcbiAgICAgICAgICAgICAgICBkc3QuZGF0YVtpKzJdLFxyXG4gICAgICAgICAgICAgICAgZHN0LmRhdGFbaSszXVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgLy8gQXBwbHkgdHJhbnNmZXIgZnVuY3Rpb25cclxuICAgICAgICAgICAgdHJhbnNmZXJGdW5jdGlvbihzcmNfcGl4ZWwsIGRzdF9waXhlbCk7XHJcblxyXG4gICAgICAgICAgICAvLyBTYXZlIHBpeGVsIGRhdGFcclxuICAgICAgICAgICAgZHN0LmRhdGFbaSAgXSA9IGRzdF9waXhlbC5yZWQ7XHJcbiAgICAgICAgICAgIGRzdC5kYXRhW2krMV0gPSBkc3RfcGl4ZWwuZ3JlZW47XHJcbiAgICAgICAgICAgIGRzdC5kYXRhW2krMl0gPSBkc3RfcGl4ZWwuYmx1ZTtcclxuICAgICAgICAgICAgZHN0LmRhdGFbaSszXSA9IGRzdF9waXhlbC5hbHBoYTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEcmF3IGltYWdlIGRhdGFcclxuICAgICAgICBjb250ZXh0LnB1dEltYWdlRGF0YShkc3QsIHgsIHkpO1xyXG4gICAgICAgIGVtcHR5ID0gZmFsc2U7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFB1dCBhIHJlY3RhbmdsZSBvZiBpbWFnZSBkYXRhIGZyb20gb25lIExheWVyIHRvIHRoaXMgTGF5ZXIgZGlyZWN0bHlcclxuICAgICAqIHdpdGhvdXQgcGVyZm9ybWluZyBhbnkgYWxwaGEgYmxlbmRpbmcuIFNpbXBseSBjb3B5IHRoZSBkYXRhLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gc3JjTGF5ZXIgVGhlIExheWVyIHRvIGNvcHkgaW1hZ2UgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY3ggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2UgTGF5ZXIncyBjb29yZGluYXRlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmN5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlIExheWVyJ3MgY29vcmRpbmF0ZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjdyBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZSBMYXllcidzXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY2ggVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBMYXllcidzIGNvb3JkaW5hdGUgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZGVzdGluYXRpb24gWCBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIGRlc3RpbmF0aW9uIFkgY29vcmRpbmF0ZS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5wdXQgPSBmdW5jdGlvbihzcmNMYXllciwgc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCwgeCwgeSkge1xyXG5cclxuICAgICAgICB2YXIgc3JjQ2FudmFzID0gc3JjTGF5ZXIuZ2V0Q2FudmFzKCk7XHJcblxyXG4gICAgICAgIC8vIElmIGVudGlyZSByZWN0YW5nbGUgb3V0c2lkZSBzb3VyY2UgY2FudmFzLCBzdG9wXHJcbiAgICAgICAgaWYgKHNyY3ggPj0gc3JjQ2FudmFzLndpZHRoIHx8IHNyY3kgPj0gc3JjQ2FudmFzLmhlaWdodCkgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBPdGhlcndpc2UsIGNsaXAgcmVjdGFuZ2xlIHRvIGFyZWFcclxuICAgICAgICBpZiAoc3JjeCArIHNyY3cgPiBzcmNDYW52YXMud2lkdGgpXHJcbiAgICAgICAgICAgIHNyY3cgPSBzcmNDYW52YXMud2lkdGggLSBzcmN4O1xyXG5cclxuICAgICAgICBpZiAoc3JjeSArIHNyY2ggPiBzcmNDYW52YXMuaGVpZ2h0KVxyXG4gICAgICAgICAgICBzcmNoID0gc3JjQ2FudmFzLmhlaWdodCAtIHNyY3k7XHJcblxyXG4gICAgICAgIC8vIFN0b3AgaWYgbm90aGluZyB0byBkcmF3LlxyXG4gICAgICAgIGlmIChzcmN3ID09PSAwIHx8IHNyY2ggPT09IDApIHJldHVybjtcclxuXHJcbiAgICAgICAgaWYgKGxheWVyLmF1dG9zaXplKSBmaXRSZWN0KHgsIHksIHNyY3csIHNyY2gpO1xyXG5cclxuICAgICAgICAvLyBHZXQgaW1hZ2UgZGF0YSBmcm9tIHNyYyBhbmQgZHN0XHJcbiAgICAgICAgdmFyIHNyYyA9IHNyY0xheWVyLmdldENhbnZhcygpLmdldENvbnRleHQoXCIyZFwiKS5nZXRJbWFnZURhdGEoc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCk7XHJcbiAgICAgICAgY29udGV4dC5wdXRJbWFnZURhdGEoc3JjLCB4LCB5KTtcclxuICAgICAgICBlbXB0eSA9IGZhbHNlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb3B5IGEgcmVjdGFuZ2xlIG9mIGltYWdlIGRhdGEgZnJvbSBvbmUgTGF5ZXIgdG8gdGhpcyBMYXllci4gVGhpc1xyXG4gICAgICogb3BlcmF0aW9uIHdpbGwgY29weSBleGFjdGx5IHRoZSBpbWFnZSBkYXRhIHRoYXQgd2lsbCBiZSBkcmF3biBvbmNlIGFsbFxyXG4gICAgICogb3BlcmF0aW9ucyBvZiB0aGUgc291cmNlIExheWVyIHRoYXQgd2VyZSBwZW5kaW5nIGF0IHRoZSB0aW1lIHRoaXNcclxuICAgICAqIGZ1bmN0aW9uIHdhcyBjYWxsZWQgYXJlIGNvbXBsZXRlLiBUaGlzIG9wZXJhdGlvbiB3aWxsIG5vdCBhbHRlciB0aGVcclxuICAgICAqIHNpemUgb2YgdGhlIHNvdXJjZSBMYXllciBldmVuIGlmIGl0cyBhdXRvc2l6ZSBwcm9wZXJ0eSBpcyBzZXQgdG8gdHJ1ZS5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IHNyY0xheWVyIFRoZSBMYXllciB0byBjb3B5IGltYWdlIGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmN4IFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgcmVjdGFuZ2xlIHdpdGhpbiB0aGUgc291cmNlIExheWVyJ3MgY29vcmRpbmF0ZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgc3BhY2UgdG8gY29weSBkYXRhIGZyb20uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3JjeSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZSBMYXllcidzIGNvb3JkaW5hdGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHNyY3cgVGhlIHdpZHRoIG9mIHRoZSByZWN0YW5nbGUgd2l0aGluIHRoZSBzb3VyY2UgTGF5ZXInc1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZSBzcGFjZSB0byBjb3B5IGRhdGEgZnJvbS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzcmNoIFRoZSBoZWlnaHQgb2YgdGhlIHJlY3RhbmdsZSB3aXRoaW4gdGhlIHNvdXJjZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgTGF5ZXIncyBjb29yZGluYXRlIHNwYWNlIHRvIGNvcHkgZGF0YSBmcm9tLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGRlc3RpbmF0aW9uIFggY29vcmRpbmF0ZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBkZXN0aW5hdGlvbiBZIGNvb3JkaW5hdGUuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY29weSA9IGZ1bmN0aW9uKHNyY0xheWVyLCBzcmN4LCBzcmN5LCBzcmN3LCBzcmNoLCB4LCB5KSB7XHJcblxyXG4gICAgICAgIHZhciBzcmNDYW52YXMgPSBzcmNMYXllci5nZXRDYW52YXMoKTtcclxuXHJcbiAgICAgICAgLy8gSWYgZW50aXJlIHJlY3RhbmdsZSBvdXRzaWRlIHNvdXJjZSBjYW52YXMsIHN0b3BcclxuICAgICAgICBpZiAoc3JjeCA+PSBzcmNDYW52YXMud2lkdGggfHwgc3JjeSA+PSBzcmNDYW52YXMuaGVpZ2h0KSByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSwgY2xpcCByZWN0YW5nbGUgdG8gYXJlYVxyXG4gICAgICAgIGlmIChzcmN4ICsgc3JjdyA+IHNyY0NhbnZhcy53aWR0aClcclxuICAgICAgICAgICAgc3JjdyA9IHNyY0NhbnZhcy53aWR0aCAtIHNyY3g7XHJcblxyXG4gICAgICAgIGlmIChzcmN5ICsgc3JjaCA+IHNyY0NhbnZhcy5oZWlnaHQpXHJcbiAgICAgICAgICAgIHNyY2ggPSBzcmNDYW52YXMuaGVpZ2h0IC0gc3JjeTtcclxuXHJcbiAgICAgICAgLy8gU3RvcCBpZiBub3RoaW5nIHRvIGRyYXcuXHJcbiAgICAgICAgaWYgKHNyY3cgPT09IDAgfHwgc3JjaCA9PT0gMCkgcmV0dXJuO1xyXG5cclxuICAgICAgICBpZiAobGF5ZXIuYXV0b3NpemUpIGZpdFJlY3QoeCwgeSwgc3Jjdywgc3JjaCk7XHJcbiAgICAgICAgY29udGV4dC5kcmF3SW1hZ2Uoc3JjQ2FudmFzLCBzcmN4LCBzcmN5LCBzcmN3LCBzcmNoLCB4LCB5LCBzcmN3LCBzcmNoKTtcclxuICAgICAgICBlbXB0eSA9IGZhbHNlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdGFydHMgYSBuZXcgcGF0aCBhdCB0aGUgc3BlY2lmaWVkIHBvaW50LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCB0byBkcmF3LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIFkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQgdG8gZHJhdy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5tb3ZlVG8gPSBmdW5jdGlvbih4LCB5KSB7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gU3RhcnQgYSBuZXcgcGF0aCBpZiBjdXJyZW50IHBhdGggaXMgY2xvc2VkXHJcbiAgICAgICAgaWYgKHBhdGhDbG9zZWQpIHtcclxuICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcclxuICAgICAgICAgICAgcGF0aENsb3NlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAobGF5ZXIuYXV0b3NpemUpIGZpdFJlY3QoeCwgeSwgMCwgMCk7XHJcbiAgICAgICAgY29udGV4dC5tb3ZlVG8oeCwgeSk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZCB0aGUgc3BlY2lmaWVkIGxpbmUgdG8gdGhlIGN1cnJlbnQgcGF0aC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgZW5kcG9pbnQgb2YgdGhlIGxpbmUgdG8gZHJhdy5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGVuZHBvaW50IG9mIHRoZSBsaW5lIHRvIGRyYXcuXHJcbiAgICAgKi9cclxuICAgIHRoaXMubGluZVRvID0gZnVuY3Rpb24oeCwgeSkge1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIFN0YXJ0IGEgbmV3IHBhdGggaWYgY3VycmVudCBwYXRoIGlzIGNsb3NlZFxyXG4gICAgICAgIGlmIChwYXRoQ2xvc2VkKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgICAgIHBhdGhDbG9zZWQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGxheWVyLmF1dG9zaXplKSBmaXRSZWN0KHgsIHksIDAsIDApO1xyXG4gICAgICAgIGNvbnRleHQubGluZVRvKHgsIHkpO1xyXG4gICAgICAgIFxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZCB0aGUgc3BlY2lmaWVkIGFyYyB0byB0aGUgY3VycmVudCBwYXRoLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgWCBjb29yZGluYXRlIG9mIHRoZSBjZW50ZXIgb2YgdGhlIGNpcmNsZSB3aGljaFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgd2lsbCBjb250YWluIHRoZSBhcmMuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBjZW50ZXIgb2YgdGhlIGNpcmNsZSB3aGljaFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgd2lsbCBjb250YWluIHRoZSBhcmMuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcmFkaXVzIFRoZSByYWRpdXMgb2YgdGhlIGNpcmNsZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydEFuZ2xlIFRoZSBzdGFydGluZyBhbmdsZSBvZiB0aGUgYXJjLCBpbiByYWRpYW5zLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGVuZEFuZ2xlIFRoZSBlbmRpbmcgYW5nbGUgb2YgdGhlIGFyYywgaW4gcmFkaWFucy5cclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gbmVnYXRpdmUgV2hldGhlciB0aGUgYXJjIHNob3VsZCBiZSBkcmF3biBpbiBvcmRlciBvZlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzaW5nIGFuZ2xlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmFyYyA9IGZ1bmN0aW9uKHgsIHksIHJhZGl1cywgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIG5lZ2F0aXZlKSB7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gU3RhcnQgYSBuZXcgcGF0aCBpZiBjdXJyZW50IHBhdGggaXMgY2xvc2VkXHJcbiAgICAgICAgaWYgKHBhdGhDbG9zZWQpIHtcclxuICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcclxuICAgICAgICAgICAgcGF0aENsb3NlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAobGF5ZXIuYXV0b3NpemUpIGZpdFJlY3QoeCwgeSwgMCwgMCk7XHJcbiAgICAgICAgY29udGV4dC5hcmMoeCwgeSwgcmFkaXVzLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgbmVnYXRpdmUpO1xyXG4gICAgICAgIFxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0YXJ0cyBhIG5ldyBwYXRoIGF0IHRoZSBzcGVjaWZpZWQgcG9pbnQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjcDF4IFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IGNvbnRyb2wgcG9pbnQuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY3AxeSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBjb250cm9sIHBvaW50LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNwMnggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIGNvbnRyb2wgcG9pbnQuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY3AyeSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGVuZHBvaW50IG9mIHRoZSBjdXJ2ZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIGVuZHBvaW50IG9mIHRoZSBjdXJ2ZS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5jdXJ2ZVRvID0gZnVuY3Rpb24oY3AxeCwgY3AxeSwgY3AyeCwgY3AyeSwgeCwgeSkge1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIFN0YXJ0IGEgbmV3IHBhdGggaWYgY3VycmVudCBwYXRoIGlzIGNsb3NlZFxyXG4gICAgICAgIGlmIChwYXRoQ2xvc2VkKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgICAgIHBhdGhDbG9zZWQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGxheWVyLmF1dG9zaXplKSBmaXRSZWN0KHgsIHksIDAsIDApO1xyXG4gICAgICAgIGNvbnRleHQuYmV6aWVyQ3VydmVUbyhjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KTtcclxuICAgICAgICBcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDbG9zZXMgdGhlIGN1cnJlbnQgcGF0aCBieSBjb25uZWN0aW5nIHRoZSBlbmQgcG9pbnQgd2l0aCB0aGUgc3RhcnRcclxuICAgICAqIHBvaW50IChpZiBhbnkpIHdpdGggYSBzdHJhaWdodCBsaW5lLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcclxuICAgICAgICBwYXRoQ2xvc2VkID0gdHJ1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGQgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgdG8gdGhlIGN1cnJlbnQgcGF0aC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICByZWN0YW5nbGUgdG8gZHJhdy5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBZIGNvb3JkaW5hdGUgb2YgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZVxyXG4gICAgICogICAgICAgICAgICAgICAgICAgcmVjdGFuZ2xlIHRvIGRyYXcuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdyBUaGUgd2lkdGggb2YgdGhlIHJlY3RhbmdsZSB0byBkcmF3LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGggVGhlIGhlaWdodCBvZiB0aGUgcmVjdGFuZ2xlIHRvIGRyYXcuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVjdCA9IGZ1bmN0aW9uKHgsIHksIHcsIGgpIHtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgLy8gU3RhcnQgYSBuZXcgcGF0aCBpZiBjdXJyZW50IHBhdGggaXMgY2xvc2VkXHJcbiAgICAgICAgaWYgKHBhdGhDbG9zZWQpIHtcclxuICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcclxuICAgICAgICAgICAgcGF0aENsb3NlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAobGF5ZXIuYXV0b3NpemUpIGZpdFJlY3QoeCwgeSwgdywgaCk7XHJcbiAgICAgICAgY29udGV4dC5yZWN0KHgsIHksIHcsIGgpO1xyXG4gICAgICAgIFxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENsaXAgYWxsIGZ1dHVyZSBkcmF3aW5nIG9wZXJhdGlvbnMgYnkgdGhlIGN1cnJlbnQgcGF0aC4gVGhlIGN1cnJlbnQgcGF0aFxyXG4gICAgICogaXMgaW1wbGljaXRseSBjbG9zZWQuIFRoZSBjdXJyZW50IHBhdGggY2FuIGNvbnRpbnVlIHRvIGJlIHJldXNlZFxyXG4gICAgICogZm9yIG90aGVyIG9wZXJhdGlvbnMgKHN1Y2ggYXMgZmlsbENvbG9yKCkpIGJ1dCBhIG5ldyBwYXRoIHdpbGwgYmUgc3RhcnRlZFxyXG4gICAgICogb25jZSBhIHBhdGggZHJhd2luZyBvcGVyYXRpb24gKHBhdGgoKSBvciByZWN0KCkpIGlzIHVzZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY2xpcCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAvLyBTZXQgbmV3IGNsaXBwaW5nIHJlZ2lvblxyXG4gICAgICAgIGNvbnRleHQuY2xpcCgpO1xyXG5cclxuICAgICAgICAvLyBQYXRoIG5vdyBpbXBsaWNpdGx5IGNsb3NlZFxyXG4gICAgICAgIHBhdGhDbG9zZWQgPSB0cnVlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdHJva2UgdGhlIGN1cnJlbnQgcGF0aCB3aXRoIHRoZSBzcGVjaWZpZWQgY29sb3IuIFRoZSBjdXJyZW50IHBhdGhcclxuICAgICAqIGlzIGltcGxpY2l0bHkgY2xvc2VkLiBUaGUgY3VycmVudCBwYXRoIGNhbiBjb250aW51ZSB0byBiZSByZXVzZWRcclxuICAgICAqIGZvciBvdGhlciBvcGVyYXRpb25zIChzdWNoIGFzIGNsaXAoKSkgYnV0IGEgbmV3IHBhdGggd2lsbCBiZSBzdGFydGVkXHJcbiAgICAgKiBvbmNlIGEgcGF0aCBkcmF3aW5nIG9wZXJhdGlvbiAocGF0aCgpIG9yIHJlY3QoKSkgaXMgdXNlZC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNhcCBUaGUgbGluZSBjYXAgc3R5bGUuIENhbiBiZSBcInJvdW5kXCIsIFwic3F1YXJlXCIsXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIG9yIFwiYnV0dFwiLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGpvaW4gVGhlIGxpbmUgam9pbiBzdHlsZS4gQ2FuIGJlIFwicm91bmRcIiwgXCJiZXZlbFwiLFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgb3IgXCJtaXRlclwiLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRoaWNrbmVzcyBUaGUgbGluZSB0aGlja25lc3MgaW4gcGl4ZWxzLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHIgVGhlIHJlZCBjb21wb25lbnQgb2YgdGhlIGNvbG9yIHRvIGZpbGwuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZyBUaGUgZ3JlZW4gY29tcG9uZW50IG9mIHRoZSBjb2xvciB0byBmaWxsLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGIgVGhlIGJsdWUgY29tcG9uZW50IG9mIHRoZSBjb2xvciB0byBmaWxsLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGEgVGhlIGFscGhhIGNvbXBvbmVudCBvZiB0aGUgY29sb3IgdG8gZmlsbC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zdHJva2VDb2xvciA9IGZ1bmN0aW9uKGNhcCwgam9pbiwgdGhpY2tuZXNzLCByLCBnLCBiLCBhKSB7XHJcblxyXG4gICAgICAgIC8vIFN0cm9rZSB3aXRoIGNvbG9yXHJcbiAgICAgICAgY29udGV4dC5saW5lQ2FwID0gY2FwO1xyXG4gICAgICAgIGNvbnRleHQubGluZUpvaW4gPSBqb2luO1xyXG4gICAgICAgIGNvbnRleHQubGluZVdpZHRoID0gdGhpY2tuZXNzO1xyXG4gICAgICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBcInJnYmEoXCIgKyByICsgXCIsXCIgKyBnICsgXCIsXCIgKyBiICsgXCIsXCIgKyBhLzI1NS4wICsgXCIpXCI7XHJcbiAgICAgICAgY29udGV4dC5zdHJva2UoKTtcclxuICAgICAgICBlbXB0eSA9IGZhbHNlO1xyXG5cclxuICAgICAgICAvLyBQYXRoIG5vdyBpbXBsaWNpdGx5IGNsb3NlZFxyXG4gICAgICAgIHBhdGhDbG9zZWQgPSB0cnVlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaWxscyB0aGUgY3VycmVudCBwYXRoIHdpdGggdGhlIHNwZWNpZmllZCBjb2xvci4gVGhlIGN1cnJlbnQgcGF0aFxyXG4gICAgICogaXMgaW1wbGljaXRseSBjbG9zZWQuIFRoZSBjdXJyZW50IHBhdGggY2FuIGNvbnRpbnVlIHRvIGJlIHJldXNlZFxyXG4gICAgICogZm9yIG90aGVyIG9wZXJhdGlvbnMgKHN1Y2ggYXMgY2xpcCgpKSBidXQgYSBuZXcgcGF0aCB3aWxsIGJlIHN0YXJ0ZWRcclxuICAgICAqIG9uY2UgYSBwYXRoIGRyYXdpbmcgb3BlcmF0aW9uIChwYXRoKCkgb3IgcmVjdCgpKSBpcyB1c2VkLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gciBUaGUgcmVkIGNvbXBvbmVudCBvZiB0aGUgY29sb3IgdG8gZmlsbC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBnIFRoZSBncmVlbiBjb21wb25lbnQgb2YgdGhlIGNvbG9yIHRvIGZpbGwuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgYmx1ZSBjb21wb25lbnQgb2YgdGhlIGNvbG9yIHRvIGZpbGwuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgYWxwaGEgY29tcG9uZW50IG9mIHRoZSBjb2xvciB0byBmaWxsLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmZpbGxDb2xvciA9IGZ1bmN0aW9uKHIsIGcsIGIsIGEpIHtcclxuXHJcbiAgICAgICAgLy8gRmlsbCB3aXRoIGNvbG9yXHJcbiAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBcInJnYmEoXCIgKyByICsgXCIsXCIgKyBnICsgXCIsXCIgKyBiICsgXCIsXCIgKyBhLzI1NS4wICsgXCIpXCI7XHJcbiAgICAgICAgY29udGV4dC5maWxsKCk7XHJcbiAgICAgICAgZW1wdHkgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gUGF0aCBub3cgaW1wbGljaXRseSBjbG9zZWRcclxuICAgICAgICBwYXRoQ2xvc2VkID0gdHJ1ZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3Ryb2tlIHRoZSBjdXJyZW50IHBhdGggd2l0aCB0aGUgaW1hZ2Ugd2l0aGluIHRoZSBzcGVjaWZpZWQgbGF5ZXIuIFRoZVxyXG4gICAgICogaW1hZ2UgZGF0YSB3aWxsIGJlIHRpbGVkIGluZmluaXRlbHkgd2l0aGluIHRoZSBzdHJva2UuIFRoZSBjdXJyZW50IHBhdGhcclxuICAgICAqIGlzIGltcGxpY2l0bHkgY2xvc2VkLiBUaGUgY3VycmVudCBwYXRoIGNhbiBjb250aW51ZSB0byBiZSByZXVzZWRcclxuICAgICAqIGZvciBvdGhlciBvcGVyYXRpb25zIChzdWNoIGFzIGNsaXAoKSkgYnV0IGEgbmV3IHBhdGggd2lsbCBiZSBzdGFydGVkXHJcbiAgICAgKiBvbmNlIGEgcGF0aCBkcmF3aW5nIG9wZXJhdGlvbiAocGF0aCgpIG9yIHJlY3QoKSkgaXMgdXNlZC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGNhcCBUaGUgbGluZSBjYXAgc3R5bGUuIENhbiBiZSBcInJvdW5kXCIsIFwic3F1YXJlXCIsXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIG9yIFwiYnV0dFwiLlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGpvaW4gVGhlIGxpbmUgam9pbiBzdHlsZS4gQ2FuIGJlIFwicm91bmRcIiwgXCJiZXZlbFwiLFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgb3IgXCJtaXRlclwiLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRoaWNrbmVzcyBUaGUgbGluZSB0aGlja25lc3MgaW4gcGl4ZWxzLlxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTGF5ZXJ9IHNyY0xheWVyIFRoZSBsYXllciB0byB1c2UgYXMgYSByZXBlYXRpbmcgcGF0dGVyblxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGhpbiB0aGUgc3Ryb2tlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnN0cm9rZUxheWVyID0gZnVuY3Rpb24oY2FwLCBqb2luLCB0aGlja25lc3MsIHNyY0xheWVyKSB7XHJcblxyXG4gICAgICAgIC8vIFN0cm9rZSB3aXRoIGltYWdlIGRhdGFcclxuICAgICAgICBjb250ZXh0LmxpbmVDYXAgPSBjYXA7XHJcbiAgICAgICAgY29udGV4dC5saW5lSm9pbiA9IGpvaW47XHJcbiAgICAgICAgY29udGV4dC5saW5lV2lkdGggPSB0aGlja25lc3M7XHJcbiAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNvbnRleHQuY3JlYXRlUGF0dGVybihcclxuICAgICAgICAgICAgc3JjTGF5ZXIuZ2V0Q2FudmFzKCksXHJcbiAgICAgICAgICAgIFwicmVwZWF0XCJcclxuICAgICAgICApO1xyXG4gICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XHJcbiAgICAgICAgZW1wdHkgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gUGF0aCBub3cgaW1wbGljaXRseSBjbG9zZWRcclxuICAgICAgICBwYXRoQ2xvc2VkID0gdHJ1ZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlsbHMgdGhlIGN1cnJlbnQgcGF0aCB3aXRoIHRoZSBpbWFnZSB3aXRoaW4gdGhlIHNwZWNpZmllZCBsYXllci4gVGhlXHJcbiAgICAgKiBpbWFnZSBkYXRhIHdpbGwgYmUgdGlsZWQgaW5maW5pdGVseSB3aXRoaW4gdGhlIHN0cm9rZS4gVGhlIGN1cnJlbnQgcGF0aFxyXG4gICAgICogaXMgaW1wbGljaXRseSBjbG9zZWQuIFRoZSBjdXJyZW50IHBhdGggY2FuIGNvbnRpbnVlIHRvIGJlIHJldXNlZFxyXG4gICAgICogZm9yIG90aGVyIG9wZXJhdGlvbnMgKHN1Y2ggYXMgY2xpcCgpKSBidXQgYSBuZXcgcGF0aCB3aWxsIGJlIHN0YXJ0ZWRcclxuICAgICAqIG9uY2UgYSBwYXRoIGRyYXdpbmcgb3BlcmF0aW9uIChwYXRoKCkgb3IgcmVjdCgpKSBpcyB1c2VkLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5MYXllcn0gc3JjTGF5ZXIgVGhlIGxheWVyIHRvIHVzZSBhcyBhIHJlcGVhdGluZyBwYXR0ZXJuXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aGluIHRoZSBmaWxsLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmZpbGxMYXllciA9IGZ1bmN0aW9uKHNyY0xheWVyKSB7XHJcblxyXG4gICAgICAgIC8vIEZpbGwgd2l0aCBpbWFnZSBkYXRhIFxyXG4gICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gY29udGV4dC5jcmVhdGVQYXR0ZXJuKFxyXG4gICAgICAgICAgICBzcmNMYXllci5nZXRDYW52YXMoKSxcclxuICAgICAgICAgICAgXCJyZXBlYXRcIlxyXG4gICAgICAgICk7XHJcbiAgICAgICAgY29udGV4dC5maWxsKCk7XHJcbiAgICAgICAgZW1wdHkgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gUGF0aCBub3cgaW1wbGljaXRseSBjbG9zZWRcclxuICAgICAgICBwYXRoQ2xvc2VkID0gdHJ1ZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHVzaCBjdXJyZW50IGxheWVyIHN0YXRlIG9udG8gc3RhY2suXHJcbiAgICAgKi9cclxuICAgIHRoaXMucHVzaCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAvLyBTYXZlIGN1cnJlbnQgc3RhdGUgb250byBzdGFja1xyXG4gICAgICAgIGNvbnRleHQuc2F2ZSgpO1xyXG4gICAgICAgIHN0YWNrU2l6ZSsrO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQb3AgbGF5ZXIgc3RhdGUgb2ZmIHN0YWNrLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnBvcCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAvLyBSZXN0b3JlIGN1cnJlbnQgc3RhdGUgZnJvbSBzdGFja1xyXG4gICAgICAgIGlmIChzdGFja1NpemUgPiAwKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHQucmVzdG9yZSgpO1xyXG4gICAgICAgICAgICBzdGFja1NpemUtLTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlc2V0IHRoZSBsYXllciwgY2xlYXJpbmcgdGhlIHN0YWNrLCB0aGUgY3VycmVudCBwYXRoLCBhbmQgYW55IHRyYW5zZm9ybVxyXG4gICAgICogbWF0cml4LlxyXG4gICAgICovXHJcbiAgICB0aGlzLnJlc2V0ID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIC8vIENsZWFyIHN0YWNrXHJcbiAgICAgICAgd2hpbGUgKHN0YWNrU2l6ZSA+IDApIHtcclxuICAgICAgICAgICAgY29udGV4dC5yZXN0b3JlKCk7XHJcbiAgICAgICAgICAgIHN0YWNrU2l6ZS0tO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVzdG9yZSB0byBpbml0aWFsIHN0YXRlXHJcbiAgICAgICAgY29udGV4dC5yZXN0b3JlKCk7XHJcbiAgICAgICAgY29udGV4dC5zYXZlKCk7XHJcblxyXG4gICAgICAgIC8vIENsZWFyIHBhdGhcclxuICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xyXG4gICAgICAgIHBhdGhDbG9zZWQgPSBmYWxzZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgZ2l2ZW4gYWZmaW5lIHRyYW5zZm9ybSAoZGVmaW5lZCB3aXRoIHNpeCB2YWx1ZXMgZnJvbSB0aGVcclxuICAgICAqIHRyYW5zZm9ybSdzIG1hdHJpeCkuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGUgVGhlIGZpZnRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGYgVGhlIHNpeHRoIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICovXHJcbiAgICB0aGlzLnNldFRyYW5zZm9ybSA9IGZ1bmN0aW9uKGEsIGIsIGMsIGQsIGUsIGYpIHtcclxuICAgICAgICBjb250ZXh0LnNldFRyYW5zZm9ybShcclxuICAgICAgICAgICAgYSwgYiwgYyxcclxuICAgICAgICAgICAgZCwgZSwgZlxyXG4gICAgICAgICAgLyowLCAwLCAxKi9cclxuICAgICAgICApO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGxpZXMgdGhlIGdpdmVuIGFmZmluZSB0cmFuc2Zvcm0gKGRlZmluZWQgd2l0aCBzaXggdmFsdWVzIGZyb20gdGhlXHJcbiAgICAgKiB0cmFuc2Zvcm0ncyBtYXRyaXgpLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgZmlyc3QgdmFsdWUgaW4gdGhlIGFmZmluZSB0cmFuc2Zvcm0ncyBtYXRyaXguXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGMgVGhlIHRoaXJkIHZhbHVlIGluIHRoZSBhZmZpbmUgdHJhbnNmb3JtJ3MgbWF0cml4LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGQgVGhlIGZvdXJ0aCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBlIFRoZSBmaWZ0aCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBmIFRoZSBzaXh0aCB2YWx1ZSBpbiB0aGUgYWZmaW5lIHRyYW5zZm9ybSdzIG1hdHJpeC5cclxuICAgICAqL1xyXG4gICAgdGhpcy50cmFuc2Zvcm0gPSBmdW5jdGlvbihhLCBiLCBjLCBkLCBlLCBmKSB7XHJcbiAgICAgICAgY29udGV4dC50cmFuc2Zvcm0oXHJcbiAgICAgICAgICAgIGEsIGIsIGMsXHJcbiAgICAgICAgICAgIGQsIGUsIGZcclxuICAgICAgICAgIC8qMCwgMCwgMSovXHJcbiAgICAgICAgKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBjaGFubmVsIG1hc2sgZm9yIGZ1dHVyZSBvcGVyYXRpb25zIG9uIHRoaXMgTGF5ZXIuXHJcbiAgICAgKiBcclxuICAgICAqIFRoZSBjaGFubmVsIG1hc2sgaXMgYSBHdWFjYW1vbGUtc3BlY2lmaWMgY29tcG9zaXRpbmcgb3BlcmF0aW9uIGlkZW50aWZpZXJcclxuICAgICAqIHdpdGggYSBzaW5nbGUgYml0IHJlcHJlc2VudGluZyBlYWNoIG9mIGZvdXIgY2hhbm5lbHMgKGluIG9yZGVyKTogc291cmNlXHJcbiAgICAgKiBpbWFnZSB3aGVyZSBkZXN0aW5hdGlvbiB0cmFuc3BhcmVudCwgc291cmNlIHdoZXJlIGRlc3RpbmF0aW9uIG9wYXF1ZSxcclxuICAgICAqIGRlc3RpbmF0aW9uIHdoZXJlIHNvdXJjZSB0cmFuc3BhcmVudCwgYW5kIGRlc3RpbmF0aW9uIHdoZXJlIHNvdXJjZVxyXG4gICAgICogb3BhcXVlLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWFzayBUaGUgY2hhbm5lbCBtYXNrIGZvciBmdXR1cmUgb3BlcmF0aW9ucyBvbiB0aGlzXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBMYXllci5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZXRDaGFubmVsTWFzayA9IGZ1bmN0aW9uKG1hc2spIHtcclxuICAgICAgICBjb250ZXh0Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9IGNvbXBvc2l0ZU9wZXJhdGlvblttYXNrXTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBtaXRlciBsaW1pdCBmb3Igc3Ryb2tlIG9wZXJhdGlvbnMgdXNpbmcgdGhlIG1pdGVyIGpvaW4uIFRoaXNcclxuICAgICAqIGxpbWl0IGlzIHRoZSBtYXhpbXVtIHJhdGlvIG9mIHRoZSBzaXplIG9mIHRoZSBtaXRlciBqb2luIHRvIHRoZSBzdHJva2VcclxuICAgICAqIHdpZHRoLiBJZiB0aGlzIHJhdGlvIGlzIGV4Y2VlZGVkLCB0aGUgbWl0ZXIgd2lsbCBub3QgYmUgZHJhd24gZm9yIHRoYXRcclxuICAgICAqIGpvaW50IG9mIHRoZSBwYXRoLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbGltaXQgVGhlIG1pdGVyIGxpbWl0IGZvciBzdHJva2Ugb3BlcmF0aW9ucyB1c2luZyB0aGVcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICBtaXRlciBqb2luLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnNldE1pdGVyTGltaXQgPSBmdW5jdGlvbihsaW1pdCkge1xyXG4gICAgICAgIGNvbnRleHQubWl0ZXJMaW1pdCA9IGxpbWl0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBJbml0aWFsaXplIGNhbnZhcyBkaW1lbnNpb25zXHJcbiAgICByZXNpemUod2lkdGgsIGhlaWdodCk7XHJcblxyXG4gICAgLy8gRXhwbGljaXRseSByZW5kZXIgY2FudmFzIGJlbG93IG90aGVyIGVsZW1lbnRzIGluIHRoZSBsYXllciAoc3VjaCBhc1xyXG4gICAgLy8gY2hpbGQgbGF5ZXJzKS4gQ2hyb21lIGFuZCBvdGhlcnMgbWF5IGZhaWwgdG8gcmVuZGVyIGxheWVycyBwcm9wZXJseVxyXG4gICAgLy8gd2l0aG91dCB0aGlzLlxyXG4gICAgY2FudmFzLnN0eWxlLnpJbmRleCA9IC0xO1xyXG5cclxufTtcclxuXHJcbi8qKlxyXG4gKiBDaGFubmVsIG1hc2sgZm9yIHRoZSBjb21wb3NpdGUgb3BlcmF0aW9uIFwicm91dFwiLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkxheWVyLlJPVVQgID0gMHgyO1xyXG5cclxuLyoqXHJcbiAqIENoYW5uZWwgbWFzayBmb3IgdGhlIGNvbXBvc2l0ZSBvcGVyYXRpb24gXCJhdG9wXCIuXHJcbiAqL1xyXG5HdWFjYW1vbGUuTGF5ZXIuQVRPUCAgPSAweDY7XHJcblxyXG4vKipcclxuICogQ2hhbm5lbCBtYXNrIGZvciB0aGUgY29tcG9zaXRlIG9wZXJhdGlvbiBcInhvclwiLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkxheWVyLlhPUiAgID0gMHhBO1xyXG5cclxuLyoqXHJcbiAqIENoYW5uZWwgbWFzayBmb3IgdGhlIGNvbXBvc2l0ZSBvcGVyYXRpb24gXCJyb3ZlclwiLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkxheWVyLlJPVkVSID0gMHhCO1xyXG5cclxuLyoqXHJcbiAqIENoYW5uZWwgbWFzayBmb3IgdGhlIGNvbXBvc2l0ZSBvcGVyYXRpb24gXCJvdmVyXCIuXHJcbiAqL1xyXG5HdWFjYW1vbGUuTGF5ZXIuT1ZFUiAgPSAweEU7XHJcblxyXG4vKipcclxuICogQ2hhbm5lbCBtYXNrIGZvciB0aGUgY29tcG9zaXRlIG9wZXJhdGlvbiBcInBsdXNcIi5cclxuICovXHJcbkd1YWNhbW9sZS5MYXllci5QTFVTICA9IDB4RjtcclxuXHJcbi8qKlxyXG4gKiBDaGFubmVsIG1hc2sgZm9yIHRoZSBjb21wb3NpdGUgb3BlcmF0aW9uIFwicmluXCIuXHJcbiAqIEJld2FyZSB0aGF0IFdlYktpdC1iYXNlZCBicm93c2VycyBtYXkgbGVhdmUgdGhlIGNvbnRlbnRzIG9mIHRoZSBkZXN0aW9uYXRpb25cclxuICogbGF5ZXIgd2hlcmUgdGhlIHNvdXJjZSBsYXllciBpcyB0cmFuc3BhcmVudCwgZGVzcGl0ZSB0aGUgZGVmaW5pdGlvbiBvZiB0aGlzXHJcbiAqIG9wZXJhdGlvbi5cclxuICovXHJcbkd1YWNhbW9sZS5MYXllci5SSU4gICA9IDB4MTtcclxuXHJcbi8qKlxyXG4gKiBDaGFubmVsIG1hc2sgZm9yIHRoZSBjb21wb3NpdGUgb3BlcmF0aW9uIFwiaW5cIi5cclxuICogQmV3YXJlIHRoYXQgV2ViS2l0LWJhc2VkIGJyb3dzZXJzIG1heSBsZWF2ZSB0aGUgY29udGVudHMgb2YgdGhlIGRlc3Rpb25hdGlvblxyXG4gKiBsYXllciB3aGVyZSB0aGUgc291cmNlIGxheWVyIGlzIHRyYW5zcGFyZW50LCBkZXNwaXRlIHRoZSBkZWZpbml0aW9uIG9mIHRoaXNcclxuICogb3BlcmF0aW9uLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkxheWVyLklOICAgID0gMHg0O1xyXG5cclxuLyoqXHJcbiAqIENoYW5uZWwgbWFzayBmb3IgdGhlIGNvbXBvc2l0ZSBvcGVyYXRpb24gXCJvdXRcIi5cclxuICogQmV3YXJlIHRoYXQgV2ViS2l0LWJhc2VkIGJyb3dzZXJzIG1heSBsZWF2ZSB0aGUgY29udGVudHMgb2YgdGhlIGRlc3Rpb25hdGlvblxyXG4gKiBsYXllciB3aGVyZSB0aGUgc291cmNlIGxheWVyIGlzIHRyYW5zcGFyZW50LCBkZXNwaXRlIHRoZSBkZWZpbml0aW9uIG9mIHRoaXNcclxuICogb3BlcmF0aW9uLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkxheWVyLk9VVCAgID0gMHg4O1xyXG5cclxuLyoqXHJcbiAqIENoYW5uZWwgbWFzayBmb3IgdGhlIGNvbXBvc2l0ZSBvcGVyYXRpb24gXCJyYXRvcFwiLlxyXG4gKiBCZXdhcmUgdGhhdCBXZWJLaXQtYmFzZWQgYnJvd3NlcnMgbWF5IGxlYXZlIHRoZSBjb250ZW50cyBvZiB0aGUgZGVzdGlvbmF0aW9uXHJcbiAqIGxheWVyIHdoZXJlIHRoZSBzb3VyY2UgbGF5ZXIgaXMgdHJhbnNwYXJlbnQsIGRlc3BpdGUgdGhlIGRlZmluaXRpb24gb2YgdGhpc1xyXG4gKiBvcGVyYXRpb24uXHJcbiAqL1xyXG5HdWFjYW1vbGUuTGF5ZXIuUkFUT1AgPSAweDk7XHJcblxyXG4vKipcclxuICogQ2hhbm5lbCBtYXNrIGZvciB0aGUgY29tcG9zaXRlIG9wZXJhdGlvbiBcInNyY1wiLlxyXG4gKiBCZXdhcmUgdGhhdCBXZWJLaXQtYmFzZWQgYnJvd3NlcnMgbWF5IGxlYXZlIHRoZSBjb250ZW50cyBvZiB0aGUgZGVzdGlvbmF0aW9uXHJcbiAqIGxheWVyIHdoZXJlIHRoZSBzb3VyY2UgbGF5ZXIgaXMgdHJhbnNwYXJlbnQsIGRlc3BpdGUgdGhlIGRlZmluaXRpb24gb2YgdGhpc1xyXG4gKiBvcGVyYXRpb24uXHJcbiAqL1xyXG5HdWFjYW1vbGUuTGF5ZXIuU1JDICAgPSAweEM7XHJcblxyXG4vKipcclxuICogUmVwcmVzZW50cyBhIHNpbmdsZSBwaXhlbCBvZiBpbWFnZSBkYXRhLiBBbGwgY29tcG9uZW50cyBoYXZlIGEgbWluaW11bSB2YWx1ZVxyXG4gKiBvZiAwIGFuZCBhIG1heGltdW0gdmFsdWUgb2YgMjU1LlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIFxyXG4gKiBAcGFyYW0ge051bWJlcn0gciBUaGUgcmVkIGNvbXBvbmVudCBvZiB0aGlzIHBpeGVsLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gZyBUaGUgZ3JlZW4gY29tcG9uZW50IG9mIHRoaXMgcGl4ZWwuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBibHVlIGNvbXBvbmVudCBvZiB0aGlzIHBpeGVsLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gYSBUaGUgYWxwaGEgY29tcG9uZW50IG9mIHRoaXMgcGl4ZWwuXHJcbiAqL1xyXG5HdWFjYW1vbGUuTGF5ZXIuUGl4ZWwgPSBmdW5jdGlvbihyLCBnLCBiLCBhKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgcmVkIGNvbXBvbmVudCBvZiB0aGlzIHBpeGVsLCB3aGVyZSAwIGlzIHRoZSBtaW5pbXVtIHZhbHVlLFxyXG4gICAgICogYW5kIDI1NSBpcyB0aGUgbWF4aW11bS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5yZWQgICA9IHI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZ3JlZW4gY29tcG9uZW50IG9mIHRoaXMgcGl4ZWwsIHdoZXJlIDAgaXMgdGhlIG1pbmltdW0gdmFsdWUsXHJcbiAgICAgKiBhbmQgMjU1IGlzIHRoZSBtYXhpbXVtLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmdyZWVuID0gZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBibHVlIGNvbXBvbmVudCBvZiB0aGlzIHBpeGVsLCB3aGVyZSAwIGlzIHRoZSBtaW5pbXVtIHZhbHVlLFxyXG4gICAgICogYW5kIDI1NSBpcyB0aGUgbWF4aW11bS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5ibHVlICA9IGI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYWxwaGEgY29tcG9uZW50IG9mIHRoaXMgcGl4ZWwsIHdoZXJlIDAgaXMgdGhlIG1pbmltdW0gdmFsdWUsXHJcbiAgICAgKiBhbmQgMjU1IGlzIHRoZSBtYXhpbXVtLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmFscGhhID0gYTtcclxuXHJcbn07XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogUHJvdmlkZXMgY3Jvc3MtYnJvd3NlciBtb3VzZSBldmVudHMgZm9yIGEgZ2l2ZW4gZWxlbWVudC4gVGhlIGV2ZW50cyBvZlxyXG4gKiB0aGUgZ2l2ZW4gZWxlbWVudCBhcmUgYXV0b21hdGljYWxseSBwb3B1bGF0ZWQgd2l0aCBoYW5kbGVycyB0aGF0IHRyYW5zbGF0ZVxyXG4gKiBtb3VzZSBldmVudHMgaW50byBhIG5vbi1icm93c2VyLXNwZWNpZmljIGV2ZW50IHByb3ZpZGVkIGJ5IHRoZVxyXG4gKiBHdWFjYW1vbGUuTW91c2UgaW5zdGFuY2UuXHJcbiAqIFxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBFbGVtZW50IHRvIHVzZSB0byBwcm92aWRlIG1vdXNlIGV2ZW50cy5cclxuICovXHJcbkd1YWNhbW9sZS5Nb3VzZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5Nb3VzZS5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBndWFjX21vdXNlID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2YgbW91c2Vtb3ZlIGV2ZW50cyB0byByZXF1aXJlIGJlZm9yZSByZS1lbmFibGluZyBtb3VzZVxyXG4gICAgICogZXZlbnQgaGFuZGxpbmcgYWZ0ZXIgcmVjZWl2aW5nIGEgdG91Y2ggZXZlbnQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMudG91Y2hNb3VzZVRocmVzaG9sZCA9IDM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWluaW11bSBhbW91bnQgb2YgcGl4ZWxzIHNjcm9sbGVkIHJlcXVpcmVkIGZvciBhIHNpbmdsZSBzY3JvbGwgYnV0dG9uXHJcbiAgICAgKiBjbGljay5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zY3JvbGxUaHJlc2hvbGQgPSA1MztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2YgcGl4ZWxzIHRvIHNjcm9sbCBwZXIgbGluZS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5QSVhFTFNfUEVSX0xJTkUgPSAxODtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2YgcGl4ZWxzIHRvIHNjcm9sbCBwZXIgcGFnZS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5QSVhFTFNfUEVSX1BBR0UgPSB0aGlzLlBJWEVMU19QRVJfTElORSAqIDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgbW91c2Ugc3RhdGUuIFRoZSBwcm9wZXJ0aWVzIG9mIHRoaXMgc3RhdGUgYXJlIHVwZGF0ZWQgd2hlblxyXG4gICAgICogbW91c2UgZXZlbnRzIGZpcmUuIFRoaXMgc3RhdGUgb2JqZWN0IGlzIGFsc28gcGFzc2VkIGluIGFzIGEgcGFyYW1ldGVyIHRvXHJcbiAgICAgKiB0aGUgaGFuZGxlciBvZiBhbnkgbW91c2UgZXZlbnRzLlxyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLk1vdXNlLlN0YXRlfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IG5ldyBHdWFjYW1vbGUuTW91c2UuU3RhdGUoXHJcbiAgICAgICAgMCwgMCwgXHJcbiAgICAgICAgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlXHJcbiAgICApO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgdGhlIHVzZXIgcHJlc3NlcyBhIG1vdXNlIGJ1dHRvbiBkb3duIG92ZXIgdGhlIGVsZW1lbnRcclxuICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEd1YWNhbW9sZS5Nb3VzZS5cclxuICAgICAqIFxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5Nb3VzZS5TdGF0ZX0gc3RhdGUgVGhlIGN1cnJlbnQgbW91c2Ugc3RhdGUuXHJcbiAgICAgKi9cclxuXHR0aGlzLm9ubW91c2Vkb3duID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIHRoZSB1c2VyIHJlbGVhc2VzIGEgbW91c2UgYnV0dG9uIGRvd24gb3ZlciB0aGUgZWxlbWVudFxyXG4gICAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgR3VhY2Ftb2xlLk1vdXNlLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLk1vdXNlLlN0YXRlfSBzdGF0ZSBUaGUgY3VycmVudCBtb3VzZSBzdGF0ZS5cclxuICAgICAqL1xyXG5cdHRoaXMub25tb3VzZXVwID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIHRoZSB1c2VyIG1vdmVzIHRoZSBtb3VzZSBvdmVyIHRoZSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aFxyXG4gICAgICogdGhpcyBHdWFjYW1vbGUuTW91c2UuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTW91c2UuU3RhdGV9IHN0YXRlIFRoZSBjdXJyZW50IG1vdXNlIHN0YXRlLlxyXG4gICAgICovXHJcblx0dGhpcy5vbm1vdXNlbW92ZSA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciB0aGUgbW91c2UgbGVhdmVzIHRoZSBib3VuZGFyaWVzIG9mIHRoZSBlbGVtZW50IGFzc29jaWF0ZWRcclxuICAgICAqIHdpdGggdGhpcyBHdWFjYW1vbGUuTW91c2UuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICovXHJcblx0dGhpcy5vbm1vdXNlb3V0ID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvdW50ZXIgb2YgbW91c2UgZXZlbnRzIHRvIGlnbm9yZS4gVGhpcyBkZWNyZW1lbnRlZCBieSBtb3VzZW1vdmUsIGFuZFxyXG4gICAgICogd2hpbGUgbm9uLXplcm8sIG1vdXNlIGV2ZW50cyB3aWxsIGhhdmUgbm8gZWZmZWN0LlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGlnbm9yZV9tb3VzZSA9IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDdW11bGF0aXZlIHNjcm9sbCBkZWx0YSBhbW91bnQuIFRoaXMgdmFsdWUgaXMgYWNjdW11bGF0ZWQgdGhyb3VnaCBzY3JvbGxcclxuICAgICAqIGV2ZW50cyBhbmQgcmVzdWx0cyBpbiBzY3JvbGwgYnV0dG9uIGNsaWNrcyBpZiBpdCBleGNlZWRzIGEgY2VydGFpblxyXG4gICAgICogdGhyZXNob2xkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBzY3JvbGxfZGVsdGEgPSAwO1xyXG5cclxuICAgIGZ1bmN0aW9uIGNhbmNlbEV2ZW50KGUpIHtcclxuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KSBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEJsb2NrIGNvbnRleHQgbWVudSBzbyByaWdodC1jbGljayBnZXRzIHNlbnQgcHJvcGVybHlcclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNvbnRleHRtZW51XCIsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICBjYW5jZWxFdmVudChlKTtcclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgZnVuY3Rpb24oZSkge1xyXG5cclxuICAgICAgICBjYW5jZWxFdmVudChlKTtcclxuXHJcbiAgICAgICAgLy8gSWYgaWdub3JpbmcgZXZlbnRzLCBkZWNyZW1lbnQgY291bnRlclxyXG4gICAgICAgIGlmIChpZ25vcmVfbW91c2UpIHtcclxuICAgICAgICAgICAgaWdub3JlX21vdXNlLS07XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGd1YWNfbW91c2UuY3VycmVudFN0YXRlLmZyb21DbGllbnRQb3NpdGlvbihlbGVtZW50LCBlLmNsaWVudFgsIGUuY2xpZW50WSk7XHJcblxyXG4gICAgICAgIGlmIChndWFjX21vdXNlLm9ubW91c2Vtb3ZlKVxyXG4gICAgICAgICAgICBndWFjX21vdXNlLm9ubW91c2Vtb3ZlKGd1YWNfbW91c2UuY3VycmVudFN0YXRlKTtcclxuXHJcbiAgICB9LCBmYWxzZSk7XHJcblxyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIGZ1bmN0aW9uKGUpIHtcclxuXHJcbiAgICAgICAgY2FuY2VsRXZlbnQoZSk7XHJcblxyXG4gICAgICAgIC8vIERvIG5vdCBoYW5kbGUgaWYgaWdub3JpbmcgZXZlbnRzXHJcbiAgICAgICAgaWYgKGlnbm9yZV9tb3VzZSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBzd2l0Y2ggKGUuYnV0dG9uKSB7XHJcbiAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgIGd1YWNfbW91c2UuY3VycmVudFN0YXRlLmxlZnQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgIGd1YWNfbW91c2UuY3VycmVudFN0YXRlLm1pZGRsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgICAgICAgZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUucmlnaHQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZ3VhY19tb3VzZS5vbm1vdXNlZG93bilcclxuICAgICAgICAgICAgZ3VhY19tb3VzZS5vbm1vdXNlZG93bihndWFjX21vdXNlLmN1cnJlbnRTdGF0ZSk7XHJcblxyXG4gICAgfSwgZmFsc2UpO1xyXG5cclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgZnVuY3Rpb24oZSkge1xyXG5cclxuICAgICAgICBjYW5jZWxFdmVudChlKTtcclxuXHJcbiAgICAgICAgLy8gRG8gbm90IGhhbmRsZSBpZiBpZ25vcmluZyBldmVudHNcclxuICAgICAgICBpZiAoaWdub3JlX21vdXNlKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHN3aXRjaCAoZS5idXR0b24pIHtcclxuICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUubGVmdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgIGd1YWNfbW91c2UuY3VycmVudFN0YXRlLm1pZGRsZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgIGd1YWNfbW91c2UuY3VycmVudFN0YXRlLnJpZ2h0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChndWFjX21vdXNlLm9ubW91c2V1cClcclxuICAgICAgICAgICAgZ3VhY19tb3VzZS5vbm1vdXNldXAoZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUpO1xyXG5cclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW91dFwiLCBmdW5jdGlvbihlKSB7XHJcblxyXG4gICAgICAgIC8vIEdldCBwYXJlbnQgb2YgdGhlIGVsZW1lbnQgdGhlIG1vdXNlIHBvaW50ZXIgaXMgbGVhdmluZ1xyXG4gICAgICAgXHRpZiAoIWUpIGUgPSB3aW5kb3cuZXZlbnQ7XHJcblxyXG4gICAgICAgIC8vIENoZWNrIHRoYXQgbW91c2VvdXQgaXMgZHVlIHRvIGFjdHVhbGx5IExFQVZJTkcgdGhlIGVsZW1lbnRcclxuICAgICAgICB2YXIgdGFyZ2V0ID0gZS5yZWxhdGVkVGFyZ2V0IHx8IGUudG9FbGVtZW50O1xyXG4gICAgICAgIHdoaWxlICh0YXJnZXQpIHtcclxuICAgICAgICAgICAgaWYgKHRhcmdldCA9PT0gZWxlbWVudClcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjYW5jZWxFdmVudChlKTtcclxuXHJcbiAgICAgICAgLy8gUmVsZWFzZSBhbGwgYnV0dG9uc1xyXG4gICAgICAgIGlmIChndWFjX21vdXNlLmN1cnJlbnRTdGF0ZS5sZWZ0XHJcbiAgICAgICAgICAgIHx8IGd1YWNfbW91c2UuY3VycmVudFN0YXRlLm1pZGRsZVxyXG4gICAgICAgICAgICB8fCBndWFjX21vdXNlLmN1cnJlbnRTdGF0ZS5yaWdodCkge1xyXG5cclxuICAgICAgICAgICAgZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUubGVmdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBndWFjX21vdXNlLmN1cnJlbnRTdGF0ZS5taWRkbGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUucmlnaHQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChndWFjX21vdXNlLm9ubW91c2V1cClcclxuICAgICAgICAgICAgICAgIGd1YWNfbW91c2Uub25tb3VzZXVwKGd1YWNfbW91c2UuY3VycmVudFN0YXRlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEZpcmUgb25tb3VzZW91dCBldmVudFxyXG4gICAgICAgIGlmIChndWFjX21vdXNlLm9ubW91c2VvdXQpXHJcbiAgICAgICAgICAgIGd1YWNfbW91c2Uub25tb3VzZW91dCgpO1xyXG5cclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICAvLyBPdmVycmlkZSBzZWxlY3Rpb24gb24gbW91c2UgZXZlbnQgZWxlbWVudC5cclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNlbGVjdHN0YXJ0XCIsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICBjYW5jZWxFdmVudChlKTtcclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICAvLyBJZ25vcmUgYWxsIHBlbmRpbmcgbW91c2UgZXZlbnRzIHdoZW4gdG91Y2ggZXZlbnRzIGFyZSB0aGUgYXBwYXJlbnQgc291cmNlXHJcbiAgICBmdW5jdGlvbiBpZ25vcmVQZW5kaW5nTW91c2VFdmVudHMoKSB7IGlnbm9yZV9tb3VzZSA9IGd1YWNfbW91c2UudG91Y2hNb3VzZVRocmVzaG9sZDsgfVxyXG5cclxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCAgaWdub3JlUGVuZGluZ01vdXNlRXZlbnRzLCBmYWxzZSk7XHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIGlnbm9yZVBlbmRpbmdNb3VzZUV2ZW50cywgZmFsc2UpO1xyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgICBpZ25vcmVQZW5kaW5nTW91c2VFdmVudHMsIGZhbHNlKTtcclxuXHJcbiAgICAvLyBTY3JvbGwgd2hlZWwgc3VwcG9ydFxyXG4gICAgZnVuY3Rpb24gbW91c2V3aGVlbF9oYW5kbGVyKGUpIHtcclxuXHJcbiAgICAgICAgLy8gRGV0ZXJtaW5lIGFwcHJveGltYXRlIHNjcm9sbCBhbW91bnQgKGluIHBpeGVscylcclxuICAgICAgICB2YXIgZGVsdGEgPSBlLmRlbHRhWSB8fCAtZS53aGVlbERlbHRhWSB8fCAtZS53aGVlbERlbHRhO1xyXG5cclxuICAgICAgICAvLyBJZiBzdWNjZXNzZnVsbHkgcmV0cmlldmVkIHNjcm9sbCBhbW91bnQsIGNvbnZlcnQgdG8gcGl4ZWxzIGlmIG5vdFxyXG4gICAgICAgIC8vIGFscmVhZHkgaW4gcGl4ZWxzXHJcbiAgICAgICAgaWYgKGRlbHRhKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBDb252ZXJ0IHRvIHBpeGVscyBpZiBkZWx0YSB3YXMgbGluZXNcclxuICAgICAgICAgICAgaWYgKGUuZGVsdGFNb2RlID09PSAxKVxyXG4gICAgICAgICAgICAgICAgZGVsdGEgPSBlLmRlbHRhWSAqIGd1YWNfbW91c2UuUElYRUxTX1BFUl9MSU5FO1xyXG5cclxuICAgICAgICAgICAgLy8gQ29udmVydCB0byBwaXhlbHMgaWYgZGVsdGEgd2FzIHBhZ2VzXHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGUuZGVsdGFNb2RlID09PSAyKVxyXG4gICAgICAgICAgICAgICAgZGVsdGEgPSBlLmRlbHRhWSAqIGd1YWNfbW91c2UuUElYRUxTX1BFUl9QQUdFO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSwgYXNzdW1lIGxlZ2FjeSBtb3VzZXdoZWVsIGV2ZW50IGFuZCBsaW5lIHNjcm9sbGluZ1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgZGVsdGEgPSBlLmRldGFpbCAqIGd1YWNfbW91c2UuUElYRUxTX1BFUl9MSU5FO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIFVwZGF0ZSBvdmVyYWxsIGRlbHRhXHJcbiAgICAgICAgc2Nyb2xsX2RlbHRhICs9IGRlbHRhO1xyXG5cclxuICAgICAgICAvLyBVcFxyXG4gICAgICAgIGlmIChzY3JvbGxfZGVsdGEgPD0gLWd1YWNfbW91c2Uuc2Nyb2xsVGhyZXNob2xkKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBSZXBlYXRlZGx5IGNsaWNrIHRoZSB1cCBidXR0b24gdW50aWwgaW5zdWZmaWNpZW50IGRlbHRhIHJlbWFpbnNcclxuICAgICAgICAgICAgZG8ge1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChndWFjX21vdXNlLm9ubW91c2Vkb3duKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUudXAgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGd1YWNfbW91c2Uub25tb3VzZWRvd24oZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChndWFjX21vdXNlLm9ubW91c2V1cCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGd1YWNfbW91c2UuY3VycmVudFN0YXRlLnVwID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgZ3VhY19tb3VzZS5vbm1vdXNldXAoZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHNjcm9sbF9kZWx0YSArPSBndWFjX21vdXNlLnNjcm9sbFRocmVzaG9sZDtcclxuXHJcbiAgICAgICAgICAgIH0gd2hpbGUgKHNjcm9sbF9kZWx0YSA8PSAtZ3VhY19tb3VzZS5zY3JvbGxUaHJlc2hvbGQpO1xyXG5cclxuICAgICAgICAgICAgLy8gUmVzZXQgZGVsdGFcclxuICAgICAgICAgICAgc2Nyb2xsX2RlbHRhID0gMDtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEb3duXHJcbiAgICAgICAgaWYgKHNjcm9sbF9kZWx0YSA+PSBndWFjX21vdXNlLnNjcm9sbFRocmVzaG9sZCkge1xyXG5cclxuICAgICAgICAgICAgLy8gUmVwZWF0ZWRseSBjbGljayB0aGUgZG93biBidXR0b24gdW50aWwgaW5zdWZmaWNpZW50IGRlbHRhIHJlbWFpbnNcclxuICAgICAgICAgICAgZG8ge1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChndWFjX21vdXNlLm9ubW91c2Vkb3duKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUuZG93biA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZ3VhY19tb3VzZS5vbm1vdXNlZG93bihndWFjX21vdXNlLmN1cnJlbnRTdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGd1YWNfbW91c2Uub25tb3VzZXVwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZ3VhY19tb3VzZS5jdXJyZW50U3RhdGUuZG93biA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGd1YWNfbW91c2Uub25tb3VzZXVwKGd1YWNfbW91c2UuY3VycmVudFN0YXRlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBzY3JvbGxfZGVsdGEgLT0gZ3VhY19tb3VzZS5zY3JvbGxUaHJlc2hvbGQ7XHJcblxyXG4gICAgICAgICAgICB9IHdoaWxlIChzY3JvbGxfZGVsdGEgPj0gZ3VhY19tb3VzZS5zY3JvbGxUaHJlc2hvbGQpO1xyXG5cclxuICAgICAgICAgICAgLy8gUmVzZXQgZGVsdGFcclxuICAgICAgICAgICAgc2Nyb2xsX2RlbHRhID0gMDtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjYW5jZWxFdmVudChlKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Nb3VzZVNjcm9sbCcsIG1vdXNld2hlZWxfaGFuZGxlciwgZmFsc2UpO1xyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXdoZWVsJywgICAgIG1vdXNld2hlZWxfaGFuZGxlciwgZmFsc2UpO1xyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd3aGVlbCcsICAgICAgICAgIG1vdXNld2hlZWxfaGFuZGxlciwgZmFsc2UpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB0aGUgYnJvd3NlciBzdXBwb3J0cyBDU1MzIGN1cnNvciBzdHlsaW5nLCBpbmNsdWRpbmcgaG90c3BvdFxyXG4gICAgICogY29vcmRpbmF0ZXMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtCb29sZWFufVxyXG4gICAgICovXHJcbiAgICB2YXIgQ1NTM19DVVJTT1JfU1VQUE9SVEVEID0gKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuXHJcbiAgICAgICAgLy8gSWYgbm8gY3Vyc29yIHByb3BlcnR5IGF0IGFsbCwgdGhlbiBubyBzdXBwb3J0XHJcbiAgICAgICAgaWYgKCEoXCJjdXJzb3JcIiBpbiBkaXYuc3R5bGUpKVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIC8vIEFwcGx5IHNpbXBsZSAxeDEgUE5HXHJcbiAgICAgICAgICAgIGRpdi5zdHlsZS5jdXJzb3IgPSBcInVybChkYXRhOmltYWdlL3BuZztiYXNlNjQsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFwiaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUFFQUFBQUJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgXCJBUU1BQUFBbDIxYktBQUFBQTFCTVZFWC8vLytueEJ2SVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBcIkFBQUFDa2xFUVZRSTEyTmdBQUFBQWdBQjRpRzhNd0FBXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIFwiQUFCSlJVNUVya0pnZ2c9PSkgMCAwLCBhdXRvXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFZlcmlmeSBjdXJzb3IgcHJvcGVydHkgaXMgc2V0IHRvIFVSTCB3aXRoIGhvdHNwb3RcclxuICAgICAgICByZXR1cm4gL1xcYnVybFxcKFteKCldKlxcKVxccyswXFxzKzBcXGIvLnRlc3QoZGl2LnN0eWxlLmN1cnNvciB8fCBcIlwiKTtcclxuXHJcbiAgICB9KSgpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hhbmdlcyB0aGUgbG9jYWwgbW91c2UgY3Vyc29yIHRvIHRoZSBnaXZlbiBjYW52YXMsIGhhdmluZyB0aGUgZ2l2ZW5cclxuICAgICAqIGhvdHNwb3QgY29vcmRpbmF0ZXMuIFRoaXMgYWZmZWN0cyBzdHlsaW5nIG9mIHRoZSBlbGVtZW50IGJhY2tpbmcgdGhpc1xyXG4gICAgICogR3VhY2Ftb2xlLk1vdXNlIG9ubHksIGFuZCBtYXkgZmFpbCBkZXBlbmRpbmcgb24gYnJvd3NlciBzdXBwb3J0IGZvclxyXG4gICAgICogc2V0dGluZyB0aGUgbW91c2UgY3Vyc29yLlxyXG4gICAgICogXHJcbiAgICAgKiBJZiBzZXR0aW5nIHRoZSBsb2NhbCBjdXJzb3IgaXMgZGVzaXJlZCwgaXQgaXMgdXAgdG8gdGhlIGltcGxlbWVudGF0aW9uXHJcbiAgICAgKiB0byBkbyBzb21ldGhpbmcgZWxzZSwgc3VjaCBhcyB1c2UgdGhlIHNvZnR3YXJlIGN1cnNvciBidWlsdCBpbnRvXHJcbiAgICAgKiBHdWFjYW1vbGUuRGlzcGxheSwgaWYgdGhlIGxvY2FsIGN1cnNvciBjYW5ub3QgYmUgc2V0LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhcyBUaGUgY3Vyc29yIGltYWdlLlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIFgtY29vcmRpbmF0ZSBvZiB0aGUgY3Vyc29yIGhvdHNwb3QuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgWS1jb29yZGluYXRlIG9mIHRoZSBjdXJzb3IgaG90c3BvdC5cclxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgdGhlIGN1cnNvciB3YXMgc3VjY2Vzc2Z1bGx5IHNldCwgZmFsc2UgaWYgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICBjdXJzb3IgY291bGQgbm90IGJlIHNldCBmb3IgYW55IHJlYXNvbi5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZXRDdXJzb3IgPSBmdW5jdGlvbihjYW52YXMsIHgsIHkpIHtcclxuXHJcbiAgICAgICAgLy8gQXR0ZW1wdCB0byBzZXQgdmlhIENTUzMgY3Vyc29yIHN0eWxpbmdcclxuICAgICAgICBpZiAoQ1NTM19DVVJTT1JfU1VQUE9SVEVEKSB7XHJcbiAgICAgICAgICAgIHZhciBkYXRhVVJMID0gY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuY3Vyc29yID0gXCJ1cmwoXCIgKyBkYXRhVVJMICsgXCIpIFwiICsgeCArIFwiIFwiICsgeSArIFwiLCBhdXRvXCI7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBzZXR0aW5nIGN1cnNvciBmYWlsZWRcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogU2ltcGxlIGNvbnRhaW5lciBmb3IgcHJvcGVydGllcyBkZXNjcmliaW5nIHRoZSBzdGF0ZSBvZiBhIG1vdXNlLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBYIHBvc2l0aW9uIG9mIHRoZSBtb3VzZSBwb2ludGVyIGluIHBpeGVscy5cclxuICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIFkgcG9zaXRpb24gb2YgdGhlIG1vdXNlIHBvaW50ZXIgaW4gcGl4ZWxzLlxyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGxlZnQgV2hldGhlciB0aGUgbGVmdCBtb3VzZSBidXR0b24gaXMgcHJlc3NlZC4gXHJcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gbWlkZGxlIFdoZXRoZXIgdGhlIG1pZGRsZSBtb3VzZSBidXR0b24gaXMgcHJlc3NlZC4gXHJcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcmlnaHQgV2hldGhlciB0aGUgcmlnaHQgbW91c2UgYnV0dG9uIGlzIHByZXNzZWQuIFxyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHVwIFdoZXRoZXIgdGhlIHVwIG1vdXNlIGJ1dHRvbiBpcyBwcmVzc2VkICh0aGUgZm91cnRoXHJcbiAqICAgICAgICAgICAgICAgICAgICAgYnV0dG9uLCB1c3VhbGx5IHBhcnQgb2YgYSBzY3JvbGwgd2hlZWwpLiBcclxuICogQHBhcmFtIHtCb29sZWFufSBkb3duIFdoZXRoZXIgdGhlIGRvd24gbW91c2UgYnV0dG9uIGlzIHByZXNzZWQgKHRoZSBmaWZ0aFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uLCB1c3VhbGx5IHBhcnQgb2YgYSBzY3JvbGwgd2hlZWwpLiBcclxuICovXHJcbkd1YWNhbW9sZS5Nb3VzZS5TdGF0ZSA9IGZ1bmN0aW9uKHgsIHksIGxlZnQsIG1pZGRsZSwgcmlnaHQsIHVwLCBkb3duKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBHdWFjYW1vbGUuTW91c2UuU3RhdGUuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgZ3VhY19zdGF0ZSA9IHRoaXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY3VycmVudCBYIHBvc2l0aW9uIG9mIHRoZSBtb3VzZSBwb2ludGVyLlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy54ID0geDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjdXJyZW50IFkgcG9zaXRpb24gb2YgdGhlIG1vdXNlIHBvaW50ZXIuXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLnkgPSB5O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB0aGUgbGVmdCBtb3VzZSBidXR0b24gaXMgY3VycmVudGx5IHByZXNzZWQuXHJcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5sZWZ0ID0gbGVmdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgdGhlIG1pZGRsZSBtb3VzZSBidXR0b24gaXMgY3VycmVudGx5IHByZXNzZWQuXHJcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5taWRkbGUgPSBtaWRkbGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIHRoZSByaWdodCBtb3VzZSBidXR0b24gaXMgY3VycmVudGx5IHByZXNzZWQuXHJcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5yaWdodCA9IHJpZ2h0O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB0aGUgdXAgbW91c2UgYnV0dG9uIGlzIGN1cnJlbnRseSBwcmVzc2VkLiBUaGlzIGlzIHRoZSBmb3VydGhcclxuICAgICAqIG1vdXNlIGJ1dHRvbiwgYXNzb2NpYXRlZCB3aXRoIHVwd2FyZCBzY3JvbGxpbmcgb2YgdGhlIG1vdXNlIHNjcm9sbFxyXG4gICAgICogd2hlZWwuXHJcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgdGhpcy51cCA9IHVwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB0aGUgZG93biBtb3VzZSBidXR0b24gaXMgY3VycmVudGx5IHByZXNzZWQuIFRoaXMgaXMgdGhlIGZpZnRoIFxyXG4gICAgICogbW91c2UgYnV0dG9uLCBhc3NvY2lhdGVkIHdpdGggZG93bndhcmQgc2Nyb2xsaW5nIG9mIHRoZSBtb3VzZSBzY3JvbGxcclxuICAgICAqIHdoZWVsLlxyXG4gICAgICogQHR5cGUge0Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIHRoaXMuZG93biA9IGRvd247XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGVzIHRoZSBwb3NpdGlvbiByZXByZXNlbnRlZCB3aXRoaW4gdGhpcyBzdGF0ZSBvYmplY3QgYnkgdGhlIGdpdmVuXHJcbiAgICAgKiBlbGVtZW50IGFuZCBjbGllbnRYL2NsaWVudFkgY29vcmRpbmF0ZXMgKGNvbW1vbmx5IGF2YWlsYWJsZSB3aXRoaW4gZXZlbnRcclxuICAgICAqIG9iamVjdHMpLiBQb3NpdGlvbiBpcyB0cmFuc2xhdGVkIGZyb20gY2xpZW50WC9jbGllbnRZIChyZWxhdGl2ZSB0b1xyXG4gICAgICogdmlld3BvcnQpIHRvIGVsZW1lbnQtcmVsYXRpdmUgY29vcmRpbmF0ZXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0aGUgY29vcmRpbmF0ZXMgc2hvdWxkIGJlIHJlbGF0aXZlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8uXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY2xpZW50WCBUaGUgWCBjb29yZGluYXRlIHRvIHRyYW5zbGF0ZSwgdmlld3BvcnQtcmVsYXRpdmUuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY2xpZW50WSBUaGUgWSBjb29yZGluYXRlIHRvIHRyYW5zbGF0ZSwgdmlld3BvcnQtcmVsYXRpdmUuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZnJvbUNsaWVudFBvc2l0aW9uID0gZnVuY3Rpb24oZWxlbWVudCwgY2xpZW50WCwgY2xpZW50WSkge1xyXG4gICAgXHJcbiAgICAgICAgZ3VhY19zdGF0ZS54ID0gY2xpZW50WCAtIGVsZW1lbnQub2Zmc2V0TGVmdDtcclxuICAgICAgICBndWFjX3N0YXRlLnkgPSBjbGllbnRZIC0gZWxlbWVudC5vZmZzZXRUb3A7XHJcblxyXG4gICAgICAgIC8vIFRoaXMgaXMgYWxsIEpVU1Qgc28gd2UgY2FuIGdldCB0aGUgbW91c2UgcG9zaXRpb24gd2l0aGluIHRoZSBlbGVtZW50XHJcbiAgICAgICAgdmFyIHBhcmVudCA9IGVsZW1lbnQub2Zmc2V0UGFyZW50O1xyXG4gICAgICAgIHdoaWxlIChwYXJlbnQgJiYgIShwYXJlbnQgPT09IGRvY3VtZW50LmJvZHkpKSB7XHJcbiAgICAgICAgICAgIGd1YWNfc3RhdGUueCAtPSBwYXJlbnQub2Zmc2V0TGVmdCAtIHBhcmVudC5zY3JvbGxMZWZ0O1xyXG4gICAgICAgICAgICBndWFjX3N0YXRlLnkgLT0gcGFyZW50Lm9mZnNldFRvcCAgLSBwYXJlbnQuc2Nyb2xsVG9wO1xyXG5cclxuICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50Lm9mZnNldFBhcmVudDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEVsZW1lbnQgdWx0aW1hdGVseSBkZXBlbmRzIG9uIHBvc2l0aW9uaW5nIHdpdGhpbiBkb2N1bWVudCBib2R5LFxyXG4gICAgICAgIC8vIHRha2UgZG9jdW1lbnQgc2Nyb2xsIGludG8gYWNjb3VudC4gXHJcbiAgICAgICAgaWYgKHBhcmVudCkge1xyXG4gICAgICAgICAgICB2YXIgZG9jdW1lbnRTY3JvbGxMZWZ0ID0gZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xyXG4gICAgICAgICAgICB2YXIgZG9jdW1lbnRTY3JvbGxUb3AgPSBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wO1xyXG5cclxuICAgICAgICAgICAgZ3VhY19zdGF0ZS54IC09IHBhcmVudC5vZmZzZXRMZWZ0IC0gZG9jdW1lbnRTY3JvbGxMZWZ0O1xyXG4gICAgICAgICAgICBndWFjX3N0YXRlLnkgLT0gcGFyZW50Lm9mZnNldFRvcCAgLSBkb2N1bWVudFNjcm9sbFRvcDtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogUHJvdmlkZXMgY3Jvc3MtYnJvd3NlciByZWxhdGl2ZSB0b3VjaCBldmVudCB0cmFuc2xhdGlvbiBmb3IgYSBnaXZlbiBlbGVtZW50LlxyXG4gKiBcclxuICogVG91Y2ggZXZlbnRzIGFyZSB0cmFuc2xhdGVkIGludG8gbW91c2UgZXZlbnRzIGFzIGlmIHRoZSB0b3VjaGVzIG9jY3VycmVkXHJcbiAqIG9uIGEgdG91Y2hwYWQgKGRyYWcgdG8gcHVzaCB0aGUgbW91c2UgcG9pbnRlciwgdGFwIHRvIGNsaWNrKS5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGhlIEVsZW1lbnQgdG8gdXNlIHRvIHByb3ZpZGUgdG91Y2ggZXZlbnRzLlxyXG4gKi9cclxuR3VhY2Ftb2xlLk1vdXNlLlRvdWNocGFkID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVmZXJlbmNlIHRvIHRoaXMgR3VhY2Ftb2xlLk1vdXNlLlRvdWNocGFkLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGd1YWNfdG91Y2hwYWQgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGRpc3RhbmNlIGEgdHdvLWZpbmdlciB0b3VjaCBtdXN0IG1vdmUgcGVyIHNjcm9sbHdoZWVsIGV2ZW50LCBpblxyXG4gICAgICogcGl4ZWxzLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnNjcm9sbFRocmVzaG9sZCA9IDIwICogKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDEpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB3YWl0IGZvciBhIHRvdWNoIHRvIGVuZCBmb3IgdGhlXHJcbiAgICAgKiBnZXN0dXJlIHRvIGJlIGNvbnNpZGVyZWQgYSBjbGljay5cclxuICAgICAqL1xyXG4gICAgdGhpcy5jbGlja1RpbWluZ1RocmVzaG9sZCA9IDI1MDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBwaXhlbHMgdG8gYWxsb3cgYSB0b3VjaCB0byBtb3ZlIGZvciB0aGUgZ2VzdHVyZSB0b1xyXG4gICAgICogYmUgY29uc2lkZXJlZCBhIGNsaWNrLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmNsaWNrTW92ZVRocmVzaG9sZCA9IDEwICogKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDEpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgbW91c2Ugc3RhdGUuIFRoZSBwcm9wZXJ0aWVzIG9mIHRoaXMgc3RhdGUgYXJlIHVwZGF0ZWQgd2hlblxyXG4gICAgICogbW91c2UgZXZlbnRzIGZpcmUuIFRoaXMgc3RhdGUgb2JqZWN0IGlzIGFsc28gcGFzc2VkIGluIGFzIGEgcGFyYW1ldGVyIHRvXHJcbiAgICAgKiB0aGUgaGFuZGxlciBvZiBhbnkgbW91c2UgZXZlbnRzLlxyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLk1vdXNlLlN0YXRlfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IG5ldyBHdWFjYW1vbGUuTW91c2UuU3RhdGUoXHJcbiAgICAgICAgMCwgMCwgXHJcbiAgICAgICAgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlXHJcbiAgICApO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgYSBtb3VzZSBidXR0b24gaXMgZWZmZWN0aXZlbHkgcHJlc3NlZC4gVGhpcyBjYW4gaGFwcGVuXHJcbiAgICAgKiBhcyBwYXJ0IG9mIGEgXCJjbGlja1wiIGdlc3R1cmUgaW5pdGlhdGVkIGJ5IHRoZSB1c2VyIGJ5IHRhcHBpbmcgb25lXHJcbiAgICAgKiBvciBtb3JlIGZpbmdlcnMgb3ZlciB0aGUgdG91Y2hwYWQgZWxlbWVudCwgYXMgcGFydCBvZiBhIFwic2Nyb2xsXCJcclxuICAgICAqIGdlc3R1cmUgaW5pdGlhdGVkIGJ5IGRyYWdnaW5nIHR3byBmaW5nZXJzIHVwIG9yIGRvd24sIGV0Yy5cclxuICAgICAqIFxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5Nb3VzZS5TdGF0ZX0gc3RhdGUgVGhlIGN1cnJlbnQgbW91c2Ugc3RhdGUuXHJcbiAgICAgKi9cclxuXHR0aGlzLm9ubW91c2Vkb3duID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIGEgbW91c2UgYnV0dG9uIGlzIGVmZmVjdGl2ZWx5IHJlbGVhc2VkLiBUaGlzIGNhbiBoYXBwZW5cclxuICAgICAqIGFzIHBhcnQgb2YgYSBcImNsaWNrXCIgZ2VzdHVyZSBpbml0aWF0ZWQgYnkgdGhlIHVzZXIgYnkgdGFwcGluZyBvbmVcclxuICAgICAqIG9yIG1vcmUgZmluZ2VycyBvdmVyIHRoZSB0b3VjaHBhZCBlbGVtZW50LCBhcyBwYXJ0IG9mIGEgXCJzY3JvbGxcIlxyXG4gICAgICogZ2VzdHVyZSBpbml0aWF0ZWQgYnkgZHJhZ2dpbmcgdHdvIGZpbmdlcnMgdXAgb3IgZG93biwgZXRjLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLk1vdXNlLlN0YXRlfSBzdGF0ZSBUaGUgY3VycmVudCBtb3VzZSBzdGF0ZS5cclxuICAgICAqL1xyXG5cdHRoaXMub25tb3VzZXVwID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIHRoZSB1c2VyIG1vdmVzIHRoZSBtb3VzZSBieSBkcmFnZ2luZyB0aGVpciBmaW5nZXIgb3ZlclxyXG4gICAgICogdGhlIHRvdWNocGFkIGVsZW1lbnQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTW91c2UuU3RhdGV9IHN0YXRlIFRoZSBjdXJyZW50IG1vdXNlIHN0YXRlLlxyXG4gICAgICovXHJcblx0dGhpcy5vbm1vdXNlbW92ZSA9IG51bGw7XHJcblxyXG4gICAgdmFyIHRvdWNoX2NvdW50ID0gMDtcclxuICAgIHZhciBsYXN0X3RvdWNoX3ggPSAwO1xyXG4gICAgdmFyIGxhc3RfdG91Y2hfeSA9IDA7XHJcbiAgICB2YXIgbGFzdF90b3VjaF90aW1lID0gMDtcclxuICAgIHZhciBwaXhlbHNfbW92ZWQgPSAwO1xyXG5cclxuICAgIHZhciB0b3VjaF9idXR0b25zID0ge1xyXG4gICAgICAgIDE6IFwibGVmdFwiLFxyXG4gICAgICAgIDI6IFwicmlnaHRcIixcclxuICAgICAgICAzOiBcIm1pZGRsZVwiXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBnZXN0dXJlX2luX3Byb2dyZXNzID0gZmFsc2U7XHJcbiAgICB2YXIgY2xpY2tfcmVsZWFzZV90aW1lb3V0ID0gbnVsbDtcclxuXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgXHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAvLyBJZiB3ZSdyZSBoYW5kbGluZyBhIGdlc3R1cmUgQU5EIHRoaXMgaXMgdGhlIGxhc3QgdG91Y2hcclxuICAgICAgICBpZiAoZ2VzdHVyZV9pbl9wcm9ncmVzcyAmJiBlLnRvdWNoZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB2YXIgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IGNvcnJlc3BvbmRpbmcgbW91c2UgYnV0dG9uXHJcbiAgICAgICAgICAgIHZhciBidXR0b24gPSB0b3VjaF9idXR0b25zW3RvdWNoX2NvdW50XTtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIG1vdXNlIGFscmVhZHkgZG93biwgcmVsZWFzZSBhbmFkIGNsZWFyIHRpbWVvdXRcclxuICAgICAgICAgICAgaWYgKGd1YWNfdG91Y2hwYWQuY3VycmVudFN0YXRlW2J1dHRvbl0pIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBGaXJlIGJ1dHRvbiB1cCBldmVudFxyXG4gICAgICAgICAgICAgICAgZ3VhY190b3VjaHBhZC5jdXJyZW50U3RhdGVbYnV0dG9uXSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGd1YWNfdG91Y2hwYWQub25tb3VzZXVwKVxyXG4gICAgICAgICAgICAgICAgICAgIGd1YWNfdG91Y2hwYWQub25tb3VzZXVwKGd1YWNfdG91Y2hwYWQuY3VycmVudFN0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDbGVhciB0aW1lb3V0LCBpZiBzZXRcclxuICAgICAgICAgICAgICAgIGlmIChjbGlja19yZWxlYXNlX3RpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KGNsaWNrX3JlbGVhc2VfdGltZW91dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgY2xpY2tfcmVsZWFzZV90aW1lb3V0ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIHNpbmdsZSB0YXAgZGV0ZWN0ZWQgKGJhc2VkIG9uIHRpbWUgYW5kIGRpc3RhbmNlKVxyXG4gICAgICAgICAgICBpZiAodGltZSAtIGxhc3RfdG91Y2hfdGltZSA8PSBndWFjX3RvdWNocGFkLmNsaWNrVGltaW5nVGhyZXNob2xkXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgcGl4ZWxzX21vdmVkIDwgZ3VhY190b3VjaHBhZC5jbGlja01vdmVUaHJlc2hvbGQpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBGaXJlIGJ1dHRvbiBkb3duIGV2ZW50XHJcbiAgICAgICAgICAgICAgICBndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZVtidXR0b25dID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGlmIChndWFjX3RvdWNocGFkLm9ubW91c2Vkb3duKVxyXG4gICAgICAgICAgICAgICAgICAgIGd1YWNfdG91Y2hwYWQub25tb3VzZWRvd24oZ3VhY190b3VjaHBhZC5jdXJyZW50U3RhdGUpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIERlbGF5IG1vdXNlIHVwIC0gbW91c2UgdXAgc2hvdWxkIGJlIGNhbmNlbGVkIGlmXHJcbiAgICAgICAgICAgICAgICAvLyB0b3VjaHN0YXJ0IHdpdGhpbiB0aW1lb3V0LlxyXG4gICAgICAgICAgICAgICAgY2xpY2tfcmVsZWFzZV90aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRmlyZSBidXR0b24gdXAgZXZlbnRcclxuICAgICAgICAgICAgICAgICAgICBndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZVtidXR0b25dID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGd1YWNfdG91Y2hwYWQub25tb3VzZXVwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBndWFjX3RvdWNocGFkLm9ubW91c2V1cChndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gR2VzdHVyZSBub3cgb3ZlclxyXG4gICAgICAgICAgICAgICAgICAgIGdlc3R1cmVfaW5fcHJvZ3Jlc3MgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICB9LCBndWFjX3RvdWNocGFkLmNsaWNrVGltaW5nVGhyZXNob2xkKTtcclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIHdlJ3JlIG5vdCB3YWl0aW5nIHRvIHNlZSBpZiB0aGlzIGlzIGEgY2xpY2ssIHN0b3AgZ2VzdHVyZVxyXG4gICAgICAgICAgICBpZiAoIWNsaWNrX3JlbGVhc2VfdGltZW91dClcclxuICAgICAgICAgICAgICAgIGdlc3R1cmVfaW5fcHJvZ3Jlc3MgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIGZ1bmN0aW9uKGUpIHtcclxuXHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICAvLyBUcmFjayBudW1iZXIgb2YgdG91Y2hlcywgYnV0IG5vIG1vcmUgdGhhbiB0aHJlZVxyXG4gICAgICAgIHRvdWNoX2NvdW50ID0gTWF0aC5taW4oZS50b3VjaGVzLmxlbmd0aCwgMyk7XHJcblxyXG4gICAgICAgIC8vIENsZWFyIHRpbWVvdXQsIGlmIHNldFxyXG4gICAgICAgIGlmIChjbGlja19yZWxlYXNlX3RpbWVvdXQpIHtcclxuICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dChjbGlja19yZWxlYXNlX3RpbWVvdXQpO1xyXG4gICAgICAgICAgICBjbGlja19yZWxlYXNlX3RpbWVvdXQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVjb3JkIGluaXRpYWwgdG91Y2ggbG9jYXRpb24gYW5kIHRpbWUgZm9yIHRvdWNoIG1vdmVtZW50XHJcbiAgICAgICAgLy8gYW5kIHRhcCBnZXN0dXJlc1xyXG4gICAgICAgIGlmICghZ2VzdHVyZV9pbl9wcm9ncmVzcykge1xyXG5cclxuICAgICAgICAgICAgLy8gU3RvcCBtb3VzZSBldmVudHMgd2hpbGUgdG91Y2hpbmdcclxuICAgICAgICAgICAgZ2VzdHVyZV9pbl9wcm9ncmVzcyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAvLyBSZWNvcmQgdG91Y2ggbG9jYXRpb24gYW5kIHRpbWVcclxuICAgICAgICAgICAgdmFyIHN0YXJ0aW5nX3RvdWNoID0gZS50b3VjaGVzWzBdO1xyXG4gICAgICAgICAgICBsYXN0X3RvdWNoX3ggPSBzdGFydGluZ190b3VjaC5jbGllbnRYO1xyXG4gICAgICAgICAgICBsYXN0X3RvdWNoX3kgPSBzdGFydGluZ190b3VjaC5jbGllbnRZO1xyXG4gICAgICAgICAgICBsYXN0X3RvdWNoX3RpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgICAgICAgICAgcGl4ZWxzX21vdmVkID0gMDtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgZnVuY3Rpb24oZSkge1xyXG5cclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgIC8vIEdldCBjaGFuZ2UgaW4gdG91Y2ggbG9jYXRpb25cclxuICAgICAgICB2YXIgdG91Y2ggPSBlLnRvdWNoZXNbMF07XHJcbiAgICAgICAgdmFyIGRlbHRhX3ggPSB0b3VjaC5jbGllbnRYIC0gbGFzdF90b3VjaF94O1xyXG4gICAgICAgIHZhciBkZWx0YV95ID0gdG91Y2guY2xpZW50WSAtIGxhc3RfdG91Y2hfeTtcclxuXHJcbiAgICAgICAgLy8gVHJhY2sgcGl4ZWxzIG1vdmVkXHJcbiAgICAgICAgcGl4ZWxzX21vdmVkICs9IE1hdGguYWJzKGRlbHRhX3gpICsgTWF0aC5hYnMoZGVsdGFfeSk7XHJcblxyXG4gICAgICAgIC8vIElmIG9ubHkgb25lIHRvdWNoIGludm9sdmVkLCB0aGlzIGlzIG1vdXNlIG1vdmVcclxuICAgICAgICBpZiAodG91Y2hfY291bnQgPT09IDEpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBhdmVyYWdlIHZlbG9jaXR5IGluIE1hbmhhdHRlbiBwaXhlbHMgcGVyIG1pbGxpc2Vjb25kXHJcbiAgICAgICAgICAgIHZhciB2ZWxvY2l0eSA9IHBpeGVsc19tb3ZlZCAvIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGxhc3RfdG91Y2hfdGltZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBTY2FsZSBtb3VzZSBtb3ZlbWVudCByZWxhdGl2ZSB0byB2ZWxvY2l0eVxyXG4gICAgICAgICAgICB2YXIgc2NhbGUgPSAxICsgdmVsb2NpdHk7XHJcblxyXG4gICAgICAgICAgICAvLyBVcGRhdGUgbW91c2UgbG9jYXRpb25cclxuICAgICAgICAgICAgZ3VhY190b3VjaHBhZC5jdXJyZW50U3RhdGUueCArPSBkZWx0YV94KnNjYWxlO1xyXG4gICAgICAgICAgICBndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZS55ICs9IGRlbHRhX3kqc2NhbGU7XHJcblxyXG4gICAgICAgICAgICAvLyBQcmV2ZW50IG1vdXNlIGZyb20gbGVhdmluZyBzY3JlZW5cclxuXHJcbiAgICAgICAgICAgIGlmIChndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZS54IDwgMClcclxuICAgICAgICAgICAgICAgIGd1YWNfdG91Y2hwYWQuY3VycmVudFN0YXRlLnggPSAwO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZS54ID49IGVsZW1lbnQub2Zmc2V0V2lkdGgpXHJcbiAgICAgICAgICAgICAgICBndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZS54ID0gZWxlbWVudC5vZmZzZXRXaWR0aCAtIDE7XHJcblxyXG4gICAgICAgICAgICBpZiAoZ3VhY190b3VjaHBhZC5jdXJyZW50U3RhdGUueSA8IDApXHJcbiAgICAgICAgICAgICAgICBndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZS55ID0gMDtcclxuICAgICAgICAgICAgZWxzZSBpZiAoZ3VhY190b3VjaHBhZC5jdXJyZW50U3RhdGUueSA+PSBlbGVtZW50Lm9mZnNldEhlaWdodClcclxuICAgICAgICAgICAgICAgIGd1YWNfdG91Y2hwYWQuY3VycmVudFN0YXRlLnkgPSBlbGVtZW50Lm9mZnNldEhlaWdodCAtIDE7XHJcblxyXG4gICAgICAgICAgICAvLyBGaXJlIG1vdmVtZW50IGV2ZW50LCBpZiBkZWZpbmVkXHJcbiAgICAgICAgICAgIGlmIChndWFjX3RvdWNocGFkLm9ubW91c2Vtb3ZlKVxyXG4gICAgICAgICAgICAgICAgZ3VhY190b3VjaHBhZC5vbm1vdXNlbW92ZShndWFjX3RvdWNocGFkLmN1cnJlbnRTdGF0ZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBVcGRhdGUgdG91Y2ggbG9jYXRpb25cclxuICAgICAgICAgICAgbGFzdF90b3VjaF94ID0gdG91Y2guY2xpZW50WDtcclxuICAgICAgICAgICAgbGFzdF90b3VjaF95ID0gdG91Y2guY2xpZW50WTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJbnRlcnByZXQgdHdvLWZpbmdlciBzd2lwZSBhcyBzY3JvbGx3aGVlbFxyXG4gICAgICAgIGVsc2UgaWYgKHRvdWNoX2NvdW50ID09PSAyKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBJZiBjaGFuZ2UgaW4gbG9jYXRpb24gcGFzc2VzIHRocmVzaG9sZCBmb3Igc2Nyb2xsXHJcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkZWx0YV95KSA+PSBndWFjX3RvdWNocGFkLnNjcm9sbFRocmVzaG9sZCkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIERlY2lkZSBidXR0b24gYmFzZWQgb24gWSBtb3ZlbWVudCBkaXJlY3Rpb25cclxuICAgICAgICAgICAgICAgIHZhciBidXR0b247XHJcbiAgICAgICAgICAgICAgICBpZiAoZGVsdGFfeSA+IDApIGJ1dHRvbiA9IFwiZG93blwiO1xyXG4gICAgICAgICAgICAgICAgZWxzZSAgICAgICAgICAgICBidXR0b24gPSBcInVwXCI7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gRmlyZSBidXR0b24gZG93biBldmVudFxyXG4gICAgICAgICAgICAgICAgZ3VhY190b3VjaHBhZC5jdXJyZW50U3RhdGVbYnV0dG9uXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ3VhY190b3VjaHBhZC5vbm1vdXNlZG93bilcclxuICAgICAgICAgICAgICAgICAgICBndWFjX3RvdWNocGFkLm9ubW91c2Vkb3duKGd1YWNfdG91Y2hwYWQuY3VycmVudFN0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBGaXJlIGJ1dHRvbiB1cCBldmVudFxyXG4gICAgICAgICAgICAgICAgZ3VhY190b3VjaHBhZC5jdXJyZW50U3RhdGVbYnV0dG9uXSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGd1YWNfdG91Y2hwYWQub25tb3VzZXVwKVxyXG4gICAgICAgICAgICAgICAgICAgIGd1YWNfdG91Y2hwYWQub25tb3VzZXVwKGd1YWNfdG91Y2hwYWQuY3VycmVudFN0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBPbmx5IHVwZGF0ZSB0b3VjaCBsb2NhdGlvbiBhZnRlciBhIHNjcm9sbCBoYXMgYmVlblxyXG4gICAgICAgICAgICAgICAgLy8gZGV0ZWN0ZWRcclxuICAgICAgICAgICAgICAgIGxhc3RfdG91Y2hfeCA9IHRvdWNoLmNsaWVudFg7XHJcbiAgICAgICAgICAgICAgICBsYXN0X3RvdWNoX3kgPSB0b3VjaC5jbGllbnRZO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfSwgZmFsc2UpO1xyXG5cclxufTtcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlcyBjcm9zcy1icm93c2VyIGFic29sdXRlIHRvdWNoIGV2ZW50IHRyYW5zbGF0aW9uIGZvciBhIGdpdmVuIGVsZW1lbnQuXHJcbiAqXHJcbiAqIFRvdWNoIGV2ZW50cyBhcmUgdHJhbnNsYXRlZCBpbnRvIG1vdXNlIGV2ZW50cyBhcyBpZiB0aGUgdG91Y2hlcyBvY2N1cnJlZFxyXG4gKiBvbiBhIHRvdWNoc2NyZWVuICh0YXBwaW5nIGFueXdoZXJlIG9uIHRoZSBzY3JlZW4gY2xpY2tzIGF0IHRoYXQgcG9pbnQsXHJcbiAqIGxvbmctcHJlc3MgdG8gcmlnaHQtY2xpY2spLlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBFbGVtZW50IHRvIHVzZSB0byBwcm92aWRlIHRvdWNoIGV2ZW50cy5cclxuICovXHJcbkd1YWNhbW9sZS5Nb3VzZS5Ub3VjaHNjcmVlbiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5Nb3VzZS5Ub3VjaHNjcmVlbi5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBndWFjX3RvdWNoc2NyZWVuID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgYSBnZXN0dXJlIGlzIGtub3duIHRvIGJlIGluIHByb2dyZXNzLiBJZiBmYWxzZSwgdG91Y2ggZXZlbnRzXHJcbiAgICAgKiB3aWxsIGJlIGlnbm9yZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGdlc3R1cmVfaW5fcHJvZ3Jlc3MgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzdGFydCBYIGxvY2F0aW9uIG9mIGEgZ2VzdHVyZS5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBnZXN0dXJlX3N0YXJ0X3ggPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHN0YXJ0IFkgbG9jYXRpb24gb2YgYSBnZXN0dXJlLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGdlc3R1cmVfc3RhcnRfeSA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdGltZW91dCBhc3NvY2lhdGVkIHdpdGggdGhlIGRlbGF5ZWQsIGNhbmNlbGxhYmxlIGNsaWNrIHJlbGVhc2UuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGNsaWNrX3JlbGVhc2VfdGltZW91dCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdGltZW91dCBhc3NvY2lhdGVkIHdpdGggbG9uZy1wcmVzcyBmb3IgcmlnaHQgY2xpY2suXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGxvbmdfcHJlc3NfdGltZW91dCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZGlzdGFuY2UgYSB0d28tZmluZ2VyIHRvdWNoIG11c3QgbW92ZSBwZXIgc2Nyb2xsd2hlZWwgZXZlbnQsIGluXHJcbiAgICAgKiBwaXhlbHMuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2Nyb2xsVGhyZXNob2xkID0gMjAgKiAod2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIGEgdG91Y2ggdG8gZW5kIGZvciB0aGVcclxuICAgICAqIGdlc3R1cmUgdG8gYmUgY29uc2lkZXJlZCBhIGNsaWNrLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmNsaWNrVGltaW5nVGhyZXNob2xkID0gMjUwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIHBpeGVscyB0byBhbGxvdyBhIHRvdWNoIHRvIG1vdmUgZm9yIHRoZSBnZXN0dXJlIHRvXHJcbiAgICAgKiBiZSBjb25zaWRlcmVkIGEgY2xpY2suXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY2xpY2tNb3ZlVGhyZXNob2xkID0gMTYgKiAod2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgYSBwcmVzcyBtdXN0IGJlIGhlbGQgZm9yIGxvbmcgcHJlc3MgdG8gYmVcclxuICAgICAqIGRldGVjdGVkLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmxvbmdQcmVzc1RocmVzaG9sZCA9IDUwMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjdXJyZW50IG1vdXNlIHN0YXRlLiBUaGUgcHJvcGVydGllcyBvZiB0aGlzIHN0YXRlIGFyZSB1cGRhdGVkIHdoZW5cclxuICAgICAqIG1vdXNlIGV2ZW50cyBmaXJlLiBUaGlzIHN0YXRlIG9iamVjdCBpcyBhbHNvIHBhc3NlZCBpbiBhcyBhIHBhcmFtZXRlciB0b1xyXG4gICAgICogdGhlIGhhbmRsZXIgb2YgYW55IG1vdXNlIGV2ZW50cy5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLk1vdXNlLlN0YXRlfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmN1cnJlbnRTdGF0ZSA9IG5ldyBHdWFjYW1vbGUuTW91c2UuU3RhdGUoXHJcbiAgICAgICAgMCwgMCxcclxuICAgICAgICBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2VcclxuICAgICk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciBhIG1vdXNlIGJ1dHRvbiBpcyBlZmZlY3RpdmVseSBwcmVzc2VkLiBUaGlzIGNhbiBoYXBwZW5cclxuICAgICAqIGFzIHBhcnQgb2YgYSBcIm1vdXNlZG93blwiIGdlc3R1cmUgaW5pdGlhdGVkIGJ5IHRoZSB1c2VyIGJ5IHByZXNzaW5nIG9uZVxyXG4gICAgICogZmluZ2VyIG92ZXIgdGhlIHRvdWNoc2NyZWVuIGVsZW1lbnQsIGFzIHBhcnQgb2YgYSBcInNjcm9sbFwiIGdlc3R1cmVcclxuICAgICAqIGluaXRpYXRlZCBieSBkcmFnZ2luZyB0d28gZmluZ2VycyB1cCBvciBkb3duLCBldGMuXHJcbiAgICAgKlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5Nb3VzZS5TdGF0ZX0gc3RhdGUgVGhlIGN1cnJlbnQgbW91c2Ugc3RhdGUuXHJcbiAgICAgKi9cclxuXHR0aGlzLm9ubW91c2Vkb3duID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIGEgbW91c2UgYnV0dG9uIGlzIGVmZmVjdGl2ZWx5IHJlbGVhc2VkLiBUaGlzIGNhbiBoYXBwZW5cclxuICAgICAqIGFzIHBhcnQgb2YgYSBcIm1vdXNldXBcIiBnZXN0dXJlIGluaXRpYXRlZCBieSB0aGUgdXNlciBieSByZW1vdmluZyB0aGVcclxuICAgICAqIGZpbmdlciBwcmVzc2VkIGFnYWluc3QgdGhlIHRvdWNoc2NyZWVuIGVsZW1lbnQsIG9yIGFzIHBhcnQgb2YgYSBcInNjcm9sbFwiXHJcbiAgICAgKiBnZXN0dXJlIGluaXRpYXRlZCBieSBkcmFnZ2luZyB0d28gZmluZ2VycyB1cCBvciBkb3duLCBldGMuXHJcbiAgICAgKlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5Nb3VzZS5TdGF0ZX0gc3RhdGUgVGhlIGN1cnJlbnQgbW91c2Ugc3RhdGUuXHJcbiAgICAgKi9cclxuXHR0aGlzLm9ubW91c2V1cCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciB0aGUgdXNlciBtb3ZlcyB0aGUgbW91c2UgYnkgZHJhZ2dpbmcgdGhlaXIgZmluZ2VyIG92ZXJcclxuICAgICAqIHRoZSB0b3VjaHNjcmVlbiBlbGVtZW50LiBOb3RlIHRoYXQgdW5saWtlIEd1YWNhbW9sZS5Nb3VzZS5Ub3VjaHBhZCxcclxuICAgICAqIGRyYWdnaW5nIGEgZmluZ2VyIG92ZXIgdGhlIHRvdWNoc2NyZWVuIGVsZW1lbnQgd2lsbCBhbHdheXMgY2F1c2VcclxuICAgICAqIHRoZSBtb3VzZSBidXR0b24gdG8gYmUgZWZmZWN0aXZlbHkgZG93biwgYXMgaWYgY2xpY2tpbmctYW5kLWRyYWdnaW5nLlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuTW91c2UuU3RhdGV9IHN0YXRlIFRoZSBjdXJyZW50IG1vdXNlIHN0YXRlLlxyXG4gICAgICovXHJcblx0dGhpcy5vbm1vdXNlbW92ZSA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVzc2VzIHRoZSBnaXZlbiBtb3VzZSBidXR0b24sIGlmIGl0IGlzbid0IGFscmVhZHkgcHJlc3NlZC4gVmFsaWRcclxuICAgICAqIGJ1dHRvbiB2YWx1ZXMgYXJlIFwibGVmdFwiLCBcIm1pZGRsZVwiLCBcInJpZ2h0XCIsIFwidXBcIiwgYW5kIFwiZG93blwiLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYnV0dG9uIFRoZSBtb3VzZSBidXR0b24gdG8gcHJlc3MuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHByZXNzX2J1dHRvbihidXR0b24pIHtcclxuICAgICAgICBpZiAoIWd1YWNfdG91Y2hzY3JlZW4uY3VycmVudFN0YXRlW2J1dHRvbl0pIHtcclxuICAgICAgICAgICAgZ3VhY190b3VjaHNjcmVlbi5jdXJyZW50U3RhdGVbYnV0dG9uXSA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmIChndWFjX3RvdWNoc2NyZWVuLm9ubW91c2Vkb3duKVxyXG4gICAgICAgICAgICAgICAgZ3VhY190b3VjaHNjcmVlbi5vbm1vdXNlZG93bihndWFjX3RvdWNoc2NyZWVuLmN1cnJlbnRTdGF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVsZWFzZXMgdGhlIGdpdmVuIG1vdXNlIGJ1dHRvbiwgaWYgaXQgaXNuJ3QgYWxyZWFkeSByZWxlYXNlZC4gVmFsaWRcclxuICAgICAqIGJ1dHRvbiB2YWx1ZXMgYXJlIFwibGVmdFwiLCBcIm1pZGRsZVwiLCBcInJpZ2h0XCIsIFwidXBcIiwgYW5kIFwiZG93blwiLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYnV0dG9uIFRoZSBtb3VzZSBidXR0b24gdG8gcmVsZWFzZS5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gcmVsZWFzZV9idXR0b24oYnV0dG9uKSB7XHJcbiAgICAgICAgaWYgKGd1YWNfdG91Y2hzY3JlZW4uY3VycmVudFN0YXRlW2J1dHRvbl0pIHtcclxuICAgICAgICAgICAgZ3VhY190b3VjaHNjcmVlbi5jdXJyZW50U3RhdGVbYnV0dG9uXSA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpZiAoZ3VhY190b3VjaHNjcmVlbi5vbm1vdXNldXApXHJcbiAgICAgICAgICAgICAgICBndWFjX3RvdWNoc2NyZWVuLm9ubW91c2V1cChndWFjX3RvdWNoc2NyZWVuLmN1cnJlbnRTdGF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xpY2tzIChwcmVzc2VzIGFuZCByZWxlYXNlcykgdGhlIGdpdmVuIG1vdXNlIGJ1dHRvbi4gVmFsaWQgYnV0dG9uXHJcbiAgICAgKiB2YWx1ZXMgYXJlIFwibGVmdFwiLCBcIm1pZGRsZVwiLCBcInJpZ2h0XCIsIFwidXBcIiwgYW5kIFwiZG93blwiLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gYnV0dG9uIFRoZSBtb3VzZSBidXR0b24gdG8gY2xpY2suXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGNsaWNrX2J1dHRvbihidXR0b24pIHtcclxuICAgICAgICBwcmVzc19idXR0b24oYnV0dG9uKTtcclxuICAgICAgICByZWxlYXNlX2J1dHRvbihidXR0b24pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTW92ZXMgdGhlIG1vdXNlIHRvIHRoZSBnaXZlbiBjb29yZGluYXRlcy4gVGhlc2UgY29vcmRpbmF0ZXMgbXVzdCBiZVxyXG4gICAgICogcmVsYXRpdmUgdG8gdGhlIGJyb3dzZXIgd2luZG93LCBhcyB0aGV5IHdpbGwgYmUgdHJhbnNsYXRlZCBiYXNlZCBvblxyXG4gICAgICogdGhlIHRvdWNoIGV2ZW50IHRhcmdldCdzIGxvY2F0aW9uIHdpdGhpbiB0aGUgYnJvd3NlciB3aW5kb3cuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIG1vdXNlIHBvaW50ZXIuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgWSBjb29yZGluYXRlIG9mIHRoZSBtb3VzZSBwb2ludGVyLlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBtb3ZlX21vdXNlKHgsIHkpIHtcclxuICAgICAgICBndWFjX3RvdWNoc2NyZWVuLmN1cnJlbnRTdGF0ZS5mcm9tQ2xpZW50UG9zaXRpb24oZWxlbWVudCwgeCwgeSk7XHJcbiAgICAgICAgaWYgKGd1YWNfdG91Y2hzY3JlZW4ub25tb3VzZW1vdmUpXHJcbiAgICAgICAgICAgIGd1YWNfdG91Y2hzY3JlZW4ub25tb3VzZW1vdmUoZ3VhY190b3VjaHNjcmVlbi5jdXJyZW50U3RhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiB0b3VjaCBldmVudCBleGNlZWRzIHRoZSBtb3ZlbWVudCB0aHJlc2hvbGQgZm9yXHJcbiAgICAgKiBjbGlja2luZywgYmFzZWQgb24gd2hlcmUgdGhlIHRvdWNoIGdlc3R1cmUgYmVnYW4uXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7VG91Y2hFdmVudH0gZSBUaGUgdG91Y2ggZXZlbnQgdG8gY2hlY2suXHJcbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHRoZSBtb3ZlbWVudCB0aHJlc2hvbGQgaXMgZXhjZWVkZWQsIGZhbHNlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZpbmdlcl9tb3ZlZChlKSB7XHJcbiAgICAgICAgdmFyIHRvdWNoID0gZS50b3VjaGVzWzBdIHx8IGUuY2hhbmdlZFRvdWNoZXNbMF07XHJcbiAgICAgICAgdmFyIGRlbHRhX3ggPSB0b3VjaC5jbGllbnRYIC0gZ2VzdHVyZV9zdGFydF94O1xyXG4gICAgICAgIHZhciBkZWx0YV95ID0gdG91Y2guY2xpZW50WSAtIGdlc3R1cmVfc3RhcnRfeTtcclxuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KGRlbHRhX3gqZGVsdGFfeCArIGRlbHRhX3kqZGVsdGFfeSkgPj0gZ3VhY190b3VjaHNjcmVlbi5jbGlja01vdmVUaHJlc2hvbGQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCZWdpbnMgYSBuZXcgZ2VzdHVyZSBhdCB0aGUgbG9jYXRpb24gb2YgdGhlIGZpcnN0IHRvdWNoIGluIHRoZSBnaXZlblxyXG4gICAgICogdG91Y2ggZXZlbnQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge1RvdWNoRXZlbnR9IGUgVGhlIHRvdWNoIGV2ZW50IGJlZ2lubmluZyB0aGlzIG5ldyBnZXN0dXJlLlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBiZWdpbl9nZXN0dXJlKGUpIHtcclxuICAgICAgICB2YXIgdG91Y2ggPSBlLnRvdWNoZXNbMF07XHJcbiAgICAgICAgZ2VzdHVyZV9pbl9wcm9ncmVzcyA9IHRydWU7XHJcbiAgICAgICAgZ2VzdHVyZV9zdGFydF94ID0gdG91Y2guY2xpZW50WDtcclxuICAgICAgICBnZXN0dXJlX3N0YXJ0X3kgPSB0b3VjaC5jbGllbnRZO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5kIHRoZSBjdXJyZW50IGdlc3R1cmUgZW50aXJlbHkuIFdhaXQgZm9yIGFsbCB0b3VjaGVzIHRvIGJlIGRvbmUgYmVmb3JlXHJcbiAgICAgKiByZXN1bWluZyBnZXN0dXJlIGRldGVjdGlvbi5cclxuICAgICAqIFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZW5kX2dlc3R1cmUoKSB7XHJcbiAgICAgICAgd2luZG93LmNsZWFyVGltZW91dChjbGlja19yZWxlYXNlX3RpbWVvdXQpO1xyXG4gICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQobG9uZ19wcmVzc190aW1lb3V0KTtcclxuICAgICAgICBnZXN0dXJlX2luX3Byb2dyZXNzID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgZnVuY3Rpb24oZSkge1xyXG5cclxuICAgICAgICAvLyBEbyBub3QgaGFuZGxlIGlmIG5vIGdlc3R1cmVcclxuICAgICAgICBpZiAoIWdlc3R1cmVfaW5fcHJvZ3Jlc3MpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gSWdub3JlIGlmIG1vcmUgdGhhbiBvbmUgdG91Y2hcclxuICAgICAgICBpZiAoZS50b3VjaGVzLmxlbmd0aCAhPT0gMCB8fCBlLmNoYW5nZWRUb3VjaGVzLmxlbmd0aCAhPT0gMSkge1xyXG4gICAgICAgICAgICBlbmRfZ2VzdHVyZSgpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBMb25nLXByZXNzLCBpZiBhbnksIGlzIG92ZXJcclxuICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KGxvbmdfcHJlc3NfdGltZW91dCk7XHJcblxyXG4gICAgICAgIC8vIEFsd2F5cyByZWxlYXNlIG1vdXNlIGJ1dHRvbiBpZiBwcmVzc2VkXHJcbiAgICAgICAgcmVsZWFzZV9idXR0b24oXCJsZWZ0XCIpO1xyXG5cclxuICAgICAgICAvLyBJZiBmaW5nZXIgaGFzbid0IG1vdmVkIGVub3VnaCB0byBjYW5jZWwgdGhlIGNsaWNrXHJcbiAgICAgICAgaWYgKCFmaW5nZXJfbW92ZWQoZSkpIHtcclxuXHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIG5vdCB5ZXQgcHJlc3NlZCwgcHJlc3MgYW5kIHN0YXJ0IGRlbGF5IHJlbGVhc2VcclxuICAgICAgICAgICAgaWYgKCFndWFjX3RvdWNoc2NyZWVuLmN1cnJlbnRTdGF0ZS5sZWZ0KSB7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIHRvdWNoID0gZS5jaGFuZ2VkVG91Y2hlc1swXTtcclxuICAgICAgICAgICAgICAgIG1vdmVfbW91c2UodG91Y2guY2xpZW50WCwgdG91Y2guY2xpZW50WSk7XHJcbiAgICAgICAgICAgICAgICBwcmVzc19idXR0b24oXCJsZWZ0XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJlbGVhc2UgYnV0dG9uIGFmdGVyIGEgZGVsYXksIGlmIG5vdCBjYW5jZWxlZFxyXG4gICAgICAgICAgICAgICAgY2xpY2tfcmVsZWFzZV90aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZV9idXR0b24oXCJsZWZ0XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZF9nZXN0dXJlKCk7XHJcbiAgICAgICAgICAgICAgICB9LCBndWFjX3RvdWNoc2NyZWVuLmNsaWNrVGltaW5nVGhyZXNob2xkKTtcclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSAvLyBlbmQgaWYgZmluZ2VyIG5vdCBtb3ZlZFxyXG5cclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIGZ1bmN0aW9uKGUpIHtcclxuXHJcbiAgICAgICAgLy8gSWdub3JlIGlmIG1vcmUgdGhhbiBvbmUgdG91Y2hcclxuICAgICAgICBpZiAoZS50b3VjaGVzLmxlbmd0aCAhPT0gMSkge1xyXG4gICAgICAgICAgICBlbmRfZ2VzdHVyZSgpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgIC8vIE5ldyB0b3VjaCBiZWdpbnMgYSBuZXcgZ2VzdHVyZVxyXG4gICAgICAgIGJlZ2luX2dlc3R1cmUoZSk7XHJcblxyXG4gICAgICAgIC8vIEtlZXAgYnV0dG9uIHByZXNzZWQgaWYgdGFwIGFmdGVyIGxlZnQgY2xpY2tcclxuICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KGNsaWNrX3JlbGVhc2VfdGltZW91dCk7XHJcblxyXG4gICAgICAgIC8vIENsaWNrIHJpZ2h0IGJ1dHRvbiBpZiB0aGlzIHR1cm5zIGludG8gYSBsb25nLXByZXNzXHJcbiAgICAgICAgbG9uZ19wcmVzc190aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciB0b3VjaCA9IGUudG91Y2hlc1swXTtcclxuICAgICAgICAgICAgbW92ZV9tb3VzZSh0b3VjaC5jbGllbnRYLCB0b3VjaC5jbGllbnRZKTtcclxuICAgICAgICAgICAgY2xpY2tfYnV0dG9uKFwicmlnaHRcIik7XHJcbiAgICAgICAgICAgIGVuZF9nZXN0dXJlKCk7XHJcbiAgICAgICAgfSwgZ3VhY190b3VjaHNjcmVlbi5sb25nUHJlc3NUaHJlc2hvbGQpO1xyXG5cclxuICAgIH0sIGZhbHNlKTtcclxuXHJcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgZnVuY3Rpb24oZSkge1xyXG5cclxuICAgICAgICAvLyBEbyBub3QgaGFuZGxlIGlmIG5vIGdlc3R1cmVcclxuICAgICAgICBpZiAoIWdlc3R1cmVfaW5fcHJvZ3Jlc3MpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gQ2FuY2VsIGxvbmcgcHJlc3MgaWYgZmluZ2VyIG1vdmVkXHJcbiAgICAgICAgaWYgKGZpbmdlcl9tb3ZlZChlKSlcclxuICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dChsb25nX3ByZXNzX3RpbWVvdXQpO1xyXG5cclxuICAgICAgICAvLyBJZ25vcmUgaWYgbW9yZSB0aGFuIG9uZSB0b3VjaFxyXG4gICAgICAgIGlmIChlLnRvdWNoZXMubGVuZ3RoICE9PSAxKSB7XHJcbiAgICAgICAgICAgIGVuZF9nZXN0dXJlKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFVwZGF0ZSBtb3VzZSBwb3NpdGlvbiBpZiBkcmFnZ2luZ1xyXG4gICAgICAgIGlmIChndWFjX3RvdWNoc2NyZWVuLmN1cnJlbnRTdGF0ZS5sZWZ0KSB7XHJcblxyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICAgICAgICAvLyBVcGRhdGUgc3RhdGVcclxuICAgICAgICAgICAgdmFyIHRvdWNoID0gZS50b3VjaGVzWzBdO1xyXG4gICAgICAgICAgICBtb3ZlX21vdXNlKHRvdWNoLmNsaWVudFgsIHRvdWNoLmNsaWVudFkpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfSwgZmFsc2UpO1xyXG5cclxufTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFRoZSBuYW1lc3BhY2UgdXNlZCBieSB0aGUgR3VhY2Ftb2xlIEphdmFTY3JpcHQgQVBJLiBBYnNvbHV0ZWx5IGFsbCBjbGFzc2VzXHJcbiAqIGRlZmluZWQgYnkgdGhlIEd1YWNhbW9sZSBKYXZhU2NyaXB0IEFQSSB3aWxsIGJlIHdpdGhpbiB0aGlzIG5hbWVzcGFjZS5cclxuICpcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBbiBvYmplY3QgdXNlZCBieSB0aGUgR3VhY2Ftb2xlIGNsaWVudCB0byBob3VzZSBhcmJpdHJhcmlseS1tYW55IG5hbWVkXHJcbiAqIGlucHV0IGFuZCBvdXRwdXQgc3RyZWFtcy5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAcGFyYW0ge0d1YWNhbW9sZS5DbGllbnR9IGNsaWVudFxyXG4gKiAgICAgVGhlIGNsaWVudCBvd25pbmcgdGhpcyBvYmplY3QuXHJcbiAqXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxyXG4gKiAgICAgVGhlIGluZGV4IG9mIHRoaXMgb2JqZWN0LlxyXG4gKi9cclxuR3VhY2Ftb2xlLk9iamVjdCA9IGZ1bmN0aW9uIGd1YWNhbW9sZU9iamVjdChjbGllbnQsIGluZGV4KSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBHdWFjYW1vbGUuT2JqZWN0LlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLk9iamVjdH1cclxuICAgICAqL1xyXG4gICAgdmFyIGd1YWNPYmplY3QgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFwIG9mIHN0cmVhbSBuYW1lIHRvIGNvcnJlc3BvbmRpbmcgcXVldWUgb2YgY2FsbGJhY2tzLiBUaGUgcXVldWUgb2ZcclxuICAgICAqIGNhbGxiYWNrcyBpcyBndWFyYW50ZWVkIHRvIGJlIGluIG9yZGVyIG9mIHJlcXVlc3QuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtPYmplY3QuPFN0cmluZywgRnVuY3Rpb25bXT59XHJcbiAgICAgKi9cclxuICAgIHZhciBib2R5Q2FsbGJhY2tzID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFuZCByZXR1cm5zIHRoZSBjYWxsYmFjayBhdCB0aGUgaGVhZCBvZiB0aGUgY2FsbGJhY2sgcXVldWUgZm9yXHJcbiAgICAgKiB0aGUgc3RyZWFtIGhhdmluZyB0aGUgZ2l2ZW4gbmFtZS4gSWYgbm8gc3VjaCBjYWxsYmFja3MgZXhpc3QsIG51bGwgaXNcclxuICAgICAqIHJldHVybmVkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gICAgICogICAgIFRoZSBuYW1lIG9mIHRoZSBzdHJlYW0gdG8gcmV0cmlldmUgYSBjYWxsYmFjayBmb3IuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufVxyXG4gICAgICogICAgIFRoZSBuZXh0IGNhbGxiYWNrIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3RyZWFtIGhhdmluZyB0aGUgZ2l2ZW4gbmFtZSxcclxuICAgICAqICAgICBvciBudWxsIGlmIG5vIHN1Y2ggY2FsbGJhY2sgZXhpc3RzLlxyXG4gICAgICovXHJcbiAgICB2YXIgZGVxdWV1ZUJvZHlDYWxsYmFjayA9IGZ1bmN0aW9uIGRlcXVldWVCb2R5Q2FsbGJhY2sobmFtZSkge1xyXG5cclxuICAgICAgICAvLyBJZiBubyBjYWxsYmFja3MgZGVmaW5lZCwgc2ltcGx5IHJldHVybiBudWxsXHJcbiAgICAgICAgdmFyIGNhbGxiYWNrcyA9IGJvZHlDYWxsYmFja3NbbmFtZV07XHJcbiAgICAgICAgaWYgKCFjYWxsYmFja3MpXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICAvLyBPdGhlcndpc2UsIHB1bGwgb2ZmIGZpcnN0IGNhbGxiYWNrLCBkZWxldGluZyB0aGUgcXVldWUgaWYgZW1wdHlcclxuICAgICAgICB2YXIgY2FsbGJhY2sgPSBjYWxsYmFja3Muc2hpZnQoKTtcclxuICAgICAgICBpZiAoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgZGVsZXRlIGJvZHlDYWxsYmFja3NbbmFtZV07XHJcblxyXG4gICAgICAgIC8vIFJldHVybiBmb3VuZCBjYWxsYmFja1xyXG4gICAgICAgIHJldHVybiBjYWxsYmFjaztcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyB0aGUgZ2l2ZW4gY2FsbGJhY2sgdG8gdGhlIHRhaWwgb2YgdGhlIGNhbGxiYWNrIHF1ZXVlIGZvciB0aGUgc3RyZWFtXHJcbiAgICAgKiBoYXZpbmcgdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXHJcbiAgICAgKiAgICAgVGhlIG5hbWUgb2YgdGhlIHN0cmVhbSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgZ2l2ZW4gY2FsbGJhY2suXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcclxuICAgICAqICAgICBUaGUgY2FsbGJhY2sgdG8gYWRkIHRvIHRoZSBxdWV1ZSBvZiB0aGUgc3RyZWFtIHdpdGggdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgKi9cclxuICAgIHZhciBlbnF1ZXVlQm9keUNhbGxiYWNrID0gZnVuY3Rpb24gZW5xdWV1ZUJvZHlDYWxsYmFjayhuYW1lLCBjYWxsYmFjaykge1xyXG5cclxuICAgICAgICAvLyBHZXQgY2FsbGJhY2sgcXVldWUgYnkgbmFtZSwgY3JlYXRpbmcgZmlyc3QgaWYgbmVjZXNzYXJ5XHJcbiAgICAgICAgdmFyIGNhbGxiYWNrcyA9IGJvZHlDYWxsYmFja3NbbmFtZV07XHJcbiAgICAgICAgaWYgKCFjYWxsYmFja3MpIHtcclxuICAgICAgICAgICAgY2FsbGJhY2tzID0gW107XHJcbiAgICAgICAgICAgIGJvZHlDYWxsYmFja3NbbmFtZV0gPSBjYWxsYmFja3M7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBBZGQgY2FsbGJhY2sgdG8gZW5kIG9mIHF1ZXVlXHJcbiAgICAgICAgY2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgaW5kZXggb2YgdGhpcyBvYmplY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGVkIHdoZW4gdGhpcyBvYmplY3QgcmVjZWl2ZXMgdGhlIGJvZHkgb2YgYSByZXF1ZXN0ZWQgaW5wdXQgc3RyZWFtLlxyXG4gICAgICogQnkgZGVmYXVsdCwgYWxsIG9iamVjdHMgd2lsbCBpbnZva2UgdGhlIGNhbGxiYWNrcyBwcm92aWRlZCB0byB0aGVpclxyXG4gICAgICogcmVxdWVzdElucHV0U3RyZWFtKCkgZnVuY3Rpb25zIGJhc2VkIG9uIHRoZSBuYW1lIG9mIHRoZSBzdHJlYW1cclxuICAgICAqIHJlcXVlc3RlZC4gVGhpcyBiZWhhdmlvciBjYW4gYmUgb3ZlcnJpZGRlbiBieSBzcGVjaWZ5aW5nIGEgZGlmZmVyZW50XHJcbiAgICAgKiBoYW5kbGVyIGhlcmUuXHJcbiAgICAgKlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5JbnB1dFN0cmVhbX0gaW5wdXRTdHJlYW1cclxuICAgICAqICAgICBUaGUgaW5wdXQgc3RyZWFtIG9mIHRoZSByZWNlaXZlZCBib2R5LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZVxyXG4gICAgICogICAgIFRoZSBtaW1ldHlwZSBvZiB0aGUgZGF0YSBiZWluZyByZWNlaXZlZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gICAgICogICAgIFRoZSBuYW1lIG9mIHRoZSBzdHJlYW0gd2hvc2UgYm9keSBoYXMgYmVlbiByZWNlaXZlZC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmJvZHkgPSBmdW5jdGlvbiBkZWZhdWx0Qm9keUhhbmRsZXIoaW5wdXRTdHJlYW0sIG1pbWV0eXBlLCBuYW1lKSB7XHJcblxyXG4gICAgICAgIC8vIENhbGwgcXVldWVkIGNhbGxiYWNrIGZvciB0aGUgcmVjZWl2ZWQgYm9keSwgaWYgYW55XHJcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gZGVxdWV1ZUJvZHlDYWxsYmFjayhuYW1lKTtcclxuICAgICAgICBpZiAoY2FsbGJhY2spXHJcbiAgICAgICAgICAgIGNhbGxiYWNrKGlucHV0U3RyZWFtLCBtaW1ldHlwZSk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxlZCB3aGVuIHRoaXMgb2JqZWN0IGlzIGJlaW5nIHVuZGVmaW5lZC4gT25jZSB1bmRlZmluZWQsIG5vIGZ1cnRoZXJcclxuICAgICAqIGNvbW11bmljYXRpb24gaW52b2x2aW5nIHRoaXMgb2JqZWN0IG1heSBvY2N1ci5cclxuICAgICAqIFxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKi9cclxuICAgIHRoaXMub251bmRlZmluZSA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXF1ZXN0cyByZWFkIGFjY2VzcyB0byB0aGUgaW5wdXQgc3RyZWFtIGhhdmluZyB0aGUgZ2l2ZW4gbmFtZS4gSWZcclxuICAgICAqIHN1Y2Nlc3NmdWwsIGEgbmV3IGlucHV0IHN0cmVhbSB3aWxsIGJlIGNyZWF0ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcclxuICAgICAqICAgICBUaGUgbmFtZSBvZiB0aGUgaW5wdXQgc3RyZWFtIHRvIHJlcXVlc3QuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2JvZHlDYWxsYmFja11cclxuICAgICAqICAgICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIGJvZHkgb2YgdGhlIHJlcXVlc3RlZCBpbnB1dCBzdHJlYW1cclxuICAgICAqICAgICBpcyByZWNlaXZlZC4gVGhpcyBjYWxsYmFjayB3aWxsIGJlIHByb3ZpZGVkIGEgR3VhY2Ftb2xlLklucHV0U3RyZWFtXHJcbiAgICAgKiAgICAgYW5kIGl0cyBtaW1ldHlwZSBhcyBpdHMgdHdvIG9ubHkgYXJndW1lbnRzLiBJZiB0aGUgb25ib2R5IGhhbmRsZXIgb2ZcclxuICAgICAqICAgICB0aGlzIG9iamVjdCBpcyBvdmVycmlkZGVuLCB0aGlzIGNhbGxiYWNrIHdpbGwgbm90IGJlIGludm9rZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVxdWVzdElucHV0U3RyZWFtID0gZnVuY3Rpb24gcmVxdWVzdElucHV0U3RyZWFtKG5hbWUsIGJvZHlDYWxsYmFjaykge1xyXG5cclxuICAgICAgICAvLyBRdWV1ZSBib2R5IGNhbGxiYWNrIGlmIHByb3ZpZGVkXHJcbiAgICAgICAgaWYgKGJvZHlDYWxsYmFjaylcclxuICAgICAgICAgICAgZW5xdWV1ZUJvZHlDYWxsYmFjayhuYW1lLCBib2R5Q2FsbGJhY2spO1xyXG5cclxuICAgICAgICAvLyBTZW5kIHJlcXVlc3QgZm9yIGlucHV0IHN0cmVhbVxyXG4gICAgICAgIGNsaWVudC5yZXF1ZXN0T2JqZWN0SW5wdXRTdHJlYW0oZ3VhY09iamVjdC5pbmRleCwgbmFtZSk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgb3V0cHV0IHN0cmVhbSBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QgYW5kIGhhdmluZyB0aGVcclxuICAgICAqIGdpdmVuIG1pbWV0eXBlIGFuZCBuYW1lLiBUaGUgbGVnYWxpdHkgb2YgYSBtaW1ldHlwZSBhbmQgbmFtZSBpcyBkaWN0YXRlZFxyXG4gICAgICogYnkgdGhlIG9iamVjdCBpdHNlbGYuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1pbWV0eXBlXHJcbiAgICAgKiAgICAgVGhlIG1pbWV0eXBlIG9mIHRoZSBkYXRhIHdoaWNoIHdpbGwgYmUgc2VudCB0byB0aGUgb3V0cHV0IHN0cmVhbS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gICAgICogICAgIFRoZSBkZWZpbmVkIG5hbWUgb2YgYW4gb3V0cHV0IHN0cmVhbSB3aXRoaW4gdGhpcyBvYmplY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0d1YWNhbW9sZS5PdXRwdXRTdHJlYW19XHJcbiAgICAgKiAgICAgQW4gb3V0cHV0IHN0cmVhbSB3aGljaCB3aWxsIHdyaXRlIGJsb2JzIHRvIHRoZSBuYW1lZCBvdXRwdXQgc3RyZWFtXHJcbiAgICAgKiAgICAgb2YgdGhpcyBvYmplY3QuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY3JlYXRlT3V0cHV0U3RyZWFtID0gZnVuY3Rpb24gY3JlYXRlT3V0cHV0U3RyZWFtKG1pbWV0eXBlLCBuYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIGNsaWVudC5jcmVhdGVPYmplY3RPdXRwdXRTdHJlYW0oZ3VhY09iamVjdC5pbmRleCwgbWltZXR5cGUsIG5hbWUpO1xyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogVGhlIHJlc2VydmVkIG5hbWUgZGVub3RpbmcgdGhlIHJvb3Qgc3RyZWFtIG9mIGFueSBvYmplY3QuIFRoZSBjb250ZW50cyBvZlxyXG4gKiB0aGUgcm9vdCBzdHJlYW0gTVVTVCBiZSBhIEpTT04gbWFwIG9mIHN0cmVhbSBuYW1lIHRvIG1pbWV0eXBlLlxyXG4gKlxyXG4gKiBAY29uc3RhbnRcclxuICogQHR5cGUge1N0cmluZ31cclxuICovXHJcbkd1YWNhbW9sZS5PYmplY3QuUk9PVF9TVFJFQU0gPSAnLyc7XHJcblxyXG4vKipcclxuICogVGhlIG1pbWV0eXBlIG9mIGEgc3RyZWFtIGNvbnRhaW5pbmcgSlNPTiB3aGljaCBtYXBzIGF2YWlsYWJsZSBzdHJlYW0gbmFtZXNcclxuICogdG8gdGhlaXIgY29ycmVzcG9uZGluZyBtaW1ldHlwZS4gVGhlIHJvb3Qgc3RyZWFtIG9mIGEgR3VhY2Ftb2xlLk9iamVjdCBNVVNUXHJcbiAqIGhhdmUgdGhpcyBtaW1ldHlwZS5cclxuICpcclxuICogQGNvbnN0YW50XHJcbiAqIEB0eXBlIHtTdHJpbmd9XHJcbiAqL1xyXG5HdWFjYW1vbGUuT2JqZWN0LlNUUkVBTV9JTkRFWF9NSU1FVFlQRSA9ICdhcHBsaWNhdGlvbi92bmQuZ2x5cHRvZG9uLmd1YWNhbW9sZS5zdHJlYW0taW5kZXgranNvbic7XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogRHluYW1pYyBvbi1zY3JlZW4ga2V5Ym9hcmQuIEdpdmVuIHRoZSBsYXlvdXQgb2JqZWN0IGZvciBhbiBvbi1zY3JlZW5cclxuICoga2V5Ym9hcmQsIHRoaXMgb2JqZWN0IHdpbGwgY29uc3RydWN0IGEgY2xpY2thYmxlIG9uLXNjcmVlbiBrZXlib2FyZCB3aXRoIGl0c1xyXG4gKiBvd24ga2V5IGV2ZW50cy5cclxuICpcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmQuTGF5b3V0fSBsYXlvdXRcclxuICogICAgIFRoZSBsYXlvdXQgb2YgdGhlIG9uLXNjcmVlbiBrZXlib2FyZCB0byBkaXNwbGF5LlxyXG4gKi9cclxuR3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmQgPSBmdW5jdGlvbihsYXlvdXQpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmR9XHJcbiAgICAgKi9cclxuICAgIHZhciBvc2sgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFwIG9mIGN1cnJlbnRseS1zZXQgbW9kaWZpZXJzIHRvIHRoZSBrZXlzeW0gYXNzb2NpYXRlZCB3aXRoIHRoZWlyXHJcbiAgICAgKiBvcmlnaW5hbCBwcmVzcy4gV2hlbiB0aGUgbW9kaWZpZXIgaXMgY2xlYXJlZCwgdGhpcyBrZXlzeW0gbXVzdCBiZVxyXG4gICAgICogcmVsZWFzZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtPYmplY3QuPFN0cmluZywgTnVtYmVyPn1cclxuICAgICAqL1xyXG4gICAgdmFyIG1vZGlmaWVyS2V5c3ltcyA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFwIG9mIGFsbCBrZXkgbmFtZXMgdG8gdGhlaXIgY3VycmVudCBwcmVzc2VkIHN0YXRlcy4gSWYgYSBrZXkgaXMgbm90XHJcbiAgICAgKiBwcmVzc2VkLCBpdCBtYXkgbm90IGJlIGluIHRoaXMgbWFwIGF0IGFsbCwgYnV0IGFsbCBwcmVzc2VkIGtleXMgd2lsbFxyXG4gICAgICogaGF2ZSBhIGNvcnJlc3BvbmRpbmcgbWFwcGluZyB0byB0cnVlLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0LjxTdHJpbmcsIEJvb2xlYW4+fVxyXG4gICAgICovXHJcbiAgICB2YXIgcHJlc3NlZCA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsIHNjYWxhYmxlIGVsZW1lbnRzIHdoaWNoIGFyZSBwYXJ0IG9mIHRoZSBvbi1zY3JlZW4ga2V5Ym9hcmQuIEVhY2hcclxuICAgICAqIHNjYWxhYmxlIGVsZW1lbnQgaXMgY2FyZWZ1bGx5IGNvbnRyb2xsZWQgdG8gZW5zdXJlIHRoZSBpbnRlcmZhY2UgbGF5b3V0XHJcbiAgICAgKiBhbmQgc2l6aW5nIHJlbWFpbnMgY29uc3RhbnQsIGV2ZW4gb24gYnJvd3NlcnMgdGhhdCB3b3VsZCBvdGhlcndpc2VcclxuICAgICAqIGV4cGVyaWVuY2Ugcm91bmRpbmcgZXJyb3IgZHVlIHRvIHVuaXQgY29udmVyc2lvbnMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtTY2FsZWRFbGVtZW50W119XHJcbiAgICAgKi9cclxuICAgIHZhciBzY2FsZWRFbGVtZW50cyA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIENTUyBjbGFzcyB0byBhbiBlbGVtZW50LlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuICAgICAqICAgICBUaGUgZWxlbWVudCB0byBhZGQgYSBjbGFzcyB0by5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gY2xhc3NuYW1lXHJcbiAgICAgKiAgICAgVGhlIG5hbWUgb2YgdGhlIGNsYXNzIHRvIGFkZC5cclxuICAgICAqL1xyXG4gICAgdmFyIGFkZENsYXNzID0gZnVuY3Rpb24gYWRkQ2xhc3MoZWxlbWVudCwgY2xhc3NuYW1lKSB7XHJcblxyXG4gICAgICAgIC8vIElmIGNsYXNzTGlzdCBzdXBwb3J0ZWQsIHVzZSB0aGF0XHJcbiAgICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0KVxyXG4gICAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoY2xhc3NuYW1lKTtcclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBzaW1wbHkgYXBwZW5kIHRoZSBjbGFzc1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgKz0gXCIgXCIgKyBjbGFzc25hbWU7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYSBDU1MgY2xhc3MgZnJvbSBhbiBlbGVtZW50LlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuICAgICAqICAgICBUaGUgZWxlbWVudCB0byByZW1vdmUgYSBjbGFzcyBmcm9tLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjbGFzc25hbWVcclxuICAgICAqICAgICBUaGUgbmFtZSBvZiB0aGUgY2xhc3MgdG8gcmVtb3ZlLlxyXG4gICAgICovXHJcbiAgICB2YXIgcmVtb3ZlQ2xhc3MgPSBmdW5jdGlvbiByZW1vdmVDbGFzcyhlbGVtZW50LCBjbGFzc25hbWUpIHtcclxuXHJcbiAgICAgICAgLy8gSWYgY2xhc3NMaXN0IHN1cHBvcnRlZCwgdXNlIHRoYXRcclxuICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QpXHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShjbGFzc25hbWUpO1xyXG5cclxuICAgICAgICAvLyBPdGhlcndpc2UsIG1hbnVhbGx5IGZpbHRlciBvdXQgY2xhc3NlcyB3aXRoIGdpdmVuIG5hbWVcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKC8oW14gXSspWyBdKi9nLFxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVtb3ZlTWF0Y2hpbmdDbGFzc2VzKG1hdGNoLCB0ZXN0Q2xhc3NuYW1lKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHNhbWUgY2xhc3MsIHJlbW92ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ZXN0Q2xhc3NuYW1lID09PSBjbGFzc25hbWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIGFsbG93XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoO1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ291bnRlciBvZiBtb3VzZSBldmVudHMgdG8gaWdub3JlLiBUaGlzIGRlY3JlbWVudGVkIGJ5IG1vdXNlbW92ZSwgYW5kXHJcbiAgICAgKiB3aGlsZSBub24temVybywgbW91c2UgZXZlbnRzIHdpbGwgaGF2ZSBubyBlZmZlY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBpZ25vcmVNb3VzZSA9IDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJZ25vcmVzIGFsbCBwZW5kaW5nIG1vdXNlIGV2ZW50cyB3aGVuIHRvdWNoIGV2ZW50cyBhcmUgdGhlIGFwcGFyZW50XHJcbiAgICAgKiBzb3VyY2UuIE1vdXNlIGV2ZW50cyBhcmUgaWdub3JlZCB1bnRpbCBhdCBsZWFzdCB0b3VjaE1vdXNlVGhyZXNob2xkXHJcbiAgICAgKiBtb3VzZSBldmVudHMgb2NjdXIgd2l0aG91dCBjb3JyZXNwb25kaW5nIHRvdWNoIGV2ZW50cy5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgaWdub3JlUGVuZGluZ01vdXNlRXZlbnRzID0gZnVuY3Rpb24gaWdub3JlUGVuZGluZ01vdXNlRXZlbnRzKCkge1xyXG4gICAgICAgIGlnbm9yZU1vdXNlID0gb3NrLnRvdWNoTW91c2VUaHJlc2hvbGQ7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gZWxlbWVudCB3aG9zZSBkaW1lbnNpb25zIGFyZSBtYWludGFpbmVkIGFjY29yZGluZyB0byBhbiBhcmJpdHJhcnlcclxuICAgICAqIHNjYWxlLiBUaGUgY29udmVyc2lvbiBmYWN0b3IgZm9yIHRoZXNlIGFyYml0cmFyeSB1bml0cyB0byBwaXhlbHMgaXNcclxuICAgICAqIHByb3ZpZGVkIGxhdGVyIHZpYSBhIGNhbGwgdG8gc2NhbGUoKS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuICAgICAqICAgICBUaGUgZWxlbWVudCB3aG9zZSBzY2FsZSBzaG91bGQgYmUgbWFpbnRhaW5lZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcclxuICAgICAqICAgICBUaGUgd2lkdGggb2YgdGhlIGVsZW1lbnQsIGluIGFyYml0cmFyeSB1bml0cywgcmVsYXRpdmUgdG8gb3RoZXJcclxuICAgICAqICAgICBTY2FsZWRFbGVtZW50cy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XHJcbiAgICAgKiAgICAgVGhlIGhlaWdodCBvZiB0aGUgZWxlbWVudCwgaW4gYXJiaXRyYXJ5IHVuaXRzLCByZWxhdGl2ZSB0byBvdGhlclxyXG4gICAgICogICAgIFNjYWxlZEVsZW1lbnRzLlxyXG4gICAgICogICAgIFxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBbc2NhbGVGb250PWZhbHNlXVxyXG4gICAgICogICAgIFdoZXRoZXIgdGhlIGxpbmUgaGVpZ2h0IGFuZCBmb250IHNpemUgc2hvdWxkIGJlIHNjYWxlZCBhcyB3ZWxsLlxyXG4gICAgICovXHJcbiAgICB2YXIgU2NhbGVkRWxlbWVudCA9IGZ1bmN0aW9uIFNjYWxlZEVsZW1lbnQoZWxlbWVudCwgd2lkdGgsIGhlaWdodCwgc2NhbGVGb250KSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSB3aWR0aCBvZiB0aGlzIFNjYWxlZEVsZW1lbnQsIGluIGFyYml0cmFyeSB1bml0cywgcmVsYXRpdmUgdG9cclxuICAgICAgICAgKiBvdGhlciBTY2FsZWRFbGVtZW50cy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIGhlaWdodCBvZiB0aGlzIFNjYWxlZEVsZW1lbnQsIGluIGFyYml0cmFyeSB1bml0cywgcmVsYXRpdmUgdG9cclxuICAgICAgICAgKiBvdGhlciBTY2FsZWRFbGVtZW50cy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xyXG4gXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVzaXplcyB0aGUgYXNzb2NpYXRlZCBlbGVtZW50LCB1cGRhdGluZyBpdHMgZGltZW5zaW9ucyBhY2NvcmRpbmcgdG9cclxuICAgICAgICAgKiB0aGUgZ2l2ZW4gcGl4ZWxzIHBlciB1bml0LlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IHBpeGVsc1xyXG4gICAgICAgICAqICAgICBUaGUgbnVtYmVyIG9mIHBpeGVscyB0byBhc3NpZ24gcGVyIGFyYml0cmFyeSB1bml0LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuc2NhbGUgPSBmdW5jdGlvbihwaXhlbHMpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFNjYWxlIGVsZW1lbnQgd2lkdGgvaGVpZ2h0XHJcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggID0gKHdpZHRoICAqIHBpeGVscykgKyBcInB4XCI7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gKGhlaWdodCAqIHBpeGVscykgKyBcInB4XCI7XHJcblxyXG4gICAgICAgICAgICAvLyBTY2FsZSBmb250LCBpZiByZXF1ZXN0ZWRcclxuICAgICAgICAgICAgaWYgKHNjYWxlRm9udCkge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5saW5lSGVpZ2h0ID0gKGhlaWdodCAqIHBpeGVscykgKyBcInB4XCI7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlLmZvbnRTaXplICAgPSBwaXhlbHMgKyBcInB4XCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB3aGV0aGVyIGFsbCBtb2RpZmllcnMgaGF2aW5nIHRoZSBnaXZlbiBuYW1lcyBhcmUgY3VycmVudGx5XHJcbiAgICAgKiBhY3RpdmUuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nW119IG5hbWVzXHJcbiAgICAgKiAgICAgVGhlIG5hbWVzIG9mIGFsbCBtb2RpZmllcnMgdG8gdGVzdC5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqICAgICB0cnVlIGlmIGFsbCBzcGVjaWZpZWQgbW9kaWZpZXJzIGFyZSBwcmVzc2VkLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgKi9cclxuICAgIHZhciBtb2RpZmllcnNQcmVzc2VkID0gZnVuY3Rpb24gbW9kaWZpZXJzUHJlc3NlZChuYW1lcykge1xyXG5cclxuICAgICAgICAvLyBJZiBhbnkgcmVxdWlyZWQgbW9kaWZpZXJzIGFyZSBub3QgcHJlc3NlZCwgcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgZm9yICh2YXIgaT0wOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFRlc3Qgd2hldGhlciBjdXJyZW50IG1vZGlmaWVyIGlzIHByZXNzZWRcclxuICAgICAgICAgICAgdmFyIG5hbWUgPSBuYW1lc1tpXTtcclxuICAgICAgICAgICAgaWYgKCEobmFtZSBpbiBtb2RpZmllcktleXN5bXMpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSwgYWxsIHJlcXVpcmVkIG1vZGlmaWVycyBhcmUgcHJlc3NlZFxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBzaW5nbGUgbWF0Y2hpbmcgS2V5IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGtleSBvZiB0aGVcclxuICAgICAqIGdpdmVuIG5hbWUsIHdoZXJlIHRoYXQgS2V5IG9iamVjdCdzIHJlcXVpcmVtZW50cyAoc3VjaCBhcyBwcmVzc2VkXHJcbiAgICAgKiBtb2RpZmllcnMpIGFyZSBhbGwgY3VycmVudGx5IHNhdGlzZmllZC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleU5hbWVcclxuICAgICAqICAgICBUaGUgbmFtZSBvZiB0aGUga2V5IHRvIHJldHJpZXZlLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXl9XHJcbiAgICAgKiAgICAgVGhlIEtleSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLCB3aGVyZSB0aGF0IG9iamVjdCdzXHJcbiAgICAgKiAgICAgcmVxdWlyZW1lbnRzIGFyZSBhbGwgY3VycmVudGx5IHNhdGlzZmllZCwgb3IgbnVsbCBpZiBubyBzdWNoIEtleVxyXG4gICAgICogICAgIGNhbiBiZSBmb3VuZC5cclxuICAgICAqL1xyXG4gICAgdmFyIGdldEFjdGl2ZUtleSA9IGZ1bmN0aW9uIGdldEFjdGl2ZUtleShrZXlOYW1lKSB7XHJcblxyXG4gICAgICAgIC8vIEdldCBrZXkgYXJyYXkgZm9yIGdpdmVuIG5hbWVcclxuICAgICAgICB2YXIga2V5cyA9IG9zay5rZXlzW2tleU5hbWVdO1xyXG4gICAgICAgIGlmICgha2V5cylcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICAgIC8vIEZpbmQgbGFzdCBtYXRjaGluZyBrZXlcclxuICAgICAgICBmb3IgKHZhciBpID0ga2V5cy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IGNhbmRpZGF0ZSBrZXlcclxuICAgICAgICAgICAgdmFyIGNhbmRpZGF0ZSA9IGtleXNbaV07XHJcblxyXG4gICAgICAgICAgICAvLyBJZiBhbGwgcmVxdWlyZWQgbW9kaWZpZXJzIGFyZSBwcmVzc2VkLCB1c2UgdGhhdCBrZXlcclxuICAgICAgICAgICAgaWYgKG1vZGlmaWVyc1ByZXNzZWQoY2FuZGlkYXRlLnJlcXVpcmVzKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBjYW5kaWRhdGU7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTm8gdmFsaWQga2V5XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByZXNzZXMgdGhlIGtleSBoYXZpbmcgdGhlIGdpdmVuIG5hbWUsIHVwZGF0aW5nIHRoZSBhc3NvY2lhdGVkIGtleVxyXG4gICAgICogZWxlbWVudCB3aXRoIHRoZSBcImd1YWMta2V5Ym9hcmQtcHJlc3NlZFwiIENTUyBjbGFzcy4gSWYgdGhlIGtleSBpc1xyXG4gICAgICogYWxyZWFkeSBwcmVzc2VkLCB0aGlzIGZ1bmN0aW9uIGhhcyBubyBlZmZlY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlOYW1lXHJcbiAgICAgKiAgICAgVGhlIG5hbWUgb2YgdGhlIGtleSB0byBwcmVzcy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5RWxlbWVudFxyXG4gICAgICogICAgIFRoZSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5LlxyXG4gICAgICovXHJcbiAgICB2YXIgcHJlc3MgPSBmdW5jdGlvbiBwcmVzcyhrZXlOYW1lLCBrZXlFbGVtZW50KSB7XHJcblxyXG4gICAgICAgIC8vIFByZXNzIGtleSBpZiBub3QgeWV0IHByZXNzZWRcclxuICAgICAgICBpZiAoIXByZXNzZWRba2V5TmFtZV0pIHtcclxuXHJcbiAgICAgICAgICAgIGFkZENsYXNzKGtleUVsZW1lbnQsIFwiZ3VhYy1rZXlib2FyZC1wcmVzc2VkXCIpO1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IGN1cnJlbnQga2V5IGJhc2VkIG9uIG1vZGlmaWVyIHN0YXRlXHJcbiAgICAgICAgICAgIHZhciBrZXkgPSBnZXRBY3RpdmVLZXkoa2V5TmFtZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBVcGRhdGUgbW9kaWZpZXIgc3RhdGVcclxuICAgICAgICAgICAgaWYgKGtleS5tb2RpZmllcikge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIENvbnN0cnVjdCBjbGFzc25hbWUgZm9yIG1vZGlmaWVyXHJcbiAgICAgICAgICAgICAgICB2YXIgbW9kaWZpZXJDbGFzcyA9IFwiZ3VhYy1rZXlib2FyZC1tb2RpZmllci1cIiArIGdldENTU05hbWUoa2V5Lm1vZGlmaWVyKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZXRyaWV2ZSBvcmlnaW5hbGx5LXByZXNzZWQga2V5c3ltLCBpZiBtb2RpZmllciB3YXMgYWxyZWFkeSBwcmVzc2VkXHJcbiAgICAgICAgICAgICAgICB2YXIgb3JpZ2luYWxLZXlzeW0gPSBtb2RpZmllcktleXN5bXNba2V5Lm1vZGlmaWVyXTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBY3RpdmF0ZSBtb2RpZmllciBpZiBub3QgcHJlc3NlZFxyXG4gICAgICAgICAgICAgICAgaWYgKCFvcmlnaW5hbEtleXN5bSkge1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKGtleWJvYXJkLCBtb2RpZmllckNsYXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBtb2RpZmllcktleXN5bXNba2V5Lm1vZGlmaWVyXSA9IGtleS5rZXlzeW07XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2VuZCBrZXkgZXZlbnRcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3NrLm9ua2V5ZG93bilcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3NrLm9ua2V5ZG93bihrZXkua2V5c3ltKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gRGVhY3RpdmF0ZSBpZiBub3QgcHJlc3NlZFxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKGtleWJvYXJkLCBtb2RpZmllckNsYXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgbW9kaWZpZXJLZXlzeW1zW2tleS5tb2RpZmllcl07XHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2VuZCBrZXkgZXZlbnRcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3NrLm9ua2V5dXApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9zay5vbmtleXVwKG9yaWdpbmFsS2V5c3ltKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBJZiBub3QgbW9kaWZpZXIsIHNlbmQga2V5IGV2ZW50IG5vd1xyXG4gICAgICAgICAgICBlbHNlIGlmIChvc2sub25rZXlkb3duKVxyXG4gICAgICAgICAgICAgICAgb3NrLm9ua2V5ZG93bihrZXkua2V5c3ltKTtcclxuXHJcbiAgICAgICAgICAgIC8vIE1hcmsga2V5IGFzIHByZXNzZWRcclxuICAgICAgICAgICAgcHJlc3NlZFtrZXlOYW1lXSA9IHRydWU7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVsZWFzZXMgdGhlIGtleSBoYXZpbmcgdGhlIGdpdmVuIG5hbWUsIHJlbW92aW5nIHRoZVxyXG4gICAgICogXCJndWFjLWtleWJvYXJkLXByZXNzZWRcIiBDU1MgY2xhc3MgZnJvbSB0aGUgYXNzb2NpYXRlZCBlbGVtZW50LiBJZiB0aGVcclxuICAgICAqIGtleSBpcyBhbHJlYWR5IHJlbGVhc2VkLCB0aGlzIGZ1bmN0aW9uIGhhcyBubyBlZmZlY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlOYW1lXHJcbiAgICAgKiAgICAgVGhlIG5hbWUgb2YgdGhlIGtleSB0byByZWxlYXNlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlFbGVtZW50XHJcbiAgICAgKiAgICAgVGhlIGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXkuXHJcbiAgICAgKi9cclxuICAgIHZhciByZWxlYXNlID0gZnVuY3Rpb24gcmVsZWFzZShrZXlOYW1lLCBrZXlFbGVtZW50KSB7XHJcblxyXG4gICAgICAgIC8vIFJlbGVhc2Uga2V5IGlmIGN1cnJlbnRseSBwcmVzc2VkXHJcbiAgICAgICAgaWYgKHByZXNzZWRba2V5TmFtZV0pIHtcclxuXHJcbiAgICAgICAgICAgIHJlbW92ZUNsYXNzKGtleUVsZW1lbnQsIFwiZ3VhYy1rZXlib2FyZC1wcmVzc2VkXCIpO1xyXG5cclxuICAgICAgICAgICAgLy8gR2V0IGN1cnJlbnQga2V5IGJhc2VkIG9uIG1vZGlmaWVyIHN0YXRlXHJcbiAgICAgICAgICAgIHZhciBrZXkgPSBnZXRBY3RpdmVLZXkoa2V5TmFtZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBTZW5kIGtleSBldmVudCBpZiBub3QgYSBtb2RpZmllciBrZXlcclxuICAgICAgICAgICAgaWYgKCFrZXkubW9kaWZpZXIgJiYgb3NrLm9ua2V5dXApXHJcbiAgICAgICAgICAgICAgICBvc2sub25rZXl1cChrZXkua2V5c3ltKTtcclxuXHJcbiAgICAgICAgICAgIC8vIE1hcmsga2V5IGFzIHJlbGVhc2VkXHJcbiAgICAgICAgICAgIHByZXNzZWRba2V5TmFtZV0gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgLy8gQ3JlYXRlIGtleWJvYXJkXHJcbiAgICB2YXIga2V5Ym9hcmQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAga2V5Ym9hcmQuY2xhc3NOYW1lID0gXCJndWFjLWtleWJvYXJkXCI7XHJcblxyXG4gICAgLy8gRG8gbm90IGFsbG93IHNlbGVjdGlvbiBvciBtb3VzZSBtb3ZlbWVudCB0byBwcm9wYWdhdGUvcmVnaXN0ZXIuXHJcbiAgICBrZXlib2FyZC5vbnNlbGVjdHN0YXJ0ID1cclxuICAgIGtleWJvYXJkLm9ubW91c2Vtb3ZlICAgPVxyXG4gICAga2V5Ym9hcmQub25tb3VzZXVwICAgICA9XHJcbiAgICBrZXlib2FyZC5vbm1vdXNlZG93biAgID0gZnVuY3Rpb24gaGFuZGxlTW91c2VFdmVudHMoZSkge1xyXG5cclxuICAgICAgICAvLyBJZiBpZ25vcmluZyBldmVudHMsIGRlY3JlbWVudCBjb3VudGVyXHJcbiAgICAgICAgaWYgKGlnbm9yZU1vdXNlKVxyXG4gICAgICAgICAgICBpZ25vcmVNb3VzZS0tO1xyXG5cclxuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG51bWJlciBvZiBtb3VzZW1vdmUgZXZlbnRzIHRvIHJlcXVpcmUgYmVmb3JlIHJlLWVuYWJsaW5nIG1vdXNlXHJcbiAgICAgKiBldmVudCBoYW5kbGluZyBhZnRlciByZWNlaXZpbmcgYSB0b3VjaCBldmVudC5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLnRvdWNoTW91c2VUaHJlc2hvbGQgPSAzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgdGhlIHVzZXIgcHJlc3NlcyBhIGtleSBvbiB0aGlzIEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBrZXlzeW0gVGhlIGtleXN5bSBvZiB0aGUga2V5IGJlaW5nIHByZXNzZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25rZXlkb3duID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIHRoZSB1c2VyIHJlbGVhc2VzIGEga2V5IG9uIHRoaXMgR3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGtleXN5bSBUaGUga2V5c3ltIG9mIHRoZSBrZXkgYmVpbmcgcmVsZWFzZWQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25rZXl1cCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUga2V5Ym9hcmQgbGF5b3V0IHByb3ZpZGVkIGF0IHRpbWUgb2YgY29uc3RydWN0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5MYXlvdXR9XHJcbiAgICAgKi9cclxuICAgIHRoaXMubGF5b3V0ID0gbmV3IEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLkxheW91dChsYXlvdXQpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBjb250YWluaW5nIHRoZSBlbnRpcmUgb24tc2NyZWVuIGtleWJvYXJkLlxyXG4gICAgICogQHJldHVybnMge0VsZW1lbnR9IFRoZSBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGVudGlyZSBvbi1zY3JlZW4ga2V5Ym9hcmQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZ2V0RWxlbWVudCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBrZXlib2FyZDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXNpemVzIGFsbCBlbGVtZW50cyB3aXRoaW4gdGhpcyBHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZCBzdWNoIHRoYXRcclxuICAgICAqIHRoZSB3aWR0aCBpcyBjbG9zZSB0byBidXQgZG9lcyBub3QgZXhjZWVkIHRoZSBzcGVjaWZpZWQgd2lkdGguIFRoZVxyXG4gICAgICogaGVpZ2h0IG9mIHRoZSBrZXlib2FyZCBpcyBkZXRlcm1pbmVkIGJhc2VkIG9uIHRoZSB3aWR0aC5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoIFRoZSB3aWR0aCB0byByZXNpemUgdGhpcyBHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZFxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgIHRvLCBpbiBwaXhlbHMuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVzaXplID0gZnVuY3Rpb24od2lkdGgpIHtcclxuXHJcbiAgICAgICAgLy8gR2V0IHBpeGVsIHNpemUgb2YgYSB1bml0XHJcbiAgICAgICAgdmFyIHVuaXQgPSBNYXRoLmZsb29yKHdpZHRoICogMTAgLyBvc2subGF5b3V0LndpZHRoKSAvIDEwO1xyXG5cclxuICAgICAgICAvLyBSZXNpemUgYWxsIHNjYWxlZCBlbGVtZW50c1xyXG4gICAgICAgIGZvciAodmFyIGk9MDsgaTxzY2FsZWRFbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgc2NhbGVkRWxlbWVudCA9IHNjYWxlZEVsZW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBzY2FsZWRFbGVtZW50LnNjYWxlKHVuaXQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2l2ZW4gdGhlIG5hbWUgb2YgYSBrZXkgYW5kIGl0cyBjb3JyZXNwb25kaW5nIGRlZmluaXRpb24sIHdoaWNoIG1heSBiZVxyXG4gICAgICogYW4gYXJyYXkgb2Yga2V5cyBvYmplY3RzLCBhIG51bWJlciAoa2V5c3ltKSwgYSBzdHJpbmcgKGtleSB0aXRsZSksIG9yIGFcclxuICAgICAqIHNpbmdsZSBrZXkgb2JqZWN0LCByZXR1cm5zIGFuIGFycmF5IG9mIGtleSBvYmplY3RzLCBkZXJpdmluZyBhbnkgbWlzc2luZ1xyXG4gICAgICogcHJvcGVydGllcyBhcyBuZWVkZWQsIGFuZCBlbnN1cmluZyB0aGUga2V5IG5hbWUgaXMgZGVmaW5lZC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcclxuICAgICAqICAgICBUaGUgbmFtZSBvZiB0aGUga2V5IGJlaW5nIGNvZXJjZWQgaW50byBhbiBhcnJheSBvZiBLZXkgb2JqZWN0cy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcnxTdHJpbmd8R3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmQuS2V5fEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLktleVtdfSBvYmplY3RcclxuICAgICAqICAgICBUaGUgb2JqZWN0IGRlZmluaW5nIHRoZSBiZWhhdmlvciBvZiB0aGUga2V5IGhhdmluZyB0aGUgZ2l2ZW4gbmFtZSxcclxuICAgICAqICAgICB3aGljaCBtYXkgYmUgdGhlIHRpdGxlIG9mIHRoZSBrZXkgKGEgc3RyaW5nKSwgdGhlIGtleXN5bSAoYSBudW1iZXIpLFxyXG4gICAgICogICAgIGEgc2luZ2xlIEtleSBvYmplY3QsIG9yIGFuIGFycmF5IG9mIEtleSBvYmplY3RzLlxyXG4gICAgICogICAgIFxyXG4gICAgICogQHJldHVybnMge0d1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLktleVtdfVxyXG4gICAgICogICAgIEFuIGFycmF5IG9mIGFsbCBrZXlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cclxuICAgICAqL1xyXG4gICAgdmFyIGFzS2V5QXJyYXkgPSBmdW5jdGlvbiBhc0tleUFycmF5KG5hbWUsIG9iamVjdCkge1xyXG5cclxuICAgICAgICAvLyBJZiBhbHJlYWR5IGFuIGFycmF5LCBqdXN0IGNvZXJjZSBpbnRvIGEgdHJ1ZSBLZXlbXSBcclxuICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgICAgdmFyIGtleXMgPSBbXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBrZXlzLnB1c2gobmV3IEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLktleShvYmplY3RbaV0sIG5hbWUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4ga2V5cztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIERlcml2ZSBrZXkgb2JqZWN0IGZyb20ga2V5c3ltIGlmIHRoYXQncyBhbGwgd2UgaGF2ZVxyXG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICByZXR1cm4gW25ldyBHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXkoe1xyXG4gICAgICAgICAgICAgICAgbmFtZSAgIDogbmFtZSxcclxuICAgICAgICAgICAgICAgIGtleXN5bSA6IG9iamVjdFxyXG4gICAgICAgICAgICB9KV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEZXJpdmUga2V5IG9iamVjdCBmcm9tIHRpdGxlIGlmIHRoYXQncyBhbGwgd2UgaGF2ZVxyXG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICByZXR1cm4gW25ldyBHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXkoe1xyXG4gICAgICAgICAgICAgICAgbmFtZSAgOiBuYW1lLFxyXG4gICAgICAgICAgICAgICAgdGl0bGUgOiBvYmplY3RcclxuICAgICAgICAgICAgfSldO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBhc3N1bWUgaXQncyBhbHJlYWR5IGEga2V5IG9iamVjdCwganVzdCBub3QgYW4gYXJyYXlcclxuICAgICAgICByZXR1cm4gW25ldyBHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXkob2JqZWN0LCBuYW1lKV07XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSByYXRoZXIgZm9yZ2l2aW5nIGtleSBtYXBwaW5nIGFsbG93ZWQgYnlcclxuICAgICAqIEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLkxheW91dCBpbnRvIGEgcmlnb3JvdXMgbWFwcGluZyBvZiBrZXkgbmFtZVxyXG4gICAgICogdG8ga2V5IGRlZmluaXRpb24sIHdoZXJlIHRoZSBrZXkgZGVmaW5pdGlvbiBpcyBhbHdheXMgYW4gYXJyYXkgb2YgS2V5XHJcbiAgICAgKiBvYmplY3RzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdC48U3RyaW5nLCBOdW1iZXJ8U3RyaW5nfEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLktleXxHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXlbXT59IGtleXNcclxuICAgICAqICAgICBBIG1hcHBpbmcgb2Yga2V5IG5hbWUgdG8ga2V5IGRlZmluaXRpb24sIHdoZXJlIHRoZSBrZXkgZGVmaW5pdGlvbiBpc1xyXG4gICAgICogICAgIHRoZSB0aXRsZSBvZiB0aGUga2V5IChhIHN0cmluZyksIHRoZSBrZXlzeW0gKGEgbnVtYmVyKSwgYSBzaW5nbGVcclxuICAgICAqICAgICBLZXkgb2JqZWN0LCBvciBhbiBhcnJheSBvZiBLZXkgb2JqZWN0cy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxTdHJpbmcsIEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLktleVtdPn1cclxuICAgICAqICAgICBBIG1vcmUtcHJlZGljdGFibGUgbWFwcGluZyBvZiBrZXkgbmFtZSB0byBrZXkgZGVmaW5pdGlvbiwgd2hlcmUgdGhlXHJcbiAgICAgKiAgICAga2V5IGRlZmluaXRpb24gaXMgYWx3YXlzIHNpbXBseSBhbiBhcnJheSBvZiBLZXkgb2JqZWN0cy5cclxuICAgICAqL1xyXG4gICAgdmFyIGdldEtleXMgPSBmdW5jdGlvbiBnZXRLZXlzKGtleXMpIHtcclxuXHJcbiAgICAgICAgdmFyIGtleUFycmF5cyA9IHt9O1xyXG5cclxuICAgICAgICAvLyBDb2VyY2UgYWxsIGtleXMgaW50byBpbmRpdmlkdWFsIGtleSBhcnJheXNcclxuICAgICAgICBmb3IgKHZhciBuYW1lIGluIGxheW91dC5rZXlzKSB7XHJcbiAgICAgICAgICAgIGtleUFycmF5c1tuYW1lXSA9IGFzS2V5QXJyYXkobmFtZSwga2V5c1tuYW1lXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ga2V5QXJyYXlzO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXAgb2YgYWxsIGtleSBuYW1lcyB0byB0aGVpciBjb3JyZXNwb25kaW5nIHNldCBvZiBrZXlzLiBFYWNoIGtleSBuYW1lXHJcbiAgICAgKiBtYXkgY29ycmVzcG9uZCB0byBtdWx0aXBsZSBrZXlzIGR1ZSB0byB0aGUgZWZmZWN0IG9mIG1vZGlmaWVycy5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0LjxTdHJpbmcsIEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLktleVtdPn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5rZXlzID0gZ2V0S2V5cyhsYXlvdXQua2V5cyk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHaXZlbiBhbiBhcmJpdHJhcnkgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbmFtZSBvZiBzb21lIGNvbXBvbmVudCBvZiB0aGVcclxuICAgICAqIG9uLXNjcmVlbiBrZXlib2FyZCwgcmV0dXJucyBhIHN0cmluZyBmb3JtYXR0ZWQgZm9yIHVzZSBhcyBhIENTUyBjbGFzc1xyXG4gICAgICogbmFtZS4gVGhlIHJlc3VsdCB3aWxsIGJlIGxvd2VyY2FzZS4gV29yZCBib3VuZGFyaWVzIHByZXZpb3VzbHkgZGVub3RlZFxyXG4gICAgICogYnkgQ2FtZWxDYXNlIHdpbGwgYmUgcmVwbGFjZWQgYnkgaW5kaXZpZHVhbCBoeXBoZW5zLCBhcyB3aWxsIGFsbFxyXG4gICAgICogY29udGlndW91cyBub24tYWxwaGFudW1lcmljIGNoYXJhY3RlcnMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXHJcbiAgICAgKiAgICAgQW4gYXJiaXRyYXJ5IHN0cmluZyByZXByZXNlbnRpbmcgdGhlIG5hbWUgb2Ygc29tZSBjb21wb25lbnQgb2YgdGhlXHJcbiAgICAgKiAgICAgb24tc2NyZWVuIGtleWJvYXJkLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9XHJcbiAgICAgKiAgICAgQSBzdHJpbmcgZm9ybWF0dGVkIGZvciB1c2UgYXMgYSBDU1MgY2xhc3MgbmFtZS5cclxuICAgICAqL1xyXG4gICAgdmFyIGdldENTU05hbWUgPSBmdW5jdGlvbiBnZXRDU1NOYW1lKG5hbWUpIHtcclxuXHJcbiAgICAgICAgLy8gQ29udmVydCBuYW1lIGZyb20gcG9zc2libHktQ2FtZWxDYXNlIHRvIGh5cGhlbmF0ZWQgbG93ZXJjYXNlXHJcbiAgICAgICAgdmFyIGNzc05hbWUgPSBuYW1lXHJcbiAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCAnJDEtJDInKVxyXG4gICAgICAgICAgICAgICAucmVwbGFjZSgvW15BLVphLXowLTldKy9nLCAnLScpXHJcbiAgICAgICAgICAgICAgIC50b0xvd2VyQ2FzZSgpO1xyXG5cclxuICAgICAgICByZXR1cm4gY3NzTmFtZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwZW5kcyBET00gZWxlbWVudHMgdG8gdGhlIGdpdmVuIGVsZW1lbnQgYXMgZGljdGF0ZWQgYnkgdGhlIGxheW91dFxyXG4gICAgICogc3RydWN0dXJlIG9iamVjdCBwcm92aWRlZC4gSWYgYSBuYW1lIGlzIHByb3ZpZGVkLCBhbiBhZGRpdGlvbmFsIENTU1xyXG4gICAgICogY2xhc3MsIHByZXBlbmRlZCB3aXRoIFwiZ3VhYy1rZXlib2FyZC1cIiwgd2lsbCBiZSBhZGRlZCB0byB0aGUgdG9wLWxldmVsXHJcbiAgICAgKiBlbGVtZW50LlxyXG4gICAgICogXHJcbiAgICAgKiBJZiB0aGUgbGF5b3V0IHN0cnVjdHVyZSBvYmplY3QgaXMgYW4gYXJyYXksIGFsbCBlbGVtZW50cyB3aXRoaW4gdGhhdFxyXG4gICAgICogYXJyYXkgd2lsbCBiZSByZWN1cnNpdmVseSBhcHBlbmRlZCBhcyBjaGlsZHJlbiBvZiBhIGdyb3VwLCBhbmQgdGhlXHJcbiAgICAgKiB0b3AtbGV2ZWwgZWxlbWVudCB3aWxsIGJlIGdpdmVuIHRoZSBDU1MgY2xhc3MgXCJndWFjLWtleWJvYXJkLWdyb3VwXCIuXHJcbiAgICAgKlxyXG4gICAgICogSWYgdGhlIGxheW91dCBzdHJ1Y3R1cmUgb2JqZWN0IGlzIGFuIG9iamVjdCwgYWxsIHByb3BlcnRpZXMgd2l0aGluIHRoYXRcclxuICAgICAqIG9iamVjdCB3aWxsIGJlIHJlY3Vyc2l2ZWx5IGFwcGVuZGVkIGFzIGNoaWxkcmVuIG9mIGEgZ3JvdXAsIGFuZCB0aGVcclxuICAgICAqIHRvcC1sZXZlbCBlbGVtZW50IHdpbGwgYmUgZ2l2ZW4gdGhlIENTUyBjbGFzcyBcImd1YWMta2V5Ym9hcmQtZ3JvdXBcIi4gVGhlXHJcbiAgICAgKiBuYW1lIG9mIGVhY2ggcHJvcGVydHkgd2lsbCBiZSBhcHBsaWVkIGFzIHRoZSBuYW1lIG9mIGVhY2ggY2hpbGQgb2JqZWN0XHJcbiAgICAgKiBmb3IgdGhlIHNha2Ugb2YgQ1NTLiBFYWNoIHByb3BlcnR5IHdpbGwgYmUgYWRkZWQgaW4gc29ydGVkIG9yZGVyLlxyXG4gICAgICpcclxuICAgICAqIElmIHRoZSBsYXlvdXQgc3RydWN0dXJlIG9iamVjdCBpcyBhIHN0cmluZywgdGhlIGtleSBoYXZpbmcgdGhhdCBuYW1lXHJcbiAgICAgKiB3aWxsIGJlIGFwcGVuZGVkLiBUaGUga2V5IHdpbGwgYmUgZ2l2ZW4gdGhlIENTUyBjbGFzc1xyXG4gICAgICogXCJndWFjLWtleWJvYXJkLWtleVwiIGFuZCBcImd1YWMta2V5Ym9hcmQta2V5LU5BTUVcIiwgd2hlcmUgTkFNRSBpcyB0aGUgbmFtZVxyXG4gICAgICogb2YgdGhlIGtleS4gSWYgdGhlIG5hbWUgb2YgdGhlIGtleSBpcyBhIHNpbmdsZSBjaGFyYWN0ZXIsIHRoaXMgd2lsbFxyXG4gICAgICogZmlyc3QgYmUgdHJhbnNmb3JtZWQgaW50byB0aGUgQy1zdHlsZSBoZXhhZGVjaW1hbCBsaXRlcmFsIGZvciB0aGVcclxuICAgICAqIFVuaWNvZGUgY29kZXBvaW50IG9mIHRoYXQgY2hhcmFjdGVyLiBGb3IgZXhhbXBsZSwgdGhlIGtleSBcIkFcIiB3b3VsZFxyXG4gICAgICogYmVjb21lIFwiZ3VhYy1rZXlib2FyZC1rZXktMHg0MVwiLlxyXG4gICAgICogXHJcbiAgICAgKiBJZiB0aGUgbGF5b3V0IHN0cnVjdHVyZSBvYmplY3QgaXMgYSBudW1iZXIsIGEgZ2FwIG9mIHRoYXQgc2l6ZSB3aWxsIGJlXHJcbiAgICAgKiBpbnNlcnRlZC4gVGhlIGdhcCB3aWxsIGJlIGdpdmVuIHRoZSBDU1MgY2xhc3MgXCJndWFjLWtleWJvYXJkLWdhcFwiLCBhbmRcclxuICAgICAqIHdpbGwgYmUgc2NhbGVkIGFjY29yZGluZyB0byB0aGUgc2FtZSBzaXplIHVuaXRzIGFzIGVhY2gga2V5LlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcclxuICAgICAqICAgICBUaGUgZWxlbWVudCB0byBhcHBlbmQgZWxlbWVudHMgdG8uXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8U3RyaW5nfE51bWJlcn0gb2JqZWN0XHJcbiAgICAgKiAgICAgVGhlIGxheW91dCBzdHJ1Y3R1cmUgb2JqZWN0IHRvIHVzZSB3aGVuIGNvbnN0cnVjdGluZyB0aGUgZWxlbWVudHMgdG9cclxuICAgICAqICAgICBhcHBlbmQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IFtuYW1lXVxyXG4gICAgICogICAgIFRoZSBuYW1lIG9mIHRoZSB0b3AtbGV2ZWwgZWxlbWVudCBiZWluZyBhcHBlbmRlZCwgaWYgYW55LlxyXG4gICAgICovXHJcbiAgICB2YXIgYXBwZW5kRWxlbWVudHMgPSBmdW5jdGlvbiBhcHBlbmRFbGVtZW50cyhlbGVtZW50LCBvYmplY3QsIG5hbWUpIHtcclxuXHJcbiAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBkaXYgd2hpY2ggd2lsbCBiZWNvbWUgdGhlIGdyb3VwIG9yIGtleVxyXG4gICAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuXHJcbiAgICAgICAgLy8gQWRkIGNsYXNzIGJhc2VkIG9uIG5hbWUsIGlmIG5hbWUgZ2l2ZW5cclxuICAgICAgICBpZiAobmFtZSlcclxuICAgICAgICAgICAgYWRkQ2xhc3MoZGl2LCAnZ3VhYy1rZXlib2FyZC0nICsgZ2V0Q1NTTmFtZShuYW1lKSk7XHJcblxyXG4gICAgICAgIC8vIElmIGFuIGFycmF5LCBhcHBlbmQgZWFjaCBlbGVtZW50XHJcbiAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XHJcblxyXG4gICAgICAgICAgICAvLyBBZGQgZ3JvdXAgY2xhc3NcclxuICAgICAgICAgICAgYWRkQ2xhc3MoZGl2LCAnZ3VhYy1rZXlib2FyZC1ncm91cCcpO1xyXG5cclxuICAgICAgICAgICAgLy8gQXBwZW5kIGFsbCBlbGVtZW50cyBvZiBhcnJheVxyXG4gICAgICAgICAgICBmb3IgKGk9MDsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgIGFwcGVuZEVsZW1lbnRzKGRpdiwgb2JqZWN0W2ldKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiBhbiBvYmplY3QsIGFwcGVuZCBlYWNoIHByb3BlcnR5IHZhbHVlXHJcbiAgICAgICAgZWxzZSBpZiAob2JqZWN0IGluc3RhbmNlb2YgT2JqZWN0KSB7XHJcblxyXG4gICAgICAgICAgICAvLyBBZGQgZ3JvdXAgY2xhc3NcclxuICAgICAgICAgICAgYWRkQ2xhc3MoZGl2LCAnZ3VhYy1rZXlib2FyZC1ncm91cCcpO1xyXG5cclxuICAgICAgICAgICAgLy8gQXBwZW5kIGFsbCBjaGlsZHJlbiwgc29ydGVkIGJ5IG5hbWVcclxuICAgICAgICAgICAgdmFyIG5hbWVzID0gT2JqZWN0LmtleXMob2JqZWN0KS5zb3J0KCk7XHJcbiAgICAgICAgICAgIGZvciAoaT0wOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBuYW1lID0gbmFtZXNbaV07XHJcbiAgICAgICAgICAgICAgICBhcHBlbmRFbGVtZW50cyhkaXYsIG9iamVjdFtuYW1lXSwgbmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiBhIG51bWJlciwgY3JlYXRlIGFzIGEgZ2FwIFxyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdudW1iZXInKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBBZGQgZ2FwIGNsYXNzXHJcbiAgICAgICAgICAgIGFkZENsYXNzKGRpdiwgJ2d1YWMta2V5Ym9hcmQtZ2FwJyk7XHJcblxyXG4gICAgICAgICAgICAvLyBNYWludGFpbiBzY2FsZVxyXG4gICAgICAgICAgICBzY2FsZWRFbGVtZW50cy5wdXNoKG5ldyBTY2FsZWRFbGVtZW50KGRpdiwgb2JqZWN0LCBvYmplY3QpKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJZiBhIHN0cmluZywgY3JlYXRlIGFzIGEga2V5XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdCA9PT0gJ3N0cmluZycpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIGtleSBuYW1lIGlzIG9ubHkgb25lIGNoYXJhY3RlciwgdXNlIGNvZGVwb2ludCBmb3IgbmFtZVxyXG4gICAgICAgICAgICB2YXIga2V5TmFtZSA9IG9iamVjdDtcclxuICAgICAgICAgICAgaWYgKGtleU5hbWUubGVuZ3RoID09PSAxKVxyXG4gICAgICAgICAgICAgICAga2V5TmFtZSA9ICcweCcgKyBrZXlOYW1lLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpO1xyXG5cclxuICAgICAgICAgICAgLy8gQWRkIGtleSBjb250YWluZXIgY2xhc3NcclxuICAgICAgICAgICAgYWRkQ2xhc3MoZGl2LCAnZ3VhYy1rZXlib2FyZC1rZXktY29udGFpbmVyJyk7XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGUga2V5IGVsZW1lbnQgd2hpY2ggd2lsbCBjb250YWluIGFsbCBwb3NzaWJsZSBjYXBzXHJcbiAgICAgICAgICAgIHZhciBrZXlFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgICAgIGtleUVsZW1lbnQuY2xhc3NOYW1lID0gJ2d1YWMta2V5Ym9hcmQta2V5ICdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAnZ3VhYy1rZXlib2FyZC1rZXktJyArIGdldENTU05hbWUoa2V5TmFtZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBBZGQgYWxsIGFzc29jaWF0ZWQga2V5cyBhcyBjYXBzIHdpdGhpbiBET01cclxuICAgICAgICAgICAgdmFyIGtleXMgPSBvc2sua2V5c1tvYmplY3RdO1xyXG4gICAgICAgICAgICBpZiAoa2V5cykge1xyXG4gICAgICAgICAgICAgICAgZm9yIChpPTA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEdldCBjdXJyZW50IGtleVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgY2FwIGVsZW1lbnQgZm9yIGtleVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYXBFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FwRWxlbWVudC5jbGFzc05hbWUgICA9ICdndWFjLWtleWJvYXJkLWNhcCc7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FwRWxlbWVudC50ZXh0Q29udGVudCA9IGtleS50aXRsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGNsYXNzZXMgZm9yIGFueSByZXF1aXJlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqPTA7IGogPCBrZXkucmVxdWlyZXMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlcXVpcmVtZW50ID0ga2V5LnJlcXVpcmVzW2pdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhjYXBFbGVtZW50LCAnZ3VhYy1rZXlib2FyZC1yZXF1aXJlcy0nICsgZ2V0Q1NTTmFtZShyZXF1aXJlbWVudCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhrZXlFbGVtZW50LCAnZ3VhYy1rZXlib2FyZC11c2VzLScgICAgICsgZ2V0Q1NTTmFtZShyZXF1aXJlbWVudCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGNhcCB0byBrZXkgd2l0aGluIERPTVxyXG4gICAgICAgICAgICAgICAgICAgIGtleUVsZW1lbnQuYXBwZW5kQ2hpbGQoY2FwRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBBZGQga2V5IHRvIERPTSwgbWFpbnRhaW4gc2NhbGVcclxuICAgICAgICAgICAgZGl2LmFwcGVuZENoaWxkKGtleUVsZW1lbnQpO1xyXG4gICAgICAgICAgICBzY2FsZWRFbGVtZW50cy5wdXNoKG5ldyBTY2FsZWRFbGVtZW50KGRpdiwgb3NrLmxheW91dC5rZXlXaWR0aHNbb2JqZWN0XSB8fCAxLCAxLCB0cnVlKSk7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSGFuZGxlcyBhIHRvdWNoIGV2ZW50IHdoaWNoIHJlc3VsdHMgaW4gdGhlIHByZXNzaW5nIG9mIGFuIE9TS1xyXG4gICAgICAgICAgICAgKiBrZXkuIFRvdWNoIGV2ZW50cyB3aWxsIHJlc3VsdCBpbiBtb3VzZSBldmVudHMgYmVpbmcgaWdub3JlZCBmb3JcclxuICAgICAgICAgICAgICogdG91Y2hNb3VzZVRocmVzaG9sZCBldmVudHMuXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7VG91Y2hFdmVudH0gZVxyXG4gICAgICAgICAgICAgKiAgICAgVGhlIHRvdWNoIGV2ZW50IGJlaW5nIGhhbmRsZWQuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB2YXIgdG91Y2hQcmVzcyA9IGZ1bmN0aW9uIHRvdWNoUHJlc3MoZSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgaWdub3JlTW91c2UgPSBvc2sudG91Y2hNb3VzZVRocmVzaG9sZDtcclxuICAgICAgICAgICAgICAgIHByZXNzKG9iamVjdCwga2V5RWxlbWVudCk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSGFuZGxlcyBhIHRvdWNoIGV2ZW50IHdoaWNoIHJlc3VsdHMgaW4gdGhlIHJlbGVhc2Ugb2YgYW4gT1NLXHJcbiAgICAgICAgICAgICAqIGtleS4gVG91Y2ggZXZlbnRzIHdpbGwgcmVzdWx0IGluIG1vdXNlIGV2ZW50cyBiZWluZyBpZ25vcmVkIGZvclxyXG4gICAgICAgICAgICAgKiB0b3VjaE1vdXNlVGhyZXNob2xkIGV2ZW50cy5cclxuICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgICAgICogQHBhcmFtIHtUb3VjaEV2ZW50fSBlXHJcbiAgICAgICAgICAgICAqICAgICBUaGUgdG91Y2ggZXZlbnQgYmVpbmcgaGFuZGxlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHZhciB0b3VjaFJlbGVhc2UgPSBmdW5jdGlvbiB0b3VjaFJlbGVhc2UoZSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgaWdub3JlTW91c2UgPSBvc2sudG91Y2hNb3VzZVRocmVzaG9sZDtcclxuICAgICAgICAgICAgICAgIHJlbGVhc2Uob2JqZWN0LCBrZXlFbGVtZW50KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBIYW5kbGVzIGEgbW91c2UgZXZlbnQgd2hpY2ggcmVzdWx0cyBpbiB0aGUgcHJlc3Npbmcgb2YgYW4gT1NLXHJcbiAgICAgICAgICAgICAqIGtleS4gSWYgbW91c2UgZXZlbnRzIGFyZSBjdXJyZW50bHkgYmVpbmcgaWdub3JlZCwgdGhpcyBoYW5kbGVyXHJcbiAgICAgICAgICAgICAqIGRvZXMgbm90aGluZy5cclxuICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgICAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBlXHJcbiAgICAgICAgICAgICAqICAgICBUaGUgdG91Y2ggZXZlbnQgYmVpbmcgaGFuZGxlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHZhciBtb3VzZVByZXNzID0gZnVuY3Rpb24gbW91c2VQcmVzcyhlKSB7XHJcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaWdub3JlTW91c2UgPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgcHJlc3Mob2JqZWN0LCBrZXlFbGVtZW50KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBIYW5kbGVzIGEgbW91c2UgZXZlbnQgd2hpY2ggcmVzdWx0cyBpbiB0aGUgcmVsZWFzZSBvZiBhbiBPU0tcclxuICAgICAgICAgICAgICoga2V5LiBJZiBtb3VzZSBldmVudHMgYXJlIGN1cnJlbnRseSBiZWluZyBpZ25vcmVkLCB0aGlzIGhhbmRsZXJcclxuICAgICAgICAgICAgICogZG9lcyBub3RoaW5nLlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAgICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGVcclxuICAgICAgICAgICAgICogICAgIFRoZSB0b3VjaCBldmVudCBiZWluZyBoYW5kbGVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdmFyIG1vdXNlUmVsZWFzZSA9IGZ1bmN0aW9uIG1vdXNlUmVsZWFzZShlKSB7XHJcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaWdub3JlTW91c2UgPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZShvYmplY3QsIGtleUVsZW1lbnQpO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLy8gSGFuZGxlIHRvdWNoIGV2ZW50cyBvbiBrZXlcclxuICAgICAgICAgICAga2V5RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0b3VjaFByZXNzLCAgIHRydWUpO1xyXG4gICAgICAgICAgICBrZXlFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCAgIHRvdWNoUmVsZWFzZSwgdHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBIYW5kbGUgbW91c2UgZXZlbnRzIG9uIGtleVxyXG4gICAgICAgICAgICBrZXlFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgbW91c2VQcmVzcywgICB0cnVlKTtcclxuICAgICAgICAgICAga2V5RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCAgIG1vdXNlUmVsZWFzZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGtleUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3V0XCIsICBtb3VzZVJlbGVhc2UsIHRydWUpO1xyXG5cclxuICAgICAgICB9IC8vIGVuZCBpZiBvYmplY3QgaXMga2V5IG5hbWVcclxuXHJcbiAgICAgICAgLy8gQWRkIG5ld2x5LWNyZWF0ZWQgZ3JvdXAva2V5XHJcbiAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChkaXYpO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLy8gQ3JlYXRlIGtleWJvYXJkIGxheW91dCBpbiBET01cclxuICAgIGFwcGVuZEVsZW1lbnRzKGtleWJvYXJkLCBsYXlvdXQubGF5b3V0KTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogUmVwcmVzZW50cyBhbiBlbnRpcmUgb24tc2NyZWVuIGtleWJvYXJkIGxheW91dCwgaW5jbHVkaW5nIGFsbCBhdmFpbGFibGVcclxuICoga2V5cywgdGhlaXIgYmVoYXZpb3JzLCBhbmQgdGhlaXIgcmVsYXRpdmUgcG9zaXRpb24gYW5kIHNpemluZy5cclxuICpcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmQuTGF5b3V0fE9iamVjdH0gdGVtcGxhdGVcclxuICogICAgIFRoZSBvYmplY3Qgd2hvc2UgaWRlbnRpY2FsbHktbmFtZWQgcHJvcGVydGllcyB3aWxsIGJlIHVzZWQgdG8gaW5pdGlhbGl6ZVxyXG4gKiAgICAgdGhlIHByb3BlcnRpZXMgb2YgdGhpcyBsYXlvdXQuXHJcbiAqL1xyXG5HdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5MYXlvdXQgPSBmdW5jdGlvbih0ZW1wbGF0ZSkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGxhbmd1YWdlIG9mIGtleWJvYXJkIGxheW91dCwgc3VjaCBhcyBcImVuX1VTXCIuIFRoaXMgcHJvcGVydHkgaXMgZm9yXHJcbiAgICAgKiBpbmZvcm1hdGlvbmFsIHB1cnBvc2VzIG9ubHksIGJ1dCBpdCBpcyByZWNvbW1lbmQgdG8gY29uZm9ybSB0byB0aGVcclxuICAgICAqIFtsYW5ndWFnZSBjb2RlXV9bY291bnRyeSBjb2RlXSBmb3JtYXQuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge1N0cmluZ31cclxuICAgICAqL1xyXG4gICAgdGhpcy5sYW5ndWFnZSA9IHRlbXBsYXRlLmxhbmd1YWdlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHR5cGUgb2Yga2V5Ym9hcmQgbGF5b3V0LCBzdWNoIGFzIFwicXdlcnR5XCIuIFRoaXMgcHJvcGVydHkgaXMgZm9yXHJcbiAgICAgKiBpbmZvcm1hdGlvbmFsIHB1cnBvc2VzIG9ubHksIGFuZCBkb2VzIG5vdCBjb25mb3JtIHRvIGFueSBzdGFuZGFyZC5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxyXG4gICAgICovXHJcbiAgICB0aGlzLnR5cGUgPSB0ZW1wbGF0ZS50eXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFwIG9mIGtleSBuYW1lIHRvIGNvcnJlc3BvbmRpbmcga2V5c3ltLCB0aXRsZSwgb3Iga2V5IG9iamVjdC4gSWYgb25seVxyXG4gICAgICogdGhlIGtleXN5bSBvciB0aXRsZSBpcyBwcm92aWRlZCwgdGhlIGtleSBvYmplY3Qgd2lsbCBiZSBjcmVhdGVkXHJcbiAgICAgKiBpbXBsaWNpdGx5LiBJbiBhbGwgY2FzZXMsIHRoZSBuYW1lIHByb3BlcnR5IG9mIHRoZSBrZXkgb2JqZWN0IHdpbGwgYmVcclxuICAgICAqIHRha2VuIGZyb20gdGhlIG5hbWUgZ2l2ZW4gaW4gdGhlIG1hcHBpbmcuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge09iamVjdC48U3RyaW5nLCBOdW1iZXJ8U3RyaW5nfEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLktleXxHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXlbXT59XHJcbiAgICAgKi9cclxuICAgIHRoaXMua2V5cyA9IHRlbXBsYXRlLmtleXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcmJpdHJhcmlseSBuZXN0ZWQsIGFyYml0cmFyaWx5IGdyb3VwZWQga2V5IG5hbWVzLiBUaGUgY29udGVudHMgb2YgdGhlXHJcbiAgICAgKiBsYXlvdXQgd2lsbCBiZSB0cmF2ZXJzZWQgdG8gcHJvZHVjZSBhbiBpZGVudGljYWxseS1uZXN0ZWQgZ3JvdXBpbmcgb2ZcclxuICAgICAqIGtleXMgaW4gdGhlIERPTSB0cmVlLiBBbGwgc3RyaW5ncyB3aWxsIGJlIHRyYW5zZm9ybWVkIGludG8gdGhlaXJcclxuICAgICAqIGNvcnJlc3BvbmRpbmcgc2V0cyBvZiBrZXlzLCB3aGlsZSBhbGwgb2JqZWN0cyBhbmQgYXJyYXlzIHdpbGwgYmVcclxuICAgICAqIHRyYW5zZm9ybWVkIGludG8gbmFtZWQgZ3JvdXBzIGFuZCBhbm9ueW1vdXMgZ3JvdXBzIHJlc3BlY3RpdmVseS4gQW55XHJcbiAgICAgKiBudW1iZXJzIHByZXNlbnQgd2lsbCBiZSB0cmFuc2Zvcm1lZCBpbnRvIGdhcHMgb2YgdGhhdCBzaXplLCBzY2FsZWRcclxuICAgICAqIGFjY29yZGluZyB0byB0aGUgc2FtZSB1bml0cyBhcyBlYWNoIGtleS5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxyXG4gICAgICovXHJcbiAgICB0aGlzLmxheW91dCA9IHRlbXBsYXRlLmxheW91dDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgZW50aXJlIGtleWJvYXJkLCBpbiBhcmJpdHJhcnkgdW5pdHMuIFRoZSB3aWR0aCBvZiBlYWNoXHJcbiAgICAgKiBrZXkgaXMgcmVsYXRpdmUgdG8gdGhpcyB3aWR0aCwgYXMgYm90aCB3aWR0aCB2YWx1ZXMgYXJlIGFzc3VtZWQgdG8gYmUgaW5cclxuICAgICAqIHRoZSBzYW1lIHVuaXRzLiBUaGUgY29udmVyc2lvbiBmYWN0b3IgYmV0d2VlbiB0aGVzZSB1bml0cyBhbmQgcGl4ZWxzIGlzXHJcbiAgICAgKiBkZXJpdmVkIGxhdGVyIHZpYSBhIGNhbGwgdG8gcmVzaXplKCkgb24gdGhlIEd1YWNhbW9sZS5PblNjcmVlbktleWJvYXJkLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMud2lkdGggPSB0ZW1wbGF0ZS53aWR0aDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSB3aWR0aCBvZiBlYWNoIGtleSwgaW4gYXJiaXRyYXJ5IHVuaXRzLCByZWxhdGl2ZSB0byBvdGhlciBrZXlzIGluXHJcbiAgICAgKiB0aGlzIGxheW91dC4gVGhlIHRydWUgcGl4ZWwgc2l6ZSBvZiBlYWNoIGtleSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlXHJcbiAgICAgKiBvdmVyYWxsIHNpemUgb2YgdGhlIGtleWJvYXJkLiBJZiBub3QgZGVmaW5lZCBoZXJlLCB0aGUgd2lkdGggb2YgZWFjaFxyXG4gICAgICoga2V5IHdpbGwgZGVmYXVsdCB0byAxLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtPYmplY3QuPFN0cmluZywgTnVtYmVyPn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5rZXlXaWR0aHMgPSB0ZW1wbGF0ZS5rZXlXaWR0aHMgfHwge307XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlcHJlc2VudHMgYSBzaW5nbGUga2V5LCBvciBhIHNpbmdsZSBwb3NzaWJsZSBiZWhhdmlvciBvZiBhIGtleS4gRWFjaCBrZXlcclxuICogb24gdGhlIG9uLXNjcmVlbiBrZXlib2FyZCBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGFzc29jaWF0ZWRcclxuICogR3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmQuS2V5LCB3aGV0aGVyIHRoYXQga2V5IGlzIGV4cGxpY2l0bHkgZGVmaW5lZCBvclxyXG4gKiBpbXBsaWVkLCBhbmQgbWF5IGhhdmUgbXVsdGlwbGUgR3VhY2Ftb2xlLk9uU2NyZWVuS2V5Ym9hcmQuS2V5IGlmIGJlaGF2aW9yXHJcbiAqIGRlcGVuZHMgb24gbW9kaWZpZXIgc3RhdGVzLlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtHdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXl8T2JqZWN0fSB0ZW1wbGF0ZVxyXG4gKiAgICAgVGhlIG9iamVjdCB3aG9zZSBpZGVudGljYWxseS1uYW1lZCBwcm9wZXJ0aWVzIHdpbGwgYmUgdXNlZCB0byBpbml0aWFsaXplXHJcbiAqICAgICB0aGUgcHJvcGVydGllcyBvZiB0aGlzIGtleS5cclxuICogICAgIFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gW25hbWVdXHJcbiAqICAgICBUaGUgbmFtZSB0byB1c2UgaW5zdGVhZCBvZiBhbnkgbmFtZSBwcm92aWRlZCB3aXRoaW4gdGhlIHRlbXBsYXRlLCBpZlxyXG4gKiAgICAgYW55LiBJZiBvbWl0dGVkLCB0aGUgbmFtZSB3aXRoaW4gdGhlIHRlbXBsYXRlIHdpbGwgYmUgdXNlZCwgYXNzdW1pbmcgdGhlXHJcbiAqICAgICB0ZW1wbGF0ZSBjb250YWlucyBhIG5hbWUuXHJcbiAqL1xyXG5HdWFjYW1vbGUuT25TY3JlZW5LZXlib2FyZC5LZXkgPSBmdW5jdGlvbih0ZW1wbGF0ZSwgbmFtZSkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHVuaXF1ZSBuYW1lIGlkZW50aWZ5aW5nIHRoaXMga2V5IHdpdGhpbiB0aGUga2V5Ym9hcmQgbGF5b3V0LlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtTdHJpbmd9XHJcbiAgICAgKi9cclxuICAgIHRoaXMubmFtZSA9IG5hbWUgfHwgdGVtcGxhdGUubmFtZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBodW1hbi1yZWFkYWJsZSB0aXRsZSB0aGF0IHdpbGwgYmUgZGlzcGxheWVkIHRvIHRoZSB1c2VyIHdpdGhpbiB0aGVcclxuICAgICAqIGtleS4gSWYgbm90IHByb3ZpZGVkLCB0aGlzIHdpbGwgYmUgZGVyaXZlZCBmcm9tIHRoZSBrZXkgbmFtZS5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxyXG4gICAgICovXHJcbiAgICB0aGlzLnRpdGxlID0gdGVtcGxhdGUudGl0bGUgfHwgdGhpcy5uYW1lO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGtleXN5bSB0byBiZSBwcmVzc2VkL3JlbGVhc2VkIHdoZW4gdGhpcyBrZXkgaXMgcHJlc3NlZC9yZWxlYXNlZC4gSWZcclxuICAgICAqIG5vdCBwcm92aWRlZCwgdGhpcyB3aWxsIGJlIGRlcml2ZWQgZnJvbSB0aGUgdGl0bGUgaWYgdGhlIHRpdGxlIGlzIGFcclxuICAgICAqIHNpbmdsZSBjaGFyYWN0ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5rZXlzeW0gPSB0ZW1wbGF0ZS5rZXlzeW0gfHwgKGZ1bmN0aW9uIGRlcml2ZUtleXN5bSh0aXRsZSkge1xyXG5cclxuICAgICAgICAvLyBEbyBub3QgZGVyaXZlIGtleXN5bSBpZiB0aXRsZSBpcyBub3QgZXhhY3RseSBvbmUgY2hhcmFjdGVyXHJcbiAgICAgICAgaWYgKCF0aXRsZSB8fCB0aXRsZS5sZW5ndGggIT09IDEpXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICAvLyBGb3IgY2hhcmFjdGVycyBiZXR3ZWVuIFUrMDAwMCBhbmQgVSswMEZGLCB0aGUga2V5c3ltIGlzIHRoZSBjb2RlcG9pbnRcclxuICAgICAgICB2YXIgY2hhckNvZGUgPSB0aXRsZS5jaGFyQ29kZUF0KDApO1xyXG4gICAgICAgIGlmIChjaGFyQ29kZSA+PSAweDAwMDAgJiYgY2hhckNvZGUgPD0gMHgwMEZGKVxyXG4gICAgICAgICAgICByZXR1cm4gY2hhckNvZGU7XHJcblxyXG4gICAgICAgIC8vIEZvciBjaGFyYWN0ZXJzIGJldHdlZW4gVSswMTAwIGFuZCBVKzEwRkZGRiwgdGhlIGtleXN5bSBpcyB0aGUgY29kZXBvaW50IG9yJ2Qgd2l0aCAweDAxMDAwMDAwXHJcbiAgICAgICAgaWYgKGNoYXJDb2RlID49IDB4MDEwMCAmJiBjaGFyQ29kZSA8PSAweDEwRkZGRilcclxuICAgICAgICAgICAgcmV0dXJuIDB4MDEwMDAwMDAgfCBjaGFyQ29kZTtcclxuXHJcbiAgICAgICAgLy8gVW5hYmxlIHRvIGRlcml2ZSBrZXlzeW1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICB9KSh0aGlzLnRpdGxlKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBtb2RpZmllciBzZXQgd2hlbiB0aGUga2V5IGlzIHByZXNzZWQgYW5kIGNsZWFyZWQgd2hlblxyXG4gICAgICogdGhpcyBrZXkgaXMgcmVsZWFzZWQsIGlmIGFueS4gVGhlIG5hbWVzIG9mIG1vZGlmaWVycyBhcmUgZGlzdGluY3QgZnJvbVxyXG4gICAgICogdGhlIG5hbWVzIG9mIGtleXM7IGJvdGggdGhlIFwiUmlnaHRTaGlmdFwiIGFuZCBcIkxlZnRTaGlmdFwiIGtleXMgbWF5IHNldFxyXG4gICAgICogdGhlIFwic2hpZnRcIiBtb2RpZmllciwgZm9yIGV4YW1wbGUuIEJ5IGRlZmF1bHQsIHRoZSBrZXkgd2lsbCBhZmZlY3Qgbm9cclxuICAgICAqIG1vZGlmaWVycy5cclxuICAgICAqIFxyXG4gICAgICogQHR5cGUge1N0cmluZ31cclxuICAgICAqL1xyXG4gICAgdGhpcy5tb2RpZmllciA9IHRlbXBsYXRlLm1vZGlmaWVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gYXJyYXkgY29udGFpbmluZyB0aGUgbmFtZXMgb2YgZWFjaCBtb2RpZmllciByZXF1aXJlZCBmb3IgdGhpcyBrZXkgdG9cclxuICAgICAqIGhhdmUgYW4gZWZmZWN0LiBGb3IgZXhhbXBsZSwgYSBsb3dlcmNhc2UgbGV0dGVyIG1heSByZXF1aXJlIG5vdGhpbmcsXHJcbiAgICAgKiB3aGlsZSBhbiB1cHBlcmNhc2UgbGV0dGVyIHdvdWxkIHJlcXVpcmUgXCJzaGlmdFwiLCBhc3N1bWluZyB0aGUgU2hpZnQga2V5XHJcbiAgICAgKiBpcyBuYW1lZCBcInNoaWZ0XCIgd2l0aGluIHRoZSBsYXlvdXQuIEJ5IGRlZmF1bHQsIHRoZSBrZXkgd2lsbCByZXF1aXJlXHJcbiAgICAgKiBubyBtb2RpZmllcnMuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge1N0cmluZ1tdfVxyXG4gICAgICovXHJcbiAgICB0aGlzLnJlcXVpcmVzID0gdGVtcGxhdGUucmVxdWlyZXMgfHwgW107XHJcblxyXG59O1xyXG4vKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIEFic3RyYWN0IHN0cmVhbSB3aGljaCBjYW4gcmVjZWl2ZSBkYXRhLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLkNsaWVudH0gY2xpZW50IFRoZSBjbGllbnQgb3duaW5nIHRoaXMgc3RyZWFtLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoaXMgc3RyZWFtLlxyXG4gKi9cclxuR3VhY2Ftb2xlLk91dHB1dFN0cmVhbSA9IGZ1bmN0aW9uKGNsaWVudCwgaW5kZXgpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIHN0cmVhbS5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBndWFjX3N0cmVhbSA9IHRoaXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgaW5kZXggb2YgdGhpcyBzdHJlYW0uXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciBhbiBhY2tub3dsZWRnZW1lbnQgaXMgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyLCBpbmRpY2F0aW5nXHJcbiAgICAgKiB0aGF0IGEgc3RyZWFtIG9wZXJhdGlvbiBoYXMgY29tcGxldGVkLCBvciBhbiBlcnJvciBoYXMgb2NjdXJyZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtHdWFjYW1vbGUuU3RhdHVzfSBzdGF0dXMgVGhlIHN0YXR1cyBvZiB0aGUgb3BlcmF0aW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uYWNrID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gYmFzZTY0LWVuY29kZWQgZGF0YSB0byB0aGlzIHN0cmVhbSBhcyBhIGJsb2IuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIFRoZSBiYXNlNjQtZW5jb2RlZCBkYXRhIHRvIHNlbmQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2VuZEJsb2IgPSBmdW5jdGlvbihkYXRhKSB7XHJcbiAgICAgICAgY2xpZW50LnNlbmRCbG9iKGd1YWNfc3RyZWFtLmluZGV4LCBkYXRhKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDbG9zZXMgdGhpcyBzdHJlYW0uXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2VuZEVuZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGNsaWVudC5lbmRTdHJlYW0oZ3VhY19zdHJlYW0uaW5kZXgpO1xyXG4gICAgfTtcclxuXHJcbn07XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogU2ltcGxlIEd1YWNhbW9sZSBwcm90b2NvbCBwYXJzZXIgdGhhdCBpbnZva2VzIGFuIG9uaW5zdHJ1Y3Rpb24gZXZlbnQgd2hlblxyXG4gKiBmdWxsIGluc3RydWN0aW9ucyBhcmUgYXZhaWxhYmxlIGZyb20gZGF0YSByZWNlaXZlZCB2aWEgcmVjZWl2ZSgpLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqL1xyXG5HdWFjYW1vbGUuUGFyc2VyID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBwYXJzZXIuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgcGFyc2VyID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEN1cnJlbnQgYnVmZmVyIG9mIHJlY2VpdmVkIGRhdGEuIFRoaXMgYnVmZmVyIGdyb3dzIHVudGlsIGEgZnVsbFxyXG4gICAgICogZWxlbWVudCBpcyBhdmFpbGFibGUuIEFmdGVyIGEgZnVsbCBlbGVtZW50IGlzIGF2YWlsYWJsZSwgdGhhdCBlbGVtZW50XHJcbiAgICAgKiBpcyBmbHVzaGVkIGludG8gdGhlIGVsZW1lbnQgYnVmZmVyLlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgYnVmZmVyID0gXCJcIjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJ1ZmZlciBvZiBhbGwgcmVjZWl2ZWQsIGNvbXBsZXRlIGVsZW1lbnRzLiBBZnRlciBhbiBlbnRpcmUgaW5zdHJ1Y3Rpb25cclxuICAgICAqIGlzIHJlYWQsIHRoaXMgYnVmZmVyIGlzIGZsdXNoZWQsIGFuZCBhIG5ldyBpbnN0cnVjdGlvbiBiZWdpbnMuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBlbGVtZW50X2J1ZmZlciA9IFtdO1xyXG5cclxuICAgIC8vIFRoZSBsb2NhdGlvbiBvZiB0aGUgbGFzdCBlbGVtZW50J3MgdGVybWluYXRvclxyXG4gICAgdmFyIGVsZW1lbnRfZW5kID0gLTE7XHJcblxyXG4gICAgLy8gV2hlcmUgdG8gc3RhcnQgdGhlIG5leHQgbGVuZ3RoIHNlYXJjaCBvciB0aGUgbmV4dCBlbGVtZW50XHJcbiAgICB2YXIgc3RhcnRfaW5kZXggPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwZW5kcyB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb24gZGF0YSBwYWNrZXQgdG8gdGhlIGludGVybmFsIGJ1ZmZlciBvZlxyXG4gICAgICogdGhpcyBHdWFjYW1vbGUuUGFyc2VyLCBleGVjdXRpbmcgYWxsIGNvbXBsZXRlZCBpbnN0cnVjdGlvbnMgYXRcclxuICAgICAqIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBidWZmZXIsIGlmIGFueS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gcGFja2V0IFRoZSBpbnN0cnVjdGlvbiBkYXRhIHRvIHJlY2VpdmUuXHJcbiAgICAgKi9cclxuICAgIHRoaXMucmVjZWl2ZSA9IGZ1bmN0aW9uKHBhY2tldCkge1xyXG5cclxuICAgICAgICAvLyBUcnVuY2F0ZSBidWZmZXIgYXMgbmVjZXNzYXJ5XHJcbiAgICAgICAgaWYgKHN0YXJ0X2luZGV4ID4gNDA5NiAmJiBlbGVtZW50X2VuZCA+PSBzdGFydF9pbmRleCkge1xyXG5cclxuICAgICAgICAgICAgYnVmZmVyID0gYnVmZmVyLnN1YnN0cmluZyhzdGFydF9pbmRleCk7XHJcblxyXG4gICAgICAgICAgICAvLyBSZXNldCBwYXJzZSByZWxhdGl2ZSB0byB0cnVuY2F0aW9uXHJcbiAgICAgICAgICAgIGVsZW1lbnRfZW5kIC09IHN0YXJ0X2luZGV4O1xyXG4gICAgICAgICAgICBzdGFydF9pbmRleCA9IDA7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQXBwZW5kIGRhdGEgdG8gYnVmZmVyXHJcbiAgICAgICAgYnVmZmVyICs9IHBhY2tldDtcclxuXHJcbiAgICAgICAgLy8gV2hpbGUgc2VhcmNoIGlzIHdpdGhpbiBjdXJyZW50bHkgcmVjZWl2ZWQgZGF0YVxyXG4gICAgICAgIHdoaWxlIChlbGVtZW50X2VuZCA8IGJ1ZmZlci5sZW5ndGgpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIHdlIGFyZSB3YWl0aW5nIGZvciBlbGVtZW50IGRhdGFcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnRfZW5kID49IHN0YXJ0X2luZGV4KSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gV2Ugbm93IGhhdmUgZW5vdWdoIGRhdGEgZm9yIHRoZSBlbGVtZW50LiBQYXJzZS5cclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gYnVmZmVyLnN1YnN0cmluZyhzdGFydF9pbmRleCwgZWxlbWVudF9lbmQpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHRlcm1pbmF0b3IgPSBidWZmZXIuc3Vic3RyaW5nKGVsZW1lbnRfZW5kLCBlbGVtZW50X2VuZCsxKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBZGQgZWxlbWVudCB0byBhcnJheVxyXG4gICAgICAgICAgICAgICAgZWxlbWVudF9idWZmZXIucHVzaChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiBsYXN0IGVsZW1lbnQsIGhhbmRsZSBpbnN0cnVjdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKHRlcm1pbmF0b3IgPT0gXCI7XCIpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IG9wY29kZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcGNvZGUgPSBlbGVtZW50X2J1ZmZlci5zaGlmdCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBDYWxsIGluc3RydWN0aW9uIGhhbmRsZXIuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlci5vbmluc3RydWN0aW9uICE9IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlci5vbmluc3RydWN0aW9uKG9wY29kZSwgZWxlbWVudF9idWZmZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBDbGVhciBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRfYnVmZmVyLmxlbmd0aCA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGVybWluYXRvciAhPSAnLCcpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSWxsZWdhbCB0ZXJtaW5hdG9yLlwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTdGFydCBzZWFyY2hpbmcgZm9yIGxlbmd0aCBhdCBjaGFyYWN0ZXIgYWZ0ZXJcclxuICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgdGVybWluYXRvclxyXG4gICAgICAgICAgICAgICAgc3RhcnRfaW5kZXggPSBlbGVtZW50X2VuZCArIDE7XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBTZWFyY2ggZm9yIGVuZCBvZiBsZW5ndGhcclxuICAgICAgICAgICAgdmFyIGxlbmd0aF9lbmQgPSBidWZmZXIuaW5kZXhPZihcIi5cIiwgc3RhcnRfaW5kZXgpO1xyXG4gICAgICAgICAgICBpZiAobGVuZ3RoX2VuZCAhPSAtMSkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IHBhcnNlSW50KGJ1ZmZlci5zdWJzdHJpbmcoZWxlbWVudF9lbmQrMSwgbGVuZ3RoX2VuZCkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSBOYU4pXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm9uLW51bWVyaWMgY2hhcmFjdGVyIGluIGVsZW1lbnQgbGVuZ3RoLlwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgc3RhcnQgb2YgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgc3RhcnRfaW5kZXggPSBsZW5ndGhfZW5kICsgMTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgbG9jYXRpb24gb2YgZWxlbWVudCB0ZXJtaW5hdG9yXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50X2VuZCA9IHN0YXJ0X2luZGV4ICsgbGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gSWYgbm8gcGVyaW9kIHlldCwgY29udGludWUgc2VhcmNoIHdoZW4gbW9yZSBkYXRhXHJcbiAgICAgICAgICAgIC8vIGlzIHJlY2VpdmVkXHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc3RhcnRfaW5kZXggPSBidWZmZXIubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSAvLyBlbmQgcGFyc2UgbG9vcFxyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCBvbmNlIGZvciBldmVyeSBjb21wbGV0ZSBHdWFjYW1vbGUgaW5zdHJ1Y3Rpb24gcmVjZWl2ZWQsIGluIG9yZGVyLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvcGNvZGUgVGhlIEd1YWNhbW9sZSBpbnN0cnVjdGlvbiBvcGNvZGUuXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJhbWV0ZXJzIFRoZSBwYXJhbWV0ZXJzIHByb3ZpZGVkIGZvciB0aGUgaW5zdHJ1Y3Rpb24sXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGFueS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmluc3RydWN0aW9uID0gbnVsbDtcclxuXHJcbn07XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogQSBkZXNjcmlwdGlvbiBvZiB0aGUgZm9ybWF0IG9mIHJhdyBQQ00gYXVkaW8sIHN1Y2ggYXMgdGhhdCB1c2VkIGJ5XHJcbiAqIEd1YWNhbW9sZS5SYXdBdWRpb1BsYXllciBhbmQgR3VhY2Ftb2xlLlJhd0F1ZGlvUmVjb3JkZXIuIFRoaXMgb2JqZWN0XHJcbiAqIGRlc2NyaWJlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHBlciBzYW1wbGUsIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMsIGFuZCB0aGVcclxuICogb3ZlcmFsbCBzYW1wbGUgcmF0ZS5cclxuICpcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLlJhd0F1ZGlvRm9ybWF0fE9iamVjdH0gdGVtcGxhdGVcclxuICogICAgIFRoZSBvYmplY3Qgd2hvc2UgcHJvcGVydGllcyBzaG91bGQgYmUgY29waWVkIGludG8gdGhlIGNvcnJlc3BvbmRpbmdcclxuICogICAgIHByb3BlcnRpZXMgb2YgdGhlIG5ldyBHdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXQuXHJcbiAqL1xyXG5HdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXQgPSBmdW5jdGlvbiBSYXdBdWRpb0Zvcm1hdCh0ZW1wbGF0ZSkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG51bWJlciBvZiBieXRlcyBpbiBlYWNoIHNhbXBsZSBvZiBhdWRpbyBkYXRhLiBUaGlzIHZhbHVlIGlzXHJcbiAgICAgKiBpbmRlcGVuZGVudCBvZiB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuYnl0ZXNQZXJTYW1wbGUgPSB0ZW1wbGF0ZS5ieXRlc1BlclNhbXBsZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2YgYXVkaW8gY2hhbm5lbHMgKGllOiAxIGZvciBtb25vLCAyIGZvciBzdGVyZW8pLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuY2hhbm5lbHMgPSB0ZW1wbGF0ZS5jaGFubmVscztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2Ygc2FtcGxlcyBwZXIgc2Vjb25kLCBwZXIgY2hhbm5lbC5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLnJhdGUgPSB0ZW1wbGF0ZS5yYXRlO1xyXG5cclxufTtcclxuXHJcbi8qKlxyXG4gKiBQYXJzZXMgdGhlIGdpdmVuIG1pbWV0eXBlLCByZXR1cm5pbmcgYSBuZXcgR3VhY2Ftb2xlLlJhd0F1ZGlvRm9ybWF0XHJcbiAqIHdoaWNoIGRlc2NyaWJlcyB0aGUgdHlwZSBvZiByYXcgYXVkaW8gZGF0YSByZXByZXNlbnRlZCBieSB0aGF0IG1pbWV0eXBlLiBJZlxyXG4gKiB0aGUgbWltZXR5cGUgaXMgbm90IGEgc3VwcG9ydGVkIHJhdyBhdWRpbyBkYXRhIG1pbWV0eXBlLCBudWxsIGlzIHJldHVybmVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbWltZXR5cGVcclxuICogICAgIFRoZSBhdWRpbyBtaW1ldHlwZSB0byBwYXJzZS5cclxuICpcclxuICogQHJldHVybnMge0d1YWNhbW9sZS5SYXdBdWRpb0Zvcm1hdH1cclxuICogICAgIEEgbmV3IEd1YWNhbW9sZS5SYXdBdWRpb0Zvcm1hdCB3aGljaCBkZXNjcmliZXMgdGhlIHR5cGUgb2YgcmF3XHJcbiAqICAgICBhdWRpbyBkYXRhIHJlcHJlc2VudGVkIGJ5IHRoZSBnaXZlbiBtaW1ldHlwZSwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW5cclxuICogICAgIG1pbWV0eXBlIGlzIG5vdCBzdXBwb3J0ZWQuXHJcbiAqL1xyXG5HdWFjYW1vbGUuUmF3QXVkaW9Gb3JtYXQucGFyc2UgPSBmdW5jdGlvbiBwYXJzZUZvcm1hdChtaW1ldHlwZSkge1xyXG5cclxuICAgIHZhciBieXRlc1BlclNhbXBsZTtcclxuXHJcbiAgICAvLyBSYXRlIGlzIGFic29sdXRlbHkgcmVxdWlyZWQgLSBpZiBudWxsIGlzIHN0aWxsIHByZXNlbnQgbGF0ZXIsIHRoZVxyXG4gICAgLy8gbWltZXR5cGUgbXVzdCBub3QgYmUgc3VwcG9ydGVkXHJcbiAgICB2YXIgcmF0ZSA9IG51bGw7XHJcblxyXG4gICAgLy8gRGVmYXVsdCBmb3IgYm90aCBcImF1ZGlvL0w4XCIgYW5kIFwiYXVkaW8vTDE2XCIgaXMgb25lIGNoYW5uZWxcclxuICAgIHZhciBjaGFubmVscyA9IDE7XHJcblxyXG4gICAgLy8gXCJhdWRpby9MOFwiIGhhcyBvbmUgYnl0ZSBwZXIgc2FtcGxlXHJcbiAgICBpZiAobWltZXR5cGUuc3Vic3RyaW5nKDAsIDkpID09PSAnYXVkaW8vTDg7Jykge1xyXG4gICAgICAgIG1pbWV0eXBlID0gbWltZXR5cGUuc3Vic3RyaW5nKDkpO1xyXG4gICAgICAgIGJ5dGVzUGVyU2FtcGxlID0gMTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBcImF1ZGlvL0wxNlwiIGhhcyB0d28gYnl0ZXMgcGVyIHNhbXBsZVxyXG4gICAgZWxzZSBpZiAobWltZXR5cGUuc3Vic3RyaW5nKDAsIDEwKSA9PT0gJ2F1ZGlvL0wxNjsnKSB7XHJcbiAgICAgICAgbWltZXR5cGUgPSBtaW1ldHlwZS5zdWJzdHJpbmcoMTApO1xyXG4gICAgICAgIGJ5dGVzUGVyU2FtcGxlID0gMjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBbGwgb3RoZXIgdHlwZXMgYXJlIHVuc3VwcG9ydGVkXHJcbiAgICBlbHNlXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgLy8gUGFyc2UgYWxsIHBhcmFtZXRlcnNcclxuICAgIHZhciBwYXJhbWV0ZXJzID0gbWltZXR5cGUuc3BsaXQoJywnKTtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xyXG5cclxuICAgICAgICB2YXIgcGFyYW1ldGVyID0gcGFyYW1ldGVyc1tpXTtcclxuXHJcbiAgICAgICAgLy8gQWxsIHBhcmFtZXRlcnMgbXVzdCBoYXZlIGFuIGVxdWFscyBzaWduIHNlcGFyYXRpbmcgbmFtZSBmcm9tIHZhbHVlXHJcbiAgICAgICAgdmFyIGVxdWFscyA9IHBhcmFtZXRlci5pbmRleE9mKCc9Jyk7XHJcbiAgICAgICAgaWYgKGVxdWFscyA9PT0gLTEpXHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICAvLyBQYXJzZSBuYW1lIGFuZCB2YWx1ZSBmcm9tIHBhcmFtZXRlciBzdHJpbmdcclxuICAgICAgICB2YXIgbmFtZSAgPSBwYXJhbWV0ZXIuc3Vic3RyaW5nKDAsIGVxdWFscyk7XHJcbiAgICAgICAgdmFyIHZhbHVlID0gcGFyYW1ldGVyLnN1YnN0cmluZyhlcXVhbHMrMSk7XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBlYWNoIHN1cHBvcnRlZCBwYXJhbWV0ZXJcclxuICAgICAgICBzd2l0Y2ggKG5hbWUpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIE51bWJlciBvZiBhdWRpbyBjaGFubmVsc1xyXG4gICAgICAgICAgICBjYXNlICdjaGFubmVscyc6XHJcbiAgICAgICAgICAgICAgICBjaGFubmVscyA9IHBhcnNlSW50KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgLy8gU2FtcGxlIHJhdGVcclxuICAgICAgICAgICAgY2FzZSAncmF0ZSc6XHJcbiAgICAgICAgICAgICAgICByYXRlID0gcGFyc2VJbnQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAvLyBBbGwgb3RoZXIgcGFyYW1ldGVycyBhcmUgdW5zdXBwb3J0ZWRcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBUaGUgcmF0ZSBwYXJhbWV0ZXIgaXMgcmVxdWlyZWRcclxuICAgIGlmIChyYXRlID09PSBudWxsKVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgIC8vIFJldHVybiBwYXJzZWQgZm9ybWF0IGRldGFpbHNcclxuICAgIHJldHVybiBuZXcgR3VhY2Ftb2xlLlJhd0F1ZGlvRm9ybWF0KHtcclxuICAgICAgICBieXRlc1BlclNhbXBsZSA6IGJ5dGVzUGVyU2FtcGxlLFxyXG4gICAgICAgIGNoYW5uZWxzICAgICAgIDogY2hhbm5lbHMsXHJcbiAgICAgICAgcmF0ZSAgICAgICAgICAgOiByYXRlXHJcbiAgICB9KTtcclxuXHJcbn07XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogQSByZWNvcmRpbmcgb2YgYSBHdWFjYW1vbGUgc2Vzc2lvbi4gR2l2ZW4gYSB7QGxpbmsgR3VhY2Ftb2xlLlR1bm5lbH0sIHRoZVxyXG4gKiBHdWFjYW1vbGUuU2Vzc2lvblJlY29yZGluZyBhdXRvbWF0aWNhbGx5IGhhbmRsZXMgaW5jb21pbmcgR3VhY2Ftb2xlXHJcbiAqIGluc3RydWN0aW9ucywgc3RvcmluZyB0aGVtIGZvciBwbGF5YmFjay4gUGxheWJhY2sgb2YgdGhlIHJlY29yZGluZyBtYXkgYmVcclxuICogY29udHJvbGxlZCB0aHJvdWdoIGZ1bmN0aW9uIGNhbGxzIHRvIHRoZSBHdWFjYW1vbGUuU2Vzc2lvblJlY29yZGluZywgZXZlblxyXG4gKiB3aGlsZSB0aGUgcmVjb3JkaW5nIGhhcyBub3QgeWV0IGZpbmlzaGVkIGJlaW5nIGNyZWF0ZWQgb3IgZG93bmxvYWRlZC5cclxuICpcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLlR1bm5lbH0gdHVubmVsXHJcbiAqICAgICBUaGUgR3VhY2Ftb2xlLlR1bm5lbCBmcm9tIHdoaWNoIHRoZSBpbnN0cnVjdGlvbnMgb2YgdGhlIHJlY29yZGluZyBzaG91bGRcclxuICogICAgIGJlIHJlYWQuXHJcbiAqL1xyXG5HdWFjYW1vbGUuU2Vzc2lvblJlY29yZGluZyA9IGZ1bmN0aW9uIFNlc3Npb25SZWNvcmRpbmcodHVubmVsKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBHdWFjYW1vbGUuU2Vzc2lvblJlY29yZGluZy5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nfVxyXG4gICAgICovXHJcbiAgICB2YXIgcmVjb3JkaW5nID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBtaW5pbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHdoaWNoIG11c3QgaGF2ZSBiZWVuIHJlYWQgYmV0d2VlblxyXG4gICAgICoga2V5ZnJhbWVzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAY29uc3RhbnRcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBLRVlGUkFNRV9DSEFSX0lOVEVSVkFMID0gMTYzODQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWluaW11bSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHdoaWNoIG11c3QgZWxhcHNlIGJldHdlZW4ga2V5ZnJhbWVzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAY29uc3RhbnRcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBLRVlGUkFNRV9USU1FX0lOVEVSVkFMID0gNTAwMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFsbCBmcmFtZXMgcGFyc2VkIGZyb20gdGhlIHByb3ZpZGVkIHR1bm5lbC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZVtdfVxyXG4gICAgICovXHJcbiAgICB2YXIgZnJhbWVzID0gW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwgaW5zdHJ1Y3Rpb25zIHdoaWNoIGhhdmUgYmVlbiByZWFkIHNpbmNlIHRoZSBsYXN0IGZyYW1lIHdhcyBhZGRlZCB0b1xyXG4gICAgICogdGhlIGZyYW1lcyBhcnJheS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZS5JbnN0cnVjdGlvbltdfVxyXG4gICAgICovXHJcbiAgICB2YXIgaW5zdHJ1Y3Rpb25zID0gW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgYXBwcm94aW1hdGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgd2hpY2ggaGF2ZSBiZWVuIHJlYWQgZnJvbSB0aGVcclxuICAgICAqIHByb3ZpZGVkIHR1bm5lbCBzaW5jZSB0aGUgbGFzdCBmcmFtZSB3YXMgZmxhZ2dlZCBmb3IgdXNlIGFzIGEga2V5ZnJhbWUuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBjaGFyYWN0ZXJzU2luY2VMYXN0S2V5ZnJhbWUgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHRpbWVzdGFtcCBvZiB0aGUgbGFzdCBmcmFtZSB3aGljaCB3YXMgZmxhZ2dlZCBmb3IgdXNlIGFzIGEga2V5ZnJhbWUuXHJcbiAgICAgKiBJZiBubyB0aW1lc3RhbXAgaGFzIHlldCBiZWVuIGZsYWdnZWQsIHRoaXMgd2lsbCBiZSAwLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgbGFzdEtleWZyYW1lVGltZXN0YW1wID0gMDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFR1bm5lbCB3aGljaCBmZWVkcyBhcmJpdHJhcnkgaW5zdHJ1Y3Rpb25zIHRvIHRoZSBjbGllbnQgdXNlZCBieSB0aGlzXHJcbiAgICAgKiBHdWFjYW1vbGUuU2Vzc2lvblJlY29yZGluZyBmb3IgcGxheWJhY2sgb2YgdGhlIHNlc3Npb24gcmVjb3JkaW5nLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLlNlc3Npb25SZWNvcmRpbmcuX1BsYXliYWNrVHVubmVsfVxyXG4gICAgICovXHJcbiAgICB2YXIgcGxheWJhY2tUdW5uZWwgPSBuZXcgR3VhY2Ftb2xlLlNlc3Npb25SZWNvcmRpbmcuX1BsYXliYWNrVHVubmVsKCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHdWFjYW1vbGUuQ2xpZW50IGluc3RhbmNlIHVzZWQgZm9yIHZpc2libGUgcGxheWJhY2sgb2YgdGhlIHNlc3Npb25cclxuICAgICAqIHJlY29yZGluZy5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5DbGllbnR9XHJcbiAgICAgKi9cclxuICAgIHZhciBwbGF5YmFja0NsaWVudCA9IG5ldyBHdWFjYW1vbGUuQ2xpZW50KHBsYXliYWNrVHVubmVsKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjdXJyZW50IGZyYW1lIHJlbmRlcmVkIHdpdGhpbiB0aGUgcGxheWJhY2sgY2xpZW50LiBJZiBubyBmcmFtZSBpc1xyXG4gICAgICogeWV0IHJlbmRlcmVkLCB0aGlzIHdpbGwgYmUgLTEuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBjdXJyZW50RnJhbWUgPSAtMTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSB0aW1lc3RhbXAgb2YgdGhlIGZyYW1lIHdoZW4gcGxheWJhY2sgYmVnYW4sIGluIG1pbGxpc2Vjb25kcy4gSWZcclxuICAgICAqIHBsYXliYWNrIGlzIG5vdCBpbiBwcm9ncmVzcywgdGhpcyB3aWxsIGJlIG51bGwuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBzdGFydFZpZGVvVGltZXN0YW1wID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSByZWFsLXdvcmxkIHRpbWVzdGFtcCB3aGVuIHBsYXliYWNrIGJlZ2FuLCBpbiBtaWxsaXNlY29uZHMuIElmXHJcbiAgICAgKiBwbGF5YmFjayBpcyBub3QgaW4gcHJvZ3Jlc3MsIHRoaXMgd2lsbCBiZSBudWxsLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgc3RhcnRSZWFsVGltZXN0YW1wID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBJRCBvZiB0aGUgdGltZW91dCB3aGljaCB3aWxsIHBsYXkgdGhlIG5leHQgZnJhbWUsIGlmIHBsYXliYWNrIGlzIGluXHJcbiAgICAgKiBwcm9ncmVzcy4gSWYgcGxheWJhY2sgaXMgbm90IGluIHByb2dyZXNzLCB0aGUgSUQgc3RvcmVkIGhlcmUgKGlmIGFueSlcclxuICAgICAqIHdpbGwgbm90IGJlIHZhbGlkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB2YXIgcGxheWJhY2tUaW1lb3V0ID0gbnVsbDtcclxuXHJcbiAgICAvLyBTdGFydCBwbGF5YmFjayBjbGllbnQgY29ubmVjdGVkXHJcbiAgICBwbGF5YmFja0NsaWVudC5jb25uZWN0KCk7XHJcblxyXG4gICAgLy8gSGlkZSBjdXJzb3IgdW5sZXNzIG1vdXNlIHBvc2l0aW9uIGlzIHJlY2VpdmVkXHJcbiAgICBwbGF5YmFja0NsaWVudC5nZXREaXNwbGF5KCkuc2hvd0N1cnNvcihmYWxzZSk7XHJcblxyXG4gICAgLy8gUmVhZCBpbnN0cnVjdGlvbnMgZnJvbSBwcm92aWRlZCB0dW5uZWwsIGV4dHJhY3RpbmcgZWFjaCBmcmFtZVxyXG4gICAgdHVubmVsLm9uaW5zdHJ1Y3Rpb24gPSBmdW5jdGlvbiBoYW5kbGVJbnN0cnVjdGlvbihvcGNvZGUsIGFyZ3MpIHtcclxuXHJcbiAgICAgICAgLy8gU3RvcmUgb3Bjb2RlIGFuZCBhcmd1bWVudHMgZm9yIHJlY2VpdmVkIGluc3RydWN0aW9uXHJcbiAgICAgICAgdmFyIGluc3RydWN0aW9uID0gbmV3IEd1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZS5JbnN0cnVjdGlvbihvcGNvZGUsIGFyZ3Muc2xpY2UoKSk7XHJcbiAgICAgICAgaW5zdHJ1Y3Rpb25zLnB1c2goaW5zdHJ1Y3Rpb24pO1xyXG4gICAgICAgIGNoYXJhY3RlcnNTaW5jZUxhc3RLZXlmcmFtZSArPSBpbnN0cnVjdGlvbi5nZXRTaXplKCk7XHJcblxyXG4gICAgICAgIC8vIE9uY2UgYSBzeW5jIGlzIHJlY2VpdmVkLCBzdG9yZSBhbGwgaW5zdHJ1Y3Rpb25zIHNpbmNlIHRoZSBsYXN0XHJcbiAgICAgICAgLy8gZnJhbWUgYXMgYSBuZXcgZnJhbWVcclxuICAgICAgICBpZiAob3Bjb2RlID09PSAnc3luYycpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFBhcnNlIGZyYW1lIHRpbWVzdGFtcCBmcm9tIHN5bmMgaW5zdHJ1Y3Rpb25cclxuICAgICAgICAgICAgdmFyIHRpbWVzdGFtcCA9IHBhcnNlSW50KGFyZ3NbMF0pO1xyXG5cclxuICAgICAgICAgICAgLy8gQWRkIGEgbmV3IGZyYW1lIGNvbnRhaW5pbmcgdGhlIGluc3RydWN0aW9ucyByZWFkIHNpbmNlIGxhc3QgZnJhbWVcclxuICAgICAgICAgICAgdmFyIGZyYW1lID0gbmV3IEd1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZSh0aW1lc3RhbXAsIGluc3RydWN0aW9ucyk7XHJcbiAgICAgICAgICAgIGZyYW1lcy5wdXNoKGZyYW1lKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFRoaXMgZnJhbWUgc2hvdWxkIGV2ZW50dWFsbHkgYmVjb21lIGEga2V5ZnJhbWUgaWYgZW5vdWdoIGRhdGFcclxuICAgICAgICAgICAgLy8gaGFzIGJlZW4gcHJvY2Vzc2VkIGFuZCBlbm91Z2ggcmVjb3JkaW5nIHRpbWUgaGFzIGVsYXBzZWQsIG9yIGlmXHJcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIGFic29sdXRlIGZpcnN0IGZyYW1lXHJcbiAgICAgICAgICAgIGlmIChmcmFtZXMubGVuZ3RoID09PSAxIHx8IChjaGFyYWN0ZXJzU2luY2VMYXN0S2V5ZnJhbWUgPj0gS0VZRlJBTUVfQ0hBUl9JTlRFUlZBTFxyXG4gICAgICAgICAgICAgICAgICAgICYmIHRpbWVzdGFtcCAtIGxhc3RLZXlmcmFtZVRpbWVzdGFtcCA+PSBLRVlGUkFNRV9USU1FX0lOVEVSVkFMKSkge1xyXG4gICAgICAgICAgICAgICAgZnJhbWUua2V5ZnJhbWUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgbGFzdEtleWZyYW1lVGltZXN0YW1wID0gdGltZXN0YW1wO1xyXG4gICAgICAgICAgICAgICAgY2hhcmFjdGVyc1NpbmNlTGFzdEtleWZyYW1lID0gMDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gQ2xlYXIgc2V0IG9mIGluc3RydWN0aW9ucyBpbiBwcmVwYXJhdGlvbiBmb3IgbmV4dCBmcmFtZVxyXG4gICAgICAgICAgICBpbnN0cnVjdGlvbnMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIC8vIE5vdGlmeSB0aGF0IGFkZGl0aW9uYWwgY29udGVudCBpcyBhdmFpbGFibGVcclxuICAgICAgICAgICAgaWYgKHJlY29yZGluZy5vbnByb2dyZXNzKVxyXG4gICAgICAgICAgICAgICAgcmVjb3JkaW5nLm9ucHJvZ3Jlc3MocmVjb3JkaW5nLmdldER1cmF0aW9uKCkpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBnaXZlbiBhYnNvbHV0ZSB0aW1lc3RhbXAgdG8gYSB0aW1lc3RhbXAgd2hpY2ggaXMgcmVsYXRpdmVcclxuICAgICAqIHRvIHRoZSBmaXJzdCBmcmFtZSBpbiB0aGUgcmVjb3JkaW5nLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZXN0YW1wXHJcbiAgICAgKiAgICAgVGhlIHRpbWVzdGFtcCB0byBjb252ZXJ0IHRvIGEgcmVsYXRpdmUgdGltZXN0YW1wLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKiAgICAgVGhlIGRpZmZlcmVuY2UgaW4gbWlsbGlzZWNvbmRzIGJldHdlZW4gdGhlIGdpdmVuIHRpbWVzdGFtcCBhbmQgdGhlXHJcbiAgICAgKiAgICAgZmlyc3QgZnJhbWUgb2YgdGhlIHJlY29yZGluZywgb3IgemVybyBpZiBubyBmcmFtZXMgeWV0IGV4aXN0LlxyXG4gICAgICovXHJcbiAgICB2YXIgdG9SZWxhdGl2ZVRpbWVzdGFtcCA9IGZ1bmN0aW9uIHRvUmVsYXRpdmVUaW1lc3RhbXAodGltZXN0YW1wKSB7XHJcblxyXG4gICAgICAgIC8vIElmIG5vIGZyYW1lcyB5ZXQgZXhpc3QsIGFsbCB0aW1lc3RhbXBzIGFyZSB6ZXJvXHJcbiAgICAgICAgaWYgKGZyYW1lcy5sZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgdGltZXN0YW1wIHJlbGF0aXZlIHRvIGZpcnN0IGZyYW1lXHJcbiAgICAgICAgcmV0dXJuIHRpbWVzdGFtcCAtIGZyYW1lc1swXS50aW1lc3RhbXA7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlYXJjaGVzIHRocm91Z2ggdGhlIGdpdmVuIHJlZ2lvbiBvZiBmcmFtZXMgZm9yIHRoZSBmcmFtZSBoYXZpbmcgYVxyXG4gICAgICogcmVsYXRpdmUgdGltZXN0YW1wIGNsb3Nlc3QgdG8gdGhlIHRpbWVzdGFtcCBnaXZlbi5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1pbkluZGV4XHJcbiAgICAgKiAgICAgVGhlIGluZGV4IG9mIHRoZSBmaXJzdCBmcmFtZSBpbiB0aGUgcmVnaW9uICh0aGUgZnJhbWUgaGF2aW5nIHRoZVxyXG4gICAgICogICAgIHNtYWxsZXN0IHRpbWVzdGFtcCkuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG1heEluZGV4XHJcbiAgICAgKiAgICAgVGhlIGluZGV4IG9mIHRoZSBsYXN0IGZyYW1lIGluIHRoZSByZWdpb24gKHRoZSBmcmFtZSBoYXZpbmcgdGhlXHJcbiAgICAgKiAgICAgbGFyZ2VzdCB0aW1lc3RhbXApLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lc3RhbXBcclxuICAgICAqICAgICBUaGUgcmVsYXRpdmUgdGltZXN0YW1wIHRvIHNlYXJjaCBmb3IsIHdoZXJlIHplcm8gZGVub3RlcyB0aGUgZmlyc3RcclxuICAgICAqICAgICBmcmFtZSBpbiB0aGUgcmVjb3JkaW5nLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKiAgICAgVGhlIGluZGV4IG9mIHRoZSBmcmFtZSBoYXZpbmcgYSByZWxhdGl2ZSB0aW1lc3RhbXAgY2xvc2VzdCB0byB0aGVcclxuICAgICAqICAgICBnaXZlbiB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgdmFyIGZpbmRGcmFtZSA9IGZ1bmN0aW9uIGZpbmRGcmFtZShtaW5JbmRleCwgbWF4SW5kZXgsIHRpbWVzdGFtcCkge1xyXG5cclxuICAgICAgICAvLyBEbyBub3Qgc2VhcmNoIGlmIHRoZSByZWdpb24gY29udGFpbnMgb25seSBvbmUgZWxlbWVudFxyXG4gICAgICAgIGlmIChtaW5JbmRleCA9PT0gbWF4SW5kZXgpXHJcbiAgICAgICAgICAgIHJldHVybiBtaW5JbmRleDtcclxuXHJcbiAgICAgICAgLy8gU3BsaXQgc2VhcmNoIHJlZ2lvbiBpbnRvIHR3byBoYWx2ZXNcclxuICAgICAgICB2YXIgbWlkSW5kZXggPSBNYXRoLmZsb29yKChtaW5JbmRleCArIG1heEluZGV4KSAvIDIpO1xyXG4gICAgICAgIHZhciBtaWRUaW1lc3RhbXAgPSB0b1JlbGF0aXZlVGltZXN0YW1wKGZyYW1lc1ttaWRJbmRleF0udGltZXN0YW1wKTtcclxuXHJcbiAgICAgICAgLy8gSWYgdGltZXN0YW1wIGlzIHdpdGhpbiBsZXNzZXIgaGFsZiwgc2VhcmNoIGFnYWluIHdpdGhpbiB0aGF0IGhhbGZcclxuICAgICAgICBpZiAodGltZXN0YW1wIDwgbWlkVGltZXN0YW1wICYmIG1pZEluZGV4ID4gbWluSW5kZXgpXHJcbiAgICAgICAgICAgIHJldHVybiBmaW5kRnJhbWUobWluSW5kZXgsIG1pZEluZGV4IC0gMSwgdGltZXN0YW1wKTtcclxuXHJcbiAgICAgICAgLy8gSWYgdGltZXN0YW1wIGlzIHdpdGhpbiBncmVhdGVyIGhhbGYsIHNlYXJjaCBhZ2FpbiB3aXRoaW4gdGhhdCBoYWxmXHJcbiAgICAgICAgaWYgKHRpbWVzdGFtcCA+IG1pZFRpbWVzdGFtcCAmJiBtaWRJbmRleCA8IG1heEluZGV4KVxyXG4gICAgICAgICAgICByZXR1cm4gZmluZEZyYW1lKG1pZEluZGV4ICsgMSwgbWF4SW5kZXgsIHRpbWVzdGFtcCk7XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSwgd2UgbHVja2VkIG91dCBhbmQgZm91bmQgYSBmcmFtZSB3aXRoIGV4YWN0bHkgdGhlXHJcbiAgICAgICAgLy8gZGVzaXJlZCB0aW1lc3RhbXBcclxuICAgICAgICByZXR1cm4gbWlkSW5kZXg7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlcGxheXMgdGhlIGluc3RydWN0aW9ucyBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGZyYW1lLCBzZW5kaW5nIHRob3NlXHJcbiAgICAgKiBpbnN0cnVjdGlvbnMgdG8gdGhlIHBsYXliYWNrIGNsaWVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XHJcbiAgICAgKiAgICAgVGhlIGluZGV4IG9mIHRoZSBmcmFtZSB3aXRoaW4gdGhlIGZyYW1lcyBhcnJheSB3aGljaCBzaG91bGQgYmVcclxuICAgICAqICAgICByZXBsYXllZC5cclxuICAgICAqL1xyXG4gICAgdmFyIHJlcGxheUZyYW1lID0gZnVuY3Rpb24gcmVwbGF5RnJhbWUoaW5kZXgpIHtcclxuXHJcbiAgICAgICAgdmFyIGZyYW1lID0gZnJhbWVzW2luZGV4XTtcclxuXHJcbiAgICAgICAgLy8gUmVwbGF5IGFsbCBpbnN0cnVjdGlvbnMgd2l0aGluIHRoZSByZXRyaWV2ZWQgZnJhbWVcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZyYW1lLmluc3RydWN0aW9ucy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgaW5zdHJ1Y3Rpb24gPSBmcmFtZS5pbnN0cnVjdGlvbnNbaV07XHJcbiAgICAgICAgICAgIHBsYXliYWNrVHVubmVsLnJlY2VpdmVJbnN0cnVjdGlvbihpbnN0cnVjdGlvbi5vcGNvZGUsIGluc3RydWN0aW9uLmFyZ3MpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU3RvcmUgY2xpZW50IHN0YXRlIGlmIGZyYW1lIGlzIGZsYWdnZWQgYXMgYSBrZXlmcmFtZVxyXG4gICAgICAgIGlmIChmcmFtZS5rZXlmcmFtZSAmJiAhZnJhbWUuY2xpZW50U3RhdGUpIHtcclxuICAgICAgICAgICAgcGxheWJhY2tDbGllbnQuZXhwb3J0U3RhdGUoZnVuY3Rpb24gc3RvcmVDbGllbnRTdGF0ZShzdGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgZnJhbWUuY2xpZW50U3RhdGUgPSBzdGF0ZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNb3ZlcyB0aGUgcGxheWJhY2sgcG9zaXRpb24gdG8gdGhlIGdpdmVuIGZyYW1lLCByZXNldHRpbmcgdGhlIHN0YXRlIG9mXHJcbiAgICAgKiB0aGUgcGxheWJhY2sgY2xpZW50IGFuZCByZXBsYXlpbmcgZnJhbWVzIGFzIG5lY2Vzc2FyeS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XHJcbiAgICAgKiAgICAgVGhlIGluZGV4IG9mIHRoZSBmcmFtZSB3aGljaCBzaG91bGQgYmVjb21lIHRoZSBuZXcgcGxheWJhY2tcclxuICAgICAqICAgICBwb3NpdGlvbi5cclxuICAgICAqL1xyXG4gICAgdmFyIHNlZWtUb0ZyYW1lID0gZnVuY3Rpb24gc2Vla1RvRnJhbWUoaW5kZXgpIHtcclxuXHJcbiAgICAgICAgdmFyIHN0YXJ0SW5kZXg7XHJcblxyXG4gICAgICAgIC8vIEJhY2sgdXAgdW50aWwgc3RhcnRJbmRleCByZXByZXNlbnRzIGN1cnJlbnQgc3RhdGVcclxuICAgICAgICBmb3IgKHN0YXJ0SW5kZXggPSBpbmRleDsgc3RhcnRJbmRleCA+PSAwOyBzdGFydEluZGV4LS0pIHtcclxuXHJcbiAgICAgICAgICAgIHZhciBmcmFtZSA9IGZyYW1lc1tzdGFydEluZGV4XTtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIHdlJ3ZlIHJlYWNoZWQgdGhlIGN1cnJlbnQgZnJhbWUsIHN0YXJ0SW5kZXggcmVwcmVzZW50c1xyXG4gICAgICAgICAgICAvLyBjdXJyZW50IHN0YXRlIGJ5IGRlZmluaXRpb25cclxuICAgICAgICAgICAgaWYgKHN0YXJ0SW5kZXggPT09IGN1cnJlbnRGcmFtZSlcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgLy8gSWYgZnJhbWUgaGFzIGFzc29jaWF0ZWQgYWJzb2x1dGUgc3RhdGUsIG1ha2UgdGhhdCBmcmFtZSB0aGVcclxuICAgICAgICAgICAgLy8gY3VycmVudCBzdGF0ZVxyXG4gICAgICAgICAgICBpZiAoZnJhbWUuY2xpZW50U3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIHBsYXliYWNrQ2xpZW50LmltcG9ydFN0YXRlKGZyYW1lLmNsaWVudFN0YXRlKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWR2YW5jZSB0byBmcmFtZSBpbmRleCBhZnRlciBjdXJyZW50IHN0YXRlXHJcbiAgICAgICAgc3RhcnRJbmRleCsrO1xyXG5cclxuICAgICAgICAvLyBSZXBsYXkgYW55IGFwcGxpY2FibGUgaW5jcmVtZW50YWwgZnJhbWVzXHJcbiAgICAgICAgZm9yICg7IHN0YXJ0SW5kZXggPD0gaW5kZXg7IHN0YXJ0SW5kZXgrKylcclxuICAgICAgICAgICAgcmVwbGF5RnJhbWUoc3RhcnRJbmRleCk7XHJcblxyXG4gICAgICAgIC8vIEN1cnJlbnQgZnJhbWUgaXMgbm93IGF0IHJlcXVlc3RlZCBpbmRleFxyXG4gICAgICAgIGN1cnJlbnRGcmFtZSA9IGluZGV4O1xyXG5cclxuICAgICAgICAvLyBOb3RpZnkgb2YgY2hhbmdlcyBpbiBwb3NpdGlvblxyXG4gICAgICAgIGlmIChyZWNvcmRpbmcub25zZWVrKVxyXG4gICAgICAgICAgICByZWNvcmRpbmcub25zZWVrKHJlY29yZGluZy5nZXRQb3NpdGlvbigpKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWR2YW5jZXMgcGxheWJhY2sgdG8gdGhlIG5leHQgZnJhbWUgaW4gdGhlIGZyYW1lcyBhcnJheSBhbmQgc2NoZWR1bGVzXHJcbiAgICAgKiBwbGF5YmFjayBvZiB0aGUgZnJhbWUgZm9sbG93aW5nIHRoYXQgZnJhbWUgYmFzZWQgb24gdGhlaXIgYXNzb2NpYXRlZFxyXG4gICAgICogdGltZXN0YW1wcy4gSWYgbm8gZnJhbWVzIGV4aXN0IGFmdGVyIHRoZSBuZXh0IGZyYW1lLCBwbGF5YmFjayBpcyBwYXVzZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGNvbnRpbnVlUGxheWJhY2sgPSBmdW5jdGlvbiBjb250aW51ZVBsYXliYWNrKCkge1xyXG5cclxuICAgICAgICAvLyBBZHZhbmNlIHRvIG5leHQgZnJhbWVcclxuICAgICAgICBzZWVrVG9GcmFtZShjdXJyZW50RnJhbWUgKyAxKTtcclxuXHJcbiAgICAgICAgLy8gSWYgZnJhbWVzIHJlbWFpbiBhZnRlciBhZHZhbmNpbmcsIHNjaGVkdWxlIG5leHQgZnJhbWVcclxuICAgICAgICBpZiAoY3VycmVudEZyYW1lICsgMSA8IGZyYW1lcy5sZW5ndGgpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFB1bGwgdGhlIHVwY29taW5nIGZyYW1lXHJcbiAgICAgICAgICAgIHZhciBuZXh0ID0gZnJhbWVzW2N1cnJlbnRGcmFtZSArIDFdO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSByZWFsIHRpbWVzdGFtcCBjb3JyZXNwb25kaW5nIHRvIHdoZW4gdGhlIG5leHRcclxuICAgICAgICAgICAgLy8gZnJhbWUgYmVnaW5zXHJcbiAgICAgICAgICAgIHZhciBuZXh0UmVhbFRpbWVzdGFtcCA9IG5leHQudGltZXN0YW1wIC0gc3RhcnRWaWRlb1RpbWVzdGFtcCArIHN0YXJ0UmVhbFRpbWVzdGFtcDtcclxuXHJcbiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgcmVsYXRpdmUgZGVsYXkgYmV0d2VlbiB0aGUgY3VycmVudCB0aW1lIGFuZFxyXG4gICAgICAgICAgICAvLyB0aGUgbmV4dCBmcmFtZSBzdGFydFxyXG4gICAgICAgICAgICB2YXIgZGVsYXkgPSBNYXRoLm1heChuZXh0UmVhbFRpbWVzdGFtcCAtIG5ldyBEYXRlKCkuZ2V0VGltZSgpLCAwKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEFkdmFuY2UgdG8gbmV4dCBmcmFtZSBhZnRlciBlbm91Z2ggdGltZSBoYXMgZWxhcHNlZFxyXG4gICAgICAgICAgICBwbGF5YmFja1RpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbiBmcmFtZURlbGF5RWxhcHNlZCgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlUGxheWJhY2soKTtcclxuICAgICAgICAgICAgfSwgZGVsYXkpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSBzdG9wIHBsYXliYWNrXHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZWNvcmRpbmcucGF1c2UoKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbiBuZXcgZnJhbWVzIGhhdmUgYmVjb21lIGF2YWlsYWJsZSB3aGlsZSB0aGUgcmVjb3JkaW5nIGlzXHJcbiAgICAgKiBiZWluZyBkb3dubG9hZGVkLlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1cmF0aW9uXHJcbiAgICAgKiAgICAgVGhlIG5ldyBkdXJhdGlvbiBvZiB0aGUgcmVjb3JkaW5nLCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25wcm9ncmVzcyA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciBwbGF5YmFjayBvZiB0aGUgcmVjb3JkaW5nIGhhcyBzdGFydGVkLlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICovXHJcbiAgICB0aGlzLm9ucGxheSA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciBwbGF5YmFjayBvZiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIHBhdXNlZC4gVGhpcyBtYXlcclxuICAgICAqIGhhcHBlbiB3aGVuIHBsYXliYWNrIGlzIGV4cGxpY2l0bHkgcGF1c2VkIHdpdGggYSBjYWxsIHRvIHBhdXNlKCksIG9yXHJcbiAgICAgKiB3aGVuIHBsYXliYWNrIGlzIGltcGxpY2l0bHkgcGF1c2VkIGR1ZSB0byByZWFjaGluZyB0aGUgZW5kIG9mIHRoZVxyXG4gICAgICogcmVjb3JkaW5nLlxyXG4gICAgICpcclxuICAgICAqIEBldmVudFxyXG4gICAgICovXHJcbiAgICB0aGlzLm9ucGF1c2UgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgdGhlIHBsYXliYWNrIHBvc2l0aW9uIHdpdGhpbiB0aGUgcmVjb3JkaW5nIGNoYW5nZXMuXHJcbiAgICAgKlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gcG9zaXRpb25cclxuICAgICAqICAgICBUaGUgbmV3IHBvc2l0aW9uIHdpdGhpbiB0aGUgcmVjb3JkaW5nLCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25zZWVrID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbm5lY3RzIHRoZSB1bmRlcmx5aW5nIHR1bm5lbCwgYmVnaW5uaW5nIGRvd25sb2FkIG9mIHRoZSBHdWFjYW1vbGVcclxuICAgICAqIHNlc3Npb24uIFBsYXliYWNrIG9mIHRoZSBHdWFjYW1vbGUgc2Vzc2lvbiBjYW5ub3Qgb2NjdXIgdW50aWwgYXQgbGVhc3RcclxuICAgICAqIG9uZSBmcmFtZSB3b3J0aCBvZiBpbnN0cnVjdGlvbnMgaGFzIGJlZW4gZG93bmxvYWRlZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YVxyXG4gICAgICogICAgIFRoZSBkYXRhIHRvIHNlbmQgdG8gdGhlIHR1bm5lbCB3aGVuIGNvbm5lY3RpbmcuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY29ubmVjdCA9IGZ1bmN0aW9uIGNvbm5lY3QoZGF0YSkge1xyXG4gICAgICAgIHR1bm5lbC5jb25uZWN0KGRhdGEpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERpc2Nvbm5lY3RzIHRoZSB1bmRlcmx5aW5nIHR1bm5lbCwgc3RvcHBpbmcgZnVydGhlciBkb3dubG9hZCBvZiB0aGVcclxuICAgICAqIEd1YWNhbW9sZSBzZXNzaW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiBkaXNjb25uZWN0KCkge1xyXG4gICAgICAgIHR1bm5lbC5kaXNjb25uZWN0KCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgdW5kZXJseWluZyBkaXNwbGF5IG9mIHRoZSBHdWFjYW1vbGUuQ2xpZW50IHVzZWQgYnkgdGhpc1xyXG4gICAgICogR3VhY2Ftb2xlLlNlc3Npb25SZWNvcmRpbmcgZm9yIHBsYXliYWNrLiBUaGUgZGlzcGxheSBjb250YWlucyBhbiBFbGVtZW50XHJcbiAgICAgKiB3aGljaCBjYW4gYmUgYWRkZWQgdG8gdGhlIERPTSwgY2F1c2luZyB0aGUgZGlzcGxheSAoYW5kIHRodXMgcGxheWJhY2sgb2ZcclxuICAgICAqIHRoZSByZWNvcmRpbmcpIHRvIGJlY29tZSB2aXNpYmxlLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm4ge0d1YWNhbW9sZS5EaXNwbGF5fVxyXG4gICAgICogICAgIFRoZSB1bmRlcmx5aW5nIGRpc3BsYXkgb2YgdGhlIEd1YWNhbW9sZS5DbGllbnQgdXNlZCBieSB0aGlzXHJcbiAgICAgKiAgICAgR3VhY2Ftb2xlLlNlc3Npb25SZWNvcmRpbmcgZm9yIHBsYXliYWNrLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmdldERpc3BsYXkgPSBmdW5jdGlvbiBnZXREaXNwbGF5KCkge1xyXG4gICAgICAgIHJldHVybiBwbGF5YmFja0NsaWVudC5nZXREaXNwbGF5KCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB3aGV0aGVyIHBsYXliYWNrIGlzIGN1cnJlbnRseSBpbiBwcm9ncmVzcy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICAgICAqICAgICB0cnVlIGlmIHBsYXliYWNrIGlzIGN1cnJlbnRseSBpbiBwcm9ncmVzcywgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmlzUGxheWluZyA9IGZ1bmN0aW9uIGlzUGxheWluZygpIHtcclxuICAgICAgICByZXR1cm4gISFzdGFydFZpZGVvVGltZXN0YW1wO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgcGxheWJhY2sgcG9zaXRpb24gd2l0aGluIHRoZSByZWNvcmRpbmcsIGluXHJcbiAgICAgKiBtaWxsaXNlY29uZHMsIHdoZXJlIHplcm8gaXMgdGhlIHN0YXJ0IG9mIHRoZSByZWNvcmRpbmcuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge051bWJlcn1cclxuICAgICAqICAgICBUaGUgY3VycmVudCBwbGF5YmFjayBwb3NpdGlvbiB3aXRoaW4gdGhlIHJlY29yZGluZywgaW4gbWlsbGlzZWNvbmRzLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gZ2V0UG9zaXRpb24oKSB7XHJcblxyXG4gICAgICAgIC8vIFBvc2l0aW9uIGlzIHNpbXBseSB6ZXJvIGlmIHBsYXliYWNrIGhhcyBub3Qgc3RhcnRlZCBhdCBhbGxcclxuICAgICAgICBpZiAoY3VycmVudEZyYW1lID09PSAtMSlcclxuICAgICAgICAgICAgcmV0dXJuIDA7XHJcblxyXG4gICAgICAgIC8vIFJldHVybiBjdXJyZW50IHBvc2l0aW9uIGFzIGEgbWlsbGlzZWNvbmQgdGltZXN0YW1wIHJlbGF0aXZlIHRvIHRoZVxyXG4gICAgICAgIC8vIHN0YXJ0IG9mIHRoZSByZWNvcmRpbmdcclxuICAgICAgICByZXR1cm4gdG9SZWxhdGl2ZVRpbWVzdGFtcChmcmFtZXNbY3VycmVudEZyYW1lXS50aW1lc3RhbXApO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBkdXJhdGlvbiBvZiB0aGlzIHJlY29yZGluZywgaW4gbWlsbGlzZWNvbmRzLiBJZiB0aGVcclxuICAgICAqIHJlY29yZGluZyBpcyBzdGlsbCBiZWluZyBkb3dubG9hZGVkLCB0aGlzIHZhbHVlIHdpbGwgZ3JhZHVhbGx5IGluY3JlYXNlLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKiAgICAgVGhlIGR1cmF0aW9uIG9mIHRoaXMgcmVjb3JkaW5nLCBpbiBtaWxsaXNlY29uZHMuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuZ2V0RHVyYXRpb24gPSBmdW5jdGlvbiBnZXREdXJhdGlvbigpIHtcclxuXHJcbiAgICAgICAgLy8gSWYgbm8gZnJhbWVzIHlldCBleGlzdCwgZHVyYXRpb24gaXMgemVyb1xyXG4gICAgICAgIGlmIChmcmFtZXMubGVuZ3RoID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuXHJcbiAgICAgICAgLy8gUmVjb3JkaW5nIGR1cmF0aW9uIGlzIHNpbXBseSB0aGUgdGltZXN0YW1wIG9mIHRoZSBsYXN0IGZyYW1lXHJcbiAgICAgICAgcmV0dXJuIHRvUmVsYXRpdmVUaW1lc3RhbXAoZnJhbWVzW2ZyYW1lcy5sZW5ndGggLSAxXS50aW1lc3RhbXApO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCZWdpbnMgY29udGludW91cyBwbGF5YmFjayBvZiB0aGUgcmVjb3JkaW5nIGRvd25sb2FkZWQgdGh1cyBmYXIuXHJcbiAgICAgKiBQbGF5YmFjayBvZiB0aGUgcmVjb3JkaW5nIHdpbGwgY29udGludWUgdW50aWwgcGF1c2UoKSBpcyBpbnZva2VkIG9yXHJcbiAgICAgKiB1bnRpbCBubyBmdXJ0aGVyIGZyYW1lcyBleGlzdC4gUGxheWJhY2sgaXMgaW5pdGlhbGx5IHBhdXNlZCB3aGVuIGFcclxuICAgICAqIEd1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nIGlzIGNyZWF0ZWQsIGFuZCBtdXN0IGJlIGV4cGxpY2l0bHkgc3RhcnRlZFxyXG4gICAgICogdGhyb3VnaCBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbi4gSWYgcGxheWJhY2sgaXMgYWxyZWFkeSBpbiBwcm9ncmVzcyxcclxuICAgICAqIHRoaXMgZnVuY3Rpb24gaGFzIG5vIGVmZmVjdC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5wbGF5ID0gZnVuY3Rpb24gcGxheSgpIHtcclxuXHJcbiAgICAgICAgLy8gSWYgcGxheWJhY2sgaXMgbm90IGFscmVhZHkgaW4gcHJvZ3Jlc3MgYW5kIGZyYW1lcyByZW1haW4sXHJcbiAgICAgICAgLy8gYmVnaW4gcGxheWJhY2tcclxuICAgICAgICBpZiAoIXJlY29yZGluZy5pc1BsYXlpbmcoKSAmJiBjdXJyZW50RnJhbWUgKyAxIDwgZnJhbWVzLmxlbmd0aCkge1xyXG5cclxuICAgICAgICAgICAgLy8gTm90aWZ5IHRoYXQgcGxheWJhY2sgaXMgc3RhcnRpbmdcclxuICAgICAgICAgICAgaWYgKHJlY29yZGluZy5vbnBsYXkpXHJcbiAgICAgICAgICAgICAgICByZWNvcmRpbmcub25wbGF5KCk7XHJcblxyXG4gICAgICAgICAgICAvLyBTdG9yZSB0aW1lc3RhbXAgb2YgcGxheWJhY2sgc3RhcnQgZm9yIHJlbGF0aXZlIHNjaGVkdWxpbmcgb2ZcclxuICAgICAgICAgICAgLy8gZnV0dXJlIGZyYW1lc1xyXG4gICAgICAgICAgICB2YXIgbmV4dCA9IGZyYW1lc1tjdXJyZW50RnJhbWUgKyAxXTtcclxuICAgICAgICAgICAgc3RhcnRWaWRlb1RpbWVzdGFtcCA9IG5leHQudGltZXN0YW1wO1xyXG4gICAgICAgICAgICBzdGFydFJlYWxUaW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEJlZ2luIHBsYXliYWNrIG9mIHZpZGVvXHJcbiAgICAgICAgICAgIGNvbnRpbnVlUGxheWJhY2soKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZWVrcyB0byB0aGUgZ2l2ZW4gcG9zaXRpb24gd2l0aGluIHRoZSByZWNvcmRpbmcuIElmIHRoZSByZWNvcmRpbmcgaXNcclxuICAgICAqIGN1cnJlbnRseSBiZWluZyBwbGF5ZWQgYmFjaywgcGxheWJhY2sgd2lsbCBjb250aW51ZSBhZnRlciB0aGUgc2VlayBpc1xyXG4gICAgICogcGVyZm9ybWVkLiBJZiB0aGUgcmVjb3JkaW5nIGlzIGN1cnJlbnRseSBwYXVzZWQsIHBsYXliYWNrIHdpbGwgYmVcclxuICAgICAqIHBhdXNlZCBhZnRlciB0aGUgc2VlayBpcyBwZXJmb3JtZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHBvc2l0aW9uXHJcbiAgICAgKiAgICAgVGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgcmVjb3JkaW5nIHRvIHNlZWsgdG8sIGluIG1pbGxpc2Vjb25kcy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zZWVrID0gZnVuY3Rpb24gc2Vlayhwb3NpdGlvbikge1xyXG5cclxuICAgICAgICAvLyBEbyBub3Qgc2VlayBpZiBubyBmcmFtZXMgZXhpc3RcclxuICAgICAgICBpZiAoZnJhbWVzLmxlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBQYXVzZSBwbGF5YmFjaywgcHJlc2VydmluZyBwbGF5YmFjayBzdGF0ZVxyXG4gICAgICAgIHZhciBvcmlnaW5hbGx5UGxheWluZyA9IHJlY29yZGluZy5pc1BsYXlpbmcoKTtcclxuICAgICAgICByZWNvcmRpbmcucGF1c2UoKTtcclxuXHJcbiAgICAgICAgLy8gUGVyZm9ybSBzZWVrXHJcbiAgICAgICAgc2Vla1RvRnJhbWUoZmluZEZyYW1lKDAsIGZyYW1lcy5sZW5ndGggLSAxLCBwb3NpdGlvbikpO1xyXG5cclxuICAgICAgICAvLyBSZXN0b3JlIHBsYXliYWNrIHN0YXRlXHJcbiAgICAgICAgaWYgKG9yaWdpbmFsbHlQbGF5aW5nKVxyXG4gICAgICAgICAgICByZWNvcmRpbmcucGxheSgpO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQYXVzZXMgcGxheWJhY2sgb2YgdGhlIHJlY29yZGluZywgaWYgcGxheWJhY2sgaXMgY3VycmVudGx5IGluIHByb2dyZXNzLlxyXG4gICAgICogSWYgcGxheWJhY2sgaXMgbm90IGluIHByb2dyZXNzLCB0aGlzIGZ1bmN0aW9uIGhhcyBubyBlZmZlY3QuIFBsYXliYWNrIGlzXHJcbiAgICAgKiBpbml0aWFsbHkgcGF1c2VkIHdoZW4gYSBHdWFjYW1vbGUuU2Vzc2lvblJlY29yZGluZyBpcyBjcmVhdGVkLCBhbmQgbXVzdFxyXG4gICAgICogYmUgZXhwbGljaXRseSBzdGFydGVkIHRocm91Z2ggYSBjYWxsIHRvIHBsYXkoKS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5wYXVzZSA9IGZ1bmN0aW9uIHBhdXNlKCkge1xyXG5cclxuICAgICAgICAvLyBTdG9wIHBsYXliYWNrIG9ubHkgaWYgcGxheWJhY2sgaXMgaW4gcHJvZ3Jlc3NcclxuICAgICAgICBpZiAocmVjb3JkaW5nLmlzUGxheWluZygpKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBOb3RpZnkgdGhhdCBwbGF5YmFjayBpcyBzdG9wcGluZ1xyXG4gICAgICAgICAgICBpZiAocmVjb3JkaW5nLm9ucGF1c2UpXHJcbiAgICAgICAgICAgICAgICByZWNvcmRpbmcub25wYXVzZSgpO1xyXG5cclxuICAgICAgICAgICAgLy8gU3RvcCBwbGF5YmFja1xyXG4gICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHBsYXliYWNrVGltZW91dCk7XHJcbiAgICAgICAgICAgIHN0YXJ0VmlkZW9UaW1lc3RhbXAgPSBudWxsO1xyXG4gICAgICAgICAgICBzdGFydFJlYWxUaW1lc3RhbXAgPSBudWxsO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogQSBzaW5nbGUgZnJhbWUgb2YgR3VhY2Ftb2xlIHNlc3Npb24gZGF0YS4gRWFjaCBmcmFtZSBpcyBtYWRlIHVwIG9mIHRoZSBzZXRcclxuICogb2YgaW5zdHJ1Y3Rpb25zIHVzZWQgdG8gZ2VuZXJhdGUgdGhhdCBmcmFtZSwgYW5kIHRoZSB0aW1lc3RhbXAgYXMgZGljdGF0ZWRcclxuICogYnkgdGhlIFwic3luY1wiIGluc3RydWN0aW9uIHRlcm1pbmF0aW5nIHRoZSBmcmFtZS4gT3B0aW9uYWxseSwgYSBmcmFtZSBtYXlcclxuICogYWxzbyBiZSBhc3NvY2lhdGVkIHdpdGggYSBzbmFwc2hvdCBvZiBHdWFjYW1vbGUgY2xpZW50IHN0YXRlLCBzdWNoIHRoYXQgdGhlXHJcbiAqIGZyYW1lIGNhbiBiZSByZW5kZXJlZCB3aXRob3V0IHJlcGxheWluZyBhbGwgcHJldmlvdXMgZnJhbWVzLlxyXG4gKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtOdW1iZXJ9IHRpbWVzdGFtcFxyXG4gKiAgICAgVGhlIHRpbWVzdGFtcCBvZiB0aGlzIGZyYW1lLCBhcyBkaWN0YXRlZCBieSB0aGUgXCJzeW5jXCIgaW5zdHJ1Y3Rpb24gd2hpY2hcclxuICogICAgIHRlcm1pbmF0ZXMgdGhlIGZyYW1lLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0d1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZS5JbnN0cnVjdGlvbltdfSBpbnN0cnVjdGlvbnNcclxuICogICAgIEFsbCBpbnN0cnVjdGlvbnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBnZW5lcmF0ZSB0aGlzIGZyYW1lIHJlbGF0aXZlIHRvXHJcbiAqICAgICB0aGUgcHJldmlvdXMgZnJhbWUgaW4gdGhlIEd1YWNhbW9sZSBzZXNzaW9uLlxyXG4gKi9cclxuR3VhY2Ftb2xlLlNlc3Npb25SZWNvcmRpbmcuX0ZyYW1lID0gZnVuY3Rpb24gX0ZyYW1lKHRpbWVzdGFtcCwgaW5zdHJ1Y3Rpb25zKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIHRoaXMgZnJhbWUgc2hvdWxkIGJlIHVzZWQgYXMgYSBrZXlmcmFtZSBpZiBwb3NzaWJsZS4gVGhpcyB2YWx1ZVxyXG4gICAgICogaXMgcHVyZWx5IGFkdmlzb3J5LiBUaGUgc3RvcmVkIGNsaWVudFN0YXRlIG11c3QgZXZlbnR1YWxseSBiZSBtYW51YWxseVxyXG4gICAgICogc2V0IGZvciB0aGUgZnJhbWUgdG8gYmUgdXNlZCBhcyBhIGtleWZyYW1lLiBCeSBkZWZhdWx0LCBmcmFtZXMgYXJlIG5vdFxyXG4gICAgICoga2V5ZnJhbWVzLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtCb29sZWFufVxyXG4gICAgICogQGRlZmF1bHQgZmFsc2VcclxuICAgICAqL1xyXG4gICAgdGhpcy5rZXlmcmFtZSA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHRpbWVzdGFtcCBvZiB0aGlzIGZyYW1lLCBhcyBkaWN0YXRlZCBieSB0aGUgXCJzeW5jXCIgaW5zdHJ1Y3Rpb24gd2hpY2hcclxuICAgICAqIHRlcm1pbmF0ZXMgdGhlIGZyYW1lLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMudGltZXN0YW1wID0gdGltZXN0YW1wO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsIGluc3RydWN0aW9ucyB3aGljaCBhcmUgbmVjZXNzYXJ5IHRvIGdlbmVyYXRlIHRoaXMgZnJhbWUgcmVsYXRpdmUgdG9cclxuICAgICAqIHRoZSBwcmV2aW91cyBmcmFtZSBpbiB0aGUgR3VhY2Ftb2xlIHNlc3Npb24uXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZS5JbnN0cnVjdGlvbltdfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmluc3RydWN0aW9ucyA9IGluc3RydWN0aW9ucztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEEgc25hcHNob3Qgb2YgY2xpZW50IHN0YXRlIGFmdGVyIHRoaXMgZnJhbWUgd2FzIHJlbmRlcmVkLCBhcyByZXR1cm5lZCBieVxyXG4gICAgICogYSBjYWxsIHRvIGV4cG9ydFN0YXRlKCkuIElmIG5vIHN1Y2ggc25hcHNob3QgaGFzIGJlZW4gdGFrZW4sIHRoaXMgd2lsbFxyXG4gICAgICogYmUgbnVsbC5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxyXG4gICAgICogQGRlZmF1bHQgbnVsbFxyXG4gICAgICovXHJcbiAgICB0aGlzLmNsaWVudFN0YXRlID0gbnVsbDtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogQSBHdWFjYW1vbGUgcHJvdG9jb2wgaW5zdHJ1Y3Rpb24uIEVhY2ggR3VhY2Ftb2xlIHByb3RvY29sIGluc3RydWN0aW9uIGlzXHJcbiAqIG1hZGUgdXAgb2YgYW4gb3Bjb2RlIGFuZCBzZXQgb2YgYXJndW1lbnRzLlxyXG4gKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtTdHJpbmd9IG9wY29kZVxyXG4gKiAgICAgVGhlIG9wY29kZSBvZiB0aGlzIEd1YWNhbW9sZSBpbnN0cnVjdGlvbi5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmdbXX0gYXJnc1xyXG4gKiAgICAgQWxsIGFyZ3VtZW50cyBhc3NvY2lhdGVkIHdpdGggdGhpcyBHdWFjYW1vbGUgaW5zdHJ1Y3Rpb24uXHJcbiAqL1xyXG5HdWFjYW1vbGUuU2Vzc2lvblJlY29yZGluZy5fRnJhbWUuSW5zdHJ1Y3Rpb24gPSBmdW5jdGlvbiBJbnN0cnVjdGlvbihvcGNvZGUsIGFyZ3MpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZS5JbnN0cnVjdGlvbi5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9GcmFtZS5JbnN0cnVjdGlvbn1cclxuICAgICAqL1xyXG4gICAgdmFyIGluc3RydWN0aW9uID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBvcGNvZGUgb2YgdGhpcyBHdWFjYW1vbGUgaW5zdHJ1Y3Rpb24uXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge1N0cmluZ31cclxuICAgICAqL1xyXG4gICAgdGhpcy5vcGNvZGUgPSBvcGNvZGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbGwgYXJndW1lbnRzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEd1YWNhbW9sZSBpbnN0cnVjdGlvbi5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7U3RyaW5nW119XHJcbiAgICAgKi9cclxuICAgIHRoaXMuYXJncyA9IGFyZ3M7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBhcHByb3hpbWF0ZSBudW1iZXIgb2YgY2hhcmFjdGVycyB3aGljaCBtYWtlIHVwIHRoaXNcclxuICAgICAqIGluc3RydWN0aW9uLiBUaGlzIHZhbHVlIGlzIG9ubHkgYXBwcm94aW1hdGUgYXMgaXQgZXhjbHVkZXMgdGhlIGxlbmd0aFxyXG4gICAgICogcHJlZml4ZXMgYW5kIHZhcmlvdXMgZGVsaW1pdGVycyB1c2VkIGJ5IHRoZSBHdWFjYW1vbGUgcHJvdG9jb2w7IG9ubHlcclxuICAgICAqIHRoZSBjb250ZW50IG9mIHRoZSBvcGNvZGUgYW5kIGVhY2ggYXJndW1lbnQgaXMgdGFrZW4gaW50byBhY2NvdW50LlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtOdW1iZXJ9XHJcbiAgICAgKiAgICAgVGhlIGFwcHJveGltYXRlIHNpemUgb2YgdGhpcyBpbnN0cnVjdGlvbiwgaW4gY2hhcmFjdGVycy5cclxuICAgICAqL1xyXG4gICAgdGhpcy5nZXRTaXplID0gZnVuY3Rpb24gZ2V0U2l6ZSgpIHtcclxuXHJcbiAgICAgICAgLy8gSW5pdCB3aXRoIGxlbmd0aCBvZiBvcGNvZGVcclxuICAgICAgICB2YXIgc2l6ZSA9IGluc3RydWN0aW9uLm9wY29kZS5sZW5ndGg7XHJcblxyXG4gICAgICAgIC8vIEFkZCBsZW5ndGggb2YgYWxsIGFyZ3VtZW50c1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5zdHJ1Y3Rpb24uYXJncy5sZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgc2l6ZSArPSBpbnN0cnVjdGlvbi5hcmdzW2ldLmxlbmd0aDtcclxuXHJcbiAgICAgICAgcmV0dXJuIHNpemU7XHJcblxyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogQSByZWFkLW9ubHkgR3VhY2Ftb2xlLlR1bm5lbCBpbXBsZW1lbnRhdGlvbiB3aGljaCBzdHJlYW1zIGluc3RydWN0aW9uc1xyXG4gKiByZWNlaXZlZCB0aHJvdWdoIGV4cGxpY2l0IGNhbGxzIHRvIGl0cyByZWNlaXZlSW5zdHJ1Y3Rpb24oKSBmdW5jdGlvbi5cclxuICpcclxuICogQHByaXZhdGVcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBhdWdtZW50cyB7R3VhY2Ftb2xlLlR1bm5lbH1cclxuICovXHJcbkd1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9QbGF5YmFja1R1bm5lbCA9IGZ1bmN0aW9uIF9QbGF5YmFja1R1bm5lbCgpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9QbGF5YmFja1R1bm5lbC5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5TZXNzaW9uUmVjb3JkaW5nLl9QbGF5YmFja1R1bm5lbH1cclxuICAgICAqL1xyXG4gICAgdmFyIHR1bm5lbCA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy5jb25uZWN0ID0gZnVuY3Rpb24gY29ubmVjdChkYXRhKSB7XHJcbiAgICAgICAgLy8gRG8gbm90aGluZ1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLnNlbmRNZXNzYWdlID0gZnVuY3Rpb24gc2VuZE1lc3NhZ2UoZWxlbWVudHMpIHtcclxuICAgICAgICAvLyBEbyBub3RoaW5nXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuZGlzY29ubmVjdCA9IGZ1bmN0aW9uIGRpc2Nvbm5lY3QoKSB7XHJcbiAgICAgICAgLy8gRG8gbm90aGluZ1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEludm9rZXMgdGhpcyB0dW5uZWwncyBvbmluc3RydWN0aW9uIGhhbmRsZXIsIG5vdGlmeWluZyB1c2VycyBvZiB0aGlzXHJcbiAgICAgKiB0dW5uZWwgKHN1Y2ggYXMgYSBHdWFjYW1vbGUuQ2xpZW50IGluc3RhbmNlKSB0aGF0IGFuIGluc3RydWN0aW9uIGhhc1xyXG4gICAgICogYmVlbiByZWNlaXZlZC4gSWYgdGhlIG9uaW5zdHJ1Y3Rpb24gaGFuZGxlciBoYXMgbm90IGJlZW4gc2V0LCB0aGlzXHJcbiAgICAgKiBmdW5jdGlvbiBoYXMgbm8gZWZmZWN0LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvcGNvZGVcclxuICAgICAqICAgICBUaGUgb3Bjb2RlIG9mIHRoZSBHdWFjYW1vbGUgaW5zdHJ1Y3Rpb24uXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gYXJnc1xyXG4gICAgICogICAgIEFsbCBhcmd1bWVudHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgR3VhY2Ftb2xlIGluc3RydWN0aW9uLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnJlY2VpdmVJbnN0cnVjdGlvbiA9IGZ1bmN0aW9uIHJlY2VpdmVJbnN0cnVjdGlvbihvcGNvZGUsIGFyZ3MpIHtcclxuICAgICAgICBpZiAodHVubmVsLm9uaW5zdHJ1Y3Rpb24pXHJcbiAgICAgICAgICAgIHR1bm5lbC5vbmluc3RydWN0aW9uKG9wY29kZSwgYXJncyk7XHJcbiAgICB9O1xyXG5cclxufTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIEd1YWNhbW9sZSBzdGF0dXMuIEVhY2ggR3VhY2Ftb2xlIHN0YXR1cyBjb25zaXN0cyBvZiBhIHN0YXR1cyBjb2RlLCBkZWZpbmVkXHJcbiAqIGJ5IHRoZSBwcm90b2NvbCwgYW5kIGFuIG9wdGlvbmFsIGh1bWFuLXJlYWRhYmxlIG1lc3NhZ2UsIHVzdWFsbHkgb25seVxyXG4gKiBpbmNsdWRlZCBmb3IgZGVidWdnaW5nIGNvbnZlbmllbmNlLlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtOdW1iZXJ9IGNvZGVcclxuICogICAgIFRoZSBHdWFjYW1vbGUgc3RhdHVzIGNvZGUsIGFzIGRlZmluZWQgYnkgR3VhY2Ftb2xlLlN0YXR1cy5Db2RlLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gW21lc3NhZ2VdXHJcbiAqICAgICBBbiBvcHRpb25hbCBodW1hbi1yZWFkYWJsZSBtZXNzYWdlLlxyXG4gKi9cclxuR3VhY2Ftb2xlLlN0YXR1cyA9IGZ1bmN0aW9uKGNvZGUsIG1lc3NhZ2UpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5TdGF0dXMuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgZ3VhY19zdGF0dXMgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIEd1YWNhbW9sZSBzdGF0dXMgY29kZS5cclxuICAgICAqIEBzZWUgR3VhY2Ftb2xlLlN0YXR1cy5Db2RlXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLmNvZGUgPSBjb2RlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gYXJiaXRyYXJ5IGh1bWFuLXJlYWRhYmxlIG1lc3NhZ2UgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3RhdHVzLCBpZiBhbnkuXHJcbiAgICAgKiBUaGUgaHVtYW4tcmVhZGFibGUgbWVzc2FnZSBpcyBub3QgcmVxdWlyZWQsIGFuZCBpcyBnZW5lcmFsbHkgcHJvdmlkZWRcclxuICAgICAqIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMgb25seS4gRm9yIHVzZXIgZmVlZGJhY2ssIGl0IGlzIGJldHRlciB0byB0cmFuc2xhdGVcclxuICAgICAqIHRoZSBHdWFjYW1vbGUgc3RhdHVzIGNvZGUgaW50byBhIG1lc3NhZ2UuXHJcbiAgICAgKiBcclxuICAgICAqIEB0eXBlIHtTdHJpbmd9XHJcbiAgICAgKi9cclxuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyBzdGF0dXMgcmVwcmVzZW50cyBhbiBlcnJvci5cclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoaXMgc3RhdHVzIHJlcHJlc2VudHMgYW4gZXJyb3IsIGZhbHNlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmlzRXJyb3IgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gZ3VhY19zdGF0dXMuY29kZSA8IDAgfHwgZ3VhY19zdGF0dXMuY29kZSA+IDB4MDBGRjtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEVudW1lcmF0aW9uIG9mIGFsbCBHdWFjYW1vbGUgc3RhdHVzIGNvZGVzLlxyXG4gKi9cclxuR3VhY2Ftb2xlLlN0YXR1cy5Db2RlID0ge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wZXJhdGlvbiBzdWNjZWVkZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJTVUNDRVNTXCI6IDB4MDAwMCxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSByZXF1ZXN0ZWQgb3BlcmF0aW9uIGlzIHVuc3VwcG9ydGVkLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIFwiVU5TVVBQT1JURURcIjogMHgwMTAwLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGR1ZSB0byBhbiBpbnRlcm5hbCBmYWlsdXJlLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIFwiU0VSVkVSX0VSUk9SXCI6IDB4MDIwMCxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBvcGVyYXRpb24gY291bGQgbm90IGJlIHBlcmZvcm1lZCBhcyB0aGUgc2VydmVyIGlzIGJ1c3kuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJTRVJWRVJfQlVTWVwiOiAweDAyMDEsXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgb3BlcmF0aW9uIGNvdWxkIG5vdCBiZSBwZXJmb3JtZWQgYmVjYXVzZSB0aGUgdXBzdHJlYW0gc2VydmVyIGlzIG5vdFxyXG4gICAgICogcmVzcG9uZGluZy5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBcIlVQU1RSRUFNX1RJTUVPVVRcIjogMHgwMjAyLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wZXJhdGlvbiB3YXMgdW5zdWNjZXNzZnVsIGR1ZSB0byBhbiBlcnJvciBvciBvdGhlcndpc2UgdW5leHBlY3RlZFxyXG4gICAgICogY29uZGl0aW9uIG9mIHRoZSB1cHN0cmVhbSBzZXJ2ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJVUFNUUkVBTV9FUlJPUlwiOiAweDAyMDMsXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgb3BlcmF0aW9uIGNvdWxkIG5vdCBiZSBwZXJmb3JtZWQgYXMgdGhlIHJlcXVlc3RlZCByZXNvdXJjZSBkb2VzIG5vdFxyXG4gICAgICogZXhpc3QuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJSRVNPVVJDRV9OT1RfRk9VTkRcIjogMHgwMjA0LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGFzIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UgaXNcclxuICAgICAqIGFscmVhZHkgaW4gdXNlLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIFwiUkVTT1VSQ0VfQ09ORkxJQ1RcIjogMHgwMjA1LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGFzIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UgaXMgbm93XHJcbiAgICAgKiBjbG9zZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJSRVNPVVJDRV9DTE9TRURcIjogMHgwMjA2LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGJlY2F1c2UgdGhlIHVwc3RyZWFtIHNlcnZlciBkb2VzXHJcbiAgICAgKiBub3QgYXBwZWFyIHRvIGV4aXN0LlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIFwiVVBTVFJFQU1fTk9UX0ZPVU5EXCI6IDB4MDIwNyxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBvcGVyYXRpb24gY291bGQgbm90IGJlIHBlcmZvcm1lZCBiZWNhdXNlIHRoZSB1cHN0cmVhbSBzZXJ2ZXIgaXMgbm90XHJcbiAgICAgKiBhdmFpbGFibGUgdG8gc2VydmljZSB0aGUgcmVxdWVzdC5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBcIlVQU1RSRUFNX1VOQVZBSUxBQkxFXCI6IDB4MDIwOCxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzZXNzaW9uIHdpdGhpbiB0aGUgdXBzdHJlYW0gc2VydmVyIGhhcyBlbmRlZCBiZWNhdXNlIGl0IGNvbmZsaWN0ZWRcclxuICAgICAqIHdpdGggYW5vdGhlciBzZXNzaW9uLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIFwiU0VTU0lPTl9DT05GTElDVFwiOiAweDAyMDksXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgc2Vzc2lvbiB3aXRoaW4gdGhlIHVwc3RyZWFtIHNlcnZlciBoYXMgZW5kZWQgYmVjYXVzZSBpdCBhcHBlYXJlZCB0b1xyXG4gICAgICogYmUgaW5hY3RpdmUuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJTRVNTSU9OX1RJTUVPVVRcIjogMHgwMjBBLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHNlc3Npb24gd2l0aGluIHRoZSB1cHN0cmVhbSBzZXJ2ZXIgaGFzIGJlZW4gZm9yY2libHkgdGVybWluYXRlZC5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBcIlNFU1NJT05fQ0xPU0VEXCI6IDB4MDIwQixcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBvcGVyYXRpb24gY291bGQgbm90IGJlIHBlcmZvcm1lZCBiZWNhdXNlIGJhZCBwYXJhbWV0ZXJzIHdlcmUgZ2l2ZW4uXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJDTElFTlRfQkFEX1JFUVVFU1RcIjogMHgwMzAwLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVybWlzc2lvbiB3YXMgZGVuaWVkIHRvIHBlcmZvcm0gdGhlIG9wZXJhdGlvbiwgYXMgdGhlIHVzZXIgaXMgbm90IHlldFxyXG4gICAgICogYXV0aG9yaXplZCAobm90IHlldCBsb2dnZWQgaW4sIGZvciBleGFtcGxlKS5cclxuICAgICAqXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBcIkNMSUVOVF9VTkFVVEhPUklaRURcIjogMHgwMzAxLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUGVybWlzc2lvbiB3YXMgZGVuaWVkIHRvIHBlcmZvcm0gdGhlIG9wZXJhdGlvbiwgYW5kIHRoaXMgcGVybWlzc2lvbiB3aWxsXHJcbiAgICAgKiBub3QgYmUgZ3JhbnRlZCBldmVuIGlmIHRoZSB1c2VyIGlzIGF1dGhvcml6ZWQuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJDTElFTlRfRk9SQklEREVOXCI6IDB4MDMwMyxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjbGllbnQgdG9vayB0b28gbG9uZyB0byByZXNwb25kLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIFwiQ0xJRU5UX1RJTUVPVVRcIjogMHgwMzA4LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNsaWVudCBzZW50IHRvbyBtdWNoIGRhdGEuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJDTElFTlRfT1ZFUlJVTlwiOiAweDAzMEQsXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY2xpZW50IHNlbnQgZGF0YSBvZiBhbiB1bnN1cHBvcnRlZCBvciB1bmV4cGVjdGVkIHR5cGUuXHJcbiAgICAgKlxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJDTElFTlRfQkFEX1RZUEVcIjogMHgwMzBGLFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG9wZXJhdGlvbiBmYWlsZWQgYmVjYXVzZSB0aGUgY3VycmVudCBjbGllbnQgaXMgYWxyZWFkeSB1c2luZyB0b29cclxuICAgICAqIG1hbnkgcmVzb3VyY2VzLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIFwiQ0xJRU5UX1RPT19NQU5ZXCI6IDB4MDMxRFxyXG5cclxufTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIHJlYWRlciB3aGljaCBhdXRvbWF0aWNhbGx5IGhhbmRsZXMgdGhlIGdpdmVuIGlucHV0IHN0cmVhbSwgcmV0dXJuaW5nXHJcbiAqIHN0cmljdGx5IHRleHQgZGF0YS4gTm90ZSB0aGF0IHRoaXMgb2JqZWN0IHdpbGwgb3ZlcndyaXRlIGFueSBpbnN0YWxsZWQgZXZlbnRcclxuICogaGFuZGxlcnMgb24gdGhlIGdpdmVuIEd1YWNhbW9sZS5JbnB1dFN0cmVhbS5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAcGFyYW0ge0d1YWNhbW9sZS5JbnB1dFN0cmVhbX0gc3RyZWFtIFRoZSBzdHJlYW0gdGhhdCBkYXRhIHdpbGwgYmUgcmVhZFxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20uXHJcbiAqL1xyXG5HdWFjYW1vbGUuU3RyaW5nUmVhZGVyID0gZnVuY3Rpb24oc3RyZWFtKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBHdWFjYW1vbGUuSW5wdXRTdHJlYW0uXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgZ3VhY19yZWFkZXIgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JhcHBlZCBHdWFjYW1vbGUuQXJyYXlCdWZmZXJSZWFkZXIuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5BcnJheUJ1ZmZlclJlYWRlcn1cclxuICAgICAqL1xyXG4gICAgdmFyIGFycmF5X3JlYWRlciA9IG5ldyBHdWFjYW1vbGUuQXJyYXlCdWZmZXJSZWFkZXIoc3RyZWFtKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBudW1iZXIgb2YgYnl0ZXMgcmVtYWluaW5nIGZvciB0aGUgY3VycmVudCBjb2RlcG9pbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBieXRlc19yZW1haW5pbmcgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgY29kZXBvaW50IHZhbHVlLCBhcyBjYWxjdWxhdGVkIGZyb20gYnl0ZXMgcmVhZCBzbyBmYXIuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHZhciBjb2RlcG9pbnQgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyB0aGUgZ2l2ZW4gVVRGLTggZGF0YSBpbnRvIGEgVW5pY29kZSBzdHJpbmcuIFRoZSBkYXRhIG1heSBlbmQgaW5cclxuICAgICAqIHRoZSBtaWRkbGUgb2YgYSBtdWx0aWJ5dGUgY2hhcmFjdGVyLlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYnVmZmVyIEFyYml0cmFyeSBVVEYtOCBkYXRhLlxyXG4gICAgICogQHJldHVybiB7U3RyaW5nfSBBIGRlY29kZWQgVW5pY29kZSBzdHJpbmcuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIF9fZGVjb2RlX3V0ZjgoYnVmZmVyKSB7XHJcblxyXG4gICAgICAgIHZhciB0ZXh0ID0gXCJcIjtcclxuXHJcbiAgICAgICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICBmb3IgKHZhciBpPTA7IGk8Ynl0ZXMubGVuZ3RoOyBpKyspIHtcclxuXHJcbiAgICAgICAgICAgIC8vIEdldCBjdXJyZW50IGJ5dGVcclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gYnl0ZXNbaV07XHJcblxyXG4gICAgICAgICAgICAvLyBTdGFydCBuZXcgY29kZXBvaW50IGlmIG5vdGhpbmcgeWV0IHJlYWRcclxuICAgICAgICAgICAgaWYgKGJ5dGVzX3JlbWFpbmluZyA9PT0gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIDEgYnl0ZSAoMHh4eHh4eHgpXHJcbiAgICAgICAgICAgICAgICBpZiAoKHZhbHVlIHwgMHg3RikgPT09IDB4N0YpXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHZhbHVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyAyIGJ5dGUgKDExMHh4eHh4KVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKHZhbHVlIHwgMHgxRikgPT09IDB4REYpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb2RlcG9pbnQgPSB2YWx1ZSAmIDB4MUY7XHJcbiAgICAgICAgICAgICAgICAgICAgYnl0ZXNfcmVtYWluaW5nID0gMTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyAzIGJ5dGUgKDExMTB4eHh4KVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKHZhbHVlIHwgMHgwRiApPT09IDB4RUYpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb2RlcG9pbnQgPSB2YWx1ZSAmIDB4MEY7XHJcbiAgICAgICAgICAgICAgICAgICAgYnl0ZXNfcmVtYWluaW5nID0gMjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyA0IGJ5dGUgKDExMTEweHh4KVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKHZhbHVlIHwgMHgwNykgPT09IDB4RjcpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb2RlcG9pbnQgPSB2YWx1ZSAmIDB4MDc7XHJcbiAgICAgICAgICAgICAgICAgICAgYnl0ZXNfcmVtYWluaW5nID0gMztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIGJ5dGVcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0ICs9IFwiXFx1RkZGRFwiO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gQ29udGludWUgZXhpc3RpbmcgY29kZXBvaW50ICgxMHh4eHh4eClcclxuICAgICAgICAgICAgZWxzZSBpZiAoKHZhbHVlIHwgMHgzRikgPT09IDB4QkYpIHtcclxuXHJcbiAgICAgICAgICAgICAgICBjb2RlcG9pbnQgPSAoY29kZXBvaW50IDw8IDYpIHwgKHZhbHVlICYgMHgzRik7XHJcbiAgICAgICAgICAgICAgICBieXRlc19yZW1haW5pbmctLTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBXcml0ZSBjb2RlcG9pbnQgaWYgZmluaXNoZWRcclxuICAgICAgICAgICAgICAgIGlmIChieXRlc19yZW1haW5pbmcgPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVwb2ludCk7XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBJbnZhbGlkIGJ5dGVcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBieXRlc19yZW1haW5pbmcgPSAwO1xyXG4gICAgICAgICAgICAgICAgdGV4dCArPSBcIlxcdUZGRkRcIjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0ZXh0O1xyXG5cclxuICAgIH1cclxuXHJcbiAgICAvLyBSZWNlaXZlIGJsb2JzIGFzIHN0cmluZ3NcclxuICAgIGFycmF5X3JlYWRlci5vbmRhdGEgPSBmdW5jdGlvbihidWZmZXIpIHtcclxuXHJcbiAgICAgICAgLy8gRGVjb2RlIFVURi04XHJcbiAgICAgICAgdmFyIHRleHQgPSBfX2RlY29kZV91dGY4KGJ1ZmZlcik7XHJcblxyXG4gICAgICAgIC8vIENhbGwgaGFuZGxlciwgaWYgcHJlc2VudFxyXG4gICAgICAgIGlmIChndWFjX3JlYWRlci5vbnRleHQpXHJcbiAgICAgICAgICAgIGd1YWNfcmVhZGVyLm9udGV4dCh0ZXh0KTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIFNpbXBseSBjYWxsIG9uZW5kIHdoZW4gZW5kIHJlY2VpdmVkXHJcbiAgICBhcnJheV9yZWFkZXIub25lbmQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBpZiAoZ3VhY19yZWFkZXIub25lbmQpXHJcbiAgICAgICAgICAgIGd1YWNfcmVhZGVyLm9uZW5kKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgb25jZSBmb3IgZXZlcnkgYmxvYiBvZiB0ZXh0IGRhdGEgcmVjZWl2ZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgVGhlIGRhdGEgcGFja2V0IHJlY2VpdmVkLlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9udGV4dCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCBvbmNlIHRoaXMgc3RyZWFtIGlzIGZpbmlzaGVkIGFuZCBubyBmdXJ0aGVyIGRhdGEgd2lsbCBiZSB3cml0dGVuLlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKi9cclxuICAgIHRoaXMub25lbmQgPSBudWxsO1xyXG5cclxufTsvKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIEEgd3JpdGVyIHdoaWNoIGF1dG9tYXRpY2FsbHkgd3JpdGVzIHRvIHRoZSBnaXZlbiBvdXRwdXQgc3RyZWFtIHdpdGggdGV4dFxyXG4gKiBkYXRhLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBwYXJhbSB7R3VhY2Ftb2xlLk91dHB1dFN0cmVhbX0gc3RyZWFtIFRoZSBzdHJlYW0gdGhhdCBkYXRhIHdpbGwgYmUgd3JpdHRlblxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0by5cclxuICovXHJcbkd1YWNhbW9sZS5TdHJpbmdXcml0ZXIgPSBmdW5jdGlvbihzdHJlYW0pIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIEd1YWNhbW9sZS5TdHJpbmdXcml0ZXIuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgZ3VhY193cml0ZXIgPSB0aGlzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JhcHBlZCBHdWFjYW1vbGUuQXJyYXlCdWZmZXJXcml0ZXIuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHR5cGUge0d1YWNhbW9sZS5BcnJheUJ1ZmZlcldyaXRlcn1cclxuICAgICAqL1xyXG4gICAgdmFyIGFycmF5X3dyaXRlciA9IG5ldyBHdWFjYW1vbGUuQXJyYXlCdWZmZXJXcml0ZXIoc3RyZWFtKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEludGVybmFsIGJ1ZmZlciBmb3IgVVRGLTggb3V0cHV0LlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDgxOTIpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIG51bWJlciBvZiBieXRlcyBjdXJyZW50bHkgaW4gdGhlIGJ1ZmZlci5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBsZW5ndGggPSAwO1xyXG5cclxuICAgIC8vIFNpbXBseSBjYWxsIG9uYWNrIGZvciBhY2tub3dsZWRnZW1lbnRzXHJcbiAgICBhcnJheV93cml0ZXIub25hY2sgPSBmdW5jdGlvbihzdGF0dXMpIHtcclxuICAgICAgICBpZiAoZ3VhY193cml0ZXIub25hY2spXHJcbiAgICAgICAgICAgIGd1YWNfd3JpdGVyLm9uYWNrKHN0YXR1cyk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXhwYW5kcyB0aGUgc2l6ZSBvZiB0aGUgdW5kZXJseWluZyBidWZmZXIgYnkgdGhlIGdpdmVuIG51bWJlciBvZiBieXRlcyxcclxuICAgICAqIHVwZGF0aW5nIHRoZSBsZW5ndGggYXBwcm9wcmlhdGVseS5cclxuICAgICAqIFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBieXRlcyBUaGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGFkZCB0byB0aGUgdW5kZXJseWluZ1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gX19leHBhbmQoYnl0ZXMpIHtcclxuXHJcbiAgICAgICAgLy8gUmVzaXplIGJ1ZmZlciBpZiBtb3JlIHNwYWNlIG5lZWRlZFxyXG4gICAgICAgIGlmIChsZW5ndGgrYnl0ZXMgPj0gYnVmZmVyLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB2YXIgbmV3X2J1ZmZlciA9IG5ldyBVaW50OEFycmF5KChsZW5ndGgrYnl0ZXMpKjIpO1xyXG4gICAgICAgICAgICBuZXdfYnVmZmVyLnNldChidWZmZXIpO1xyXG4gICAgICAgICAgICBidWZmZXIgPSBuZXdfYnVmZmVyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGVuZ3RoICs9IGJ5dGVzO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGVuZHMgYSBzaW5nbGUgVW5pY29kZSBjaGFyYWN0ZXIgdG8gdGhlIGN1cnJlbnQgYnVmZmVyLCByZXNpemluZyB0aGVcclxuICAgICAqIGJ1ZmZlciBpZiBuZWNlc3NhcnkuIFRoZSBjaGFyYWN0ZXIgd2lsbCBiZSBlbmNvZGVkIGFzIFVURi04LlxyXG4gICAgICogXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvZGVwb2ludCBUaGUgY29kZXBvaW50IG9mIHRoZSBVbmljb2RlIGNoYXJhY3RlciB0b1xyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmQuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIF9fYXBwZW5kX3V0ZjgoY29kZXBvaW50KSB7XHJcblxyXG4gICAgICAgIHZhciBtYXNrO1xyXG4gICAgICAgIHZhciBieXRlcztcclxuXHJcbiAgICAgICAgLy8gMSBieXRlXHJcbiAgICAgICAgaWYgKGNvZGVwb2ludCA8PSAweDdGKSB7XHJcbiAgICAgICAgICAgIG1hc2sgPSAweDAwO1xyXG4gICAgICAgICAgICBieXRlcyA9IDE7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyAyIGJ5dGVcclxuICAgICAgICBlbHNlIGlmIChjb2RlcG9pbnQgPD0gMHg3RkYpIHtcclxuICAgICAgICAgICAgbWFzayA9IDB4QzA7XHJcbiAgICAgICAgICAgIGJ5dGVzID0gMjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIDMgYnl0ZVxyXG4gICAgICAgIGVsc2UgaWYgKGNvZGVwb2ludCA8PSAweEZGRkYpIHtcclxuICAgICAgICAgICAgbWFzayA9IDB4RTA7XHJcbiAgICAgICAgICAgIGJ5dGVzID0gMztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIDQgYnl0ZVxyXG4gICAgICAgIGVsc2UgaWYgKGNvZGVwb2ludCA8PSAweDFGRkZGRikge1xyXG4gICAgICAgICAgICBtYXNrID0gMHhGMDtcclxuICAgICAgICAgICAgYnl0ZXMgPSA0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgaW52YWxpZCBjb2RlcG9pbnQsIGFwcGVuZCByZXBsYWNlbWVudCBjaGFyYWN0ZXJcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgX19hcHBlbmRfdXRmOCgweEZGRkQpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBPZmZzZXQgYnVmZmVyIGJ5IHNpemVcclxuICAgICAgICBfX2V4cGFuZChieXRlcyk7XHJcbiAgICAgICAgdmFyIG9mZnNldCA9IGxlbmd0aCAtIDE7XHJcblxyXG4gICAgICAgIC8vIEFkZCB0cmFpbGluZyBieXRlcywgaWYgYW55XHJcbiAgICAgICAgZm9yICh2YXIgaT0xOyBpPGJ5dGVzOyBpKyspIHtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldC0tXSA9IDB4ODAgfCAoY29kZXBvaW50ICYgMHgzRik7XHJcbiAgICAgICAgICAgIGNvZGVwb2ludCA+Pj0gNjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNldCBpbml0aWFsIGJ5dGVcclxuICAgICAgICBidWZmZXJbb2Zmc2V0XSA9IG1hc2sgfCBjb2RlcG9pbnQ7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGUgZ2l2ZW4gc3RyaW5nIGFzIFVURi04LCByZXR1cm5pbmcgYW4gQXJyYXlCdWZmZXIgY29udGFpbmluZ1xyXG4gICAgICogdGhlIHJlc3VsdGluZyBieXRlcy5cclxuICAgICAqIFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IFRoZSBzdHJpbmcgdG8gZW5jb2RlIGFzIFVURi04LlxyXG4gICAgICogQHJldHVybiB7VWludDhBcnJheX0gVGhlIGVuY29kZWQgVVRGLTggZGF0YS5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gX19lbmNvZGVfdXRmOCh0ZXh0KSB7XHJcblxyXG4gICAgICAgIC8vIEZpbGwgYnVmZmVyIHdpdGggVVRGLThcclxuICAgICAgICBmb3IgKHZhciBpPTA7IGk8dGV4dC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgY29kZXBvaW50ID0gdGV4dC5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgICAgICBfX2FwcGVuZF91dGY4KGNvZGVwb2ludCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBGbHVzaCBidWZmZXJcclxuICAgICAgICBpZiAobGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICB2YXIgb3V0X2J1ZmZlciA9IGJ1ZmZlci5zdWJhcnJheSgwLCBsZW5ndGgpO1xyXG4gICAgICAgICAgICBsZW5ndGggPSAwO1xyXG4gICAgICAgICAgICByZXR1cm4gb3V0X2J1ZmZlcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2VuZHMgdGhlIGdpdmVuIHRleHQuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IFRoZSB0ZXh0IHRvIHNlbmQuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2VuZFRleHQgPSBmdW5jdGlvbih0ZXh0KSB7XHJcbiAgICAgICAgaWYgKHRleHQubGVuZ3RoKVxyXG4gICAgICAgICAgICBhcnJheV93cml0ZXIuc2VuZERhdGEoX19lbmNvZGVfdXRmOCh0ZXh0KSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2lnbmFscyB0aGF0IG5vIGZ1cnRoZXIgdGV4dCB3aWxsIGJlIHNlbnQsIGVmZmVjdGl2ZWx5IGNsb3NpbmcgdGhlXHJcbiAgICAgKiBzdHJlYW0uXHJcbiAgICAgKi9cclxuICAgIHRoaXMuc2VuZEVuZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGFycmF5X3dyaXRlci5zZW5kRW5kKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZWQgZm9yIHJlY2VpdmVkIGRhdGEsIGlmIGFja25vd2xlZGdlZCBieSB0aGUgc2VydmVyLlxyXG4gICAgICogQGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5TdGF0dXN9IHN0YXR1cyBUaGUgc3RhdHVzIG9mIHRoZSBvcGVyYXRpb24uXHJcbiAgICAgKi9cclxuICAgIHRoaXMub25hY2sgPSBudWxsO1xyXG5cclxufTsvKlxyXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXHJcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxyXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxyXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXHJcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcclxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXHJcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuICpcclxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxyXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxyXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcclxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xyXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG52YXIgR3VhY2Ftb2xlID0gR3VhY2Ftb2xlIHx8IHt9O1xyXG5cclxuLyoqXHJcbiAqIENvcmUgb2JqZWN0IHByb3ZpZGluZyBhYnN0cmFjdCBjb21tdW5pY2F0aW9uIGZvciBHdWFjYW1vbGUuIFRoaXMgb2JqZWN0XHJcbiAqIGlzIGEgbnVsbCBpbXBsZW1lbnRhdGlvbiB3aG9zZSBmdW5jdGlvbnMgZG8gbm90aGluZy4gR3VhY2Ftb2xlIGFwcGxpY2F0aW9uc1xyXG4gKiBzaG91bGQgdXNlIHtAbGluayBHdWFjYW1vbGUuSFRUUFR1bm5lbH0gaW5zdGVhZCwgb3IgaW1wbGVtZW50IHRoZWlyIG93biB0dW5uZWwgYmFzZWRcclxuICogb24gdGhpcyBvbmUuXHJcbiAqIFxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHNlZSBHdWFjYW1vbGUuSFRUUFR1bm5lbFxyXG4gKi9cclxuR3VhY2Ftb2xlLlR1bm5lbCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29ubmVjdCB0byB0aGUgdHVubmVsIHdpdGggdGhlIGdpdmVuIG9wdGlvbmFsIGRhdGEuIFRoaXMgZGF0YSBpc1xyXG4gICAgICogdHlwaWNhbGx5IHVzZWQgZm9yIGF1dGhlbnRpY2F0aW9uLiBUaGUgZm9ybWF0IG9mIGRhdGEgYWNjZXB0ZWQgaXNcclxuICAgICAqIHVwIHRvIHRoZSB0dW5uZWwgaW1wbGVtZW50YXRpb24uXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIHNlbmQgdG8gdGhlIHR1bm5lbCB3aGVuIGNvbm5lY3RpbmcuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY29ubmVjdCA9IGZ1bmN0aW9uKGRhdGEpIHt9O1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIERpc2Nvbm5lY3QgZnJvbSB0aGUgdHVubmVsLlxyXG4gICAgICovXHJcbiAgICB0aGlzLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbigpIHt9O1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIFNlbmQgdGhlIGdpdmVuIG1lc3NhZ2UgdGhyb3VnaCB0aGUgdHVubmVsIHRvIHRoZSBzZXJ2aWNlIG9uIHRoZSBvdGhlclxyXG4gICAgICogc2lkZS4gQWxsIG1lc3NhZ2VzIGFyZSBndWFyYW50ZWVkIHRvIGJlIHJlY2VpdmVkIGluIHRoZSBvcmRlciBzZW50LlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gey4uLip9IGVsZW1lbnRzXHJcbiAgICAgKiAgICAgVGhlIGVsZW1lbnRzIG9mIHRoZSBtZXNzYWdlIHRvIHNlbmQgdG8gdGhlIHNlcnZpY2Ugb24gdGhlIG90aGVyIHNpZGVcclxuICAgICAqICAgICBvZiB0aGUgdHVubmVsLlxyXG4gICAgICovXHJcbiAgICB0aGlzLnNlbmRNZXNzYWdlID0gZnVuY3Rpb24oZWxlbWVudHMpIHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhpcyB0dW5uZWwuXHJcbiAgICAgKiBcclxuICAgICAqIEB0eXBlIHtOdW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuc3RhdGUgPSBHdWFjYW1vbGUuVHVubmVsLlN0YXRlLkNPTk5FQ1RJTkc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWF4aW11bSBhbW91bnQgb2YgdGltZSB0byB3YWl0IGZvciBkYXRhIHRvIGJlIHJlY2VpdmVkLCBpblxyXG4gICAgICogbWlsbGlzZWNvbmRzLiBJZiBkYXRhIGlzIG5vdCByZWNlaXZlZCB3aXRoaW4gdGhpcyBhbW91bnQgb2YgdGltZSxcclxuICAgICAqIHRoZSB0dW5uZWwgaXMgY2xvc2VkIHdpdGggYW4gZXJyb3IuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDE1MDAwLlxyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICB0aGlzLnJlY2VpdmVUaW1lb3V0ID0gMTUwMDA7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgVVVJRCB1bmlxdWVseSBpZGVudGlmeWluZyB0aGlzIHR1bm5lbC4gSWYgbm90IHlldCBrbm93biwgdGhpcyB3aWxsXHJcbiAgICAgKiBiZSBudWxsLlxyXG4gICAgICpcclxuICAgICAqIEB0eXBlIHtTdHJpbmd9XHJcbiAgICAgKi9cclxuICAgIHRoaXMudXVpZCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlZCB3aGVuZXZlciBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZCBieSB0aGUgdHVubmVsLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXZlbnRcclxuICAgICAqIEBwYXJhbSB7R3VhY2Ftb2xlLlN0YXR1c30gc3RhdHVzIEEgc3RhdHVzIG9iamVjdCB3aGljaCBkZXNjcmliZXMgdGhlXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbmVycm9yID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIHdoZW5ldmVyIHRoZSBzdGF0ZSBvZiB0aGUgdHVubmVsIGNoYW5nZXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXRlIFRoZSBuZXcgc3RhdGUgb2YgdGhlIGNsaWVudC5cclxuICAgICAqL1xyXG4gICAgdGhpcy5vbnN0YXRlY2hhbmdlID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVkIG9uY2UgZm9yIGV2ZXJ5IGNvbXBsZXRlIEd1YWNhbW9sZSBpbnN0cnVjdGlvbiByZWNlaXZlZCwgaW4gb3JkZXIuXHJcbiAgICAgKiBcclxuICAgICAqIEBldmVudFxyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG9wY29kZSBUaGUgR3VhY2Ftb2xlIGluc3RydWN0aW9uIG9wY29kZS5cclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhcmFtZXRlcnMgVGhlIHBhcmFtZXRlcnMgcHJvdmlkZWQgZm9yIHRoZSBpbnN0cnVjdGlvbixcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgYW55LlxyXG4gICAgICovXHJcbiAgICB0aGlzLm9uaW5zdHJ1Y3Rpb24gPSBudWxsO1xyXG5cclxufTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgR3VhY2Ftb2xlIHByb3RvY29sIGluc3RydWN0aW9uIG9wY29kZSByZXNlcnZlZCBmb3IgYXJiaXRyYXJ5IGludGVybmFsXHJcbiAqIHVzZSBieSB0dW5uZWwgaW1wbGVtZW50YXRpb25zLiBUaGUgdmFsdWUgb2YgdGhpcyBvcGNvZGUgaXMgZ3VhcmFudGVlZCB0byBiZVxyXG4gKiB0aGUgZW1wdHkgc3RyaW5nIChcIlwiKS4gVHVubmVsIGltcGxlbWVudGF0aW9ucyBtYXkgdXNlIHRoaXMgb3Bjb2RlIGZvciBhbnlcclxuICogcHVycG9zZS4gSXQgaXMgY3VycmVudGx5IHVzZWQgYnkgdGhlIEhUVFAgdHVubmVsIHRvIG1hcmsgdGhlIGVuZCBvZiB0aGUgSFRUUFxyXG4gKiByZXNwb25zZSwgYW5kIGJ5IHRoZSBXZWJTb2NrZXQgdHVubmVsIHRvIHRyYW5zbWl0IHRoZSB0dW5uZWwgVVVJRC5cclxuICpcclxuICogQGNvbnN0YW50XHJcbiAqIEB0eXBlIHtTdHJpbmd9XHJcbiAqL1xyXG5HdWFjYW1vbGUuVHVubmVsLklOVEVSTkFMX0RBVEFfT1BDT0RFID0gJyc7XHJcblxyXG4vKipcclxuICogQWxsIHBvc3NpYmxlIHR1bm5lbCBzdGF0ZXMuXHJcbiAqL1xyXG5HdWFjYW1vbGUuVHVubmVsLlN0YXRlID0ge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjb25uZWN0aW9uIGlzIGluIHBlbmRpbmcuIEl0IGlzIG5vdCB5ZXQga25vd24gd2hldGhlciBjb25uZWN0aW9uIHdhc1xyXG4gICAgICogc3VjY2Vzc2Z1bC5cclxuICAgICAqIFxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJDT05ORUNUSU5HXCI6IDAsXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25uZWN0aW9uIHdhcyBzdWNjZXNzZnVsLCBhbmQgZGF0YSBpcyBiZWluZyByZWNlaXZlZC5cclxuICAgICAqIFxyXG4gICAgICogQHR5cGUge051bWJlcn1cclxuICAgICAqL1xyXG4gICAgXCJPUEVOXCI6IDEsXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY29ubmVjdGlvbiBpcyBjbG9zZWQuIENvbm5lY3Rpb24gbWF5IG5vdCBoYXZlIGJlZW4gc3VjY2Vzc2Z1bCwgdGhlXHJcbiAgICAgKiB0dW5uZWwgbWF5IGhhdmUgYmVlbiBleHBsaWNpdGx5IGNsb3NlZCBieSBlaXRoZXIgc2lkZSwgb3IgYW4gZXJyb3IgbWF5XHJcbiAgICAgKiBoYXZlIG9jY3VycmVkLlxyXG4gICAgICogXHJcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBcIkNMT1NFRFwiOiAyXHJcblxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEd1YWNhbW9sZSBUdW5uZWwgaW1wbGVtZW50ZWQgb3ZlciBIVFRQIHZpYSBYTUxIdHRwUmVxdWVzdC5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAYXVnbWVudHMgR3VhY2Ftb2xlLlR1bm5lbFxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gdHVubmVsVVJMXHJcbiAqICAgICBUaGUgVVJMIG9mIHRoZSBIVFRQIHR1bm5lbGluZyBzZXJ2aWNlLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtjcm9zc0RvbWFpbj1mYWxzZV1cclxuICogICAgIFdoZXRoZXIgdHVubmVsIHJlcXVlc3RzIHdpbGwgYmUgY3Jvc3MtZG9tYWluLCBhbmQgdGh1cyBtdXN0IHVzZSBDT1JTXHJcbiAqICAgICBtZWNoYW5pc21zIGFuZCBoZWFkZXJzLiBCeSBkZWZhdWx0LCBpdCBpcyBhc3N1bWVkIHRoYXQgdHVubmVsIHJlcXVlc3RzXHJcbiAqICAgICB3aWxsIGJlIG1hZGUgdG8gdGhlIHNhbWUgZG9tYWluLlxyXG4gKi9cclxuR3VhY2Ftb2xlLkhUVFBUdW5uZWwgPSBmdW5jdGlvbih0dW5uZWxVUkwsIGNyb3NzRG9tYWluKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBIVFRQIHR1bm5lbC5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciB0dW5uZWwgPSB0aGlzO1xyXG5cclxuICAgIHZhciBUVU5ORUxfQ09OTkVDVCA9IHR1bm5lbFVSTCArIFwiP2Nvbm5lY3RcIjtcclxuICAgIHZhciBUVU5ORUxfUkVBRCAgICA9IHR1bm5lbFVSTCArIFwiP3JlYWQ6XCI7XHJcbiAgICB2YXIgVFVOTkVMX1dSSVRFICAgPSB0dW5uZWxVUkwgKyBcIj93cml0ZTpcIjtcclxuXHJcbiAgICB2YXIgUE9MTElOR19FTkFCTEVEICAgICA9IDE7XHJcbiAgICB2YXIgUE9MTElOR19ESVNBQkxFRCAgICA9IDA7XHJcblxyXG4gICAgLy8gRGVmYXVsdCB0byBwb2xsaW5nIC0gd2lsbCBiZSB0dXJuZWQgb2ZmIGF1dG9tYXRpY2FsbHkgaWYgbm90IG5lZWRlZFxyXG4gICAgdmFyIHBvbGxpbmdNb2RlID0gUE9MTElOR19FTkFCTEVEO1xyXG5cclxuICAgIHZhciBzZW5kaW5nTWVzc2FnZXMgPSBmYWxzZTtcclxuICAgIHZhciBvdXRwdXRNZXNzYWdlQnVmZmVyID0gXCJcIjtcclxuXHJcbiAgICAvLyBJZiByZXF1ZXN0cyBhcmUgZXhwZWN0ZWQgdG8gYmUgY3Jvc3MtZG9tYWluLCB0aGUgY29va2llIHRoYXQgdGhlIEhUVFBcclxuICAgIC8vIHR1bm5lbCBkZXBlbmRzIG9uIHdpbGwgb25seSBiZSBzZW50IGlmIHdpdGhDcmVkZW50aWFscyBpcyB0cnVlXHJcbiAgICB2YXIgd2l0aENyZWRlbnRpYWxzID0gISFjcm9zc0RvbWFpbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjdXJyZW50IHJlY2VpdmUgdGltZW91dCBJRCwgaWYgYW55LlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIHJlY2VpdmVfdGltZW91dCA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWF0ZXMgYSB0aW1lb3V0IHdoaWNoLCBpZiBkYXRhIGlzIG5vdCByZWNlaXZlZCwgY2F1c2VzIHRoZSB0dW5uZWxcclxuICAgICAqIHRvIGNsb3NlIHdpdGggYW4gZXJyb3IuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHJlc2V0X3RpbWVvdXQoKSB7XHJcblxyXG4gICAgICAgIC8vIEdldCByaWQgb2Ygb2xkIHRpbWVvdXQgKGlmIGFueSlcclxuICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHJlY2VpdmVfdGltZW91dCk7XHJcblxyXG4gICAgICAgIC8vIFNldCBuZXcgdGltZW91dFxyXG4gICAgICAgIHJlY2VpdmVfdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY2xvc2VfdHVubmVsKG5ldyBHdWFjYW1vbGUuU3RhdHVzKEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5VUFNUUkVBTV9USU1FT1VULCBcIlNlcnZlciB0aW1lb3V0LlwiKSk7XHJcbiAgICAgICAgfSwgdHVubmVsLnJlY2VpdmVUaW1lb3V0KTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDbG9zZXMgdGhpcyB0dW5uZWwsIHNpZ25hbGluZyB0aGUgZ2l2ZW4gc3RhdHVzIGFuZCBjb3JyZXNwb25kaW5nXHJcbiAgICAgKiBtZXNzYWdlLCB3aGljaCB3aWxsIGJlIHNlbnQgdG8gdGhlIG9uZXJyb3IgaGFuZGxlciBpZiB0aGUgc3RhdHVzIGlzXHJcbiAgICAgKiBhbiBlcnJvciBzdGF0dXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5TdGF0dXN9IHN0YXR1cyBUaGUgc3RhdHVzIGNhdXNpbmcgdGhlIGNvbm5lY3Rpb24gdG9cclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlO1xyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBjbG9zZV90dW5uZWwoc3RhdHVzKSB7XHJcblxyXG4gICAgICAgIC8vIElnbm9yZSBpZiBhbHJlYWR5IGNsb3NlZFxyXG4gICAgICAgIGlmICh0dW5uZWwuc3RhdGUgPT09IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuQ0xPU0VEKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIElmIGNvbm5lY3Rpb24gY2xvc2VkIGFibm9ybWFsbHksIHNpZ25hbCBlcnJvci5cclxuICAgICAgICBpZiAoc3RhdHVzLmNvZGUgIT09IEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5TVUNDRVNTICYmIHR1bm5lbC5vbmVycm9yKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBJZ25vcmUgUkVTT1VSQ0VfTk9UX0ZPVU5EIGlmIHdlJ3ZlIGFscmVhZHkgY29ubmVjdGVkLCBhcyB0aGF0XHJcbiAgICAgICAgICAgIC8vIG9ubHkgc2lnbmFscyBlbmQtb2Ytc3RyZWFtIGZvciB0aGUgSFRUUCB0dW5uZWwuXHJcbiAgICAgICAgICAgIGlmICh0dW5uZWwuc3RhdGUgPT09IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuQ09OTkVDVElOR1xyXG4gICAgICAgICAgICAgICAgICAgIHx8IHN0YXR1cy5jb2RlICE9PSBHdWFjYW1vbGUuU3RhdHVzLkNvZGUuUkVTT1VSQ0VfTk9UX0ZPVU5EKVxyXG4gICAgICAgICAgICAgICAgdHVubmVsLm9uZXJyb3Ioc3RhdHVzKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBNYXJrIGFzIGNsb3NlZFxyXG4gICAgICAgIHR1bm5lbC5zdGF0ZSA9IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuQ0xPU0VEO1xyXG5cclxuICAgICAgICAvLyBSZXNldCBvdXRwdXQgbWVzc2FnZSBidWZmZXJcclxuICAgICAgICBzZW5kaW5nTWVzc2FnZXMgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgaWYgKHR1bm5lbC5vbnN0YXRlY2hhbmdlKVxyXG4gICAgICAgICAgICB0dW5uZWwub25zdGF0ZWNoYW5nZSh0dW5uZWwuc3RhdGUpO1xyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgdGhpcy5zZW5kTWVzc2FnZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAvLyBEbyBub3QgYXR0ZW1wdCB0byBzZW5kIG1lc3NhZ2VzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAodHVubmVsLnN0YXRlICE9PSBHdWFjYW1vbGUuVHVubmVsLlN0YXRlLk9QRU4pXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gRG8gbm90IGF0dGVtcHQgdG8gc2VuZCBlbXB0eSBtZXNzYWdlc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIHRoZSBnaXZlbiB2YWx1ZSB0byBhIGxlbmd0aC9zdHJpbmcgcGFpciBmb3IgdXNlIGFzIGFuXHJcbiAgICAgICAgICogZWxlbWVudCBpbiBhIEd1YWNhbW9sZSBpbnN0cnVjdGlvbi5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cclxuICAgICAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBjb252ZXJ0ZWQgdmFsdWUuIFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIGdldEVsZW1lbnQodmFsdWUpIHtcclxuICAgICAgICAgICAgdmFyIHN0cmluZyA9IG5ldyBTdHJpbmcodmFsdWUpO1xyXG4gICAgICAgICAgICByZXR1cm4gc3RyaW5nLmxlbmd0aCArIFwiLlwiICsgc3RyaW5nOyBcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEluaXRpYWxpemVkIG1lc3NhZ2Ugd2l0aCBmaXJzdCBlbGVtZW50XHJcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBnZXRFbGVtZW50KGFyZ3VtZW50c1swXSk7XHJcblxyXG4gICAgICAgIC8vIEFwcGVuZCByZW1haW5pbmcgZWxlbWVudHNcclxuICAgICAgICBmb3IgKHZhciBpPTE7IGk8YXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICBtZXNzYWdlICs9IFwiLFwiICsgZ2V0RWxlbWVudChhcmd1bWVudHNbaV0pO1xyXG5cclxuICAgICAgICAvLyBGaW5hbCB0ZXJtaW5hdG9yXHJcbiAgICAgICAgbWVzc2FnZSArPSBcIjtcIjtcclxuXHJcbiAgICAgICAgLy8gQWRkIG1lc3NhZ2UgdG8gYnVmZmVyXHJcbiAgICAgICAgb3V0cHV0TWVzc2FnZUJ1ZmZlciArPSBtZXNzYWdlO1xyXG5cclxuICAgICAgICAvLyBTZW5kIGlmIG5vdCBjdXJyZW50bHkgc2VuZGluZ1xyXG4gICAgICAgIGlmICghc2VuZGluZ01lc3NhZ2VzKVxyXG4gICAgICAgICAgICBzZW5kUGVuZGluZ01lc3NhZ2VzKCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBzZW5kUGVuZGluZ01lc3NhZ2VzKCkge1xyXG5cclxuICAgICAgICAvLyBEbyBub3QgYXR0ZW1wdCB0byBzZW5kIG1lc3NhZ2VzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAodHVubmVsLnN0YXRlICE9PSBHdWFjYW1vbGUuVHVubmVsLlN0YXRlLk9QRU4pXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgaWYgKG91dHB1dE1lc3NhZ2VCdWZmZXIubGVuZ3RoID4gMCkge1xyXG5cclxuICAgICAgICAgICAgc2VuZGluZ01lc3NhZ2VzID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIHZhciBtZXNzYWdlX3htbGh0dHByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgICAgIG1lc3NhZ2VfeG1saHR0cHJlcXVlc3Qub3BlbihcIlBPU1RcIiwgVFVOTkVMX1dSSVRFICsgdHVubmVsLnV1aWQpO1xyXG4gICAgICAgICAgICBtZXNzYWdlX3htbGh0dHByZXF1ZXN0LndpdGhDcmVkZW50aWFscyA9IHdpdGhDcmVkZW50aWFscztcclxuICAgICAgICAgICAgbWVzc2FnZV94bWxodHRwcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC10eXBlXCIsIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIpO1xyXG5cclxuICAgICAgICAgICAgLy8gT25jZSByZXNwb25zZSByZWNlaXZlZCwgc2VuZCBuZXh0IHF1ZXVlZCBldmVudC5cclxuICAgICAgICAgICAgbWVzc2FnZV94bWxodHRwcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlX3htbGh0dHByZXF1ZXN0LnJlYWR5U3RhdGUgPT09IDQpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyBzZW5kLCBoYW5kbGUgaXRcclxuICAgICAgICAgICAgICAgICAgICBpZiAobWVzc2FnZV94bWxodHRwcmVxdWVzdC5zdGF0dXMgIT09IDIwMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlSFRUUFR1bm5lbEVycm9yKG1lc3NhZ2VfeG1saHR0cHJlcXVlc3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIGNvbnRpbnVlIHRoZSBzZW5kIGxvb3BcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQZW5kaW5nTWVzc2FnZXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBtZXNzYWdlX3htbGh0dHByZXF1ZXN0LnNlbmQob3V0cHV0TWVzc2FnZUJ1ZmZlcik7XHJcbiAgICAgICAgICAgIG91dHB1dE1lc3NhZ2VCdWZmZXIgPSBcIlwiOyAvLyBDbGVhciBidWZmZXJcclxuXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgc2VuZGluZ01lc3NhZ2VzID0gZmFsc2U7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGhhbmRsZUhUVFBUdW5uZWxFcnJvcih4bWxodHRwcmVxdWVzdCkge1xyXG5cclxuICAgICAgICB2YXIgY29kZSA9IHBhcnNlSW50KHhtbGh0dHByZXF1ZXN0LmdldFJlc3BvbnNlSGVhZGVyKFwiR3VhY2Ftb2xlLVN0YXR1cy1Db2RlXCIpKTtcclxuICAgICAgICB2YXIgbWVzc2FnZSA9IHhtbGh0dHByZXF1ZXN0LmdldFJlc3BvbnNlSGVhZGVyKFwiR3VhY2Ftb2xlLUVycm9yLU1lc3NhZ2VcIik7XHJcblxyXG4gICAgICAgIGNsb3NlX3R1bm5lbChuZXcgR3VhY2Ftb2xlLlN0YXR1cyhjb2RlLCBtZXNzYWdlKSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlKHhtbGh0dHByZXF1ZXN0KSB7XHJcblxyXG4gICAgICAgIHZhciBpbnRlcnZhbCA9IG51bGw7XHJcbiAgICAgICAgdmFyIG5leHRSZXF1ZXN0ID0gbnVsbDtcclxuXHJcbiAgICAgICAgdmFyIGRhdGFVcGRhdGVFdmVudHMgPSAwO1xyXG5cclxuICAgICAgICAvLyBUaGUgbG9jYXRpb24gb2YgdGhlIGxhc3QgZWxlbWVudCdzIHRlcm1pbmF0b3JcclxuICAgICAgICB2YXIgZWxlbWVudEVuZCA9IC0xO1xyXG5cclxuICAgICAgICAvLyBXaGVyZSB0byBzdGFydCB0aGUgbmV4dCBsZW5ndGggc2VhcmNoIG9yIHRoZSBuZXh0IGVsZW1lbnRcclxuICAgICAgICB2YXIgc3RhcnRJbmRleCA9IDA7XHJcblxyXG4gICAgICAgIC8vIFBhcnNlZCBlbGVtZW50c1xyXG4gICAgICAgIHZhciBlbGVtZW50cyA9IG5ldyBBcnJheSgpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBwYXJzZVJlc3BvbnNlKCkge1xyXG5cclxuICAgICAgICAgICAgLy8gRG8gbm90IGhhbmRsZSByZXNwb25zZXMgaWYgbm90IGNvbm5lY3RlZFxyXG4gICAgICAgICAgICBpZiAodHVubmVsLnN0YXRlICE9PSBHdWFjYW1vbGUuVHVubmVsLlN0YXRlLk9QRU4pIHtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgLy8gQ2xlYW4gdXAgaW50ZXJ2YWwgaWYgcG9sbGluZ1xyXG4gICAgICAgICAgICAgICAgaWYgKGludGVydmFsICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBwYXJzZSByZXNwb25zZSB5ZXQgaWYgbm90IHJlYWR5XHJcbiAgICAgICAgICAgIGlmICh4bWxodHRwcmVxdWVzdC5yZWFkeVN0YXRlIDwgMikgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgLy8gQXR0ZW1wdCB0byByZWFkIHN0YXR1c1xyXG4gICAgICAgICAgICB2YXIgc3RhdHVzO1xyXG4gICAgICAgICAgICB0cnkgeyBzdGF0dXMgPSB4bWxodHRwcmVxdWVzdC5zdGF0dXM7IH1cclxuXHJcbiAgICAgICAgICAgIC8vIElmIHN0YXR1cyBjb3VsZCBub3QgYmUgcmVhZCwgYXNzdW1lIHN1Y2Nlc3NmdWwuXHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7IHN0YXR1cyA9IDIwMDsgfVxyXG5cclxuICAgICAgICAgICAgLy8gU3RhcnQgbmV4dCByZXF1ZXN0IGFzIHNvb24gYXMgcG9zc2libGUgSUYgcmVxdWVzdCB3YXMgc3VjY2Vzc2Z1bFxyXG4gICAgICAgICAgICBpZiAoIW5leHRSZXF1ZXN0ICYmIHN0YXR1cyA9PT0gMjAwKVxyXG4gICAgICAgICAgICAgICAgbmV4dFJlcXVlc3QgPSBtYWtlUmVxdWVzdCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gUGFyc2Ugc3RyZWFtIHdoZW4gZGF0YSBpcyByZWNlaXZlZCBhbmQgd2hlbiBjb21wbGV0ZS5cclxuICAgICAgICAgICAgaWYgKHhtbGh0dHByZXF1ZXN0LnJlYWR5U3RhdGUgPT09IDMgfHxcclxuICAgICAgICAgICAgICAgIHhtbGh0dHByZXF1ZXN0LnJlYWR5U3RhdGUgPT09IDQpIHtcclxuXHJcbiAgICAgICAgICAgICAgICByZXNldF90aW1lb3V0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQWxzbyBwb2xsIGV2ZXJ5IDMwbXMgKHNvbWUgYnJvd3NlcnMgZG9uJ3QgcmVwZWF0ZWRseSBjYWxsIG9ucmVhZHlzdGF0ZWNoYW5nZSBmb3IgbmV3IGRhdGEpXHJcbiAgICAgICAgICAgICAgICBpZiAocG9sbGluZ01vZGUgPT09IFBPTExJTkdfRU5BQkxFRCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh4bWxodHRwcmVxdWVzdC5yZWFkeVN0YXRlID09PSAzICYmICFpbnRlcnZhbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChwYXJzZVJlc3BvbnNlLCAzMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeG1saHR0cHJlcXVlc3QucmVhZHlTdGF0ZSA9PT0gNCAmJiBpbnRlcnZhbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSWYgY2FuY2VsZWQsIHN0b3AgdHJhbnNmZXJcclxuICAgICAgICAgICAgICAgIGlmICh4bWxodHRwcmVxdWVzdC5zdGF0dXMgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0dW5uZWwuZGlzY29ubmVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBIYWx0IG9uIGVycm9yIGR1cmluZyByZXF1ZXN0XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh4bWxodHRwcmVxdWVzdC5zdGF0dXMgIT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZUhUVFBUdW5uZWxFcnJvcih4bWxodHRwcmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIEF0dGVtcHQgdG8gcmVhZCBpbi1wcm9ncmVzcyBkYXRhXHJcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudDtcclxuICAgICAgICAgICAgICAgIHRyeSB7IGN1cnJlbnQgPSB4bWxodHRwcmVxdWVzdC5yZXNwb25zZVRleHQ7IH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgYXR0ZW1wdCB0byBwYXJzZSBpZiBkYXRhIGNvdWxkIG5vdCBiZSByZWFkXHJcbiAgICAgICAgICAgICAgICBjYXRjaCAoZSkgeyByZXR1cm47IH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBXaGlsZSBzZWFyY2ggaXMgd2l0aGluIGN1cnJlbnRseSByZWNlaXZlZCBkYXRhXHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoZWxlbWVudEVuZCA8IGN1cnJlbnQubGVuZ3RoKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHdlIGFyZSB3YWl0aW5nIGZvciBlbGVtZW50IGRhdGFcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudEVuZCA+PSBzdGFydEluZGV4KSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBub3cgaGF2ZSBlbm91Z2ggZGF0YSBmb3IgdGhlIGVsZW1lbnQuIFBhcnNlLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IGN1cnJlbnQuc3Vic3RyaW5nKHN0YXJ0SW5kZXgsIGVsZW1lbnRFbmQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVybWluYXRvciA9IGN1cnJlbnQuc3Vic3RyaW5nKGVsZW1lbnRFbmQsIGVsZW1lbnRFbmQrMSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgZWxlbWVudCB0byBhcnJheVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgbGFzdCBlbGVtZW50LCBoYW5kbGUgaW5zdHJ1Y3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlcm1pbmF0b3IgPT09IFwiO1wiKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IG9wY29kZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9wY29kZSA9IGVsZW1lbnRzLnNoaWZ0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2FsbCBpbnN0cnVjdGlvbiBoYW5kbGVyLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR1bm5lbC5vbmluc3RydWN0aW9uKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1bm5lbC5vbmluc3RydWN0aW9uKG9wY29kZSwgZWxlbWVudHMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENsZWFyIGVsZW1lbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RhcnQgc2VhcmNoaW5nIGZvciBsZW5ndGggYXQgY2hhcmFjdGVyIGFmdGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgdGVybWluYXRvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydEluZGV4ID0gZWxlbWVudEVuZCArIDE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2VhcmNoIGZvciBlbmQgb2YgbGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlbmd0aEVuZCA9IGN1cnJlbnQuaW5kZXhPZihcIi5cIiwgc3RhcnRJbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxlbmd0aEVuZCAhPT0gLTEpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gcGFyc2VJbnQoY3VycmVudC5zdWJzdHJpbmcoZWxlbWVudEVuZCsxLCBsZW5ndGhFbmQpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHdlJ3JlIGRvbmUgcGFyc2luZywgaGFuZGxlIHRoZSBuZXh0IHJlc3BvbnNlLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2xlYW4gdXAgaW50ZXJ2YWwgaWYgcG9sbGluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludGVydmFsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIG9iamVjdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1saHR0cHJlcXVlc3Qub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbGh0dHByZXF1ZXN0LmFib3J0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RhcnQgaGFuZGxpbmcgbmV4dCByZXF1ZXN0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFJlcXVlc3QpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlUmVzcG9uc2UobmV4dFJlcXVlc3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvbmUgcGFyc2luZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgc3RhcnQgb2YgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydEluZGV4ID0gbGVuZ3RoRW5kICsgMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBsb2NhdGlvbiBvZiBlbGVtZW50IHRlcm1pbmF0b3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudEVuZCA9IHN0YXJ0SW5kZXggKyBsZW5ndGg7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBubyBwZXJpb2QgeWV0LCBjb250aW51ZSBzZWFyY2ggd2hlbiBtb3JlIGRhdGFcclxuICAgICAgICAgICAgICAgICAgICAvLyBpcyByZWNlaXZlZFxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydEluZGV4ID0gY3VycmVudC5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB9IC8vIGVuZCBwYXJzZSBsb29wXHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgcmVzcG9uc2UgcG9sbGluZyBlbmFibGVkLCBhdHRlbXB0IHRvIGRldGVjdCBpZiBzdGlsbFxyXG4gICAgICAgIC8vIG5lY2Vzc2FyeSAodmlhIHdyYXBwaW5nIHBhcnNlUmVzcG9uc2UoKSlcclxuICAgICAgICBpZiAocG9sbGluZ01vZGUgPT09IFBPTExJTkdfRU5BQkxFRCkge1xyXG4gICAgICAgICAgICB4bWxodHRwcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiB3ZSByZWNlaXZlIHR3byBvciBtb3JlIHJlYWR5U3RhdGU9PTMgZXZlbnRzLFxyXG4gICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgbm8gbmVlZCB0byBwb2xsLlxyXG4gICAgICAgICAgICAgICAgaWYgKHhtbGh0dHByZXF1ZXN0LnJlYWR5U3RhdGUgPT09IDMpIHtcclxuICAgICAgICAgICAgICAgICAgICBkYXRhVXBkYXRlRXZlbnRzKys7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFVcGRhdGVFdmVudHMgPj0gMikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2xsaW5nTW9kZSA9IFBPTExJTkdfRElTQUJMRUQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHhtbGh0dHByZXF1ZXN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHBhcnNlUmVzcG9uc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHBhcnNlUmVzcG9uc2UoKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSwganVzdCBwYXJzZVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgeG1saHR0cHJlcXVlc3Qub25yZWFkeXN0YXRlY2hhbmdlID0gcGFyc2VSZXNwb25zZTtcclxuXHJcbiAgICAgICAgcGFyc2VSZXNwb25zZSgpO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFyYml0cmFyeSBpbnRlZ2VyLCB1bmlxdWUgZm9yIGVhY2ggdHVubmVsIHJlYWQgcmVxdWVzdC5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciByZXF1ZXN0X2lkID0gMDtcclxuXHJcbiAgICBmdW5jdGlvbiBtYWtlUmVxdWVzdCgpIHtcclxuXHJcbiAgICAgICAgLy8gTWFrZSByZXF1ZXN0LCBpbmNyZW1lbnQgcmVxdWVzdCBJRFxyXG4gICAgICAgIHZhciB4bWxodHRwcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG4gICAgICAgIHhtbGh0dHByZXF1ZXN0Lm9wZW4oXCJHRVRcIiwgVFVOTkVMX1JFQUQgKyB0dW5uZWwudXVpZCArIFwiOlwiICsgKHJlcXVlc3RfaWQrKykpO1xyXG4gICAgICAgIHhtbGh0dHByZXF1ZXN0LndpdGhDcmVkZW50aWFscyA9IHdpdGhDcmVkZW50aWFscztcclxuICAgICAgICB4bWxodHRwcmVxdWVzdC5zZW5kKG51bGwpO1xyXG5cclxuICAgICAgICByZXR1cm4geG1saHR0cHJlcXVlc3Q7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY29ubmVjdCA9IGZ1bmN0aW9uKGRhdGEpIHtcclxuXHJcbiAgICAgICAgLy8gU3RhcnQgd2FpdGluZyBmb3IgY29ubmVjdFxyXG4gICAgICAgIHJlc2V0X3RpbWVvdXQoKTtcclxuXHJcbiAgICAgICAgLy8gU3RhcnQgdHVubmVsIGFuZCBjb25uZWN0XHJcbiAgICAgICAgdmFyIGNvbm5lY3RfeG1saHR0cHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICBjb25uZWN0X3htbGh0dHByZXF1ZXN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAgICAgaWYgKGNvbm5lY3RfeG1saHR0cHJlcXVlc3QucmVhZHlTdGF0ZSAhPT0gNClcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIC8vIElmIGZhaWx1cmUsIHRocm93IGVycm9yXHJcbiAgICAgICAgICAgIGlmIChjb25uZWN0X3htbGh0dHByZXF1ZXN0LnN0YXR1cyAhPT0gMjAwKSB7XHJcbiAgICAgICAgICAgICAgICBoYW5kbGVIVFRQVHVubmVsRXJyb3IoY29ubmVjdF94bWxodHRwcmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJlc2V0X3RpbWVvdXQoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEdldCBVVUlEIGZyb20gcmVzcG9uc2VcclxuICAgICAgICAgICAgdHVubmVsLnV1aWQgPSBjb25uZWN0X3htbGh0dHByZXF1ZXN0LnJlc3BvbnNlVGV4dDtcclxuXHJcbiAgICAgICAgICAgIHR1bm5lbC5zdGF0ZSA9IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuT1BFTjtcclxuICAgICAgICAgICAgaWYgKHR1bm5lbC5vbnN0YXRlY2hhbmdlKVxyXG4gICAgICAgICAgICAgICAgdHVubmVsLm9uc3RhdGVjaGFuZ2UodHVubmVsLnN0YXRlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFN0YXJ0IHJlYWRpbmcgZGF0YVxyXG4gICAgICAgICAgICBoYW5kbGVSZXNwb25zZShtYWtlUmVxdWVzdCgpKTtcclxuXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29ubmVjdF94bWxodHRwcmVxdWVzdC5vcGVuKFwiUE9TVFwiLCBUVU5ORUxfQ09OTkVDVCwgdHJ1ZSk7XHJcbiAgICAgICAgY29ubmVjdF94bWxodHRwcmVxdWVzdC53aXRoQ3JlZGVudGlhbHMgPSB3aXRoQ3JlZGVudGlhbHM7XHJcbiAgICAgICAgY29ubmVjdF94bWxodHRwcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC10eXBlXCIsIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIpO1xyXG4gICAgICAgIGNvbm5lY3RfeG1saHR0cHJlcXVlc3Quc2VuZChkYXRhKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuZGlzY29ubmVjdCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGNsb3NlX3R1bm5lbChuZXcgR3VhY2Ftb2xlLlN0YXR1cyhHdWFjYW1vbGUuU3RhdHVzLkNvZGUuU1VDQ0VTUywgXCJNYW51YWxseSBjbG9zZWQuXCIpKTtcclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuR3VhY2Ftb2xlLkhUVFBUdW5uZWwucHJvdG90eXBlID0gbmV3IEd1YWNhbW9sZS5UdW5uZWwoKTtcclxuXHJcbi8qKlxyXG4gKiBHdWFjYW1vbGUgVHVubmVsIGltcGxlbWVudGVkIG92ZXIgV2ViU29ja2V0IHZpYSBYTUxIdHRwUmVxdWVzdC5cclxuICogXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAYXVnbWVudHMgR3VhY2Ftb2xlLlR1bm5lbFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gdHVubmVsVVJMIFRoZSBVUkwgb2YgdGhlIFdlYlNvY2tldCB0dW5uZWxpbmcgc2VydmljZS5cclxuICovXHJcbkd1YWNhbW9sZS5XZWJTb2NrZXRUdW5uZWwgPSBmdW5jdGlvbih0dW5uZWxVUkwpIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZmVyZW5jZSB0byB0aGlzIFdlYlNvY2tldCB0dW5uZWwuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgdHVubmVsID0gdGhpcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBXZWJTb2NrZXQgdXNlZCBieSB0aGlzIHR1bm5lbC5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBzb2NrZXQgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgcmVjZWl2ZSB0aW1lb3V0IElELCBpZiBhbnkuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICB2YXIgcmVjZWl2ZV90aW1lb3V0ID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBXZWJTb2NrZXQgcHJvdG9jb2wgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvdG9jb2wgdXNlZCBmb3IgdGhlIGN1cnJlbnRcclxuICAgICAqIGxvY2F0aW9uLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIHdzX3Byb3RvY29sID0ge1xyXG4gICAgICAgIFwiaHR0cDpcIjogIFwid3M6XCIsXHJcbiAgICAgICAgXCJodHRwczpcIjogXCJ3c3M6XCJcclxuICAgIH07XHJcblxyXG4gICAgLy8gVHJhbnNmb3JtIGN1cnJlbnQgVVJMIHRvIFdlYlNvY2tldCBVUkxcclxuXHJcbiAgICAvLyBJZiBub3QgYWxyZWFkeSBhIHdlYnNvY2tldCBVUkxcclxuICAgIGlmICggICB0dW5uZWxVUkwuc3Vic3RyaW5nKDAsIDMpICE9PSBcIndzOlwiXHJcbiAgICAgICAgJiYgdHVubmVsVVJMLnN1YnN0cmluZygwLCA0KSAhPT0gXCJ3c3M6XCIpIHtcclxuXHJcbiAgICAgICAgdmFyIHByb3RvY29sID0gd3NfcHJvdG9jb2xbd2luZG93LmxvY2F0aW9uLnByb3RvY29sXTtcclxuXHJcbiAgICAgICAgLy8gSWYgYWJzb2x1dGUgVVJMLCBjb252ZXJ0IHRvIGFic29sdXRlIFdTIFVSTFxyXG4gICAgICAgIGlmICh0dW5uZWxVUkwuc3Vic3RyaW5nKDAsIDEpID09PSBcIi9cIilcclxuICAgICAgICAgICAgdHVubmVsVVJMID1cclxuICAgICAgICAgICAgICAgIHByb3RvY29sXHJcbiAgICAgICAgICAgICAgICArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0XHJcbiAgICAgICAgICAgICAgICArIHR1bm5lbFVSTDtcclxuXHJcbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBjb25zdHJ1Y3QgYWJzb2x1dGUgZnJvbSByZWxhdGl2ZSBVUkxcclxuICAgICAgICBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgIC8vIEdldCBwYXRoIGZyb20gcGF0aG5hbWVcclxuICAgICAgICAgICAgdmFyIHNsYXNoID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLmxhc3RJbmRleE9mKFwiL1wiKTtcclxuICAgICAgICAgICAgdmFyIHBhdGggID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLnN1YnN0cmluZygwLCBzbGFzaCArIDEpO1xyXG5cclxuICAgICAgICAgICAgLy8gQ29uc3RydWN0IGFic29sdXRlIFVSTFxyXG4gICAgICAgICAgICB0dW5uZWxVUkwgPVxyXG4gICAgICAgICAgICAgICAgcHJvdG9jb2xcclxuICAgICAgICAgICAgICAgICsgXCIvL1wiICsgd2luZG93LmxvY2F0aW9uLmhvc3RcclxuICAgICAgICAgICAgICAgICsgcGF0aFxyXG4gICAgICAgICAgICAgICAgKyB0dW5uZWxVUkw7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWF0ZXMgYSB0aW1lb3V0IHdoaWNoLCBpZiBkYXRhIGlzIG5vdCByZWNlaXZlZCwgY2F1c2VzIHRoZSB0dW5uZWxcclxuICAgICAqIHRvIGNsb3NlIHdpdGggYW4gZXJyb3IuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHJlc2V0X3RpbWVvdXQoKSB7XHJcblxyXG4gICAgICAgIC8vIEdldCByaWQgb2Ygb2xkIHRpbWVvdXQgKGlmIGFueSlcclxuICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHJlY2VpdmVfdGltZW91dCk7XHJcblxyXG4gICAgICAgIC8vIFNldCBuZXcgdGltZW91dFxyXG4gICAgICAgIHJlY2VpdmVfdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY2xvc2VfdHVubmVsKG5ldyBHdWFjYW1vbGUuU3RhdHVzKEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5VUFNUUkVBTV9USU1FT1VULCBcIlNlcnZlciB0aW1lb3V0LlwiKSk7XHJcbiAgICAgICAgfSwgdHVubmVsLnJlY2VpdmVUaW1lb3V0KTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDbG9zZXMgdGhpcyB0dW5uZWwsIHNpZ25hbGluZyB0aGUgZ2l2ZW4gc3RhdHVzIGFuZCBjb3JyZXNwb25kaW5nXHJcbiAgICAgKiBtZXNzYWdlLCB3aGljaCB3aWxsIGJlIHNlbnQgdG8gdGhlIG9uZXJyb3IgaGFuZGxlciBpZiB0aGUgc3RhdHVzIGlzXHJcbiAgICAgKiBhbiBlcnJvciBzdGF0dXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5TdGF0dXN9IHN0YXR1cyBUaGUgc3RhdHVzIGNhdXNpbmcgdGhlIGNvbm5lY3Rpb24gdG9cclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlO1xyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBjbG9zZV90dW5uZWwoc3RhdHVzKSB7XHJcblxyXG4gICAgICAgIC8vIElnbm9yZSBpZiBhbHJlYWR5IGNsb3NlZFxyXG4gICAgICAgIGlmICh0dW5uZWwuc3RhdGUgPT09IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuQ0xPU0VEKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIElmIGNvbm5lY3Rpb24gY2xvc2VkIGFibm9ybWFsbHksIHNpZ25hbCBlcnJvci5cclxuICAgICAgICBpZiAoc3RhdHVzLmNvZGUgIT09IEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5TVUNDRVNTICYmIHR1bm5lbC5vbmVycm9yKVxyXG4gICAgICAgICAgICB0dW5uZWwub25lcnJvcihzdGF0dXMpO1xyXG5cclxuICAgICAgICAvLyBNYXJrIGFzIGNsb3NlZFxyXG4gICAgICAgIHR1bm5lbC5zdGF0ZSA9IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuQ0xPU0VEO1xyXG4gICAgICAgIGlmICh0dW5uZWwub25zdGF0ZWNoYW5nZSlcclxuICAgICAgICAgICAgdHVubmVsLm9uc3RhdGVjaGFuZ2UodHVubmVsLnN0YXRlKTtcclxuXHJcbiAgICAgICAgc29ja2V0LmNsb3NlKCk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc2VuZE1lc3NhZ2UgPSBmdW5jdGlvbihlbGVtZW50cykge1xyXG5cclxuICAgICAgICAvLyBEbyBub3QgYXR0ZW1wdCB0byBzZW5kIG1lc3NhZ2VzIGlmIG5vdCBjb25uZWN0ZWRcclxuICAgICAgICBpZiAodHVubmVsLnN0YXRlICE9PSBHdWFjYW1vbGUuVHVubmVsLlN0YXRlLk9QRU4pXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gRG8gbm90IGF0dGVtcHQgdG8gc2VuZCBlbXB0eSBtZXNzYWdlc1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIHRoZSBnaXZlbiB2YWx1ZSB0byBhIGxlbmd0aC9zdHJpbmcgcGFpciBmb3IgdXNlIGFzIGFuXHJcbiAgICAgICAgICogZWxlbWVudCBpbiBhIEd1YWNhbW9sZSBpbnN0cnVjdGlvbi5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cclxuICAgICAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBjb252ZXJ0ZWQgdmFsdWUuIFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIGdldEVsZW1lbnQodmFsdWUpIHtcclxuICAgICAgICAgICAgdmFyIHN0cmluZyA9IG5ldyBTdHJpbmcodmFsdWUpO1xyXG4gICAgICAgICAgICByZXR1cm4gc3RyaW5nLmxlbmd0aCArIFwiLlwiICsgc3RyaW5nOyBcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEluaXRpYWxpemVkIG1lc3NhZ2Ugd2l0aCBmaXJzdCBlbGVtZW50XHJcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBnZXRFbGVtZW50KGFyZ3VtZW50c1swXSk7XHJcblxyXG4gICAgICAgIC8vIEFwcGVuZCByZW1haW5pbmcgZWxlbWVudHNcclxuICAgICAgICBmb3IgKHZhciBpPTE7IGk8YXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICBtZXNzYWdlICs9IFwiLFwiICsgZ2V0RWxlbWVudChhcmd1bWVudHNbaV0pO1xyXG5cclxuICAgICAgICAvLyBGaW5hbCB0ZXJtaW5hdG9yXHJcbiAgICAgICAgbWVzc2FnZSArPSBcIjtcIjtcclxuXHJcbiAgICAgICAgc29ja2V0LnNlbmQobWVzc2FnZSk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmNvbm5lY3QgPSBmdW5jdGlvbihkYXRhKSB7XHJcblxyXG4gICAgICAgIHJlc2V0X3RpbWVvdXQoKTtcclxuXHJcbiAgICAgICAgLy8gQ29ubmVjdCBzb2NrZXRcclxuICAgICAgICBzb2NrZXQgPSBuZXcgV2ViU29ja2V0KHR1bm5lbFVSTCArIFwiP1wiICsgZGF0YSwgXCJndWFjYW1vbGVcIik7XHJcblxyXG4gICAgICAgIHNvY2tldC5vbm9wZW4gPSBmdW5jdGlvbihldmVudCkge1xyXG4gICAgICAgICAgICByZXNldF90aW1lb3V0KCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgc29ja2V0Lm9uY2xvc2UgPSBmdW5jdGlvbihldmVudCkge1xyXG4gICAgICAgICAgICBjbG9zZV90dW5uZWwobmV3IEd1YWNhbW9sZS5TdGF0dXMocGFyc2VJbnQoZXZlbnQucmVhc29uKSwgZXZlbnQucmVhc29uKSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBcclxuICAgICAgICBzb2NrZXQub25lcnJvciA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGNsb3NlX3R1bm5lbChuZXcgR3VhY2Ftb2xlLlN0YXR1cyhHdWFjYW1vbGUuU3RhdHVzLkNvZGUuU0VSVkVSX0VSUk9SLCBldmVudC5kYXRhKSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgc29ja2V0Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcblxyXG4gICAgICAgICAgICByZXNldF90aW1lb3V0KCk7XHJcblxyXG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IGV2ZW50LmRhdGE7XHJcbiAgICAgICAgICAgIHZhciBzdGFydEluZGV4ID0gMDtcclxuICAgICAgICAgICAgdmFyIGVsZW1lbnRFbmQ7XHJcblxyXG4gICAgICAgICAgICB2YXIgZWxlbWVudHMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIGRvIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZWFyY2ggZm9yIGVuZCBvZiBsZW5ndGhcclxuICAgICAgICAgICAgICAgIHZhciBsZW5ndGhFbmQgPSBtZXNzYWdlLmluZGV4T2YoXCIuXCIsIHN0YXJ0SW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGxlbmd0aEVuZCAhPT0gLTEpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgbGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IHBhcnNlSW50KG1lc3NhZ2Uuc3Vic3RyaW5nKGVsZW1lbnRFbmQrMSwgbGVuZ3RoRW5kKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBzdGFydCBvZiBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRJbmRleCA9IGxlbmd0aEVuZCArIDE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBsb2NhdGlvbiBvZiBlbGVtZW50IHRlcm1pbmF0b3JcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50RW5kID0gc3RhcnRJbmRleCArIGxlbmd0aDtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIC8vIElmIG5vIHBlcmlvZCwgaW5jb21wbGV0ZSBpbnN0cnVjdGlvbi5cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBjbG9zZV90dW5uZWwobmV3IEd1YWNhbW9sZS5TdGF0dXMoR3VhY2Ftb2xlLlN0YXR1cy5Db2RlLlNFUlZFUl9FUlJPUiwgXCJJbmNvbXBsZXRlIGluc3RydWN0aW9uLlwiKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gV2Ugbm93IGhhdmUgZW5vdWdoIGRhdGEgZm9yIHRoZSBlbGVtZW50LiBQYXJzZS5cclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gbWVzc2FnZS5zdWJzdHJpbmcoc3RhcnRJbmRleCwgZWxlbWVudEVuZCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGVybWluYXRvciA9IG1lc3NhZ2Uuc3Vic3RyaW5nKGVsZW1lbnRFbmQsIGVsZW1lbnRFbmQrMSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQWRkIGVsZW1lbnQgdG8gYXJyYXlcclxuICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goZWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSWYgbGFzdCBlbGVtZW50LCBoYW5kbGUgaW5zdHJ1Y3Rpb25cclxuICAgICAgICAgICAgICAgIGlmICh0ZXJtaW5hdG9yID09PSBcIjtcIikge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBHZXQgb3Bjb2RlXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wY29kZSA9IGVsZW1lbnRzLnNoaWZ0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBzdGF0ZSBhbmQgVVVJRCB3aGVuIGZpcnN0IGluc3RydWN0aW9uIHJlY2VpdmVkXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR1bm5lbC5zdGF0ZSAhPT0gR3VhY2Ftb2xlLlR1bm5lbC5TdGF0ZS5PUEVOKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBc3NvY2lhdGUgdHVubmVsIFVVSUQgaWYgcmVjZWl2ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wY29kZSA9PT0gR3VhY2Ftb2xlLlR1bm5lbC5JTlRFUk5BTF9EQVRBX09QQ09ERSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1bm5lbC51dWlkID0gZWxlbWVudHNbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBUdW5uZWwgaXMgbm93IG9wZW4gYW5kIFVVSUQgaXMgYXZhaWxhYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR1bm5lbC5zdGF0ZSA9IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuT1BFTjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR1bm5lbC5vbnN0YXRlY2hhbmdlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHVubmVsLm9uc3RhdGVjaGFuZ2UodHVubmVsLnN0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBDYWxsIGluc3RydWN0aW9uIGhhbmRsZXIuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wY29kZSAhPT0gR3VhY2Ftb2xlLlR1bm5lbC5JTlRFUk5BTF9EQVRBX09QQ09ERSAmJiB0dW5uZWwub25pbnN0cnVjdGlvbilcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHVubmVsLm9uaW5zdHJ1Y3Rpb24ob3Bjb2RlLCBlbGVtZW50cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIENsZWFyIGVsZW1lbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMubGVuZ3RoID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU3RhcnQgc2VhcmNoaW5nIGZvciBsZW5ndGggYXQgY2hhcmFjdGVyIGFmdGVyXHJcbiAgICAgICAgICAgICAgICAvLyBlbGVtZW50IHRlcm1pbmF0b3JcclxuICAgICAgICAgICAgICAgIHN0YXJ0SW5kZXggPSBlbGVtZW50RW5kICsgMTtcclxuXHJcbiAgICAgICAgICAgIH0gd2hpbGUgKHN0YXJ0SW5kZXggPCBtZXNzYWdlLmxlbmd0aCk7XHJcblxyXG4gICAgICAgIH07XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBjbG9zZV90dW5uZWwobmV3IEd1YWNhbW9sZS5TdGF0dXMoR3VhY2Ftb2xlLlN0YXR1cy5Db2RlLlNVQ0NFU1MsIFwiTWFudWFsbHkgY2xvc2VkLlwiKSk7XHJcbiAgICB9O1xyXG5cclxufTtcclxuXHJcbkd1YWNhbW9sZS5XZWJTb2NrZXRUdW5uZWwucHJvdG90eXBlID0gbmV3IEd1YWNhbW9sZS5UdW5uZWwoKTtcclxuXHJcbi8qKlxyXG4gKiBHdWFjYW1vbGUgVHVubmVsIHdoaWNoIGN5Y2xlcyBiZXR3ZWVuIGFsbCBzcGVjaWZpZWQgdHVubmVscyB1bnRpbFxyXG4gKiBubyB0dW5uZWxzIGFyZSBsZWZ0LiBBbm90aGVyIHR1bm5lbCBpcyB1c2VkIGlmIGFuIGVycm9yIG9jY3VycyBidXRcclxuICogbm8gaW5zdHJ1Y3Rpb25zIGhhdmUgYmVlbiByZWNlaXZlZC4gSWYgYW4gaW5zdHJ1Y3Rpb24gaGFzIGJlZW5cclxuICogcmVjZWl2ZWQsIG9yIG5vIHR1bm5lbHMgcmVtYWluLCB0aGUgZXJyb3IgaXMgcGFzc2VkIGRpcmVjdGx5IG91dFxyXG4gKiB0aHJvdWdoIHRoZSBvbmVycm9yIGhhbmRsZXIgKGlmIGRlZmluZWQpLlxyXG4gKiBcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqIEBhdWdtZW50cyBHdWFjYW1vbGUuVHVubmVsXHJcbiAqIEBwYXJhbSB7Li4uKn0gdHVubmVsQ2hhaW5cclxuICogICAgIFRoZSB0dW5uZWxzIHRvIHVzZSwgaW4gb3JkZXIgb2YgcHJpb3JpdHkuXHJcbiAqL1xyXG5HdWFjYW1vbGUuQ2hhaW5lZFR1bm5lbCA9IGZ1bmN0aW9uKHR1bm5lbENoYWluKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhpcyBjaGFpbmVkIHR1bm5lbC5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciBjaGFpbmVkX3R1bm5lbCA9IHRoaXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEYXRhIHBhc3NlZCBpbiB2aWEgY29ubmVjdCgpLCB0byBiZSB1c2VkIGZvclxyXG4gICAgICogd3JhcHBlZCBjYWxscyB0byBvdGhlciB0dW5uZWxzJyBjb25uZWN0KCkgZnVuY3Rpb25zLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIGNvbm5lY3RfZGF0YTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFycmF5IG9mIGFsbCB0dW5uZWxzIHBhc3NlZCB0byB0aGlzIENoYWluZWRUdW5uZWwgdGhyb3VnaCB0aGVcclxuICAgICAqIGNvbnN0cnVjdG9yIGFyZ3VtZW50cy5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHZhciB0dW5uZWxzID0gW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdHVubmVsIGNvbW1pdHRlZCB2aWEgY29tbWl0X3R1bm5lbCgpLCBpZiBhbnksIG9yIG51bGwgaWYgbm8gdHVubmVsXHJcbiAgICAgKiBoYXMgeWV0IGJlZW4gY29tbWl0dGVkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7R3VhY2Ftb2xlLlR1bm5lbH1cclxuICAgICAqL1xyXG4gICAgdmFyIGNvbW1pdHRlZFR1bm5lbCA9IG51bGw7XHJcblxyXG4gICAgLy8gTG9hZCBhbGwgdHVubmVscyBpbnRvIGFycmF5XHJcbiAgICBmb3IgKHZhciBpPTA7IGk8YXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIHR1bm5lbHMucHVzaChhcmd1bWVudHNbaV0pO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB0dW5uZWwuXHJcbiAgICAgKiBcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge0d1YWNhbW9sZS5UdW5uZWx9IHR1bm5lbCBUaGUgdHVubmVsIHRvIHNldCBhcyB0aGUgY3VycmVudCB0dW5uZWwuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGF0dGFjaCh0dW5uZWwpIHtcclxuXHJcbiAgICAgICAgLy8gU2V0IG93biBmdW5jdGlvbnMgdG8gdHVubmVsJ3MgZnVuY3Rpb25zXHJcbiAgICAgICAgY2hhaW5lZF90dW5uZWwuZGlzY29ubmVjdCAgPSB0dW5uZWwuZGlzY29ubmVjdDtcclxuICAgICAgICBjaGFpbmVkX3R1bm5lbC5zZW5kTWVzc2FnZSA9IHR1bm5lbC5zZW5kTWVzc2FnZTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRmFpbHMgdGhlIGN1cnJlbnRseS1hdHRhY2hlZCB0dW5uZWwsIGF0dGFjaGluZyBhIG5ldyB0dW5uZWwgaWZcclxuICAgICAgICAgKiBwb3NzaWJsZS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtHdWFjYW1vbGUuU3RhdHVzfSBbc3RhdHVzXVxyXG4gICAgICAgICAqICAgICBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBmYWlsdXJlIHRoYXQgb2NjdXJlZCBpbiB0aGVcclxuICAgICAgICAgKiAgICAgY3VycmVudGx5LWF0dGFjaGVkIHR1bm5lbCwgaWYga25vd24uXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcmV0dXJuIHtHdWFjYW1vbGUuVHVubmVsfVxyXG4gICAgICAgICAqICAgICBUaGUgbmV4dCB0dW5uZWwsIG9yIG51bGwgaWYgdGhlcmUgYXJlIG5vIG1vcmUgdHVubmVscyB0byB0cnkgb3JcclxuICAgICAgICAgKiAgICAgaWYgbm8gbW9yZSB0dW5uZWxzIHNob3VsZCBiZSB0cmllZC5cclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgZmFpbFR1bm5lbCA9IGZ1bmN0aW9uIGZhaWxUdW5uZWwoc3RhdHVzKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBEbyBub3QgYXR0ZW1wdCB0byBjb250aW51ZSB1c2luZyBuZXh0IHR1bm5lbCBvbiBzZXJ2ZXIgdGltZW91dFxyXG4gICAgICAgICAgICBpZiAoc3RhdHVzICYmIHN0YXR1cy5jb2RlID09PSBHdWFjYW1vbGUuU3RhdHVzLkNvZGUuVVBTVFJFQU1fVElNRU9VVCkge1xyXG4gICAgICAgICAgICAgICAgdHVubmVscyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEdldCBuZXh0IHR1bm5lbFxyXG4gICAgICAgICAgICB2YXIgbmV4dF90dW5uZWwgPSB0dW5uZWxzLnNoaWZ0KCk7XHJcblxyXG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBJUyBhIG5leHQgdHVubmVsLCB0cnkgdXNpbmcgaXQuXHJcbiAgICAgICAgICAgIGlmIChuZXh0X3R1bm5lbCkge1xyXG4gICAgICAgICAgICAgICAgdHVubmVsLm9uZXJyb3IgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgdHVubmVsLm9uaW5zdHJ1Y3Rpb24gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgdHVubmVsLm9uc3RhdGVjaGFuZ2UgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgYXR0YWNoKG5leHRfdHVubmVsKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG5leHRfdHVubmVsO1xyXG5cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBVc2UgdGhlIGN1cnJlbnQgdHVubmVsIGZyb20gdGhpcyBwb2ludCBmb3J3YXJkLiBEbyBub3QgdHJ5IGFueSBtb3JlXHJcbiAgICAgICAgICogdHVubmVscywgZXZlbiBpZiB0aGUgY3VycmVudCB0dW5uZWwgZmFpbHMuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBjb21taXRfdHVubmVsKCkge1xyXG4gICAgICAgICAgICB0dW5uZWwub25zdGF0ZWNoYW5nZSA9IGNoYWluZWRfdHVubmVsLm9uc3RhdGVjaGFuZ2U7XHJcbiAgICAgICAgICAgIHR1bm5lbC5vbmluc3RydWN0aW9uID0gY2hhaW5lZF90dW5uZWwub25pbnN0cnVjdGlvbjtcclxuICAgICAgICAgICAgdHVubmVsLm9uZXJyb3IgPSBjaGFpbmVkX3R1bm5lbC5vbmVycm9yO1xyXG4gICAgICAgICAgICBjaGFpbmVkX3R1bm5lbC51dWlkID0gdHVubmVsLnV1aWQ7XHJcbiAgICAgICAgICAgIGNvbW1pdHRlZFR1bm5lbCA9IHR1bm5lbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFdyYXAgb3duIG9uc3RhdGVjaGFuZ2Ugd2l0aGluIGN1cnJlbnQgdHVubmVsXHJcbiAgICAgICAgdHVubmVsLm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbihzdGF0ZSkge1xyXG5cclxuICAgICAgICAgICAgc3dpdGNoIChzdGF0ZSkge1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIElmIG9wZW4sIHVzZSB0aGlzIHR1bm5lbCBmcm9tIHRoaXMgcG9pbnQgZm9yd2FyZC5cclxuICAgICAgICAgICAgICAgIGNhc2UgR3VhY2Ftb2xlLlR1bm5lbC5TdGF0ZS5PUEVOOlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbW1pdF90dW5uZWwoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhaW5lZF90dW5uZWwub25zdGF0ZWNoYW5nZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5lZF90dW5uZWwub25zdGF0ZWNoYW5nZShzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSWYgY2xvc2VkLCBtYXJrIGZhaWx1cmUsIGF0dGVtcHQgbmV4dCB0dW5uZWxcclxuICAgICAgICAgICAgICAgIGNhc2UgR3VhY2Ftb2xlLlR1bm5lbC5TdGF0ZS5DTE9TRUQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmYWlsVHVubmVsKCkgJiYgY2hhaW5lZF90dW5uZWwub25zdGF0ZWNoYW5nZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5lZF90dW5uZWwub25zdGF0ZWNoYW5nZShzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBXcmFwIG93biBvbmluc3RydWN0aW9uIHdpdGhpbiBjdXJyZW50IHR1bm5lbFxyXG4gICAgICAgIHR1bm5lbC5vbmluc3RydWN0aW9uID0gZnVuY3Rpb24ob3Bjb2RlLCBlbGVtZW50cykge1xyXG5cclxuICAgICAgICAgICAgLy8gQWNjZXB0IGN1cnJlbnQgdHVubmVsXHJcbiAgICAgICAgICAgIGNvbW1pdF90dW5uZWwoKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEludm9rZSBoYW5kbGVyXHJcbiAgICAgICAgICAgIGlmIChjaGFpbmVkX3R1bm5lbC5vbmluc3RydWN0aW9uKVxyXG4gICAgICAgICAgICAgICAgY2hhaW5lZF90dW5uZWwub25pbnN0cnVjdGlvbihvcGNvZGUsIGVsZW1lbnRzKTtcclxuXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gQXR0YWNoIG5leHQgdHVubmVsIG9uIGVycm9yXHJcbiAgICAgICAgdHVubmVsLm9uZXJyb3IgPSBmdW5jdGlvbihzdGF0dXMpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIE1hcmsgZmFpbHVyZSwgYXR0ZW1wdCBuZXh0IHR1bm5lbFxyXG4gICAgICAgICAgICBpZiAoIWZhaWxUdW5uZWwoc3RhdHVzKSAmJiBjaGFpbmVkX3R1bm5lbC5vbmVycm9yKVxyXG4gICAgICAgICAgICAgICAgY2hhaW5lZF90dW5uZWwub25lcnJvcihzdGF0dXMpO1xyXG5cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBBdHRlbXB0IGNvbm5lY3Rpb25cclxuICAgICAgICB0dW5uZWwuY29ubmVjdChjb25uZWN0X2RhdGEpO1xyXG4gICAgICAgIFxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY29ubmVjdCA9IGZ1bmN0aW9uKGRhdGEpIHtcclxuICAgICAgIFxyXG4gICAgICAgIC8vIFJlbWVtYmVyIGNvbm5lY3QgZGF0YVxyXG4gICAgICAgIGNvbm5lY3RfZGF0YSA9IGRhdGE7XHJcblxyXG4gICAgICAgIC8vIEdldCBjb21taXR0ZWQgdHVubmVsIGlmIGV4aXN0cyBvciB0aGUgZmlyc3QgdHVubmVsIG9uIHRoZSBsaXN0XHJcbiAgICAgICAgdmFyIG5leHRfdHVubmVsID0gY29tbWl0dGVkVHVubmVsID8gY29tbWl0dGVkVHVubmVsIDogdHVubmVscy5zaGlmdCgpO1xyXG5cclxuICAgICAgICAvLyBBdHRhY2ggZmlyc3QgdHVubmVsXHJcbiAgICAgICAgaWYgKG5leHRfdHVubmVsKVxyXG4gICAgICAgICAgICBhdHRhY2gobmV4dF90dW5uZWwpO1xyXG5cclxuICAgICAgICAvLyBJZiB0aGVyZSBJUyBubyBmaXJzdCB0dW5uZWwsIGVycm9yXHJcbiAgICAgICAgZWxzZSBpZiAoY2hhaW5lZF90dW5uZWwub25lcnJvcilcclxuICAgICAgICAgICAgY2hhaW5lZF90dW5uZWwub25lcnJvcihHdWFjYW1vbGUuU3RhdHVzLkNvZGUuU0VSVkVSX0VSUk9SLCBcIk5vIHR1bm5lbHMgdG8gdHJ5LlwiKTtcclxuXHJcbiAgICB9O1xyXG4gICAgXHJcbn07XHJcblxyXG5HdWFjYW1vbGUuQ2hhaW5lZFR1bm5lbC5wcm90b3R5cGUgPSBuZXcgR3VhY2Ftb2xlLlR1bm5lbCgpO1xyXG5cclxuLyoqXHJcbiAqIEd1YWNhbW9sZSBUdW5uZWwgd2hpY2ggcmVwbGF5cyBhIEd1YWNhbW9sZSBwcm90b2NvbCBkdW1wIGZyb20gYSBzdGF0aWMgZmlsZVxyXG4gKiByZWNlaXZlZCB2aWEgSFRUUC4gSW5zdHJ1Y3Rpb25zIHdpdGhpbiB0aGUgZmlsZSBhcmUgcGFyc2VkIGFuZCBoYW5kbGVkIGFzXHJcbiAqIHF1aWNrbHkgYXMgcG9zc2libGUsIHdoaWxlIHRoZSBmaWxlIGlzIGJlaW5nIGRvd25sb2FkZWQuXHJcbiAqXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKiBAYXVnbWVudHMgR3VhY2Ftb2xlLlR1bm5lbFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXHJcbiAqICAgICBUaGUgVVJMIG9mIGEgR3VhY2Ftb2xlIHByb3RvY29sIGR1bXAuXHJcbiAqXHJcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2Nyb3NzRG9tYWluPWZhbHNlXVxyXG4gKiAgICAgV2hldGhlciB0dW5uZWwgcmVxdWVzdHMgd2lsbCBiZSBjcm9zcy1kb21haW4sIGFuZCB0aHVzIG11c3QgdXNlIENPUlNcclxuICogICAgIG1lY2hhbmlzbXMgYW5kIGhlYWRlcnMuIEJ5IGRlZmF1bHQsIGl0IGlzIGFzc3VtZWQgdGhhdCB0dW5uZWwgcmVxdWVzdHNcclxuICogICAgIHdpbGwgYmUgbWFkZSB0byB0aGUgc2FtZSBkb21haW4uXHJcbiAqL1xyXG5HdWFjYW1vbGUuU3RhdGljSFRUUFR1bm5lbCA9IGZ1bmN0aW9uIFN0YXRpY0hUVFBUdW5uZWwodXJsLCBjcm9zc0RvbWFpbikge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVmZXJlbmNlIHRvIHRoaXMgR3VhY2Ftb2xlLlN0YXRpY0hUVFBUdW5uZWwuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgdmFyIHR1bm5lbCA9IHRoaXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY3VycmVudCwgaW4tcHJvZ3Jlc3MgSFRUUCByZXF1ZXN0LiBJZiBubyByZXF1ZXN0IGlzIGN1cnJlbnRseSBpblxyXG4gICAgICogcHJvZ3Jlc3MsIHRoaXMgd2lsbCBiZSBudWxsLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAdHlwZSB7WE1MSHR0cFJlcXVlc3R9XHJcbiAgICAgKi9cclxuICAgIHZhciB4aHIgPSBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hhbmdlcyB0aGUgc3RvcmVkIG51bWVyaWMgc3RhdGUgb2YgdGhpcyB0dW5uZWwsIGZpcmluZyB0aGUgb25zdGF0ZWNoYW5nZVxyXG4gICAgICogZXZlbnQgaWYgdGhlIG5ldyBzdGF0ZSBpcyBkaWZmZXJlbnQgYW5kIGEgaGFuZGxlciBoYXMgYmVlbiBkZWZpbmVkLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3RhdGVcclxuICAgICAqICAgICBUaGUgbmV3IHN0YXRlIG9mIHRoaXMgdHVubmVsLlxyXG4gICAgICovXHJcbiAgICB2YXIgc2V0U3RhdGUgPSBmdW5jdGlvbiBzZXRTdGF0ZShzdGF0ZSkge1xyXG5cclxuICAgICAgICAvLyBOb3RpZnkgb25seSBpZiBzdGF0ZSBjaGFuZ2VzXHJcbiAgICAgICAgaWYgKHN0YXRlICE9PSB0dW5uZWwuc3RhdGUpIHtcclxuICAgICAgICAgICAgdHVubmVsLnN0YXRlID0gc3RhdGU7XHJcbiAgICAgICAgICAgIGlmICh0dW5uZWwub25zdGF0ZWNoYW5nZSlcclxuICAgICAgICAgICAgICAgIHR1bm5lbC5vbnN0YXRlY2hhbmdlKHN0YXRlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIEd1YWNhbW9sZSBwcm90b2NvbCBzdGF0dXMgY29kZSB3aGljaCBtb3N0IGNsb3NlbHlcclxuICAgICAqIHJlcHJlc2VudHMgdGhlIGdpdmVuIEhUVFAgc3RhdHVzIGNvZGUuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBodHRwU3RhdHVzXHJcbiAgICAgKiAgICAgVGhlIEhUVFAgc3RhdHVzIGNvZGUgdG8gdHJhbnNsYXRlIGludG8gYSBHdWFjYW1vbGUgcHJvdG9jb2wgc3RhdHVzXHJcbiAgICAgKiAgICAgY29kZS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7TnVtYmVyfVxyXG4gICAgICogICAgIFRoZSBHdWFjYW1vbGUgcHJvdG9jb2wgc3RhdHVzIGNvZGUgd2hpY2ggbW9zdCBjbG9zZWx5IHJlcHJlc2VudHMgdGhlXHJcbiAgICAgKiAgICAgZ2l2ZW4gSFRUUCBzdGF0dXMgY29kZS5cclxuICAgICAqL1xyXG4gICAgdmFyIGdldEd1YWNhbW9sZVN0YXR1c0NvZGUgPSBmdW5jdGlvbiBnZXRHdWFjYW1vbGVTdGF0dXNDb2RlKGh0dHBTdGF0dXMpIHtcclxuXHJcbiAgICAgICAgLy8gVHJhbnNsYXRlIHN0YXR1cyBjb2RlcyB3aXRoIGtub3duIGVxdWl2YWxlbnRzXHJcbiAgICAgICAgc3dpdGNoIChodHRwU3RhdHVzKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBIVFRQIDQwMCAtIEJhZCByZXF1ZXN0XHJcbiAgICAgICAgICAgIGNhc2UgNDAwOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5DTElFTlRfQkFEX1JFUVVFU1Q7XHJcblxyXG4gICAgICAgICAgICAvLyBIVFRQIDQwMyAtIEZvcmJpZGRlblxyXG4gICAgICAgICAgICBjYXNlIDQwMzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBHdWFjYW1vbGUuU3RhdHVzLkNvZGUuQ0xJRU5UX0ZPUkJJRERFTjtcclxuXHJcbiAgICAgICAgICAgIC8vIEhUVFAgNDA0IC0gUmVzb3VyY2Ugbm90IGZvdW5kXHJcbiAgICAgICAgICAgIGNhc2UgNDA0OlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5SRVNPVVJDRV9OT1RfRk9VTkQ7XHJcblxyXG4gICAgICAgICAgICAvLyBIVFRQIDQyOSAtIFRvbyBtYW55IHJlcXVlc3RzXHJcbiAgICAgICAgICAgIGNhc2UgNDI5OlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEd1YWNhbW9sZS5TdGF0dXMuQ29kZS5DTElFTlRfVE9PX01BTlk7XHJcblxyXG4gICAgICAgICAgICAvLyBIVFRQIDUwMyAtIFNlcnZlciB1bmF2YWlsYWJsZVxyXG4gICAgICAgICAgICBjYXNlIDUwMzpcclxuICAgICAgICAgICAgICAgIHJldHVybiBHdWFjYW1vbGUuU3RhdHVzLkNvZGUuU0VSVkVSX0JVU1k7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRGVmYXVsdCBhbGwgb3RoZXIgY29kZXMgdG8gZ2VuZXJpYyBpbnRlcm5hbCBlcnJvclxyXG4gICAgICAgIHJldHVybiBHdWFjYW1vbGUuU3RhdHVzLkNvZGUuU0VSVkVSX0VSUk9SO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5zZW5kTWVzc2FnZSA9IGZ1bmN0aW9uIHNlbmRNZXNzYWdlKGVsZW1lbnRzKSB7XHJcbiAgICAgICAgLy8gRG8gbm90aGluZ1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmNvbm5lY3QgPSBmdW5jdGlvbiBjb25uZWN0KGRhdGEpIHtcclxuXHJcbiAgICAgICAgLy8gRW5zdXJlIGFueSBleGlzdGluZyBjb25uZWN0aW9uIGlzIGtpbGxlZFxyXG4gICAgICAgIHR1bm5lbC5kaXNjb25uZWN0KCk7XHJcblxyXG4gICAgICAgIC8vIENvbm5lY3Rpb24gaXMgbm93IHN0YXJ0aW5nXHJcbiAgICAgICAgc2V0U3RhdGUoR3VhY2Ftb2xlLlR1bm5lbC5TdGF0ZS5DT05ORUNUSU5HKTtcclxuXHJcbiAgICAgICAgLy8gU3RhcnQgYSBuZXcgY29ubmVjdGlvblxyXG4gICAgICAgIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG4gICAgICAgIHhoci5vcGVuKCdHRVQnLCB1cmwpO1xyXG4gICAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSAhIWNyb3NzRG9tYWluO1xyXG4gICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAndGV4dCc7XHJcbiAgICAgICAgeGhyLnNlbmQobnVsbCk7XHJcblxyXG4gICAgICAgIHZhciBvZmZzZXQgPSAwO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgR3VhY2Ftb2xlIHByb3RvY29sIHBhcnNlciBzcGVjaWZpY2FsbHkgZm9yIHRoaXMgY29ubmVjdGlvblxyXG4gICAgICAgIHZhciBwYXJzZXIgPSBuZXcgR3VhY2Ftb2xlLlBhcnNlcigpO1xyXG5cclxuICAgICAgICAvLyBJbnZva2UgdHVubmVsJ3Mgb25pbnN0cnVjdGlvbiBoYW5kbGVyIGZvciBlYWNoIHBhcnNlZCBpbnN0cnVjdGlvblxyXG4gICAgICAgIHBhcnNlci5vbmluc3RydWN0aW9uID0gZnVuY3Rpb24gaW5zdHJ1Y3Rpb25SZWNlaXZlZChvcGNvZGUsIGFyZ3MpIHtcclxuICAgICAgICAgICAgaWYgKHR1bm5lbC5vbmluc3RydWN0aW9uKVxyXG4gICAgICAgICAgICAgICAgdHVubmVsLm9uaW5zdHJ1Y3Rpb24ob3Bjb2RlLCBhcmdzKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBDb250aW51b3VzbHkgcGFyc2UgcmVjZWl2ZWQgZGF0YVxyXG4gICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiByZWFkeVN0YXRlQ2hhbmdlZCgpIHtcclxuXHJcbiAgICAgICAgICAgIC8vIFBhcnNlIHdoaWxlIGRhdGEgaXMgYmVpbmcgcmVjZWl2ZWRcclxuICAgICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSAzIHx8IHhoci5yZWFkeVN0YXRlID09PSA0KSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBvcGVuXHJcbiAgICAgICAgICAgICAgICBzZXRTdGF0ZShHdWFjYW1vbGUuVHVubmVsLlN0YXRlLk9QRU4pO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBidWZmZXIgPSB4aHIucmVzcG9uc2VUZXh0O1xyXG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IGJ1ZmZlci5sZW5ndGg7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUGFyc2Ugb25seSB0aGUgcG9ydGlvbiBvZiBkYXRhIHdoaWNoIGlzIG5ld2x5IHJlY2VpdmVkXHJcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgbGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VyLnJlY2VpdmUoYnVmZmVyLnN1YnN0cmluZyhvZmZzZXQpKTtcclxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBsZW5ndGg7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBDbGVhbiB1cCBhbmQgY2xvc2Ugd2hlbiBkb25lXHJcbiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNClcclxuICAgICAgICAgICAgICAgIHR1bm5lbC5kaXNjb25uZWN0KCk7XHJcblxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIFJlc2V0IHN0YXRlIGFuZCBjbG9zZSB1cG9uIGVycm9yXHJcbiAgICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbiBodHRwRXJyb3IoKSB7XHJcblxyXG4gICAgICAgICAgICAvLyBGYWlsIGlmIGZpbGUgY291bGQgbm90IGJlIGRvd25sb2FkZWQgdmlhIEhUVFBcclxuICAgICAgICAgICAgaWYgKHR1bm5lbC5vbmVycm9yKVxyXG4gICAgICAgICAgICAgICAgdHVubmVsLm9uZXJyb3IobmV3IEd1YWNhbW9sZS5TdGF0dXMoZ2V0R3VhY2Ftb2xlU3RhdHVzQ29kZSh4aHIuc3RhdHVzKSwgeGhyLnN0YXR1c1RleHQpKTtcclxuXHJcbiAgICAgICAgICAgIHR1bm5lbC5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuZGlzY29ubmVjdCA9IGZ1bmN0aW9uIGRpc2Nvbm5lY3QoKSB7XHJcblxyXG4gICAgICAgIC8vIEFib3J0IGFuZCBkaXNwb3NlIG9mIFhIUiBpZiBhIHJlcXVlc3QgaXMgaW4gcHJvZ3Jlc3NcclxuICAgICAgICBpZiAoeGhyKSB7XHJcbiAgICAgICAgICAgIHhoci5hYm9ydCgpO1xyXG4gICAgICAgICAgICB4aHIgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ29ubmVjdGlvbiBpcyBub3cgY2xvc2VkXHJcbiAgICAgICAgc2V0U3RhdGUoR3VhY2Ftb2xlLlR1bm5lbC5TdGF0ZS5DTE9TRUQpO1xyXG5cclxuICAgIH07XHJcblxyXG59O1xyXG5cclxuR3VhY2Ftb2xlLlN0YXRpY0hUVFBUdW5uZWwucHJvdG90eXBlID0gbmV3IEd1YWNhbW9sZS5UdW5uZWwoKTtcclxuLypcclxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxyXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcclxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cclxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxyXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXHJcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxyXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcbiAqXHJcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcclxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cclxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXHJcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcclxuICogdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxudmFyIEd1YWNhbW9sZSA9IEd1YWNhbW9sZSB8fCB7fTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgdW5pcXVlIElEIG9mIHRoaXMgdmVyc2lvbiBvZiB0aGUgR3VhY2Ftb2xlIEphdmFTY3JpcHQgQVBJLiBUaGlzIElEIHdpbGxcclxuICogYmUgdGhlIHZlcnNpb24gc3RyaW5nIG9mIHRoZSBndWFjYW1vbGUtY29tbW9uLWpzIE1hdmVuIHByb2plY3QsIGFuZCBjYW4gYmVcclxuICogdXNlZCBpbiBkb3duc3RyZWFtIGFwcGxpY2F0aW9ucyBhcyBhIHNhbml0eSBjaGVjayB0aGF0IHRoZSBwcm9wZXIgdmVyc2lvblxyXG4gKiBvZiB0aGUgQVBJcyBpcyBiZWluZyB1c2VkIChpbiBjYXNlIGFuIG9sZGVyIHZlcnNpb24gaXMgY2FjaGVkLCBmb3IgZXhhbXBsZSkuXHJcbiAqXHJcbiAqIEB0eXBlIHtTdHJpbmd9XHJcbiAqL1xyXG5HdWFjYW1vbGUuQVBJX1ZFUlNJT04gPSBcIjAuOS4xMi1pbmN1YmF0aW5nXCI7XHJcbi8qXHJcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcclxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXHJcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXHJcbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcclxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxyXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcclxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG4gKlxyXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKlxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXHJcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXHJcbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxyXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXHJcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbnZhciBHdWFjYW1vbGUgPSBHdWFjYW1vbGUgfHwge307XHJcblxyXG4vKipcclxuICogQWJzdHJhY3QgdmlkZW8gcGxheWVyIHdoaWNoIGFjY2VwdHMsIHF1ZXVlcyBhbmQgcGxheXMgYmFjayBhcmJpdHJhcnkgdmlkZW9cclxuICogZGF0YS4gSXQgaXMgdXAgdG8gaW1wbGVtZW50YXRpb25zIG9mIHRoaXMgY2xhc3MgdG8gcHJvdmlkZSBzb21lIG1lYW5zIG9mXHJcbiAqIGhhbmRsaW5nIGEgcHJvdmlkZWQgR3VhY2Ftb2xlLklucHV0U3RyZWFtIGFuZCByZW5kZXJpbmcgdGhlIHJlY2VpdmVkIGRhdGEgdG9cclxuICogdGhlIHByb3ZpZGVkIEd1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllci4gRGF0YSByZWNlaXZlZCBhbG9uZyB0aGVcclxuICogcHJvdmlkZWQgc3RyZWFtIGlzIHRvIGJlIHBsYXllZCBiYWNrIGltbWVkaWF0ZWx5LlxyXG4gKlxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbkd1YWNhbW9sZS5WaWRlb1BsYXllciA9IGZ1bmN0aW9uIFZpZGVvUGxheWVyKCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTm90aWZpZXMgdGhpcyBHdWFjYW1vbGUuVmlkZW9QbGF5ZXIgdGhhdCBhbGwgdmlkZW8gdXAgdG8gdGhlIGN1cnJlbnRcclxuICAgICAqIHBvaW50IGluIHRpbWUgaGFzIGJlZW4gZ2l2ZW4gdmlhIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSwgYW5kIHRoYXQgYW55XHJcbiAgICAgKiBkaWZmZXJlbmNlIGluIHRpbWUgYmV0d2VlbiBxdWV1ZWQgdmlkZW8gZGF0YSBhbmQgdGhlIGN1cnJlbnQgdGltZSBjYW4gYmVcclxuICAgICAqIGNvbnNpZGVyZWQgbGF0ZW5jeS5cclxuICAgICAqL1xyXG4gICAgdGhpcy5zeW5jID0gZnVuY3Rpb24gc3luYygpIHtcclxuICAgICAgICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIC0gZG8gbm90aGluZ1xyXG4gICAgfTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiBtaW1ldHlwZSBpcyBzdXBwb3J0ZWQgYnkgYW55IGJ1aWx0LWluXHJcbiAqIGltcGxlbWVudGF0aW9uIG9mIEd1YWNhbW9sZS5WaWRlb1BsYXllciwgYW5kIHRodXMgd2lsbCBiZSBwcm9wZXJseSBoYW5kbGVkXHJcbiAqIGJ5IEd1YWNhbW9sZS5WaWRlb1BsYXllci5nZXRJbnN0YW5jZSgpLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbWltZXR5cGVcclxuICogICAgIFRoZSBtaW1ldHlwZSB0byBjaGVjay5cclxuICpcclxuICogQHJldHVybnMge0Jvb2xlYW59XHJcbiAqICAgICB0cnVlIGlmIHRoZSBnaXZlbiBtaW1ldHlwZSBpcyBzdXBwb3J0ZWQgYnkgYW55IGJ1aWx0LWluXHJcbiAqICAgICBHdWFjYW1vbGUuVmlkZW9QbGF5ZXIsIGZhbHNlIG90aGVyd2lzZS5cclxuICovXHJcbkd1YWNhbW9sZS5WaWRlb1BsYXllci5pc1N1cHBvcnRlZFR5cGUgPSBmdW5jdGlvbiBpc1N1cHBvcnRlZFR5cGUobWltZXR5cGUpIHtcclxuXHJcbiAgICAvLyBUaGVyZSBhcmUgY3VycmVudGx5IG5vIGJ1aWx0LWluIHZpZGVvIHBsYXllcnMgKGFuZCB0aGVyZWZvcmUgbm9cclxuICAgIC8vIHN1cHBvcnRlZCB0eXBlcylcclxuICAgIHJldHVybiBmYWxzZTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIG1pbWV0eXBlcyBzdXBwb3J0ZWQgYnkgYW55IGJ1aWx0LWluXHJcbiAqIEd1YWNhbW9sZS5WaWRlb1BsYXllciwgaW4gcm91Z2ggb3JkZXIgb2YgcHJpb3JpdHkuIEJld2FyZSB0aGF0IG9ubHkgdGhlIGNvcmVcclxuICogbWltZXR5cGVzIHRoZW1zZWx2ZXMgd2lsbCBiZSBsaXN0ZWQuIEFueSBtaW1ldHlwZSBwYXJhbWV0ZXJzLCBldmVuIHJlcXVpcmVkXHJcbiAqIG9uZXMsIHdpbGwgbm90IGJlIGluY2x1ZGVkIGluIHRoZSBsaXN0LlxyXG4gKlxyXG4gKiBAcmV0dXJucyB7U3RyaW5nW119XHJcbiAqICAgICBBIGxpc3Qgb2YgYWxsIG1pbWV0eXBlcyBzdXBwb3J0ZWQgYnkgYW55IGJ1aWx0LWluIEd1YWNhbW9sZS5WaWRlb1BsYXllcixcclxuICogICAgIGV4Y2x1ZGluZyBhbnkgcGFyYW1ldGVycy5cclxuICovXHJcbkd1YWNhbW9sZS5WaWRlb1BsYXllci5nZXRTdXBwb3J0ZWRUeXBlcyA9IGZ1bmN0aW9uIGdldFN1cHBvcnRlZFR5cGVzKCkge1xyXG5cclxuICAgIC8vIFRoZXJlIGFyZSBjdXJyZW50bHkgbm8gYnVpbHQtaW4gdmlkZW8gcGxheWVycyAoYW5kIHRoZXJlZm9yZSBub1xyXG4gICAgLy8gc3VwcG9ydGVkIHR5cGVzKVxyXG4gICAgcmV0dXJuIFtdO1xyXG5cclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIEd1YWNhbW9sZS5WaWRlb1BsYXllciBwcm92aWRpbmcgc3VwcG9ydCBmb3IgdGhlIGdpdmVuXHJcbiAqIHZpZGVvIGZvcm1hdC4gSWYgc3VwcG9ydCBmb3IgdGhlIGdpdmVuIHZpZGVvIGZvcm1hdCBpcyBub3QgYXZhaWxhYmxlLCBudWxsXHJcbiAqIGlzIHJldHVybmVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0d1YWNhbW9sZS5JbnB1dFN0cmVhbX0gc3RyZWFtXHJcbiAqICAgICBUaGUgR3VhY2Ftb2xlLklucHV0U3RyZWFtIHRvIHJlYWQgdmlkZW8gZGF0YSBmcm9tLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0d1YWNhbW9sZS5EaXNwbGF5LlZpc2libGVMYXllcn0gbGF5ZXJcclxuICogICAgIFRoZSBkZXN0aW5hdGlvbiBsYXllciBpbiB3aGljaCB0aGlzIEd1YWNhbW9sZS5WaWRlb1BsYXllciBzaG91bGQgcGxheVxyXG4gKiAgICAgdGhlIHJlY2VpdmVkIHZpZGVvIGRhdGEuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBtaW1ldHlwZVxyXG4gKiAgICAgVGhlIG1pbWV0eXBlIG9mIHRoZSB2aWRlbyBkYXRhIGluIHRoZSBwcm92aWRlZCBzdHJlYW0uXHJcbiAqXHJcbiAqIEByZXR1cm4ge0d1YWNhbW9sZS5WaWRlb1BsYXllcn1cclxuICogICAgIEEgR3VhY2Ftb2xlLlZpZGVvUGxheWVyIGluc3RhbmNlIHN1cHBvcnRpbmcgdGhlIGdpdmVuIG1pbWV0eXBlIGFuZFxyXG4gKiAgICAgcmVhZGluZyBmcm9tIHRoZSBnaXZlbiBzdHJlYW0sIG9yIG51bGwgaWYgc3VwcG9ydCBmb3IgdGhlIGdpdmVuIG1pbWV0eXBlXHJcbiAqICAgICBpcyBhYnNlbnQuXHJcbiAqL1xyXG5HdWFjYW1vbGUuVmlkZW9QbGF5ZXIuZ2V0SW5zdGFuY2UgPSBmdW5jdGlvbiBnZXRJbnN0YW5jZShzdHJlYW0sIGxheWVyLCBtaW1ldHlwZSkge1xyXG5cclxuICAgIC8vIFRoZXJlIGFyZSBjdXJyZW50bHkgbm8gYnVpbHQtaW4gdmlkZW8gcGxheWVyc1xyXG4gICAgcmV0dXJuIG51bGw7XHJcblxyXG59O1xyXG5cblxuLyoqKiBFWFBPUlRTIEZST00gZXhwb3J0cy1sb2FkZXIgKioqL1xubW9kdWxlLmV4cG9ydHMgPSBHdWFjYW1vbGU7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9ndWFjYW1vbGUtY29tbW9uLWpzLTFjMGVlNDEuanNcbi8vIG1vZHVsZSBpZCA9IDI5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBUb2tlbml6ZXIgPSByZXF1aXJlKFwiLi9Ub2tlbml6ZXIuanNcIik7XG5cbi8qXG5cdE9wdGlvbnM6XG5cblx0eG1sTW9kZTogRGlzYWJsZXMgdGhlIHNwZWNpYWwgYmVoYXZpb3IgZm9yIHNjcmlwdC9zdHlsZSB0YWdzIChmYWxzZSBieSBkZWZhdWx0KVxuXHRsb3dlckNhc2VBdHRyaWJ1dGVOYW1lczogY2FsbCAudG9Mb3dlckNhc2UgZm9yIGVhY2ggYXR0cmlidXRlIG5hbWUgKHRydWUgaWYgeG1sTW9kZSBpcyBgZmFsc2VgKVxuXHRsb3dlckNhc2VUYWdzOiBjYWxsIC50b0xvd2VyQ2FzZSBmb3IgZWFjaCB0YWcgbmFtZSAodHJ1ZSBpZiB4bWxNb2RlIGlzIGBmYWxzZWApXG4qL1xuXG4vKlxuXHRDYWxsYmFja3M6XG5cblx0b25jZGF0YWVuZCxcblx0b25jZGF0YXN0YXJ0LFxuXHRvbmNsb3NldGFnLFxuXHRvbmNvbW1lbnQsXG5cdG9uY29tbWVudGVuZCxcblx0b25lcnJvcixcblx0b25vcGVudGFnLFxuXHRvbnByb2Nlc3NpbmdpbnN0cnVjdGlvbixcblx0b25yZXNldCxcblx0b250ZXh0XG4qL1xuXG52YXIgZm9ybVRhZ3MgPSB7XG5cdGlucHV0OiB0cnVlLFxuXHRvcHRpb246IHRydWUsXG5cdG9wdGdyb3VwOiB0cnVlLFxuXHRzZWxlY3Q6IHRydWUsXG5cdGJ1dHRvbjogdHJ1ZSxcblx0ZGF0YWxpc3Q6IHRydWUsXG5cdHRleHRhcmVhOiB0cnVlXG59O1xuXG52YXIgb3BlbkltcGxpZXNDbG9zZSA9IHtcblx0dHIgICAgICA6IHsgdHI6dHJ1ZSwgdGg6dHJ1ZSwgdGQ6dHJ1ZSB9LFxuXHR0aCAgICAgIDogeyB0aDp0cnVlIH0sXG5cdHRkICAgICAgOiB7IHRoZWFkOnRydWUsIHRoOnRydWUsIHRkOnRydWUgfSxcblx0Ym9keSAgICA6IHsgaGVhZDp0cnVlLCBsaW5rOnRydWUsIHNjcmlwdDp0cnVlIH0sXG5cdGxpICAgICAgOiB7IGxpOnRydWUgfSxcblx0cCAgICAgICA6IHsgcDp0cnVlIH0sXG5cdGgxICAgICAgOiB7IHA6dHJ1ZSB9LFxuXHRoMiAgICAgIDogeyBwOnRydWUgfSxcblx0aDMgICAgICA6IHsgcDp0cnVlIH0sXG5cdGg0ICAgICAgOiB7IHA6dHJ1ZSB9LFxuXHRoNSAgICAgIDogeyBwOnRydWUgfSxcblx0aDYgICAgICA6IHsgcDp0cnVlIH0sXG5cdHNlbGVjdCAgOiBmb3JtVGFncyxcblx0aW5wdXQgICA6IGZvcm1UYWdzLFxuXHRvdXRwdXQgIDogZm9ybVRhZ3MsXG5cdGJ1dHRvbiAgOiBmb3JtVGFncyxcblx0ZGF0YWxpc3Q6IGZvcm1UYWdzLFxuXHR0ZXh0YXJlYTogZm9ybVRhZ3MsXG5cdG9wdGlvbiAgOiB7IG9wdGlvbjp0cnVlIH0sXG5cdG9wdGdyb3VwOiB7IG9wdGdyb3VwOnRydWUgfVxufTtcblxudmFyIHZvaWRFbGVtZW50cyA9IHtcblx0X19wcm90b19fOiBudWxsLFxuXHRhcmVhOiB0cnVlLFxuXHRiYXNlOiB0cnVlLFxuXHRiYXNlZm9udDogdHJ1ZSxcblx0YnI6IHRydWUsXG5cdGNvbDogdHJ1ZSxcblx0Y29tbWFuZDogdHJ1ZSxcblx0ZW1iZWQ6IHRydWUsXG5cdGZyYW1lOiB0cnVlLFxuXHRocjogdHJ1ZSxcblx0aW1nOiB0cnVlLFxuXHRpbnB1dDogdHJ1ZSxcblx0aXNpbmRleDogdHJ1ZSxcblx0a2V5Z2VuOiB0cnVlLFxuXHRsaW5rOiB0cnVlLFxuXHRtZXRhOiB0cnVlLFxuXHRwYXJhbTogdHJ1ZSxcblx0c291cmNlOiB0cnVlLFxuXHR0cmFjazogdHJ1ZSxcblx0d2JyOiB0cnVlLFxuXG5cdC8vY29tbW9uIHNlbGYgY2xvc2luZyBzdmcgZWxlbWVudHNcblx0cGF0aDogdHJ1ZSxcblx0Y2lyY2xlOiB0cnVlLFxuXHRlbGxpcHNlOiB0cnVlLFxuXHRsaW5lOiB0cnVlLFxuXHRyZWN0OiB0cnVlLFxuXHR1c2U6IHRydWUsXG5cdHN0b3A6IHRydWUsXG5cdHBvbHlsaW5lOiB0cnVlLFxuXHRwb2x5Z29uOiB0cnVlXG59O1xuXG52YXIgcmVfbmFtZUVuZCA9IC9cXHN8XFwvLztcblxuZnVuY3Rpb24gUGFyc2VyKGNicywgb3B0aW9ucyl7XG5cdHRoaXMuX29wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXHR0aGlzLl9jYnMgPSBjYnMgfHwge307XG5cblx0dGhpcy5fdGFnbmFtZSA9IFwiXCI7XG5cdHRoaXMuX2F0dHJpYm5hbWUgPSBcIlwiO1xuXHR0aGlzLl9hdHRyaWJ2YWx1ZSA9IFwiXCI7XG5cdHRoaXMuX2F0dHJpYnMgPSBudWxsO1xuXHR0aGlzLl9zdGFjayA9IFtdO1xuXG5cdHRoaXMuc3RhcnRJbmRleCA9IDA7XG5cdHRoaXMuZW5kSW5kZXggPSBudWxsO1xuXG5cdHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzID0gXCJsb3dlckNhc2VUYWdzXCIgaW4gdGhpcy5fb3B0aW9ucyA/XG5cdFx0XHRcdFx0XHRcdFx0XHQhIXRoaXMuX29wdGlvbnMubG93ZXJDYXNlVGFncyA6XG5cdFx0XHRcdFx0XHRcdFx0XHQhdGhpcy5fb3B0aW9ucy54bWxNb2RlO1xuXHR0aGlzLl9sb3dlckNhc2VBdHRyaWJ1dGVOYW1lcyA9IFwibG93ZXJDYXNlQXR0cmlidXRlTmFtZXNcIiBpbiB0aGlzLl9vcHRpb25zID9cblx0XHRcdFx0XHRcdFx0XHRcdCEhdGhpcy5fb3B0aW9ucy5sb3dlckNhc2VBdHRyaWJ1dGVOYW1lcyA6XG5cdFx0XHRcdFx0XHRcdFx0XHQhdGhpcy5fb3B0aW9ucy54bWxNb2RlO1xuXG5cdGlmKHRoaXMuX29wdGlvbnMuVG9rZW5pemVyKSB7XG5cdFx0VG9rZW5pemVyID0gdGhpcy5fb3B0aW9ucy5Ub2tlbml6ZXI7XG5cdH1cblx0dGhpcy5fdG9rZW5pemVyID0gbmV3IFRva2VuaXplcih0aGlzLl9vcHRpb25zLCB0aGlzKTtcblxuXHRpZih0aGlzLl9jYnMub25wYXJzZXJpbml0KSB0aGlzLl9jYnMub25wYXJzZXJpbml0KHRoaXMpO1xufVxuXG5yZXF1aXJlKFwiaW5oZXJpdHNcIikoUGFyc2VyLCByZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcik7XG5cblBhcnNlci5wcm90b3R5cGUuX3VwZGF0ZVBvc2l0aW9uID0gZnVuY3Rpb24oaW5pdGlhbE9mZnNldCl7XG5cdGlmKHRoaXMuZW5kSW5kZXggPT09IG51bGwpe1xuXHRcdGlmKHRoaXMuX3Rva2VuaXplci5fc2VjdGlvblN0YXJ0IDw9IGluaXRpYWxPZmZzZXQpe1xuXHRcdFx0dGhpcy5zdGFydEluZGV4ID0gMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5zdGFydEluZGV4ID0gdGhpcy5fdG9rZW5pemVyLl9zZWN0aW9uU3RhcnQgLSBpbml0aWFsT2Zmc2V0O1xuXHRcdH1cblx0fVxuXHRlbHNlIHRoaXMuc3RhcnRJbmRleCA9IHRoaXMuZW5kSW5kZXggKyAxO1xuXHR0aGlzLmVuZEluZGV4ID0gdGhpcy5fdG9rZW5pemVyLmdldEFic29sdXRlSW5kZXgoKTtcbn07XG5cbi8vVG9rZW5pemVyIGV2ZW50IGhhbmRsZXJzXG5QYXJzZXIucHJvdG90eXBlLm9udGV4dCA9IGZ1bmN0aW9uKGRhdGEpe1xuXHR0aGlzLl91cGRhdGVQb3NpdGlvbigxKTtcblx0dGhpcy5lbmRJbmRleC0tO1xuXG5cdGlmKHRoaXMuX2Nicy5vbnRleHQpIHRoaXMuX2Nicy5vbnRleHQoZGF0YSk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLm9ub3BlbnRhZ25hbWUgPSBmdW5jdGlvbihuYW1lKXtcblx0aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe1xuXHRcdG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cdH1cblxuXHR0aGlzLl90YWduYW1lID0gbmFtZTtcblxuXHRpZighdGhpcy5fb3B0aW9ucy54bWxNb2RlICYmIG5hbWUgaW4gb3BlbkltcGxpZXNDbG9zZSkge1xuXHRcdGZvcihcblx0XHRcdHZhciBlbDtcblx0XHRcdChlbCA9IHRoaXMuX3N0YWNrW3RoaXMuX3N0YWNrLmxlbmd0aCAtIDFdKSBpbiBvcGVuSW1wbGllc0Nsb3NlW25hbWVdO1xuXHRcdFx0dGhpcy5vbmNsb3NldGFnKGVsKVxuXHRcdCk7XG5cdH1cblxuXHRpZih0aGlzLl9vcHRpb25zLnhtbE1vZGUgfHwgIShuYW1lIGluIHZvaWRFbGVtZW50cykpe1xuXHRcdHRoaXMuX3N0YWNrLnB1c2gobmFtZSk7XG5cdH1cblxuXHRpZih0aGlzLl9jYnMub25vcGVudGFnbmFtZSkgdGhpcy5fY2JzLm9ub3BlbnRhZ25hbWUobmFtZSk7XG5cdGlmKHRoaXMuX2Nicy5vbm9wZW50YWcpIHRoaXMuX2F0dHJpYnMgPSB7fTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25vcGVudGFnZW5kID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7XG5cblx0aWYodGhpcy5fYXR0cmlicyl7XG5cdFx0aWYodGhpcy5fY2JzLm9ub3BlbnRhZykgdGhpcy5fY2JzLm9ub3BlbnRhZyh0aGlzLl90YWduYW1lLCB0aGlzLl9hdHRyaWJzKTtcblx0XHR0aGlzLl9hdHRyaWJzID0gbnVsbDtcblx0fVxuXG5cdGlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUgJiYgdGhpcy5fY2JzLm9uY2xvc2V0YWcgJiYgdGhpcy5fdGFnbmFtZSBpbiB2b2lkRWxlbWVudHMpe1xuXHRcdHRoaXMuX2Nicy5vbmNsb3NldGFnKHRoaXMuX3RhZ25hbWUpO1xuXHR9XG5cblx0dGhpcy5fdGFnbmFtZSA9IFwiXCI7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLm9uY2xvc2V0YWcgPSBmdW5jdGlvbihuYW1lKXtcblx0dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7XG5cblx0aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe1xuXHRcdG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cdH1cblxuXHRpZih0aGlzLl9zdGFjay5sZW5ndGggJiYgKCEobmFtZSBpbiB2b2lkRWxlbWVudHMpIHx8IHRoaXMuX29wdGlvbnMueG1sTW9kZSkpe1xuXHRcdHZhciBwb3MgPSB0aGlzLl9zdGFjay5sYXN0SW5kZXhPZihuYW1lKTtcblx0XHRpZihwb3MgIT09IC0xKXtcblx0XHRcdGlmKHRoaXMuX2Nicy5vbmNsb3NldGFnKXtcblx0XHRcdFx0cG9zID0gdGhpcy5fc3RhY2subGVuZ3RoIC0gcG9zO1xuXHRcdFx0XHR3aGlsZShwb3MtLSkgdGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fc3RhY2sucG9wKCkpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB0aGlzLl9zdGFjay5sZW5ndGggPSBwb3M7XG5cdFx0fSBlbHNlIGlmKG5hbWUgPT09IFwicFwiICYmICF0aGlzLl9vcHRpb25zLnhtbE1vZGUpe1xuXHRcdFx0dGhpcy5vbm9wZW50YWduYW1lKG5hbWUpO1xuXHRcdFx0dGhpcy5fY2xvc2VDdXJyZW50VGFnKCk7XG5cdFx0fVxuXHR9IGVsc2UgaWYoIXRoaXMuX29wdGlvbnMueG1sTW9kZSAmJiAobmFtZSA9PT0gXCJiclwiIHx8IG5hbWUgPT09IFwicFwiKSl7XG5cdFx0dGhpcy5vbm9wZW50YWduYW1lKG5hbWUpO1xuXHRcdHRoaXMuX2Nsb3NlQ3VycmVudFRhZygpO1xuXHR9XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLm9uc2VsZmNsb3Npbmd0YWcgPSBmdW5jdGlvbigpe1xuXHRpZih0aGlzLl9vcHRpb25zLnhtbE1vZGUgfHwgdGhpcy5fb3B0aW9ucy5yZWNvZ25pemVTZWxmQ2xvc2luZyl7XG5cdFx0dGhpcy5fY2xvc2VDdXJyZW50VGFnKCk7XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5vbm9wZW50YWdlbmQoKTtcblx0fVxufTtcblxuUGFyc2VyLnByb3RvdHlwZS5fY2xvc2VDdXJyZW50VGFnID0gZnVuY3Rpb24oKXtcblx0dmFyIG5hbWUgPSB0aGlzLl90YWduYW1lO1xuXG5cdHRoaXMub25vcGVudGFnZW5kKCk7XG5cblx0Ly9zZWxmLWNsb3NpbmcgdGFncyB3aWxsIGJlIG9uIHRoZSB0b3Agb2YgdGhlIHN0YWNrXG5cdC8vKGNoZWFwZXIgY2hlY2sgdGhhbiBpbiBvbmNsb3NldGFnKVxuXHRpZih0aGlzLl9zdGFja1t0aGlzLl9zdGFjay5sZW5ndGggLSAxXSA9PT0gbmFtZSl7XG5cdFx0aWYodGhpcy5fY2JzLm9uY2xvc2V0YWcpe1xuXHRcdFx0dGhpcy5fY2JzLm9uY2xvc2V0YWcobmFtZSk7XG5cdFx0fVxuXHRcdHRoaXMuX3N0YWNrLnBvcCgpO1xuXHR9XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLm9uYXR0cmlibmFtZSA9IGZ1bmN0aW9uKG5hbWUpe1xuXHRpZih0aGlzLl9sb3dlckNhc2VBdHRyaWJ1dGVOYW1lcyl7XG5cdFx0bmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fVxuXHR0aGlzLl9hdHRyaWJuYW1lID0gbmFtZTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25hdHRyaWJkYXRhID0gZnVuY3Rpb24odmFsdWUpe1xuXHR0aGlzLl9hdHRyaWJ2YWx1ZSArPSB2YWx1ZTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25hdHRyaWJlbmQgPSBmdW5jdGlvbigpe1xuXHRpZih0aGlzLl9jYnMub25hdHRyaWJ1dGUpIHRoaXMuX2Nicy5vbmF0dHJpYnV0ZSh0aGlzLl9hdHRyaWJuYW1lLCB0aGlzLl9hdHRyaWJ2YWx1ZSk7XG5cdGlmKFxuXHRcdHRoaXMuX2F0dHJpYnMgJiZcblx0XHQhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuX2F0dHJpYnMsIHRoaXMuX2F0dHJpYm5hbWUpXG5cdCl7XG5cdFx0dGhpcy5fYXR0cmlic1t0aGlzLl9hdHRyaWJuYW1lXSA9IHRoaXMuX2F0dHJpYnZhbHVlO1xuXHR9XG5cdHRoaXMuX2F0dHJpYm5hbWUgPSBcIlwiO1xuXHR0aGlzLl9hdHRyaWJ2YWx1ZSA9IFwiXCI7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9nZXRJbnN0cnVjdGlvbk5hbWUgPSBmdW5jdGlvbih2YWx1ZSl7XG5cdHZhciBpZHggPSB2YWx1ZS5zZWFyY2gocmVfbmFtZUVuZCksXG5cdCAgICBuYW1lID0gaWR4IDwgMCA/IHZhbHVlIDogdmFsdWUuc3Vic3RyKDAsIGlkeCk7XG5cblx0aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe1xuXHRcdG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cdH1cblxuXHRyZXR1cm4gbmFtZTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25kZWNsYXJhdGlvbiA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0aWYodGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKXtcblx0XHR2YXIgbmFtZSA9IHRoaXMuX2dldEluc3RydWN0aW9uTmFtZSh2YWx1ZSk7XG5cdFx0dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKFwiIVwiICsgbmFtZSwgXCIhXCIgKyB2YWx1ZSk7XG5cdH1cbn07XG5cblBhcnNlci5wcm90b3R5cGUub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24gPSBmdW5jdGlvbih2YWx1ZSl7XG5cdGlmKHRoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbil7XG5cdFx0dmFyIG5hbWUgPSB0aGlzLl9nZXRJbnN0cnVjdGlvbk5hbWUodmFsdWUpO1xuXHRcdHRoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbihcIj9cIiArIG5hbWUsIFwiP1wiICsgdmFsdWUpO1xuXHR9XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLm9uY29tbWVudCA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0dGhpcy5fdXBkYXRlUG9zaXRpb24oNCk7XG5cblx0aWYodGhpcy5fY2JzLm9uY29tbWVudCkgdGhpcy5fY2JzLm9uY29tbWVudCh2YWx1ZSk7XG5cdGlmKHRoaXMuX2Nicy5vbmNvbW1lbnRlbmQpIHRoaXMuX2Nicy5vbmNvbW1lbnRlbmQoKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25jZGF0YSA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7XG5cblx0aWYodGhpcy5fb3B0aW9ucy54bWxNb2RlIHx8IHRoaXMuX29wdGlvbnMucmVjb2duaXplQ0RBVEEpe1xuXHRcdGlmKHRoaXMuX2Nicy5vbmNkYXRhc3RhcnQpIHRoaXMuX2Nicy5vbmNkYXRhc3RhcnQoKTtcblx0XHRpZih0aGlzLl9jYnMub250ZXh0KSB0aGlzLl9jYnMub250ZXh0KHZhbHVlKTtcblx0XHRpZih0aGlzLl9jYnMub25jZGF0YWVuZCkgdGhpcy5fY2JzLm9uY2RhdGFlbmQoKTtcblx0fSBlbHNlIHtcblx0XHR0aGlzLm9uY29tbWVudChcIltDREFUQVtcIiArIHZhbHVlICsgXCJdXVwiKTtcblx0fVxufTtcblxuUGFyc2VyLnByb3RvdHlwZS5vbmVycm9yID0gZnVuY3Rpb24oZXJyKXtcblx0aWYodGhpcy5fY2JzLm9uZXJyb3IpIHRoaXMuX2Nicy5vbmVycm9yKGVycik7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLm9uZW5kID0gZnVuY3Rpb24oKXtcblx0aWYodGhpcy5fY2JzLm9uY2xvc2V0YWcpe1xuXHRcdGZvcihcblx0XHRcdHZhciBpID0gdGhpcy5fc3RhY2subGVuZ3RoO1xuXHRcdFx0aSA+IDA7XG5cdFx0XHR0aGlzLl9jYnMub25jbG9zZXRhZyh0aGlzLl9zdGFja1stLWldKVxuXHRcdCk7XG5cdH1cblx0aWYodGhpcy5fY2JzLm9uZW5kKSB0aGlzLl9jYnMub25lbmQoKTtcbn07XG5cblxuLy9SZXNldHMgdGhlIHBhcnNlciB0byBhIGJsYW5rIHN0YXRlLCByZWFkeSB0byBwYXJzZSBhIG5ldyBIVE1MIGRvY3VtZW50XG5QYXJzZXIucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKXtcblx0aWYodGhpcy5fY2JzLm9ucmVzZXQpIHRoaXMuX2Nicy5vbnJlc2V0KCk7XG5cdHRoaXMuX3Rva2VuaXplci5yZXNldCgpO1xuXG5cdHRoaXMuX3RhZ25hbWUgPSBcIlwiO1xuXHR0aGlzLl9hdHRyaWJuYW1lID0gXCJcIjtcblx0dGhpcy5fYXR0cmlicyA9IG51bGw7XG5cdHRoaXMuX3N0YWNrID0gW107XG5cblx0aWYodGhpcy5fY2JzLm9ucGFyc2VyaW5pdCkgdGhpcy5fY2JzLm9ucGFyc2VyaW5pdCh0aGlzKTtcbn07XG5cbi8vUGFyc2VzIGEgY29tcGxldGUgSFRNTCBkb2N1bWVudCBhbmQgcHVzaGVzIGl0IHRvIHRoZSBoYW5kbGVyXG5QYXJzZXIucHJvdG90eXBlLnBhcnNlQ29tcGxldGUgPSBmdW5jdGlvbihkYXRhKXtcblx0dGhpcy5yZXNldCgpO1xuXHR0aGlzLmVuZChkYXRhKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihjaHVuayl7XG5cdHRoaXMuX3Rva2VuaXplci53cml0ZShjaHVuayk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGNodW5rKXtcblx0dGhpcy5fdG9rZW5pemVyLmVuZChjaHVuayk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fdG9rZW5pemVyLnBhdXNlKCk7XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCl7XG5cdHRoaXMuX3Rva2VuaXplci5yZXN1bWUoKTtcbn07XG5cbi8vYWxpYXMgZm9yIGJhY2t3YXJkcyBjb21wYXRcblBhcnNlci5wcm90b3R5cGUucGFyc2VDaHVuayA9IFBhcnNlci5wcm90b3R5cGUud3JpdGU7XG5QYXJzZXIucHJvdG90eXBlLmRvbmUgPSBQYXJzZXIucHJvdG90eXBlLmVuZDtcblxubW9kdWxlLmV4cG9ydHMgPSBQYXJzZXI7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vaHRtbHBhcnNlcjIvbGliL1BhcnNlci5qc1xuLy8gbW9kdWxlIGlkID0gMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBUb2tlbml6ZXI7XG5cbnZhciBkZWNvZGVDb2RlUG9pbnQgPSByZXF1aXJlKFwiZW50aXRpZXMvbGliL2RlY29kZV9jb2RlcG9pbnQuanNcIiksXG4gICAgZW50aXR5TWFwID0gcmVxdWlyZShcImVudGl0aWVzL21hcHMvZW50aXRpZXMuanNvblwiKSxcbiAgICBsZWdhY3lNYXAgPSByZXF1aXJlKFwiZW50aXRpZXMvbWFwcy9sZWdhY3kuanNvblwiKSxcbiAgICB4bWxNYXAgICAgPSByZXF1aXJlKFwiZW50aXRpZXMvbWFwcy94bWwuanNvblwiKSxcblxuICAgIGkgPSAwLFxuXG4gICAgVEVYVCAgICAgICAgICAgICAgICAgICAgICA9IGkrKyxcbiAgICBCRUZPUkVfVEFHX05BTUUgICAgICAgICAgID0gaSsrLCAvL2FmdGVyIDxcbiAgICBJTl9UQUdfTkFNRSAgICAgICAgICAgICAgID0gaSsrLFxuICAgIElOX1NFTEZfQ0xPU0lOR19UQUcgICAgICAgPSBpKyssXG4gICAgQkVGT1JFX0NMT1NJTkdfVEFHX05BTUUgICA9IGkrKyxcbiAgICBJTl9DTE9TSU5HX1RBR19OQU1FICAgICAgID0gaSsrLFxuICAgIEFGVEVSX0NMT1NJTkdfVEFHX05BTUUgICAgPSBpKyssXG5cbiAgICAvL2F0dHJpYnV0ZXNcbiAgICBCRUZPUkVfQVRUUklCVVRFX05BTUUgICAgID0gaSsrLFxuICAgIElOX0FUVFJJQlVURV9OQU1FICAgICAgICAgPSBpKyssXG4gICAgQUZURVJfQVRUUklCVVRFX05BTUUgICAgICA9IGkrKyxcbiAgICBCRUZPUkVfQVRUUklCVVRFX1ZBTFVFICAgID0gaSsrLFxuICAgIElOX0FUVFJJQlVURV9WQUxVRV9EUSAgICAgPSBpKyssIC8vIFwiXG4gICAgSU5fQVRUUklCVVRFX1ZBTFVFX1NRICAgICA9IGkrKywgLy8gJ1xuICAgIElOX0FUVFJJQlVURV9WQUxVRV9OUSAgICAgPSBpKyssXG5cbiAgICAvL2RlY2xhcmF0aW9uc1xuICAgIEJFRk9SRV9ERUNMQVJBVElPTiAgICAgICAgPSBpKyssIC8vICFcbiAgICBJTl9ERUNMQVJBVElPTiAgICAgICAgICAgID0gaSsrLFxuXG4gICAgLy9wcm9jZXNzaW5nIGluc3RydWN0aW9uc1xuICAgIElOX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSBpKyssIC8vID9cblxuICAgIC8vY29tbWVudHNcbiAgICBCRUZPUkVfQ09NTUVOVCAgICAgICAgICAgID0gaSsrLFxuICAgIElOX0NPTU1FTlQgICAgICAgICAgICAgICAgPSBpKyssXG4gICAgQUZURVJfQ09NTUVOVF8xICAgICAgICAgICA9IGkrKyxcbiAgICBBRlRFUl9DT01NRU5UXzIgICAgICAgICAgID0gaSsrLFxuXG4gICAgLy9jZGF0YVxuICAgIEJFRk9SRV9DREFUQV8xICAgICAgICAgICAgPSBpKyssIC8vIFtcbiAgICBCRUZPUkVfQ0RBVEFfMiAgICAgICAgICAgID0gaSsrLCAvLyBDXG4gICAgQkVGT1JFX0NEQVRBXzMgICAgICAgICAgICA9IGkrKywgLy8gRFxuICAgIEJFRk9SRV9DREFUQV80ICAgICAgICAgICAgPSBpKyssIC8vIEFcbiAgICBCRUZPUkVfQ0RBVEFfNSAgICAgICAgICAgID0gaSsrLCAvLyBUXG4gICAgQkVGT1JFX0NEQVRBXzYgICAgICAgICAgICA9IGkrKywgLy8gQVxuICAgIElOX0NEQVRBICAgICAgICAgICAgICAgICAgPSBpKyssIC8vIFtcbiAgICBBRlRFUl9DREFUQV8xICAgICAgICAgICAgID0gaSsrLCAvLyBdXG4gICAgQUZURVJfQ0RBVEFfMiAgICAgICAgICAgICA9IGkrKywgLy8gXVxuXG4gICAgLy9zcGVjaWFsIHRhZ3NcbiAgICBCRUZPUkVfU1BFQ0lBTCAgICAgICAgICAgID0gaSsrLCAvL1NcbiAgICBCRUZPUkVfU1BFQ0lBTF9FTkQgICAgICAgID0gaSsrLCAgIC8vU1xuXG4gICAgQkVGT1JFX1NDUklQVF8xICAgICAgICAgICA9IGkrKywgLy9DXG4gICAgQkVGT1JFX1NDUklQVF8yICAgICAgICAgICA9IGkrKywgLy9SXG4gICAgQkVGT1JFX1NDUklQVF8zICAgICAgICAgICA9IGkrKywgLy9JXG4gICAgQkVGT1JFX1NDUklQVF80ICAgICAgICAgICA9IGkrKywgLy9QXG4gICAgQkVGT1JFX1NDUklQVF81ICAgICAgICAgICA9IGkrKywgLy9UXG4gICAgQUZURVJfU0NSSVBUXzEgICAgICAgICAgICA9IGkrKywgLy9DXG4gICAgQUZURVJfU0NSSVBUXzIgICAgICAgICAgICA9IGkrKywgLy9SXG4gICAgQUZURVJfU0NSSVBUXzMgICAgICAgICAgICA9IGkrKywgLy9JXG4gICAgQUZURVJfU0NSSVBUXzQgICAgICAgICAgICA9IGkrKywgLy9QXG4gICAgQUZURVJfU0NSSVBUXzUgICAgICAgICAgICA9IGkrKywgLy9UXG5cbiAgICBCRUZPUkVfU1RZTEVfMSAgICAgICAgICAgID0gaSsrLCAvL1RcbiAgICBCRUZPUkVfU1RZTEVfMiAgICAgICAgICAgID0gaSsrLCAvL1lcbiAgICBCRUZPUkVfU1RZTEVfMyAgICAgICAgICAgID0gaSsrLCAvL0xcbiAgICBCRUZPUkVfU1RZTEVfNCAgICAgICAgICAgID0gaSsrLCAvL0VcbiAgICBBRlRFUl9TVFlMRV8xICAgICAgICAgICAgID0gaSsrLCAvL1RcbiAgICBBRlRFUl9TVFlMRV8yICAgICAgICAgICAgID0gaSsrLCAvL1lcbiAgICBBRlRFUl9TVFlMRV8zICAgICAgICAgICAgID0gaSsrLCAvL0xcbiAgICBBRlRFUl9TVFlMRV80ICAgICAgICAgICAgID0gaSsrLCAvL0VcblxuICAgIEJFRk9SRV9FTlRJVFkgICAgICAgICAgICAgPSBpKyssIC8vJlxuICAgIEJFRk9SRV9OVU1FUklDX0VOVElUWSAgICAgPSBpKyssIC8vI1xuICAgIElOX05BTUVEX0VOVElUWSAgICAgICAgICAgPSBpKyssXG4gICAgSU5fTlVNRVJJQ19FTlRJVFkgICAgICAgICA9IGkrKyxcbiAgICBJTl9IRVhfRU5USVRZICAgICAgICAgICAgID0gaSsrLCAvL1hcblxuICAgIGogPSAwLFxuXG4gICAgU1BFQ0lBTF9OT05FICAgICAgICAgICAgICA9IGorKyxcbiAgICBTUEVDSUFMX1NDUklQVCAgICAgICAgICAgID0gaisrLFxuICAgIFNQRUNJQUxfU1RZTEUgICAgICAgICAgICAgPSBqKys7XG5cbmZ1bmN0aW9uIHdoaXRlc3BhY2UoYyl7XG5cdHJldHVybiBjID09PSBcIiBcIiB8fCBjID09PSBcIlxcblwiIHx8IGMgPT09IFwiXFx0XCIgfHwgYyA9PT0gXCJcXGZcIiB8fCBjID09PSBcIlxcclwiO1xufVxuXG5mdW5jdGlvbiBjaGFyYWN0ZXJTdGF0ZShjaGFyLCBTVUNDRVNTKXtcblx0cmV0dXJuIGZ1bmN0aW9uKGMpe1xuXHRcdGlmKGMgPT09IGNoYXIpIHRoaXMuX3N0YXRlID0gU1VDQ0VTUztcblx0fTtcbn1cblxuZnVuY3Rpb24gaWZFbHNlU3RhdGUodXBwZXIsIFNVQ0NFU1MsIEZBSUxVUkUpe1xuXHR2YXIgbG93ZXIgPSB1cHBlci50b0xvd2VyQ2FzZSgpO1xuXG5cdGlmKHVwcGVyID09PSBsb3dlcil7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGMpe1xuXHRcdFx0aWYoYyA9PT0gbG93ZXIpe1xuXHRcdFx0XHR0aGlzLl9zdGF0ZSA9IFNVQ0NFU1M7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLl9zdGF0ZSA9IEZBSUxVUkU7XG5cdFx0XHRcdHRoaXMuX2luZGV4LS07XG5cdFx0XHR9XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oYyl7XG5cdFx0XHRpZihjID09PSBsb3dlciB8fCBjID09PSB1cHBlcil7XG5cdFx0XHRcdHRoaXMuX3N0YXRlID0gU1VDQ0VTUztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuX3N0YXRlID0gRkFJTFVSRTtcblx0XHRcdFx0dGhpcy5faW5kZXgtLTtcblx0XHRcdH1cblx0XHR9O1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvbnN1bWVTcGVjaWFsTmFtZUNoYXIodXBwZXIsIE5FWFRfU1RBVEUpe1xuXHR2YXIgbG93ZXIgPSB1cHBlci50b0xvd2VyQ2FzZSgpO1xuXG5cdHJldHVybiBmdW5jdGlvbihjKXtcblx0XHRpZihjID09PSBsb3dlciB8fCBjID09PSB1cHBlcil7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IE5FWFRfU1RBVEU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX3N0YXRlID0gSU5fVEFHX05BTUU7XG5cdFx0XHR0aGlzLl9pbmRleC0tOyAvL2NvbnN1bWUgdGhlIHRva2VuIGFnYWluXG5cdFx0fVxuXHR9O1xufVxuXG5mdW5jdGlvbiBUb2tlbml6ZXIob3B0aW9ucywgY2JzKXtcblx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHR0aGlzLl9idWZmZXIgPSBcIlwiO1xuXHR0aGlzLl9zZWN0aW9uU3RhcnQgPSAwO1xuXHR0aGlzLl9pbmRleCA9IDA7XG5cdHRoaXMuX2J1ZmZlck9mZnNldCA9IDA7IC8vY2hhcnMgcmVtb3ZlZCBmcm9tIF9idWZmZXJcblx0dGhpcy5fYmFzZVN0YXRlID0gVEVYVDtcblx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfTk9ORTtcblx0dGhpcy5fY2JzID0gY2JzO1xuXHR0aGlzLl9ydW5uaW5nID0gdHJ1ZTtcblx0dGhpcy5fZW5kZWQgPSBmYWxzZTtcblx0dGhpcy5feG1sTW9kZSA9ICEhKG9wdGlvbnMgJiYgb3B0aW9ucy54bWxNb2RlKTtcblx0dGhpcy5fZGVjb2RlRW50aXRpZXMgPSAhIShvcHRpb25zICYmIG9wdGlvbnMuZGVjb2RlRW50aXRpZXMpO1xufVxuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZVRleHQgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI8XCIpe1xuXHRcdGlmKHRoaXMuX2luZGV4ID4gdGhpcy5fc2VjdGlvblN0YXJ0KXtcblx0XHRcdHRoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKTtcblx0XHR9XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiB0aGlzLl9zcGVjaWFsID09PSBTUEVDSUFMX05PTkUgJiYgYyA9PT0gXCImXCIpe1xuXHRcdGlmKHRoaXMuX2luZGV4ID4gdGhpcy5fc2VjdGlvblN0YXJ0KXtcblx0XHRcdHRoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKTtcblx0XHR9XG5cdFx0dGhpcy5fYmFzZVN0YXRlID0gVEVYVDtcblx0XHR0aGlzLl9zdGF0ZSA9IEJFRk9SRV9FTlRJVFk7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlVGFnTmFtZSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi9cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQ0xPU0lOR19UQUdfTkFNRTtcblx0fSBlbHNlIGlmKGMgPT09IFwiPFwiKXtcblx0XHR0aGlzLl9jYnMub250ZXh0KHRoaXMuX2dldFNlY3Rpb24oKSk7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH0gZWxzZSBpZihjID09PSBcIj5cIiB8fCB0aGlzLl9zcGVjaWFsICE9PSBTUEVDSUFMX05PTkUgfHwgd2hpdGVzcGFjZShjKSkge1xuXHRcdHRoaXMuX3N0YXRlID0gVEVYVDtcblx0fSBlbHNlIGlmKGMgPT09IFwiIVwiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IEJFRk9SRV9ERUNMQVJBVElPTjtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleCArIDE7XG5cdH0gZWxzZSBpZihjID09PSBcIj9cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIHtcblx0XHR0aGlzLl9zdGF0ZSA9ICghdGhpcy5feG1sTW9kZSAmJiAoYyA9PT0gXCJzXCIgfHwgYyA9PT0gXCJTXCIpKSA/XG5cdFx0XHRcdFx0XHRCRUZPUkVfU1BFQ0lBTCA6IElOX1RBR19OQU1FO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4O1xuXHR9XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluVGFnTmFtZSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi9cIiB8fCBjID09PSBcIj5cIiB8fCB3aGl0ZXNwYWNlKGMpKXtcblx0XHR0aGlzLl9lbWl0VG9rZW4oXCJvbm9wZW50YWduYW1lXCIpO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9OQU1FO1xuXHRcdHRoaXMuX2luZGV4LS07XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2xvc2VpbmdUYWdOYW1lID0gZnVuY3Rpb24oYyl7XG5cdGlmKHdoaXRlc3BhY2UoYykpO1xuXHRlbHNlIGlmKGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdH0gZWxzZSBpZih0aGlzLl9zcGVjaWFsICE9PSBTUEVDSUFMX05PTkUpe1xuXHRcdGlmKGMgPT09IFwic1wiIHx8IGMgPT09IFwiU1wiKXtcblx0XHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX1NQRUNJQUxfRU5EO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdFx0XHR0aGlzLl9pbmRleC0tO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DbG9zZWluZ1RhZ05hbWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25jbG9zZXRhZ1wiKTtcblx0XHR0aGlzLl9zdGF0ZSA9IEFGVEVSX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZSA9IGZ1bmN0aW9uKGMpe1xuXHQvL3NraXAgZXZlcnl0aGluZyB1bnRpbCBcIj5cIlxuXHRpZihjID09PSBcIj5cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVOYW1lID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9jYnMub25vcGVudGFnZW5kKCk7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIGlmKGMgPT09IFwiL1wiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX1NFTEZfQ0xPU0lOR19UQUc7XG5cdH0gZWxzZSBpZighd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9BVFRSSUJVVEVfTkFNRTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJblNlbGZDbG9zaW5nVGFnID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9jYnMub25zZWxmY2xvc2luZ3RhZygpO1xuXHRcdHRoaXMuX3N0YXRlID0gVEVYVDtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleCArIDE7XG5cdH0gZWxzZSBpZighd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQVRUUklCVVRFX05BTUU7XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZU5hbWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI9XCIgfHwgYyA9PT0gXCIvXCIgfHwgYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fY2JzLm9uYXR0cmlibmFtZSh0aGlzLl9nZXRTZWN0aW9uKCkpO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IC0xO1xuXHRcdHRoaXMuX3N0YXRlID0gQUZURVJfQVRUUklCVVRFX05BTUU7XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckF0dHJpYnV0ZU5hbWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI9XCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9WQUxVRTtcblx0fSBlbHNlIGlmKGMgPT09IFwiL1wiIHx8IGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9jYnMub25hdHRyaWJlbmQoKTtcblx0XHR0aGlzLl9zdGF0ZSA9IEJFRk9SRV9BVFRSSUJVVEVfTkFNRTtcblx0XHR0aGlzLl9pbmRleC0tO1xuXHR9IGVsc2UgaWYoIXdoaXRlc3BhY2UoYykpe1xuXHRcdHRoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fQVRUUklCVVRFX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQXR0cmlidXRlVmFsdWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCJcXFwiXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fQVRUUklCVVRFX1ZBTFVFX0RRO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIGlmKGMgPT09IFwiJ1wiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0FUVFJJQlVURV9WQUxVRV9TUTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleCArIDE7XG5cdH0gZWxzZSBpZighd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9BVFRSSUJVVEVfVkFMVUVfTlE7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdFx0dGhpcy5faW5kZXgtLTsgLy9yZWNvbnN1bWUgdG9rZW5cblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiXFxcIlwiKXtcblx0XHR0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7XG5cdFx0dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQVRUUklCVVRFX05BTUU7XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiBjID09PSBcIiZcIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Jhc2VTdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0VOVElUWTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVzID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiJ1wiKXtcblx0XHR0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7XG5cdFx0dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQVRUUklCVVRFX05BTUU7XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiBjID09PSBcIiZcIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Jhc2VTdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0VOVElUWTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXMgPSBmdW5jdGlvbihjKXtcblx0aWYod2hpdGVzcGFjZShjKSB8fCBjID09PSBcIj5cIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9OQU1FO1xuXHRcdHRoaXMuX2luZGV4LS07XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiBjID09PSBcIiZcIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Jhc2VTdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0VOVElUWTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVEZWNsYXJhdGlvbiA9IGZ1bmN0aW9uKGMpe1xuXHR0aGlzLl9zdGF0ZSA9IGMgPT09IFwiW1wiID8gQkVGT1JFX0NEQVRBXzEgOlxuXHRcdFx0XHRcdGMgPT09IFwiLVwiID8gQkVGT1JFX0NPTU1FTlQgOlxuXHRcdFx0XHRcdFx0SU5fREVDTEFSQVRJT047XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluRGVjbGFyYXRpb24gPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIpe1xuXHRcdHRoaXMuX2Nicy5vbmRlY2xhcmF0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJblByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIj5cIil7XG5cdFx0dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDb21tZW50ID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiLVwiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NPTU1FTlQ7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHR9IGVsc2Uge1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fREVDTEFSQVRJT047XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5Db21tZW50ID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiLVwiKSB0aGlzLl9zdGF0ZSA9IEFGVEVSX0NPTU1FTlRfMTtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDb21tZW50MSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi1cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBBRlRFUl9DT01NRU5UXzI7XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9DT01NRU5UO1xuXHR9XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ29tbWVudDIgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIpe1xuXHRcdC8vcmVtb3ZlIDIgdHJhaWxpbmcgY2hhcnNcblx0XHR0aGlzLl9jYnMub25jb21tZW50KHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LCB0aGlzLl9pbmRleCAtIDIpKTtcblx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHR9IGVsc2UgaWYoYyAhPT0gXCItXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fQ09NTUVOVDtcblx0fVxuXHQvLyBlbHNlOiBzdGF5IGluIEFGVEVSX0NPTU1FTlRfMiAoYC0tLT5gKVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTEgPSBpZkVsc2VTdGF0ZShcIkNcIiwgQkVGT1JFX0NEQVRBXzIsIElOX0RFQ0xBUkFUSU9OKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGEyID0gaWZFbHNlU3RhdGUoXCJEXCIsIEJFRk9SRV9DREFUQV8zLCBJTl9ERUNMQVJBVElPTik7XG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhMyA9IGlmRWxzZVN0YXRlKFwiQVwiLCBCRUZPUkVfQ0RBVEFfNCwgSU5fREVDTEFSQVRJT04pO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTQgPSBpZkVsc2VTdGF0ZShcIlRcIiwgQkVGT1JFX0NEQVRBXzUsIElOX0RFQ0xBUkFUSU9OKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE1ID0gaWZFbHNlU3RhdGUoXCJBXCIsIEJFRk9SRV9DREFUQV82LCBJTl9ERUNMQVJBVElPTik7XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE2ID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiW1wiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NEQVRBO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIHtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0RFQ0xBUkFUSU9OO1xuXHRcdHRoaXMuX2luZGV4LS07XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DZGF0YSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIl1cIikgdGhpcy5fc3RhdGUgPSBBRlRFUl9DREFUQV8xO1xufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMSA9IGNoYXJhY3RlclN0YXRlKFwiXVwiLCBBRlRFUl9DREFUQV8yKTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMiA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIj5cIil7XG5cdFx0Ly9yZW1vdmUgMiB0cmFpbGluZyBjaGFyc1xuXHRcdHRoaXMuX2Nicy5vbmNkYXRhKHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LCB0aGlzLl9pbmRleCAtIDIpKTtcblx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHR9IGVsc2UgaWYoYyAhPT0gXCJdXCIpIHtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NEQVRBO1xuXHR9XG5cdC8vZWxzZTogc3RheSBpbiBBRlRFUl9DREFUQV8yIChgXV1dPmApXG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNwZWNpYWwgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCJjXCIgfHwgYyA9PT0gXCJDXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX1NDUklQVF8xO1xuXHR9IGVsc2UgaWYoYyA9PT0gXCJ0XCIgfHwgYyA9PT0gXCJUXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX1NUWUxFXzE7XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9UQUdfTkFNRTtcblx0XHR0aGlzLl9pbmRleC0tOyAvL2NvbnN1bWUgdGhlIHRva2VuIGFnYWluXG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3BlY2lhbEVuZCA9IGZ1bmN0aW9uKGMpe1xuXHRpZih0aGlzLl9zcGVjaWFsID09PSBTUEVDSUFMX1NDUklQVCAmJiAoYyA9PT0gXCJjXCIgfHwgYyA9PT0gXCJDXCIpKXtcblx0XHR0aGlzLl9zdGF0ZSA9IEFGVEVSX1NDUklQVF8xO1xuXHR9IGVsc2UgaWYodGhpcy5fc3BlY2lhbCA9PT0gU1BFQ0lBTF9TVFlMRSAmJiAoYyA9PT0gXCJ0XCIgfHwgYyA9PT0gXCJUXCIpKXtcblx0XHR0aGlzLl9zdGF0ZSA9IEFGVEVSX1NUWUxFXzE7XG5cdH1cblx0ZWxzZSB0aGlzLl9zdGF0ZSA9IFRFWFQ7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDEgPSBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiUlwiLCBCRUZPUkVfU0NSSVBUXzIpO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQyID0gY29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIklcIiwgQkVGT1JFX1NDUklQVF8zKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0MyA9IGNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJQXCIsIEJFRk9SRV9TQ1JJUFRfNCk7XG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDQgPSBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiVFwiLCBCRUZPUkVfU0NSSVBUXzUpO1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCIvXCIgfHwgYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfU0NSSVBUO1xuXHR9XG5cdHRoaXMuX3N0YXRlID0gSU5fVEFHX05BTUU7XG5cdHRoaXMuX2luZGV4LS07IC8vY29uc3VtZSB0aGUgdG9rZW4gYWdhaW5cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQxID0gaWZFbHNlU3RhdGUoXCJSXCIsIEFGVEVSX1NDUklQVF8yLCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQyID0gaWZFbHNlU3RhdGUoXCJJXCIsIEFGVEVSX1NDUklQVF8zLCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQzID0gaWZFbHNlU3RhdGUoXCJQXCIsIEFGVEVSX1NDUklQVF80LCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ0ID0gaWZFbHNlU3RhdGUoXCJUXCIsIEFGVEVSX1NDUklQVF81LCBURVhUKTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclNjcmlwdDUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfTk9ORTtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggLSA2O1xuXHRcdHRoaXMuX2luZGV4LS07IC8vcmVjb25zdW1lIHRoZSB0b2tlblxuXHR9XG5cdGVsc2UgdGhpcy5fc3RhdGUgPSBURVhUO1xufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTEgPSBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiWVwiLCBCRUZPUkVfU1RZTEVfMik7XG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlMiA9IGNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJMXCIsIEJFRk9SRV9TVFlMRV8zKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3R5bGUzID0gY29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkVcIiwgQkVGT1JFX1NUWUxFXzQpO1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlNCA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi9cIiB8fCBjID09PSBcIj5cIiB8fCB3aGl0ZXNwYWNlKGMpKXtcblx0XHR0aGlzLl9zcGVjaWFsID0gU1BFQ0lBTF9TVFlMRTtcblx0fVxuXHR0aGlzLl9zdGF0ZSA9IElOX1RBR19OQU1FO1xuXHR0aGlzLl9pbmRleC0tOyAvL2NvbnN1bWUgdGhlIHRva2VuIGFnYWluXG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGUxID0gaWZFbHNlU3RhdGUoXCJZXCIsIEFGVEVSX1NUWUxFXzIsIFRFWFQpO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlMiA9IGlmRWxzZVN0YXRlKFwiTFwiLCBBRlRFUl9TVFlMRV8zLCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTMgPSBpZkVsc2VTdGF0ZShcIkVcIiwgQUZURVJfU1RZTEVfNCwgVEVYVCk7XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTQgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfTk9ORTtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggLSA1O1xuXHRcdHRoaXMuX2luZGV4LS07IC8vcmVjb25zdW1lIHRoZSB0b2tlblxuXHR9XG5cdGVsc2UgdGhpcy5fc3RhdGUgPSBURVhUO1xufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVFbnRpdHkgPSBpZkVsc2VTdGF0ZShcIiNcIiwgQkVGT1JFX05VTUVSSUNfRU5USVRZLCBJTl9OQU1FRF9FTlRJVFkpO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5ID0gaWZFbHNlU3RhdGUoXCJYXCIsIElOX0hFWF9FTlRJVFksIElOX05VTUVSSUNfRU5USVRZKTtcblxuLy9mb3IgZW50aXRpZXMgdGVybWluYXRlZCB3aXRoIGEgc2VtaWNvbG9uXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9wYXJzZU5hbWVkRW50aXR5U3RyaWN0ID0gZnVuY3Rpb24oKXtcblx0Ly9vZmZzZXQgPSAxXG5cdGlmKHRoaXMuX3NlY3Rpb25TdGFydCArIDEgPCB0aGlzLl9pbmRleCl7XG5cdFx0dmFyIGVudGl0eSA9IHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0ICsgMSwgdGhpcy5faW5kZXgpLFxuXHRcdCAgICBtYXAgPSB0aGlzLl94bWxNb2RlID8geG1sTWFwIDogZW50aXR5TWFwO1xuXG5cdFx0aWYobWFwLmhhc093blByb3BlcnR5KGVudGl0eSkpe1xuXHRcdFx0dGhpcy5fZW1pdFBhcnRpYWwobWFwW2VudGl0eV0pO1xuXHRcdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHRcdH1cblx0fVxufTtcblxuXG4vL3BhcnNlcyBsZWdhY3kgZW50aXRpZXMgKHdpdGhvdXQgdHJhaWxpbmcgc2VtaWNvbG9uKVxuVG9rZW5pemVyLnByb3RvdHlwZS5fcGFyc2VMZWdhY3lFbnRpdHkgPSBmdW5jdGlvbigpe1xuXHR2YXIgc3RhcnQgPSB0aGlzLl9zZWN0aW9uU3RhcnQgKyAxLFxuXHQgICAgbGltaXQgPSB0aGlzLl9pbmRleCAtIHN0YXJ0O1xuXG5cdGlmKGxpbWl0ID4gNikgbGltaXQgPSA2OyAvL3RoZSBtYXggbGVuZ3RoIG9mIGxlZ2FjeSBlbnRpdGllcyBpcyA2XG5cblx0d2hpbGUobGltaXQgPj0gMil7IC8vdGhlIG1pbiBsZW5ndGggb2YgbGVnYWN5IGVudGl0aWVzIGlzIDJcblx0XHR2YXIgZW50aXR5ID0gdGhpcy5fYnVmZmVyLnN1YnN0cihzdGFydCwgbGltaXQpO1xuXG5cdFx0aWYobGVnYWN5TWFwLmhhc093blByb3BlcnR5KGVudGl0eSkpe1xuXHRcdFx0dGhpcy5fZW1pdFBhcnRpYWwobGVnYWN5TWFwW2VudGl0eV0pO1xuXHRcdFx0dGhpcy5fc2VjdGlvblN0YXJ0ICs9IGxpbWl0ICsgMTtcblx0XHRcdHJldHVybjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGltaXQtLTtcblx0XHR9XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5OYW1lZEVudGl0eSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIjtcIil7XG5cdFx0dGhpcy5fcGFyc2VOYW1lZEVudGl0eVN0cmljdCgpO1xuXHRcdGlmKHRoaXMuX3NlY3Rpb25TdGFydCArIDEgPCB0aGlzLl9pbmRleCAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0XHR0aGlzLl9wYXJzZUxlZ2FjeUVudGl0eSgpO1xuXHRcdH1cblx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0fSBlbHNlIGlmKChjIDwgXCJhXCIgfHwgYyA+IFwielwiKSAmJiAoYyA8IFwiQVwiIHx8IGMgPiBcIlpcIikgJiYgKGMgPCBcIjBcIiB8fCBjID4gXCI5XCIpKXtcblx0XHRpZih0aGlzLl94bWxNb2RlKTtcblx0XHRlbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydCArIDEgPT09IHRoaXMuX2luZGV4KTtcblx0XHRlbHNlIGlmKHRoaXMuX2Jhc2VTdGF0ZSAhPT0gVEVYVCl7XG5cdFx0XHRpZihjICE9PSBcIj1cIil7XG5cdFx0XHRcdHRoaXMuX3BhcnNlTmFtZWRFbnRpdHlTdHJpY3QoKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKTtcblx0XHR9XG5cblx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0XHR0aGlzLl9pbmRleC0tO1xuXHR9XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9kZWNvZGVOdW1lcmljRW50aXR5ID0gZnVuY3Rpb24ob2Zmc2V0LCBiYXNlKXtcblx0dmFyIHNlY3Rpb25TdGFydCA9IHRoaXMuX3NlY3Rpb25TdGFydCArIG9mZnNldDtcblxuXHRpZihzZWN0aW9uU3RhcnQgIT09IHRoaXMuX2luZGV4KXtcblx0XHQvL3BhcnNlIGVudGl0eVxuXHRcdHZhciBlbnRpdHkgPSB0aGlzLl9idWZmZXIuc3Vic3RyaW5nKHNlY3Rpb25TdGFydCwgdGhpcy5faW5kZXgpO1xuXHRcdHZhciBwYXJzZWQgPSBwYXJzZUludChlbnRpdHksIGJhc2UpO1xuXG5cdFx0dGhpcy5fZW1pdFBhcnRpYWwoZGVjb2RlQ29kZVBvaW50KHBhcnNlZCkpO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4O1xuXHR9IGVsc2Uge1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydC0tO1xuXHR9XG5cblx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluTnVtZXJpY0VudGl0eSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIjtcIil7XG5cdFx0dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLCAxMCk7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0Kys7XG5cdH0gZWxzZSBpZihjIDwgXCIwXCIgfHwgYyA+IFwiOVwiKXtcblx0XHRpZighdGhpcy5feG1sTW9kZSl7XG5cdFx0XHR0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDIsIDEwKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cdFx0fVxuXHRcdHRoaXMuX2luZGV4LS07XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5IZXhFbnRpdHkgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI7XCIpe1xuXHRcdHRoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywgMTYpO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCsrO1xuXHR9IGVsc2UgaWYoKGMgPCBcImFcIiB8fCBjID4gXCJmXCIpICYmIChjIDwgXCJBXCIgfHwgYyA+IFwiRlwiKSAmJiAoYyA8IFwiMFwiIHx8IGMgPiBcIjlcIikpe1xuXHRcdGlmKCF0aGlzLl94bWxNb2RlKXtcblx0XHRcdHRoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywgMTYpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0XHR9XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fY2xlYW51cCA9IGZ1bmN0aW9uICgpe1xuXHRpZih0aGlzLl9zZWN0aW9uU3RhcnQgPCAwKXtcblx0XHR0aGlzLl9idWZmZXIgPSBcIlwiO1xuXHRcdHRoaXMuX2J1ZmZlck9mZnNldCArPSB0aGlzLl9pbmRleDtcblx0XHR0aGlzLl9pbmRleCA9IDA7XG5cdH0gZWxzZSBpZih0aGlzLl9ydW5uaW5nKXtcblx0XHRpZih0aGlzLl9zdGF0ZSA9PT0gVEVYVCl7XG5cdFx0XHRpZih0aGlzLl9zZWN0aW9uU3RhcnQgIT09IHRoaXMuX2luZGV4KXtcblx0XHRcdFx0dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9idWZmZXIuc3Vic3RyKHRoaXMuX3NlY3Rpb25TdGFydCkpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5fYnVmZmVyID0gXCJcIjtcblx0XHRcdHRoaXMuX2J1ZmZlck9mZnNldCArPSB0aGlzLl9pbmRleDtcblx0XHRcdHRoaXMuX2luZGV4ID0gMDtcblx0XHR9IGVsc2UgaWYodGhpcy5fc2VjdGlvblN0YXJ0ID09PSB0aGlzLl9pbmRleCl7XG5cdFx0XHQvL3RoZSBzZWN0aW9uIGp1c3Qgc3RhcnRlZFxuXHRcdFx0dGhpcy5fYnVmZmVyID0gXCJcIjtcblx0XHRcdHRoaXMuX2J1ZmZlck9mZnNldCArPSB0aGlzLl9pbmRleDtcblx0XHRcdHRoaXMuX2luZGV4ID0gMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly9yZW1vdmUgZXZlcnl0aGluZyB1bm5lY2Vzc2FyeVxuXHRcdFx0dGhpcy5fYnVmZmVyID0gdGhpcy5fYnVmZmVyLnN1YnN0cih0aGlzLl9zZWN0aW9uU3RhcnQpO1xuXHRcdFx0dGhpcy5faW5kZXggLT0gdGhpcy5fc2VjdGlvblN0YXJ0O1xuXHRcdFx0dGhpcy5fYnVmZmVyT2Zmc2V0ICs9IHRoaXMuX3NlY3Rpb25TdGFydDtcblx0XHR9XG5cblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSAwO1xuXHR9XG59O1xuXG4vL1RPRE8gbWFrZSBldmVudHMgY29uZGl0aW9uYWxcblRva2VuaXplci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihjaHVuayl7XG5cdGlmKHRoaXMuX2VuZGVkKSB0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi53cml0ZSgpIGFmdGVyIGRvbmUhXCIpKTtcblxuXHR0aGlzLl9idWZmZXIgKz0gY2h1bms7XG5cdHRoaXMuX3BhcnNlKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9wYXJzZSA9IGZ1bmN0aW9uKCl7XG5cdHdoaWxlKHRoaXMuX2luZGV4IDwgdGhpcy5fYnVmZmVyLmxlbmd0aCAmJiB0aGlzLl9ydW5uaW5nKXtcblx0XHR2YXIgYyA9IHRoaXMuX2J1ZmZlci5jaGFyQXQodGhpcy5faW5kZXgpO1xuXHRcdGlmKHRoaXMuX3N0YXRlID09PSBURVhUKSB7XG5cdFx0XHR0aGlzLl9zdGF0ZVRleHQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfVEFHX05BTUUpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVUYWdOYW1lKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fVEFHX05BTUUpIHtcblx0XHRcdHRoaXMuX3N0YXRlSW5UYWdOYW1lKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0NMT1NJTkdfVEFHX05BTUUpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVDbG9zZWluZ1RhZ05hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9DTE9TSU5HX1RBR19OQU1FKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5DbG9zZWluZ1RhZ05hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBBRlRFUl9DTE9TSU5HX1RBR19OQU1FKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJDbG9zZWluZ1RhZ05hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9TRUxGX0NMT1NJTkdfVEFHKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5TZWxmQ2xvc2luZ1RhZyhjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCpcdGF0dHJpYnV0ZXNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9BVFRSSUJVVEVfTkFNRSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZU5hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9BVFRSSUJVVEVfTkFNRSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUluQXR0cmlidXRlTmFtZShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX0FUVFJJQlVURV9OQU1FKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJBdHRyaWJ1dGVOYW1lKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0FUVFJJQlVURV9WQUxVRSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZVZhbHVlKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fQVRUUklCVVRFX1ZBTFVFX0RRKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZURvdWJsZVF1b3RlcyhjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX0FUVFJJQlVURV9WQUxVRV9TUSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVTaW5nbGVRdW90ZXMoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9BVFRSSUJVVEVfVkFMVUVfTlEpe1xuXHRcdFx0dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXMoYyk7XG5cdFx0fVxuXG5cdFx0Lypcblx0XHQqXHRkZWNsYXJhdGlvbnNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9ERUNMQVJBVElPTil7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZURlY2xhcmF0aW9uKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fREVDTEFSQVRJT04pe1xuXHRcdFx0dGhpcy5fc3RhdGVJbkRlY2xhcmF0aW9uKGMpO1xuXHRcdH1cblxuXHRcdC8qXG5cdFx0Klx0cHJvY2Vzc2luZyBpbnN0cnVjdGlvbnNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04pe1xuXHRcdFx0dGhpcy5fc3RhdGVJblByb2Nlc3NpbmdJbnN0cnVjdGlvbihjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCpcdGNvbW1lbnRzXG5cdFx0Ki9cblx0XHRlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfQ09NTUVOVCl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUNvbW1lbnQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9DT01NRU5UKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5Db21tZW50KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ09NTUVOVF8xKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJDb21tZW50MShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX0NPTU1FTlRfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyQ29tbWVudDIoYyk7XG5cdFx0fVxuXG5cdFx0Lypcblx0XHQqXHRjZGF0YVxuXHRcdCovXG5cdFx0ZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0NEQVRBXzEpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTEoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfQ0RBVEFfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhMihjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9DREFUQV8zKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlQ2RhdGEzKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0NEQVRBXzQpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfQ0RBVEFfNSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhNShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9DREFUQV82KXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlQ2RhdGE2KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fQ0RBVEEpe1xuXHRcdFx0dGhpcy5fc3RhdGVJbkNkYXRhKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ0RBVEFfMSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyQ2RhdGExKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ0RBVEFfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyQ2RhdGEyKGMpO1xuXHRcdH1cblxuXHRcdC8qXG5cdFx0KiBzcGVjaWFsIHRhZ3Ncblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TUEVDSUFMKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU3BlY2lhbChjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TUEVDSUFMX0VORCl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVNwZWNpYWxFbmQoYyk7XG5cdFx0fVxuXG5cdFx0Lypcblx0XHQqIHNjcmlwdFxuXHRcdCovXG5cdFx0ZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX1NDUklQVF8xKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU2NyaXB0MShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TQ1JJUFRfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDIoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfU0NSSVBUXzMpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQzKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX1NDUklQVF80KXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU2NyaXB0NChjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TQ1JJUFRfNSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDUoYyk7XG5cdFx0fVxuXG5cdFx0ZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfU0NSSVBUXzEpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclNjcmlwdDEoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBBRlRFUl9TQ1JJUFRfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0MihjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NDUklQVF8zKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQzKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfU0NSSVBUXzQpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclNjcmlwdDQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBBRlRFUl9TQ1JJUFRfNSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0NShjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCogc3R5bGVcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TVFlMRV8xKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU3R5bGUxKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX1NUWUxFXzIpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTIoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfU1RZTEVfMyl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlMyhjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TVFlMRV80KXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU3R5bGU0KGMpO1xuXHRcdH1cblxuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzEpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlMShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzIpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlMihjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzMpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlMyhjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzQpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlNChjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCogZW50aXRpZXNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9FTlRJVFkpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVFbnRpdHkoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfTlVNRVJJQ19FTlRJVFkpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fTkFNRURfRU5USVRZKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5OYW1lZEVudGl0eShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX05VTUVSSUNfRU5USVRZKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5OdW1lcmljRW50aXR5KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fSEVYX0VOVElUWSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUluSGV4RW50aXR5KGMpO1xuXHRcdH1cblxuXHRcdGVsc2Uge1xuXHRcdFx0dGhpcy5fY2JzLm9uZXJyb3IoRXJyb3IoXCJ1bmtub3duIF9zdGF0ZVwiKSwgdGhpcy5fc3RhdGUpO1xuXHRcdH1cblxuXHRcdHRoaXMuX2luZGV4Kys7XG5cdH1cblxuXHR0aGlzLl9jbGVhbnVwKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fcnVubmluZyA9IGZhbHNlO1xufTtcblRva2VuaXplci5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fcnVubmluZyA9IHRydWU7XG5cblx0aWYodGhpcy5faW5kZXggPCB0aGlzLl9idWZmZXIubGVuZ3RoKXtcblx0XHR0aGlzLl9wYXJzZSgpO1xuXHR9XG5cdGlmKHRoaXMuX2VuZGVkKXtcblx0XHR0aGlzLl9maW5pc2goKTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihjaHVuayl7XG5cdGlmKHRoaXMuX2VuZGVkKSB0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi5lbmQoKSBhZnRlciBkb25lIVwiKSk7XG5cdGlmKGNodW5rKSB0aGlzLndyaXRlKGNodW5rKTtcblxuXHR0aGlzLl9lbmRlZCA9IHRydWU7XG5cblx0aWYodGhpcy5fcnVubmluZykgdGhpcy5fZmluaXNoKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9maW5pc2ggPSBmdW5jdGlvbigpe1xuXHQvL2lmIHRoZXJlIGlzIHJlbWFpbmluZyBkYXRhLCBlbWl0IGl0IGluIGEgcmVhc29uYWJsZSB3YXlcblx0aWYodGhpcy5fc2VjdGlvblN0YXJ0IDwgdGhpcy5faW5kZXgpe1xuXHRcdHRoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpO1xuXHR9XG5cblx0dGhpcy5fY2JzLm9uZW5kKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9oYW5kbGVUcmFpbGluZ0RhdGEgPSBmdW5jdGlvbigpe1xuXHR2YXIgZGF0YSA9IHRoaXMuX2J1ZmZlci5zdWJzdHIodGhpcy5fc2VjdGlvblN0YXJ0KTtcblxuXHRpZih0aGlzLl9zdGF0ZSA9PT0gSU5fQ0RBVEEgfHwgdGhpcy5fc3RhdGUgPT09IEFGVEVSX0NEQVRBXzEgfHwgdGhpcy5fc3RhdGUgPT09IEFGVEVSX0NEQVRBXzIpe1xuXHRcdHRoaXMuX2Nicy5vbmNkYXRhKGRhdGEpO1xuXHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX0NPTU1FTlQgfHwgdGhpcy5fc3RhdGUgPT09IEFGVEVSX0NPTU1FTlRfMSB8fCB0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ09NTUVOVF8yKXtcblx0XHR0aGlzLl9jYnMub25jb21tZW50KGRhdGEpO1xuXHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX05BTUVEX0VOVElUWSAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKTtcblx0XHRpZih0aGlzLl9zZWN0aW9uU3RhcnQgPCB0aGlzLl9pbmRleCl7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0XHRcdHRoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpO1xuXHRcdH1cblx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9OVU1FUklDX0VOVElUWSAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLCAxMCk7XG5cdFx0aWYodGhpcy5fc2VjdGlvblN0YXJ0IDwgdGhpcy5faW5kZXgpe1xuXHRcdFx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cdFx0XHR0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKTtcblx0XHR9XG5cdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fSEVYX0VOVElUWSAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgzLCAxNik7XG5cdFx0aWYodGhpcy5fc2VjdGlvblN0YXJ0IDwgdGhpcy5faW5kZXgpe1xuXHRcdFx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cdFx0XHR0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKTtcblx0XHR9XG5cdH0gZWxzZSBpZihcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fVEFHX05BTUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gQkVGT1JFX0FUVFJJQlVURV9OQU1FICYmXG5cdFx0dGhpcy5fc3RhdGUgIT09IEJFRk9SRV9BVFRSSUJVVEVfVkFMVUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gQUZURVJfQVRUUklCVVRFX05BTUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fQVRUUklCVVRFX05BTUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fQVRUUklCVVRFX1ZBTFVFX1NRICYmXG5cdFx0dGhpcy5fc3RhdGUgIT09IElOX0FUVFJJQlVURV9WQUxVRV9EUSAmJlxuXHRcdHRoaXMuX3N0YXRlICE9PSBJTl9BVFRSSUJVVEVfVkFMVUVfTlEgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fQ0xPU0lOR19UQUdfTkFNRVxuXHQpe1xuXHRcdHRoaXMuX2Nicy5vbnRleHQoZGF0YSk7XG5cdH1cblx0Ly9lbHNlLCBpZ25vcmUgcmVtYWluaW5nIGRhdGFcblx0Ly9UT0RPIGFkZCBhIHdheSB0byByZW1vdmUgY3VycmVudCB0YWdcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpe1xuXHRUb2tlbml6ZXIuY2FsbCh0aGlzLCB7eG1sTW9kZTogdGhpcy5feG1sTW9kZSwgZGVjb2RlRW50aXRpZXM6IHRoaXMuX2RlY29kZUVudGl0aWVzfSwgdGhpcy5fY2JzKTtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuZ2V0QWJzb2x1dGVJbmRleCA9IGZ1bmN0aW9uKCl7XG5cdHJldHVybiB0aGlzLl9idWZmZXJPZmZzZXQgKyB0aGlzLl9pbmRleDtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX2dldFNlY3Rpb24gPSBmdW5jdGlvbigpe1xuXHRyZXR1cm4gdGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQsIHRoaXMuX2luZGV4KTtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX2VtaXRUb2tlbiA9IGZ1bmN0aW9uKG5hbWUpe1xuXHR0aGlzLl9jYnNbbmFtZV0odGhpcy5fZ2V0U2VjdGlvbigpKTtcblx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gLTE7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9lbWl0UGFydGlhbCA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0aWYodGhpcy5fYmFzZVN0YXRlICE9PSBURVhUKXtcblx0XHR0aGlzLl9jYnMub25hdHRyaWJkYXRhKHZhbHVlKTsgLy9UT0RPIGltcGxlbWVudCB0aGUgbmV3IGV2ZW50XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5fY2JzLm9udGV4dCh2YWx1ZSk7XG5cdH1cbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vaHRtbHBhcnNlcjIvbGliL1Rva2VuaXplci5qc1xuLy8gbW9kdWxlIGlkID0gMzFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBQYXJzZXIgPSByZXF1aXJlKFwiLi9QYXJzZXIuanNcIiksXG4gICAgV3JpdGFibGVTdHJlYW0gPSByZXF1aXJlKFwic3RyZWFtXCIpLldyaXRhYmxlIHx8IHJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW1cIikuV3JpdGFibGUsXG4gICAgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoXCJzdHJpbmdfZGVjb2RlclwiKS5TdHJpbmdEZWNvZGVyLFxuICAgIEJ1ZmZlciA9IHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO1xuXG5mdW5jdGlvbiBTdHJlYW0oY2JzLCBvcHRpb25zKXtcblx0dmFyIHBhcnNlciA9IHRoaXMuX3BhcnNlciA9IG5ldyBQYXJzZXIoY2JzLCBvcHRpb25zKTtcblx0dmFyIGRlY29kZXIgPSB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoKTtcblxuXHRXcml0YWJsZVN0cmVhbS5jYWxsKHRoaXMsIHtkZWNvZGVTdHJpbmdzOiBmYWxzZX0pO1xuXG5cdHRoaXMub25jZShcImZpbmlzaFwiLCBmdW5jdGlvbigpe1xuXHRcdHBhcnNlci5lbmQoZGVjb2Rlci5lbmQoKSk7XG5cdH0pO1xufVxuXG5yZXF1aXJlKFwiaW5oZXJpdHNcIikoU3RyZWFtLCBXcml0YWJsZVN0cmVhbSk7XG5cbldyaXRhYmxlU3RyZWFtLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKXtcblx0aWYoY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIpIGNodW5rID0gdGhpcy5fZGVjb2Rlci53cml0ZShjaHVuayk7XG5cdHRoaXMuX3BhcnNlci53cml0ZShjaHVuayk7XG5cdGNiKCk7XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9odG1scGFyc2VyMi9saWIvV3JpdGFibGVTdHJlYW0uanNcbi8vIG1vZHVsZSBpZCA9IDMyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2lzYXJyYXkvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDMzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL19zdHJlYW1fdHJhbnNmb3JtJyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1xuLy8gbW9kdWxlIGlkID0gMzRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24gKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW07XG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIFN0cmVhbSA9IHJlcXVpcmUoJ3N0JyArICdyZWFtJyk7XG4gIH0gY2F0Y2ggKF8pIHt9IGZpbmFsbHkge1xuICAgIGlmICghU3RyZWFtKSBTdHJlYW0gPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG4gIH1cbn0pKCk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPHJlcGxhY2VtZW50PiovXG52YXIgYnVmZmVyU2hpbSA9IHJlcXVpcmUoJ2J1ZmZlci1zaGltcycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBkZWJ1Z1V0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgZGVidWcgPSB2b2lkIDA7XG5pZiAoZGVidWdVdGlsICYmIGRlYnVnVXRpbC5kZWJ1Z2xvZykge1xuICBkZWJ1ZyA9IGRlYnVnVXRpbC5kZWJ1Z2xvZygnc3RyZWFtJyk7XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9O1xufVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QnKTtcbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIoZW1pdHRlciwgZXZlbnQsIGZuKSB7XG4gIC8vIFNhZGx5IHRoaXMgaXMgbm90IGNhY2hlYWJsZSBhcyBzb21lIGxpYnJhcmllcyBidW5kbGUgdGhlaXIgb3duXG4gIC8vIGV2ZW50IGVtaXR0ZXIgaW1wbGVtZW50YXRpb24gd2l0aCB0aGVtLlxuICBpZiAodHlwZW9mIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50LCBmbik7XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBhIGhhY2sgdG8gbWFrZSBzdXJlIHRoYXQgb3VyIGVycm9yIGhhbmRsZXIgaXMgYXR0YWNoZWQgYmVmb3JlIGFueVxuICAgIC8vIHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLiBUaGlzIGlzIGhlcmUgb25seSBiZWNhdXNlIHRoaXMgY29kZSBuZWVkc1xuICAgIC8vIHRvIGNvbnRpbnVlIHRvIHdvcmsgd2l0aCBvbGRlciB2ZXJzaW9ucyBvZiBOb2RlLmpzIHRoYXQgZG8gbm90IGluY2x1ZGVcbiAgICAvLyB0aGUgcHJlcGVuZExpc3RlbmVyKCkgbWV0aG9kLiBUaGUgZ29hbCBpcyB0byBldmVudHVhbGx5IHJlbW92ZSB0aGlzIGhhY2suXG4gICAgaWYgKCFlbWl0dGVyLl9ldmVudHMgfHwgIWVtaXR0ZXIuX2V2ZW50c1tldmVudF0pIGVtaXR0ZXIub24oZXZlbnQsIGZuKTtlbHNlIGlmIChpc0FycmF5KGVtaXR0ZXIuX2V2ZW50c1tldmVudF0pKSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XSA9IFtmbiwgZW1pdHRlci5fZXZlbnRzW2V2ZW50XV07XG4gIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcuIFVzZWQgdG8gbWFrZSByZWFkKG4pIGlnbm9yZSBuIGFuZCB0b1xuICAvLyBtYWtlIGFsbCB0aGUgYnVmZmVyIG1lcmdpbmcgYW5kIGxlbmd0aCBjaGVja3MgZ28gYXdheVxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfn50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgLy8gQSBsaW5rZWQgbGlzdCBpcyB1c2VkIHRvIHN0b3JlIGRhdGEgY2h1bmtzIGluc3RlYWQgb2YgYW4gYXJyYXkgYmVjYXVzZSB0aGVcbiAgLy8gbGlua2VkIGxpc3QgY2FuIHJlbW92ZSBlbGVtZW50cyBmcm9tIHRoZSBiZWdpbm5pbmcgZmFzdGVyIHRoYW5cbiAgLy8gYXJyYXkuc2hpZnQoKVxuICB0aGlzLmJ1ZmZlciA9IG5ldyBCdWZmZXJMaXN0KCk7XG4gIHRoaXMubGVuZ3RoID0gMDtcbiAgdGhpcy5waXBlcyA9IG51bGw7XG4gIHRoaXMucGlwZXNDb3VudCA9IDA7XG4gIHRoaXMuZmxvd2luZyA9IG51bGw7XG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgdGhpcy5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIHRoaXMucmVhZGluZyA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIHdoZW5ldmVyIHdlIHJldHVybiBudWxsLCB0aGVuIHdlIHNldCBhIGZsYWcgdG8gc2F5XG4gIC8vIHRoYXQgd2UncmUgYXdhaXRpbmcgYSAncmVhZGFibGUnIGV2ZW50IGVtaXNzaW9uLlxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG4gIHRoaXMucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gd2hlbiBwaXBpbmcsIHdlIG9ubHkgY2FyZSBhYm91dCAncmVhZGFibGUnIGV2ZW50cyB0aGF0IGhhcHBlblxuICAvLyBhZnRlciByZWFkKClpbmcgYWxsIHRoZSBieXRlcyBhbmQgbm90IGdldHRpbmcgYW55IHB1c2hiYWNrLlxuICB0aGlzLnJhbk91dCA9IGZhbHNlO1xuXG4gIC8vIHRoZSBudW1iZXIgb2Ygd3JpdGVycyB0aGF0IGFyZSBhd2FpdGluZyBhIGRyYWluIGV2ZW50IGluIC5waXBlKClzXG4gIHRoaXMuYXdhaXREcmFpbiA9IDA7XG5cbiAgLy8gaWYgdHJ1ZSwgYSBtYXliZVJlYWRNb3JlIGhhcyBiZWVuIHNjaGVkdWxlZFxuICB0aGlzLnJlYWRpbmdNb3JlID0gZmFsc2U7XG5cbiAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IG51bGw7XG4gIGlmIChvcHRpb25zLmVuY29kaW5nKSB7XG4gICAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBSZWFkYWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSkgcmV0dXJuIG5ldyBSZWFkYWJsZShvcHRpb25zKTtcblxuICB0aGlzLl9yZWFkYWJsZVN0YXRlID0gbmV3IFJlYWRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zLnJlYWQgPT09ICdmdW5jdGlvbicpIHRoaXMuX3JlYWQgPSBvcHRpb25zLnJlYWQ7XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE1hbnVhbGx5IHNob3ZlIHNvbWV0aGluZyBpbnRvIHRoZSByZWFkKCkgYnVmZmVyLlxuLy8gVGhpcyByZXR1cm5zIHRydWUgaWYgdGhlIGhpZ2hXYXRlck1hcmsgaGFzIG5vdCBiZWVuIGhpdCB5ZXQsXG4vLyBzaW1pbGFyIHRvIGhvdyBXcml0YWJsZS53cml0ZSgpIHJldHVybnMgdHJ1ZSBpZiB5b3Ugc2hvdWxkXG4vLyB3cml0ZSgpIHNvbWUgbW9yZS5cblJlYWRhYmxlLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG4gICAgaWYgKGVuY29kaW5nICE9PSBzdGF0ZS5lbmNvZGluZykge1xuICAgICAgY2h1bmsgPSBidWZmZXJTaGltLmZyb20oY2h1bmssIGVuY29kaW5nKTtcbiAgICAgIGVuY29kaW5nID0gJyc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgZmFsc2UpO1xufTtcblxuLy8gVW5zaGlmdCBzaG91bGQgKmFsd2F5cyogYmUgc29tZXRoaW5nIGRpcmVjdGx5IG91dCBvZiByZWFkKClcblJlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgJycsIHRydWUpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBhZGRUb0Zyb250KSB7XG4gIHZhciBlciA9IGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspO1xuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIH0gZWxzZSBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoc3RhdGUuZW5kZWQgJiYgIWFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRicpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRFbWl0dGVkICYmIGFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBfZSA9IG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIF9lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHNraXBBZGQ7XG4gICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhYWRkVG9Gcm9udCAmJiAhZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcbiAgICAgICAgc2tpcEFkZCA9ICFzdGF0ZS5vYmplY3RNb2RlICYmIGNodW5rLmxlbmd0aCA9PT0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFhZGRUb0Zyb250KSBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG5cbiAgICAgIC8vIERvbid0IGFkZCB0byB0aGUgYnVmZmVyIGlmIHdlJ3ZlIGRlY29kZWQgdG8gYW4gZW1wdHkgc3RyaW5nIGNodW5rIGFuZFxuICAgICAgLy8gd2UncmUgbm90IGluIG9iamVjdCBtb2RlXG4gICAgICBpZiAoIXNraXBBZGQpIHtcbiAgICAgICAgLy8gaWYgd2Ugd2FudCB0aGUgZGF0YSBub3csIGp1c3QgZW1pdCBpdC5cbiAgICAgICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5zeW5jKSB7XG4gICAgICAgICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gICAgICAgICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICAgICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICAgICAgaWYgKGFkZFRvRnJvbnQpIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcblxuICAgICAgICAgIGlmIChzdGF0ZS5uZWVkUmVhZGFibGUpIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFhZGRUb0Zyb250KSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIG5lZWRNb3JlRGF0YShzdGF0ZSk7XG59XG5cbi8vIGlmIGl0J3MgcGFzdCB0aGUgaGlnaCB3YXRlciBtYXJrLCB3ZSBjYW4gcHVzaCBpbiBzb21lIG1vcmUuXG4vLyBBbHNvLCBpZiB3ZSBoYXZlIG5vIGRhdGEgeWV0LCB3ZSBjYW4gc3RhbmQgc29tZVxuLy8gbW9yZSBieXRlcy4gIFRoaXMgaXMgdG8gd29yayBhcm91bmQgY2FzZXMgd2hlcmUgaHdtPTAsXG4vLyBzdWNoIGFzIHRoZSByZXBsLiAgQWxzbywgaWYgdGhlIHB1c2goKSB0cmlnZ2VyZWQgYVxuLy8gcmVhZGFibGUgZXZlbnQsIGFuZCB0aGUgdXNlciBjYWxsZWQgcmVhZChsYXJnZU51bWJlcikgc3VjaCB0aGF0XG4vLyBuZWVkUmVhZGFibGUgd2FzIHNldCwgdGhlbiB3ZSBvdWdodCB0byBwdXNoIG1vcmUsIHNvIHRoYXQgYW5vdGhlclxuLy8gJ3JlYWRhYmxlJyBldmVudCB3aWxsIGJlIHRyaWdnZXJlZC5cbmZ1bmN0aW9uIG5lZWRNb3JlRGF0YShzdGF0ZSkge1xuICByZXR1cm4gIXN0YXRlLmVuZGVkICYmIChzdGF0ZS5uZWVkUmVhZGFibGUgfHwgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gOE1CXG52YXIgTUFYX0hXTSA9IDB4ODAwMDAwO1xuZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMiB0byBwcmV2ZW50IGluY3JlYXNpbmcgaHdtIGV4Y2Vzc2l2ZWx5IGluXG4gICAgLy8gdGlueSBhbW91bnRzXG4gICAgbi0tO1xuICAgIG4gfD0gbiA+Pj4gMTtcbiAgICBuIHw9IG4gPj4+IDI7XG4gICAgbiB8PSBuID4+PiA0O1xuICAgIG4gfD0gbiA+Pj4gODtcbiAgICBuIHw9IG4gPj4+IDE2O1xuICAgIG4rKztcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKSB7XG4gIGlmIChuIDw9IDAgfHwgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSByZXR1cm4gMDtcbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldHVybiAxO1xuICBpZiAobiAhPT0gbikge1xuICAgIC8vIE9ubHkgZmxvdyBvbmUgYnVmZmVyIGF0IGEgdGltZVxuICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmxlbmd0aCkgcmV0dXJuIHN0YXRlLmJ1ZmZlci5oZWFkLmRhdGEubGVuZ3RoO2Vsc2UgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgfVxuICAvLyBJZiB3ZSdyZSBhc2tpbmcgZm9yIG1vcmUgdGhhbiB0aGUgY3VycmVudCBod20sIHRoZW4gcmFpc2UgdGhlIGh3bS5cbiAgaWYgKG4gPiBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSBzdGF0ZS5oaWdoV2F0ZXJNYXJrID0gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7XG4gIGlmIChuIDw9IHN0YXRlLmxlbmd0aCkgcmV0dXJuIG47XG4gIC8vIERvbid0IGhhdmUgZW5vdWdoXG4gIGlmICghc3RhdGUuZW5kZWQpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIHJldHVybiAwO1xuICB9XG4gIHJldHVybiBzdGF0ZS5sZW5ndGg7XG59XG5cbi8vIHlvdSBjYW4gb3ZlcnJpZGUgZWl0aGVyIHRoaXMgbWV0aG9kLCBvciB0aGUgYXN5bmMgX3JlYWQobikgYmVsb3cuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIGRlYnVnKCdyZWFkJywgbik7XG4gIG4gPSBwYXJzZUludChuLCAxMCk7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBuT3JpZyA9IG47XG5cbiAgaWYgKG4gIT09IDApIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUubmVlZFJlYWRhYmxlICYmIChzdGF0ZS5sZW5ndGggPj0gc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBkZWJ1ZygncmVhZDogZW1pdFJlYWRhYmxlJywgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7ZWxzZSBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBuID0gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSk7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQsIGFuZCB3ZSdyZSBub3cgY2xlYXIsIHRoZW4gZmluaXNoIGl0IHVwLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkge1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIGVuZFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWxsIHRoZSBhY3R1YWwgY2h1bmsgZ2VuZXJhdGlvbiBsb2dpYyBuZWVkcyB0byBiZVxuICAvLyAqYmVsb3cqIHRoZSBjYWxsIHRvIF9yZWFkLiAgVGhlIHJlYXNvbiBpcyB0aGF0IGluIGNlcnRhaW5cbiAgLy8gc3ludGhldGljIHN0cmVhbSBjYXNlcywgc3VjaCBhcyBwYXNzdGhyb3VnaCBzdHJlYW1zLCBfcmVhZFxuICAvLyBtYXkgYmUgYSBjb21wbGV0ZWx5IHN5bmNocm9ub3VzIG9wZXJhdGlvbiB3aGljaCBtYXkgY2hhbmdlXG4gIC8vIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZCBidWZmZXIsIHByb3ZpZGluZyBlbm91Z2ggZGF0YSB3aGVuXG4gIC8vIGJlZm9yZSB0aGVyZSB3YXMgKm5vdCogZW5vdWdoLlxuICAvL1xuICAvLyBTbywgdGhlIHN0ZXBzIGFyZTpcbiAgLy8gMS4gRmlndXJlIG91dCB3aGF0IHRoZSBzdGF0ZSBvZiB0aGluZ3Mgd2lsbCBiZSBhZnRlciB3ZSBkb1xuICAvLyBhIHJlYWQgZnJvbSB0aGUgYnVmZmVyLlxuICAvL1xuICAvLyAyLiBJZiB0aGF0IHJlc3VsdGluZyBzdGF0ZSB3aWxsIHRyaWdnZXIgYSBfcmVhZCwgdGhlbiBjYWxsIF9yZWFkLlxuICAvLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgYXN5bmNocm9ub3VzLCBvciBzeW5jaHJvbm91cy4gIFllcywgaXQgaXNcbiAgLy8gZGVlcGx5IHVnbHkgdG8gd3JpdGUgQVBJcyB0aGlzIHdheSwgYnV0IHRoYXQgc3RpbGwgZG9lc24ndCBtZWFuXG4gIC8vIHRoYXQgdGhlIFJlYWRhYmxlIGNsYXNzIHNob3VsZCBiZWhhdmUgaW1wcm9wZXJseSwgYXMgc3RyZWFtcyBhcmVcbiAgLy8gZGVzaWduZWQgdG8gYmUgc3luYy9hc3luYyBhZ25vc3RpYy5cbiAgLy8gVGFrZSBub3RlIGlmIHRoZSBfcmVhZCBjYWxsIGlzIHN5bmMgb3IgYXN5bmMgKGllLCBpZiB0aGUgcmVhZCBjYWxsXG4gIC8vIGhhcyByZXR1cm5lZCB5ZXQpLCBzbyB0aGF0IHdlIGtub3cgd2hldGhlciBvciBub3QgaXQncyBzYWZlIHRvIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBldGMuXG4gIC8vXG4gIC8vIDMuIEFjdHVhbGx5IHB1bGwgdGhlIHJlcXVlc3RlZCBjaHVua3Mgb3V0IG9mIHRoZSBidWZmZXIgYW5kIHJldHVybi5cblxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG4gIHZhciBkb1JlYWQgPSBzdGF0ZS5uZWVkUmVhZGFibGU7XG4gIGRlYnVnKCduZWVkIHJlYWRhYmxlJywgZG9SZWFkKTtcblxuICAvLyBpZiB3ZSBjdXJyZW50bHkgaGF2ZSBsZXNzIHRoYW4gdGhlIGhpZ2hXYXRlck1hcmssIHRoZW4gYWxzbyByZWFkIHNvbWVcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCB8fCBzdGF0ZS5sZW5ndGggLSBuIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRvUmVhZCA9IHRydWU7XG4gICAgZGVidWcoJ2xlbmd0aCBsZXNzIHRoYW4gd2F0ZXJtYXJrJywgZG9SZWFkKTtcbiAgfVxuXG4gIC8vIGhvd2V2ZXIsIGlmIHdlJ3ZlIGVuZGVkLCB0aGVuIHRoZXJlJ3Mgbm8gcG9pbnQsIGFuZCBpZiB3ZSdyZSBhbHJlYWR5XG4gIC8vIHJlYWRpbmcsIHRoZW4gaXQncyB1bm5lY2Vzc2FyeS5cbiAgaWYgKHN0YXRlLmVuZGVkIHx8IHN0YXRlLnJlYWRpbmcpIHtcbiAgICBkb1JlYWQgPSBmYWxzZTtcbiAgICBkZWJ1ZygncmVhZGluZyBvciBlbmRlZCcsIGRvUmVhZCk7XG4gIH0gZWxzZSBpZiAoZG9SZWFkKSB7XG4gICAgZGVidWcoJ2RvIHJlYWQnKTtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIGN1cnJlbnRseSB6ZXJvLCB0aGVuIHdlICpuZWVkKiBhIHJlYWRhYmxlIGV2ZW50LlxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgLy8gY2FsbCBpbnRlcm5hbCByZWFkIG1ldGhvZFxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG4gICAgc3RhdGUuc3luYyA9IGZhbHNlO1xuICAgIC8vIElmIF9yZWFkIHB1c2hlZCBkYXRhIHN5bmNocm9ub3VzbHksIHRoZW4gYHJlYWRpbmdgIHdpbGwgYmUgZmFsc2UsXG4gICAgLy8gYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICAgIGlmICghc3RhdGUucmVhZGluZykgbiA9IGhvd011Y2hUb1JlYWQobk9yaWcsIHN0YXRlKTtcbiAgfVxuXG4gIHZhciByZXQ7XG4gIGlmIChuID4gMCkgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO2Vsc2UgcmV0ID0gbnVsbDtcblxuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBuID0gMDtcbiAgfSBlbHNlIHtcbiAgICBzdGF0ZS5sZW5ndGggLT0gbjtcbiAgfVxuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAgIC8vIElmIHdlIHRyaWVkIHRvIHJlYWQoKSBwYXN0IHRoZSBFT0YsIHRoZW4gZW1pdCBlbmQgb24gdGhlIG5leHQgdGljay5cbiAgICBpZiAobk9yaWcgIT09IG4gJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO1xuICB9XG5cbiAgaWYgKHJldCAhPT0gbnVsbCkgdGhpcy5lbWl0KCdkYXRhJywgcmV0KTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXIgPSBudWxsO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpIHByb2Nlc3NOZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIGRlYnVnKCdlbWl0IHJlYWRhYmxlJyk7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICBmbG93KHN0cmVhbSk7XG59XG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRlYnVnKCdtYXliZVJlYWRNb3JlIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztlbHNlIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ19yZWFkKCkgaXMgbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgc3dpdGNoIChzdGF0ZS5waXBlc0NvdW50KSB7XG4gICAgY2FzZSAwOlxuICAgICAgc3RhdGUucGlwZXMgPSBkZXN0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgc3RhdGUucGlwZXMgPSBbc3RhdGUucGlwZXMsIGRlc3RdO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuICBzdGF0ZS5waXBlc0NvdW50ICs9IDE7XG4gIGRlYnVnKCdwaXBlIGNvdW50PSVkIG9wdHM9JWonLCBzdGF0ZS5waXBlc0NvdW50LCBwaXBlT3B0cyk7XG5cbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcblxuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogY2xlYW51cDtcbiAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHByb2Nlc3NOZXh0VGljayhlbmRGbik7ZWxzZSBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuXG4gIGRlc3Qub24oJ3VucGlwZScsIG9udW5waXBlKTtcbiAgZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUpIHtcbiAgICBkZWJ1Zygnb251bnBpcGUnKTtcbiAgICBpZiAocmVhZGFibGUgPT09IHNyYykge1xuICAgICAgY2xlYW51cCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGRlYnVnKCdvbmVuZCcpO1xuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuICAvLyB3aGVuIHRoZSBkZXN0IGRyYWlucywgaXQgcmVkdWNlcyB0aGUgYXdhaXREcmFpbiBjb3VudGVyXG4gIC8vIG9uIHRoZSBzb3VyY2UuICBUaGlzIHdvdWxkIGJlIG1vcmUgZWxlZ2FudCB3aXRoIGEgLm9uY2UoKVxuICAvLyBoYW5kbGVyIGluIGZsb3coKSwgYnV0IGFkZGluZyBhbmQgcmVtb3ZpbmcgcmVwZWF0ZWRseSBpc1xuICAvLyB0b28gc2xvdy5cbiAgdmFyIG9uZHJhaW4gPSBwaXBlT25EcmFpbihzcmMpO1xuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIHZhciBjbGVhbmVkVXAgPSBmYWxzZTtcbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBkZWJ1ZygnY2xlYW51cCcpO1xuICAgIC8vIGNsZWFudXAgZXZlbnQgaGFuZGxlcnMgb25jZSB0aGUgcGlwZSBpcyBicm9rZW5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcigndW5waXBlJywgb251bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcblxuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpIG9uZHJhaW4oKTtcbiAgfVxuXG4gIC8vIElmIHRoZSB1c2VyIHB1c2hlcyBtb3JlIGRhdGEgd2hpbGUgd2UncmUgd3JpdGluZyB0byBkZXN0IHRoZW4gd2UnbGwgZW5kIHVwXG4gIC8vIGluIG9uZGF0YSBhZ2Fpbi4gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIGluY3JlYXNlIGF3YWl0RHJhaW4gb25jZSBiZWNhdXNlXG4gIC8vIGRlc3Qgd2lsbCBvbmx5IGVtaXQgb25lICdkcmFpbicgZXZlbnQgZm9yIHRoZSBtdWx0aXBsZSB3cml0ZXMuXG4gIC8vID0+IEludHJvZHVjZSBhIGd1YXJkIG9uIGluY3JlYXNpbmcgYXdhaXREcmFpbi5cbiAgdmFyIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgZGVidWcoJ29uZGF0YScpO1xuICAgIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgICB2YXIgcmV0ID0gZGVzdC53cml0ZShjaHVuayk7XG4gICAgaWYgKGZhbHNlID09PSByZXQgJiYgIWluY3JlYXNlZEF3YWl0RHJhaW4pIHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIHVucGlwZWQgZHVyaW5nIGBkZXN0LndyaXRlKClgLCBpdCBpcyBwb3NzaWJsZVxuICAgICAgLy8gdG8gZ2V0IHN0dWNrIGluIGEgcGVybWFuZW50bHkgcGF1c2VkIHN0YXRlIGlmIHRoYXQgd3JpdGVcbiAgICAgIC8vIGFsc28gcmV0dXJuZWQgZmFsc2UuXG4gICAgICAvLyA9PiBDaGVjayB3aGV0aGVyIGBkZXN0YCBpcyBzdGlsbCBhIHBpcGluZyBkZXN0aW5hdGlvbi5cbiAgICAgIGlmICgoc3RhdGUucGlwZXNDb3VudCA9PT0gMSAmJiBzdGF0ZS5waXBlcyA9PT0gZGVzdCB8fCBzdGF0ZS5waXBlc0NvdW50ID4gMSAmJiBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KSAhPT0gLTEpICYmICFjbGVhbmVkVXApIHtcbiAgICAgICAgZGVidWcoJ2ZhbHNlIHdyaXRlIHJlc3BvbnNlLCBwYXVzZScsIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICAgICAgaW5jcmVhc2VkQXdhaXREcmFpbiA9IHRydWU7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKSBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSB1c2VybGFuZCBvbmVzLlxuICBwcmVwZW5kTGlzdGVuZXIoZGVzdCwgJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gaWYgd2UncmUgbm90IHBpcGluZyBhbnl3aGVyZSwgdGhlbiBkbyBub3RoaW5nLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMCkgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKSByZXR1cm4gdGhpcztcblxuICAgIGlmICghZGVzdCkgZGVzdCA9IHN0YXRlLnBpcGVzO1xuXG4gICAgLy8gZ290IGEgbWF0Y2guXG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBpZiAoZGVzdCkgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgZGVzdHNbaV0uZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgfXJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGZpbmQgdGhlIHJpZ2h0IG9uZS5cbiAgdmFyIGluZGV4ID0gaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCk7XG4gIGlmIChpbmRleCA9PT0gLTEpIHJldHVybiB0aGlzO1xuXG4gIHN0YXRlLnBpcGVzLnNwbGljZShpbmRleCwgMSk7XG4gIHN0YXRlLnBpcGVzQ291bnQgLT0gMTtcbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHN0YXRlLnBpcGVzID0gc3RhdGUucGlwZXNbMF07XG5cbiAgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIHNldCB1cCBkYXRhIGV2ZW50cyBpZiB0aGV5IGFyZSBhc2tlZCBmb3Jcbi8vIEVuc3VyZSByZWFkYWJsZSBsaXN0ZW5lcnMgZXZlbnR1YWxseSBnZXQgc29tZXRoaW5nXG5SZWFkYWJsZS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcblxuICBpZiAoZXYgPT09ICdkYXRhJykge1xuICAgIC8vIFN0YXJ0IGZsb3dpbmcgb24gbmV4dCB0aWNrIGlmIHN0cmVhbSBpc24ndCBleHBsaWNpdGx5IHBhdXNlZFxuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgIT09IGZhbHNlKSB0aGlzLnJlc3VtZSgpO1xuICB9IGVsc2UgaWYgKGV2ID09PSAncmVhZGFibGUnKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKSB7XG4gICAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIGlmICghc3RhdGUucmVhZGluZykge1xuICAgICAgICBwcm9jZXNzTmV4dFRpY2soblJlYWRpbmdOZXh0VGljaywgdGhpcyk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxlbmd0aCkge1xuICAgICAgICBlbWl0UmVhZGFibGUodGhpcywgc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5mdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpIHtcbiAgZGVidWcoJ3JlYWRhYmxlIG5leHR0aWNrIHJlYWQgMCcpO1xuICBzZWxmLnJlYWQoMCk7XG59XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdyZXN1bWUnKTtcbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICByZXN1bWUodGhpcywgc3RhdGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpIHtcbiAgICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhyZXN1bWVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICBzdGF0ZS5hd2FpdERyYWluID0gMDtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIHdoaWxlIChzdGF0ZS5mbG93aW5nICYmIHN0cmVhbS5yZWFkKCkgIT09IG51bGwpIHt9XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24gKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgcGF1c2VkID0gZmFsc2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSBzZWxmLnB1c2goY2h1bmspO1xuICAgIH1cblxuICAgIHNlbGYucHVzaChudWxsKTtcbiAgfSk7XG5cbiAgc3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZGF0YScpO1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyKSBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuXG4gICAgLy8gZG9uJ3Qgc2tpcCBvdmVyIGZhbHN5IHZhbHVlcyBpbiBvYmplY3RNb2RlXG4gICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgJiYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpKSByZXR1cm47ZWxzZSBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgKCFjaHVuayB8fCAhY2h1bmsubGVuZ3RoKSkgcmV0dXJuO1xuXG4gICAgdmFyIHJldCA9IHNlbGYucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgICB9KGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByb3h5IGNlcnRhaW4gaW1wb3J0YW50IGV2ZW50cy5cbiAgdmFyIGV2ZW50cyA9IFsnZXJyb3InLCAnY2xvc2UnLCAnZGVzdHJveScsICdwYXVzZScsICdyZXN1bWUnXTtcbiAgZm9yRWFjaChldmVudHMsIGZ1bmN0aW9uIChldikge1xuICAgIHN0cmVhbS5vbihldiwgc2VsZi5lbWl0LmJpbmQoc2VsZiwgZXYpKTtcbiAgfSk7XG5cbiAgLy8gd2hlbiB3ZSB0cnkgdG8gY29uc3VtZSBzb21lIG1vcmUgYnl0ZXMsIHNpbXBseSB1bnBhdXNlIHRoZVxuICAvLyB1bmRlcmx5aW5nIHN0cmVhbS5cbiAgc2VsZi5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgX3JlYWQnLCBuKTtcbiAgICBpZiAocGF1c2VkKSB7XG4gICAgICBwYXVzZWQgPSBmYWxzZTtcbiAgICAgIHN0cmVhbS5yZXN1bWUoKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG4vLyBleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcblxuLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgLy8gbm90aGluZyBidWZmZXJlZFxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICB2YXIgcmV0O1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0ID0gc3RhdGUuYnVmZmVyLnNoaWZ0KCk7ZWxzZSBpZiAoIW4gfHwgbiA+PSBzdGF0ZS5sZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGxpc3RcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgcmV0ID0gc3RhdGUuYnVmZmVyLmpvaW4oJycpO2Vsc2UgaWYgKHN0YXRlLmJ1ZmZlci5sZW5ndGggPT09IDEpIHJldCA9IHN0YXRlLmJ1ZmZlci5oZWFkLmRhdGE7ZWxzZSByZXQgPSBzdGF0ZS5idWZmZXIuY29uY2F0KHN0YXRlLmxlbmd0aCk7XG4gICAgc3RhdGUuYnVmZmVyLmNsZWFyKCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVhZCBwYXJ0IG9mIGxpc3RcbiAgICByZXQgPSBmcm9tTGlzdFBhcnRpYWwobiwgc3RhdGUuYnVmZmVyLCBzdGF0ZS5kZWNvZGVyKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbi8vIEV4dHJhY3RzIG9ubHkgZW5vdWdoIGJ1ZmZlcmVkIGRhdGEgdG8gc2F0aXNmeSB0aGUgYW1vdW50IHJlcXVlc3RlZC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gZnJvbUxpc3RQYXJ0aWFsKG4sIGxpc3QsIGhhc1N0cmluZ3MpIHtcbiAgdmFyIHJldDtcbiAgaWYgKG4gPCBsaXN0LmhlYWQuZGF0YS5sZW5ndGgpIHtcbiAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5nc1xuICAgIHJldCA9IGxpc3QuaGVhZC5kYXRhLnNsaWNlKDAsIG4pO1xuICAgIGxpc3QuaGVhZC5kYXRhID0gbGlzdC5oZWFkLmRhdGEuc2xpY2Uobik7XG4gIH0gZWxzZSBpZiAobiA9PT0gbGlzdC5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgLy8gZmlyc3QgY2h1bmsgaXMgYSBwZXJmZWN0IG1hdGNoXG4gICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlc3VsdCBzcGFucyBtb3JlIHRoYW4gb25lIGJ1ZmZlclxuICAgIHJldCA9IGhhc1N0cmluZ3MgPyBjb3B5RnJvbUJ1ZmZlclN0cmluZyhuLCBsaXN0KSA6IGNvcHlGcm9tQnVmZmVyKG4sIGxpc3QpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8vIENvcGllcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgY2hhcmFjdGVycyBmcm9tIHRoZSBsaXN0IG9mIGJ1ZmZlcmVkIGRhdGFcbi8vIGNodW5rcy5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gY29weUZyb21CdWZmZXJTdHJpbmcobiwgbGlzdCkge1xuICB2YXIgcCA9IGxpc3QuaGVhZDtcbiAgdmFyIGMgPSAxO1xuICB2YXIgcmV0ID0gcC5kYXRhO1xuICBuIC09IHJldC5sZW5ndGg7XG4gIHdoaWxlIChwID0gcC5uZXh0KSB7XG4gICAgdmFyIHN0ciA9IHAuZGF0YTtcbiAgICB2YXIgbmIgPSBuID4gc3RyLmxlbmd0aCA/IHN0ci5sZW5ndGggOiBuO1xuICAgIGlmIChuYiA9PT0gc3RyLmxlbmd0aCkgcmV0ICs9IHN0cjtlbHNlIHJldCArPSBzdHIuc2xpY2UoMCwgbik7XG4gICAgbiAtPSBuYjtcbiAgICBpZiAobiA9PT0gMCkge1xuICAgICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSB7XG4gICAgICAgICsrYztcbiAgICAgICAgaWYgKHAubmV4dCkgbGlzdC5oZWFkID0gcC5uZXh0O2Vsc2UgbGlzdC5oZWFkID0gbGlzdC50YWlsID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpc3QuaGVhZCA9IHA7XG4gICAgICAgIHAuZGF0YSA9IHN0ci5zbGljZShuYik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgKytjO1xuICB9XG4gIGxpc3QubGVuZ3RoIC09IGM7XG4gIHJldHVybiByZXQ7XG59XG5cbi8vIENvcGllcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgYnl0ZXMgZnJvbSB0aGUgbGlzdCBvZiBidWZmZXJlZCBkYXRhIGNodW5rcy5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gY29weUZyb21CdWZmZXIobiwgbGlzdCkge1xuICB2YXIgcmV0ID0gYnVmZmVyU2hpbS5hbGxvY1Vuc2FmZShuKTtcbiAgdmFyIHAgPSBsaXN0LmhlYWQ7XG4gIHZhciBjID0gMTtcbiAgcC5kYXRhLmNvcHkocmV0KTtcbiAgbiAtPSBwLmRhdGEubGVuZ3RoO1xuICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgIHZhciBidWYgPSBwLmRhdGE7XG4gICAgdmFyIG5iID0gbiA+IGJ1Zi5sZW5ndGggPyBidWYubGVuZ3RoIDogbjtcbiAgICBidWYuY29weShyZXQsIHJldC5sZW5ndGggLSBuLCAwLCBuYik7XG4gICAgbiAtPSBuYjtcbiAgICBpZiAobiA9PT0gMCkge1xuICAgICAgaWYgKG5iID09PSBidWYubGVuZ3RoKSB7XG4gICAgICAgICsrYztcbiAgICAgICAgaWYgKHAubmV4dCkgbGlzdC5oZWFkID0gcC5uZXh0O2Vsc2UgbGlzdC5oZWFkID0gbGlzdC50YWlsID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpc3QuaGVhZCA9IHA7XG4gICAgICAgIHAuZGF0YSA9IGJ1Zi5zbGljZShuYik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgKytjO1xuICB9XG4gIGxpc3QubGVuZ3RoIC09IGM7XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgYmVmb3JlIGNvbnN1bWluZyBhbGwgdGhlIGJ5dGVzLCB0aGVuIHRoYXQgaXMgYVxuICAvLyBidWcgaW4gbm9kZS4gIFNob3VsZCBuZXZlciBoYXBwZW4uXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKSB0aHJvdyBuZXcgRXJyb3IoJ1wiZW5kUmVhZGFibGUoKVwiIGNhbGxlZCBvbiBub24tZW1wdHkgc3RyZWFtJyk7XG5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhlbmRSZWFkYWJsZU5ULCBzdGF0ZSwgc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZU5UKHN0YXRlLCBzdHJlYW0pIHtcbiAgLy8gQ2hlY2sgdGhhdCB3ZSBkaWRuJ3QgZ2V0IG9uZSBsYXN0IHVuc2hpZnQuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICBzdGF0ZS5lbmRFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0ucmVhZGFibGUgPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZW5kJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzXG4vLyBtb2R1bGUgaWQgPSAzNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHtcclxuXHRTSElGVDogMHhGRkUxLFxyXG5cdENUUkw6IDB4RkZFMyxcclxuXHRBTFQ6IDB4RkZFOSxcclxuXHRERUxFVEU6IDB4RkZGRixcclxuXHRFTlRFUjogMHhGRjBELFxyXG5cdFdJTjogMHhGRkVCXHJcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9jb250cm9sLXN5bWtleXMuanNcbi8vIG1vZHVsZSBpZCA9IDM2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0ge1xyXG5cdElETEU6IFx0XHRcdDAsXHJcblx0Q09OTkVDVElORzogXHQxLFxyXG5cdFdBSVRJTkc6IFx0XHQyLFxyXG5cdENPTk5FQ1RFRDogICAgXHQzLFxyXG5cdERJU0NPTk5FQ1RJTkc6IFx0NCxcclxuXHRESVNDT05ORUNURUQ6IFx0NVxyXG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2d1YWNhbW9sZS1jbGllbnQvZ3VhY2Ftb2xlLXN0YXRlcy5qc1xuLy8gbW9kdWxlIGlkID0gMzdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBhbmd1bGFyO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiYW5ndWxhclwiXG4vLyBtb2R1bGUgaWQgPSAzOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9XG4vKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4vKioqKioqLyBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuLyoqKioqKi8gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbi8qKioqKiovIFx0XHRcdGk6IG1vZHVsZUlkLFxuLyoqKioqKi8gXHRcdFx0bDogZmFsc2UsXG4vKioqKioqLyBcdFx0XHRleHBvcnRzOiB7fVxuLyoqKioqKi8gXHRcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuLyoqKioqKi8gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuLyoqKioqKi8gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbi8qKioqKiovIFx0fVxuLyoqKioqKi9cbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuLyoqKioqKi8gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbi8qKioqKiovIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuLyoqKioqKi8gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuLyoqKioqKi8gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4vKioqKioqLyBcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3Rcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4vKioqKioqLyBcdC8vIG1vZGUgJiAyOiBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiB2YWx1ZSBpbnRvIHRoZSBuc1xuLyoqKioqKi8gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3Rcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnQgPSBmdW5jdGlvbih2YWx1ZSwgbW9kZSkge1xuLyoqKioqKi8gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xuLyoqKioqKi8gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4vKioqKioqLyBcdFx0aWYoKG1vZGUgJiA0KSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcbi8qKioqKiovIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4vKioqKioqLyBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5zLCAnZGVmYXVsdCcsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuLyoqKioqKi8gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcbi8qKioqKiovIFx0XHRyZXR1cm4gbnM7XG4vKioqKioqLyBcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbi8qKioqKiovIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4vKioqKioqLyBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbi8qKioqKiovIFx0XHRyZXR1cm4gZ2V0dGVyO1xuLyoqKioqKi8gXHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiL3Jlc291cmNlcy9qcy9jc0NsaWVudC9taW4vXCI7XG4vKioqKioqL1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vKioqKioqLyBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IFwiLi9zcmMvYXBwL0NvbW1vbi9MaWJyYXJpZXMvY29tbW9uLmxpYnJhcmllcy5icm93c2VyU2Vzc2lvblByb3ZpZGVyLnRzXCIpO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoe1xuXG4vKioqLyBcIi4vc3JjL2FwcC9Db21tb24vTGlicmFyaWVzL2NvbW1vbi5saWJyYXJpZXMuYnJvd3NlclNlc3Npb25Qcm92aWRlci50c1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9zcmMvYXBwL0NvbW1vbi9MaWJyYXJpZXMvY29tbW9uLmxpYnJhcmllcy5icm93c2VyU2Vzc2lvblByb3ZpZGVyLnRzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb21tb25fbGlicmFyaWVzX3V1aWRTZXJ2aWNlXzEgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvbW1vbi5saWJyYXJpZXMudXVpZFNlcnZpY2UgKi8gXCIuL3NyYy9hcHAvQ29tbW9uL0xpYnJhcmllcy9jb21tb24ubGlicmFyaWVzLnV1aWRTZXJ2aWNlLnRzXCIpO1xyXG52YXIgc2Vzc2lvblN0b3JhZ2VLZXkgPSBcImNzU3RnckJyb3dzZXJTZXNzaW9uXCI7XHJcbnZhciBicm93c2VyU2Vzc2lvbiA9IGdldFNlc3Npb25TdG9yYWdlKCk7XHJcbnZhciBCcm93c2VyU2Vzc2lvblByb3ZpZGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gQnJvd3NlclNlc3Npb25Qcm92aWRlcigpIHtcclxuICAgIH1cclxuICAgIEJyb3dzZXJTZXNzaW9uUHJvdmlkZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gYnJvd3NlclNlc3Npb247XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEJyb3dzZXJTZXNzaW9uUHJvdmlkZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuQnJvd3NlclNlc3Npb25Qcm92aWRlciA9IEJyb3dzZXJTZXNzaW9uUHJvdmlkZXI7XHJcbmZ1bmN0aW9uIGdldFNlc3Npb25TdG9yYWdlKCkge1xyXG4gICAgdmFyIHBhcmVudFdpbmRvdyA9IHdpbmRvdy5wYXJlbnQ7XHJcbiAgICBpZiAocGFyZW50V2luZG93LmNzICYmIHBhcmVudFdpbmRvdy5jcy5icm93c2VyU2Vzc2lvbikge1xyXG4gICAgICAgIHJldHVybiBwYXJlbnRXaW5kb3cuY3MuYnJvd3NlclNlc3Npb247XHJcbiAgICB9XHJcbiAgICB2YXIgYnJvd3NlclNlc3Npb24gPSBKU09OLnBhcnNlKHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHNlc3Npb25TdG9yYWdlS2V5KSk7XHJcbiAgICBpZiAoYnJvd3NlclNlc3Npb24gPT0gbnVsbCkge1xyXG4gICAgICAgIGJyb3dzZXJTZXNzaW9uID0ge1xyXG4gICAgICAgICAgICBpZDogbmV3IGNvbW1vbl9saWJyYXJpZXNfdXVpZFNlcnZpY2VfMS5VdWlkU2VydmljZSgpLmdlbmVyYXRlKCksXHJcbiAgICAgICAgICAgIHNlcXVlbmNlOiAwXHJcbiAgICAgICAgfTtcclxuICAgICAgICB3aW5kb3cuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShzZXNzaW9uU3RvcmFnZUtleSwgSlNPTi5zdHJpbmdpZnkoYnJvd3NlclNlc3Npb24pKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGJyb3dzZXJTZXNzaW9uLnNlcXVlbmNlICs9IDE7XHJcbiAgICAgICAgd2luZG93LnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc2Vzc2lvblN0b3JhZ2VLZXksIEpTT04uc3RyaW5naWZ5KGJyb3dzZXJTZXNzaW9uKSk7XHJcbiAgICB9XHJcbiAgICBwdWJsaXNoU2Vzc2lvbklkT25HbG9iYWxTY29wZShicm93c2VyU2Vzc2lvbik7XHJcbiAgICByZXR1cm4gYnJvd3NlclNlc3Npb247XHJcbn1cclxuZnVuY3Rpb24gcHVibGlzaFNlc3Npb25JZE9uR2xvYmFsU2NvcGUoYnJvd3NlclNlc3Npb24pIHtcclxuICAgIHZhciBjdXN0b21XaW5kb3cgPSB3aW5kb3c7XHJcbiAgICBjdXN0b21XaW5kb3cuY3MgPSBjdXN0b21XaW5kb3cuY3MgfHwge307XHJcbiAgICBjdXN0b21XaW5kb3cuY3MuYnJvd3NlclNlc3Npb24gPSBicm93c2VyU2Vzc2lvbjtcclxufVxyXG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9zcmMvYXBwL0NvbW1vbi9MaWJyYXJpZXMvY29tbW9uLmxpYnJhcmllcy51dWlkU2VydmljZS50c1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vc3JjL2FwcC9Db21tb24vTGlicmFyaWVzL2NvbW1vbi5saWJyYXJpZXMudXVpZFNlcnZpY2UudHMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcblxyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBCQVNFNjRVUklDSEFSUyA9IFwiMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXotX1wiLnNwbGl0KFwiXCIpO1xyXG52YXIgVXVpZFNlcnZpY2UgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBVdWlkU2VydmljZSgpIHtcclxuICAgIH1cclxuICAgIFV1aWRTZXJ2aWNlLnByb3RvdHlwZS5nZW5lcmF0ZSA9IGZ1bmN0aW9uIChsZW4sIHJhZGl4KSB7XHJcbiAgICAgICAgaWYgKGxlbiA9PT0gdm9pZCAwKSB7IGxlbiA9IDIyOyB9XHJcbiAgICAgICAgaWYgKHJhZGl4ID09PSB2b2lkIDApIHsgcmFkaXggPSBCQVNFNjRVUklDSEFSUy5sZW5ndGg7IH1cclxuICAgICAgICB2YXIgbmV3SWQgPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIG5ld0lkW2ldID0gQkFTRTY0VVJJQ0hBUlNbMCB8IE1hdGgucmFuZG9tKCkgKiByYWRpeF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBuZXdJZC5qb2luKFwiXCIpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBVdWlkU2VydmljZTtcclxufSgpKTtcclxuZXhwb3J0cy5VdWlkU2VydmljZSA9IFV1aWRTZXJ2aWNlO1xyXG5cblxuLyoqKi8gfSlcblxuLyoqKioqKi8gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1icm93c2VyU2Vzc2lvblByb3ZpZGVyLmpzLm1hcFxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Jyb3dzZXJTZXNzaW9uUHJvdmlkZXIuanNcbi8vIG1vZHVsZSBpZCA9IDM5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIihmdW5jdGlvbigpIHtcclxuXHRpZiAoIWlzQW5ndWxhckRlZmluZWQoKSlcclxuXHRcdHJldHVybjtcclxuXHJcblx0cmVxdWlyZSgnLi9zdHlsZXMvc3R5bGUuY3NzJyk7XHJcblxyXG5cdHJlcXVpcmUoJy4vZGlyZWN0aXZlcy9jaG9jb2xhdGV5LWNsaWVudCcpO1xyXG5cdHJlcXVpcmUoXCIuL2RpcmVjdGl2ZXMvZGV0YWlscy1wYW5lXCIpO1xyXG5cdHJlcXVpcmUoJy4vZGlyZWN0aXZlcy9wYWNrYWdlLWxpc3QnKTtcclxuXHRyZXF1aXJlKCcuL2RpcmVjdGl2ZXMvcGFja2FnZS1pdGVtJyk7XHJcblx0cmVxdWlyZSgnLi9kaXJlY3RpdmVzL3BhY2thZ2UtZGV0YWlsZWQtaXRlbScpO1xyXG5cdHJlcXVpcmUoJy4vZGlyZWN0aXZlcy9zZWFyY2gtaW5wdXQnKTtcclxuXHRyZXF1aXJlKCcuL2RpcmVjdGl2ZXMvc3Bpbm5lcicpO1xyXG5cdHJlcXVpcmUoJy4vZGlyZWN0aXZlcy9wYWNrYWdlcy1wYW5lJyk7XHJcblx0cmVxdWlyZSgnLi9kaXJlY3RpdmVzL21hcmtkb3duJyk7XHJcblx0cmVxdWlyZSgnLi9kaXJlY3RpdmVzL2Nob2NvbGF0ZXktYnV0dG9uJyk7XHJcblxyXG5cdG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9uZy1tb2R1bGUnKTtcclxufSkoKTtcclxuXHJcbmZ1bmN0aW9uIGlzQW5ndWxhckRlZmluZWQoKSB7XHJcblx0dHJ5IHtcclxuXHRcdHJlcXVpcmUoJ2FuZ3VsYXInKTsvL2luIG5ldyBtb2R1bGVzIGluc3RlYWQgbmV4dCAyIGxpbmVzLCBzaG91bGQgYmU6IFwicmV0dXJuICEhcmVxdWlyZSgnYW5ndWxhcicpLm1vZHVsZTtcIlxyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fSBjYXRjaCAoZXgpIHtcclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gNDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidHJ5IHtcclxuICAgIHZhciAkID0gcmVxdWlyZShcImpRdWVyeVwiKTtcclxuXHJcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbWFpbicpOyAgICBcclxufSBjYXRjaCAoXykge1xyXG4gICAgY29uc29sZS5sb2coXCJjbG91ZHNoYXJlLXRvdXIgcGFja2FnZSBpcyBub3QgYXZhaWxhYmxlIGJlY2F1c2Ugb2YgbWlzc2luZyBleHRlcm5hbHNcIik7XHJcbiAgICBtb2R1bGUuZXhwb3J0cyA9IG51bGw7XHJcbn1cclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2xvdWRzaGFyZS10b3VyL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSA0MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9XHJcbi8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcclxuLyoqKioqKi8gXHQvLyBUaGUgbW9kdWxlIGNhY2hlXHJcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxyXG4vKioqKioqLyBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxyXG4vKioqKioqLyBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcclxuLyoqKioqKi8gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XHJcbi8qKioqKiovIFx0XHR9XHJcbi8qKioqKiovIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxyXG4vKioqKioqLyBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xyXG4vKioqKioqLyBcdFx0XHRpOiBtb2R1bGVJZCxcclxuLyoqKioqKi8gXHRcdFx0bDogZmFsc2UsXHJcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9XHJcbi8qKioqKiovIFx0XHR9O1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXHJcbi8qKioqKiovIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcclxuLyoqKioqKi8gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXHJcbi8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XHJcbi8qKioqKiovIFx0fVxyXG4vKioqKioqL1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXHJcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxyXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXHJcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XHJcbi8qKioqKiovIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XHJcbi8qKioqKiovIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xyXG4vKioqKioqLyBcdFx0fVxyXG4vKioqKioqLyBcdH07XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xyXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcclxuLyoqKioqKi8gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xyXG4vKioqKioqLyBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcclxuLyoqKioqKi8gXHRcdH1cclxuLyoqKioqKi8gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XHJcbi8qKioqKiovIFx0fTtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3RcclxuLyoqKioqKi8gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcclxuLyoqKioqKi8gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcclxuLyoqKioqKi8gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3RcclxuLyoqKioqKi8gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXHJcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcclxuLyoqKioqKi8gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xyXG4vKioqKioqLyBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcclxuLyoqKioqKi8gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XHJcbi8qKioqKiovIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xyXG4vKioqKioqLyBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcclxuLyoqKioqKi8gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcclxuLyoqKioqKi8gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcclxuLyoqKioqKi8gXHRcdHJldHVybiBucztcclxuLyoqKioqKi8gXHR9O1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXHJcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XHJcbi8qKioqKiovIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cclxuLyoqKioqKi8gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcclxuLyoqKioqKi8gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcclxuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcclxuLyoqKioqKi8gXHRcdHJldHVybiBnZXR0ZXI7XHJcbi8qKioqKiovIFx0fTtcclxuLyoqKioqKi9cclxuLyoqKioqKi8gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcclxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XHJcbi8qKioqKiovXHJcbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cclxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIi9yZXNvdXJjZXMvanMvY3NDbGllbnQvbWluL1wiO1xyXG4vKioqKioqL1xyXG4vKioqKioqL1xyXG4vKioqKioqLyBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xyXG4vKioqKioqLyBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IFwiLi9zcmMvU2VsZlNlcnZpY2UvQ29ubmVjdGl2aXR5VGVzdC9GYWlsdXJlSW5mb3JtYXRpb24vaW5kZXguZGVwbG95LmpzXCIpO1xyXG4vKioqKioqLyB9KVxyXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKioqKioqLyAoe1xyXG5cclxuLyoqKi8gXCIuL3NyYy9TZWxmU2VydmljZS9Db25uZWN0aXZpdHlUZXN0L0ZhaWx1cmVJbmZvcm1hdGlvbi9jb25uZWN0aXZpdHlUZXN0LmZhaWx1cmVJbmZvcm1hdGlvbi5kaXJlY3RpdmUuanNcIjpcclxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL3NyYy9TZWxmU2VydmljZS9Db25uZWN0aXZpdHlUZXN0L0ZhaWx1cmVJbmZvcm1hdGlvbi9jb25uZWN0aXZpdHlUZXN0LmZhaWx1cmVJbmZvcm1hdGlvbi5kaXJlY3RpdmUuanMgKioqIVxyXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcbi8qISBleHBvcnRzIHByb3ZpZGVkOiBkZWZhdWx0ICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcclxuXHJcblwidXNlIHN0cmljdFwiO1xyXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XHJcbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XHJcblxyXG4vKiBoYXJtb255IGRlZmF1bHQgZXhwb3J0ICovIF9fd2VicGFja19leHBvcnRzX19bXCJkZWZhdWx0XCJdID0gKGZ1bmN0aW9uIChuZ01vZHVsZSkge1xyXG4gIG5nTW9kdWxlLmRpcmVjdGl2ZShcImNzQ29ubmVjdGl2aXR5VGVzdEZhaWx1cmVJbmZvcm1hdGlvblwiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICByZXN0cmljdDogXCJFXCIsXHJcbiAgICAgIHNjb3BlOiB7XHJcbiAgICAgICAgZmFpbGVkVGVzdHM6IFwiPVwiLFxyXG4gICAgICAgIHJlZ2lvbk5hbWU6IFwiPVwiLFxyXG4gICAgICAgIGdhdGV3YXlIb3N0OiBcIj1cIlxyXG4gICAgICB9LFxyXG4gICAgICB0ZW1wbGF0ZTogX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9jb25uZWN0aXZpdHlUZXN0LmZhaWx1cmVJbmZvcm1hdGlvbi50ZW1wbGF0ZS5odG1sICovIFwiLi9zcmMvU2VsZlNlcnZpY2UvQ29ubmVjdGl2aXR5VGVzdC9GYWlsdXJlSW5mb3JtYXRpb24vY29ubmVjdGl2aXR5VGVzdC5mYWlsdXJlSW5mb3JtYXRpb24udGVtcGxhdGUuaHRtbFwiKSxcclxuICAgICAgYmluZFRvQ29udHJvbGxlcjogdHJ1ZSxcclxuICAgICAgY29udHJvbGxlckFzOiBcImN0cmxcIixcclxuICAgICAgY29udHJvbGxlcjogQ29ubmVjdGl2aXR5VGVzdEZhaWx1cmVJbmZvcm1hdGlvblxyXG4gICAgfTtcclxuICB9KTtcclxuXHJcbiAgdmFyIENvbm5lY3Rpdml0eVRlc3RGYWlsdXJlSW5mb3JtYXRpb24gPSBmdW5jdGlvbiBDb25uZWN0aXZpdHlUZXN0RmFpbHVyZUluZm9ybWF0aW9uKCRzY29wZSkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ29ubmVjdGl2aXR5VGVzdEZhaWx1cmVJbmZvcm1hdGlvbik7XHJcblxyXG4gICAgdGhpcy4kc2NvcGUgPSAkc2NvcGU7XHJcbiAgICB0aGlzLiRzY29wZS4kd2F0Y2goZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gX3RoaXMuZmFpbGVkVGVzdHM7XHJcbiAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBmYWlsZWRUZXN0cyA9IF90aGlzLmZhaWxlZFRlc3RzIHx8IFtdO1xyXG4gICAgICBfdGhpcy5wcm9jZXNzZWRGYWlsZWRUZXN0cyA9IFwiXCI7XHJcblxyXG4gICAgICBpZiAoZmFpbGVkVGVzdHMuaW5kZXhPZihcIndzLWJyb3dzZXItc3VwcG9ydFwiKSA+PSAwKSB7XHJcbiAgICAgICAgX3RoaXMucHJvY2Vzc2VkRmFpbGVkVGVzdHMgPSBcIndzLWJyb3dzZXItc3VwcG9ydFwiO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgICBbXCJ3cy1lY2hvLXNlcnZlclwiLCBcImNlcnRpZmljYXRlLWF1dGhvcml0eVwiLCBcIndzLWdhdGV3YXktc2VydmVyXCJdLmZvckVhY2goZnVuY3Rpb24gKHRlc3RJZCkge1xyXG4gICAgICAgIGlmIChmYWlsZWRUZXN0cy5pbmRleE9mKHRlc3RJZCkgPj0gMCkge1xyXG4gICAgICAgICAgcmVzdWx0LnB1c2godGVzdElkKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICBfdGhpcy5wcm9jZXNzZWRGYWlsZWRUZXN0cyA9IHJlc3VsdC5qb2luKFwiLFwiKTtcclxuICAgIH0sIHRydWUpO1xyXG4gIH07XHJcblxyXG4gIENvbm5lY3Rpdml0eVRlc3RGYWlsdXJlSW5mb3JtYXRpb24uJGluamVjdCA9IFtcIiRzY29wZVwiXTtcclxufSk7XHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9zcmMvU2VsZlNlcnZpY2UvQ29ubmVjdGl2aXR5VGVzdC9GYWlsdXJlSW5mb3JtYXRpb24vY29ubmVjdGl2aXR5VGVzdC5mYWlsdXJlSW5mb3JtYXRpb24udGVtcGxhdGUuaHRtbFwiOlxyXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXHJcbiAgISoqKiAuL3NyYy9TZWxmU2VydmljZS9Db25uZWN0aXZpdHlUZXN0L0ZhaWx1cmVJbmZvcm1hdGlvbi9jb25uZWN0aXZpdHlUZXN0LmZhaWx1cmVJbmZvcm1hdGlvbi50ZW1wbGF0ZS5odG1sICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXHJcbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPWNzLWNvbm5lY3Rpdml0eS10ZXN0cy1mYWlsdXJlLWluZm9ybWF0aW9uIG5nLXNob3c9Y3RybC5wcm9jZXNzZWRGYWlsZWRUZXN0cz48ZGl2IG5nLXN3aXRjaD1jdHJsLnByb2Nlc3NlZEZhaWxlZFRlc3RzPjxkaXYgbmctc3dpdGNoLXdoZW49d3MtYnJvd3Nlci1zdXBwb3J0PjxwIHRyYW5zbGF0ZT5Zb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBXZWJTb2NrZXRzLiBXZWJTb2NrZXRzIHN1cHBvcnQgaXMgcmVxdWlyZWQgZm9yIGFjY2VzcyB0byBWTXMgb24gQ2xvdWRTaGFyZS48L3A+PHAgdHJhbnNsYXRlPlRvIGZpeCB0aGlzIHByb2JsZW0sIHlvdSBjYW4gZWl0aGVyIHN3aXRjaCB0byBhIGRpZmZlcmVudCBicm93c2VyLCBzdWNoIGFzIENocm9tZSBvciBGaXJlZm94LCBvciB0cnkgdXBncmFkaW5nIHRvIHRoZSBsYXRlc3QgdmVyc2lvbiBvZiB5b3VyIGJyb3dzZXIuPC9wPjwvZGl2PjxkaXYgbmctc3dpdGNoLXdoZW49d3MtZWNoby1zZXJ2ZXI+PHAgdHJhbnNsYXRlPk91ciB0ZXN0IGNvdWxkIG5vdCBlc3RhYmxpc2ggYSBzZWN1cmUgV2ViU29ja2V0IGNvbm5lY3Rpb24gdG8gPGNvZGU+ZWNoby53ZWJzb2NrZXQub3JnPC9jb2RlPi4gSG93ZXZlciwgeW91IGFyZSBhYmxlIHRvIGNvbm5lY3Qgc3VjY2Vzc2Z1bGx5IHRvIENsb3VkU2hhcmUncyByZW1vdGUgYWNjZXNzIGdhdGV3YXkuPC9wPjxwIHRyYW5zbGF0ZT5FaXRoZXIgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggPGNvZGU+ZWNoby53ZWJzb2NrZXQub3JnPC9jb2RlPiBzZXJ2ZXIsIG9yIHRoZSBXZWJTb2NrZXRzIGVjaG8gc2VydmVyIHRlc3Qgd2FzIGJsb2NrZWQgYnkgYSBmaXJld2FsbCBydWxlLjwvcD48cCB0cmFuc2xhdGU+VGhlcmUgaXMgbm8gbmVlZCB0byBmaXggdGhpcyBwcm9ibGVtIGluIG9yZGVyIHRvIGNvbm5lY3QgdG8gVk1zIG9uIENsb3VkU2hhcmUuPC9wPjwvZGl2PjxkaXYgbmctc3dpdGNoLXdoZW49Y2VydGlmaWNhdGUtYXV0aG9yaXR5PjxwIHRyYW5zbGF0ZT5Zb3UgYXJlIGFibGUgdG8gY29ubmVjdCBzdWNjZXNzZnVsbHkgdG8gQ2xvdWRTaGFyZSdzIHJlbW90ZSBhY2Nlc3MgZ2F0ZXdheSB2aWEgV2ViU29ja2V0cy4gSG93ZXZlciwgeW91ciBjb21wdXRlciBvciBicm93c2VyIGlzIG1pc3NpbmcgcmVxdWlyZWQgY2VydGlmaWNhdGUgYXV0aG9yaXR5IHRydXN0cy4gWW91IGFyZSBsaWtlbHkgdG8gZXhwZXJpZW5jZSBpbnRlcm1pdHRlbnQgZGlzY29ubmVjdGlvbnMgd2hlbiB5b3UgY29ubmVjdCB0byBDbG91ZFNoYXJlIFZNcy48L3A+PHAgdHJhbnNsYXRlPlRvIGZpeCB0aGlzIHByb2JsZW0sIHBsZWFzZSBjb250YWN0IHlvdXIgYWRtaW5pc3RyYXRvciBhbmQgbWFrZSBzdXJlIEdvRGFkZHkgY2VydGlmaWNhdGVzIGFyZSB0cnVzdGVkIGJ5IHlvdXIgY29tcHV0ZXIgYW5kIGJyb3dzZXIuPC9wPjwvZGl2PjxkaXYgbmctc3dpdGNoLXdoZW49d3MtZ2F0ZXdheS1zZXJ2ZXI+PHAgdHJhbnNsYXRlLXBhcmFtcy1yZWdpb24tbmFtZT1jdHJsLnJlZ2lvbk5hbWUgdHJhbnNsYXRlLXBhcmFtcy1nYXRld2F5LWhvc3Q9Y3RybC5nYXRld2F5SG9zdCB0cmFuc2xhdGU+T3VyIHRlc3QgY291bGQgbm90IGVzdGFibGlzaCBhIHNlY3VyZSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byBDbG91ZFNoYXJlJ3MgcmVtb3RlIGFjY2VzcyBnYXRld2F5IGluICd7e3JlZ2lvbk5hbWV9fScgcmVnaW9uICg8Y29kZT57e2dhdGV3YXlIb3N0fX08L2NvZGU+KS48L3A+PHAgdHJhbnNsYXRlPllvdSBjYW5ub3QgY29ubmVjdCB0byBDbG91ZFNoYXJlIFZNcy48L3A+PHAgdHJhbnNsYXRlLXBhcmFtcy1nYXRld2F5LWhvc3Q9Y3RybC5nYXRld2F5SG9zdCB0cmFuc2xhdGU+VG8gZml4IHRoaXMgcHJvYmxlbSwgcGxlYXNlIGNvbnRhY3QgeW91ciBhZG1pbmlzdHJhdG9yIGFuZCBtYWtlIHN1cmUgc2VjdXJlIEhUVFAgYW5kIFdlYlNvY2tldCBjb25uZWN0aW9ucyB0byA8Y29kZT57e2dhdGV3YXlIb3N0fX08L2NvZGU+IG9uIHBvcnQgNDQzIGFyZSBub3QgYmxvY2tlZCBieSBhbnkgZmlyZXdhbGwgb3Igb3RoZXIgc2VjdXJpdHkgbWVhc3VyZS48L3A+PC9kaXY+PGRpdiBuZy1zd2l0Y2gtd2hlbj13cy1lY2hvLXNlcnZlcixjZXJ0aWZpY2F0ZS1hdXRob3JpdHk+PHAgdHJhbnNsYXRlPllvdSBhcmUgYWJsZSB0byBjb25uZWN0IHN1Y2Nlc3NmdWxseSB0byBDbG91ZFNoYXJlJ3MgcmVtb3RlIGFjY2VzcyBnYXRld2F5LiBIb3dldmVyLCBvdXIgdGVzdCBjb3VsZCBub3QgZXN0YWJsaXNoIGEgc2VjdXJlIFdlYlNvY2tldCBjb25uZWN0aW9uIHRvIDxjb2RlPmVjaG8ud2Vic29ja2V0Lm9yZzwvY29kZT4uIEluIGFkZGl0aW9uLCB5b3VyIGNvbXB1dGVyIG9yIGJyb3dzZXIgaXMgbWlzc2luZyByZXF1aXJlZCBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgdHJ1c3RzLjwvcD48cCB0cmFuc2xhdGU+WW91IG1pZ2h0IGV4cGVyaWVuY2UgaW50ZXJtaXR0ZWQgZGlzY29ubmVjdGlvbnMsIGR1ZSB0byB0aGUgbWlzc2luZyBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkgdHJ1c3RzLiBUbyBmaXggdGhpcyBwcm9ibGVtLCBwbGVhc2UgY29udGFjdCB5b3VyIGFkbWluaXN0cmF0b3IgYW5kIG1ha2Ugc3VyZSBHb0RhZGR5J3MgY2VydGlmaWNhdGVzIGFyZSB0cnVzdGVkIG9uIHlvdXIgY29tcHV0ZXIuPC9wPjxwIHRyYW5zbGF0ZT5FaXRoZXIgdGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhlIDxjb2RlPmVjaG8ud2Vic29ja2V0cy5vcmc8L2NvZGU+IHNlcnZlciBvciB0aGUgV2ViU29ja2V0cyBlY2hvIHNlcnZlciB0ZXN0IHdhcyBibG9ja2VkIGJ5IGEgZmlyZXdhbGwgcnVsZS4gVGhlcmUgaXMgbm8gbmVlZCB0byBmaXggdGhpcyBwcm9ibGVtIGluIG9yZGVyIHRvIGNvbm5lY3QgdG8gVk1zIG9uIENsb3VkU2hhcmUuPC9wPjwvZGl2PjxkaXYgbmctc3dpdGNoLXdoZW49d3MtZWNoby1zZXJ2ZXIsd3MtZ2F0ZXdheS1zZXJ2ZXI+PHAgdHJhbnNsYXRlLXBhcmFtcy1yZWdpb24tbmFtZT1jdHJsLnJlZ2lvbk5hbWUgdHJhbnNsYXRlLXBhcmFtcy1nYXRld2F5LWhvc3Q9Y3RybC5nYXRld2F5SG9zdCB0cmFuc2xhdGU+T3VyIHRlc3QgY291bGQgbm90IGVzdGFibGlzaCBhIHNlY3VyZSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byAne3tyZWdpb25OYW1lfX0nICg8Y29kZT57e2dhdGV3YXlIb3N0fX08L2NvZGU+KSBvciB0byA8Y29kZT5lY2hvLndlYnNvY2tldHMub3JnPC9jb2RlPi48L3A+PHAgdHJhbnNsYXRlPllvdSBjYW5ub3QgY29ubmVjdCB0byBWTXMgb24gQ2xvdWRTaGFyZS48L3A+PHAgdHJhbnNsYXRlLXBhcmFtcy1nYXRld2F5LWhvc3Q9Y3RybC5nYXRld2F5SG9zdCB0cmFuc2xhdGU+VG8gZml4IHRoaXMgcHJvYmxlbSwgcGxlYXNlIGNvbnRhY3QgeW91ciBhZG1pbmlzdHJhdG9yIGFuZCBtYWtlIHN1cmUgc2VjdXJlIEhUVFAgYW5kIFdlYlNvY2tldCBjb25uZWN0aW9ucyB0byA8Y29kZT57e2dhdGV3YXlIb3N0fX08L2NvZGU+IG9uIHBvcnQgNDQzIGFyZSBub3QgYmxvY2tlZCBieSBhbnkgZmlyZXdhbGwgb3Igb3RoZXIgc2VjdXJpdHkgbWVhc3VyZS48L3A+PC9kaXY+PGRpdiBuZy1zd2l0Y2gtd2hlbj1jZXJ0aWZpY2F0ZS1hdXRob3JpdHksd3MtZ2F0ZXdheS1zZXJ2ZXI+PHAgdHJhbnNsYXRlLXBhcmFtcy1yZWdpb24tbmFtZT1jdHJsLnJlZ2lvbk5hbWUgdHJhbnNsYXRlLXBhcmFtcy1nYXRld2F5LWhvc3Q9Y3RybC5nYXRld2F5SG9zdCB0cmFuc2xhdGU+T3VyIHRlc3QgY291bGQgbm90IGVzdGFibGlzaCBhIHNlY3VyZSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byBDbG91ZFNoYXJlJ3MgcmVtb3RlIGFjY2VzcyBnYXRld2F5IGluICd7e3JlZ2lvbk5hbWV9fScgKDxjb2RlPnt7Z2F0ZXdheUhvc3R9fTwvY29kZT4pLiBJbiBhZGRpdGlvbiwgeW91ciBjb21wdXRlciBvciBicm93c2VyIGlzIG1pc3NpbmcgcmVxdWlyZWQgY2VydGlmaWNhdGUgYXV0aG9yaXR5IHRydXN0cy48L3A+PHAgdHJhbnNsYXRlPllvdSBjYW5ub3QgY29ubmVjdCB0byBWTXMgb24gQ2xvdWRTaGFyZS48L3A+PHA+PHNwYW4gdHJhbnNsYXRlPlRvIGZpeCB0aGVzZSBwcm9ibGVtcywgcGxlYXNlIGNvbnRhY3QgeW91ciBhZG1pbmlzdHJhdG9yIGFuZCBtYWtlIHN1cmU6PC9zcGFuPjx1bD48bGkgdHJhbnNsYXRlLXBhcmFtcy1nYXRld2F5LWhvc3Q9Y3RybC5nYXRld2F5SG9zdCB0cmFuc2xhdGU+U2VjdXJlIEhUVFAgYW5kIFdlYlNvY2tldCBjb25uZWN0aW9ucyB0byA8Y29kZT57e2dhdGV3YXlIb3N0fX08L2NvZGU+IG9uIHBvcnQgNDQzIGFyZSBub3QgYmxvY2tlZCBieSBhbnkgZmlyZXdhbGwgb3Igb3RoZXIgc2VjdXJpdHkgbWVhc3VyZS48L2xpPjxsaSB0cmFuc2xhdGU+R29EYWRkeSdzIGNlcnRpZmljYXRlcyBhcmUgdHJ1c3RlZCBvbiB5b3VyIGNvbXB1dGVyIGFuZCBicm93c2VyLjwvbGk+PC91bD48L3A+PC9kaXY+PGRpdiBuZy1zd2l0Y2gtd2hlbj13cy1lY2hvLXNlcnZlcixjZXJ0aWZpY2F0ZS1hdXRob3JpdHksd3MtZ2F0ZXdheS1zZXJ2ZXI+PHAgdHJhbnNsYXRlLXBhcmFtcy1yZWdpb24tbmFtZT1jdHJsLnJlZ2lvbk5hbWUgdHJhbnNsYXRlLXBhcmFtcy1nYXRld2F5LWhvc3Q9Y3RybC5nYXRld2F5SG9zdCB0cmFuc2xhdGU+T3VyIHRlc3QgY291bGQgbm90IGVzdGFibGlzaCBhIHNlY3VyZSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byAne3tyZWdpb25OYW1lfX0nIHJlZ2lvbiAoPGNvZGU+e3tnYXRld2F5SG9zdH19PC9jb2RlPikgb3IgdG8gPGNvZGU+ZWNoby53ZWJzb2NrZXQub3JnPC9jb2RlPi4gSW4gYWRkaXRpb24sIHlvdXIgY29tcHV0ZXIgb3IgYnJvd3NlciBpcyBtaXNzaW5nIHJlcXVpcmVkIGNlcnRpZmljYXRlIGF1dGhvcml0eSB0cnVzdHMuPC9wPjxwIHRyYW5zbGF0ZT5Zb3UgY2Fubm90IGNvbm5lY3QgdG8gVk1zIG9uIENsb3VkU2hhcmUuPC9wPjxwPjxzcGFuIHRyYW5zbGF0ZT5UbyBmaXggdGhlc2UgcHJvYmxlbXMsIHBsZWFzZSBjb250YWN0IHlvdXIgYWRtaW5pc3RyYXRvciBhbmQgbWFrZSBzdXJlOjwvc3Bhbj48dWw+PGxpIHRyYW5zbGF0ZS1wYXJhbXMtZ2F0ZXdheS1ob3N0PWN0cmwuZ2F0ZXdheUhvc3QgdHJhbnNsYXRlPlNlY3VyZSBIVFRQIGFuZCBXZWJTb2NrZXQgY29ubmVjdGlvbnMgdG8gPGNvZGU+e3tnYXRld2F5SG9zdH19PC9jb2RlPiBvbiBwb3J0IDQ0MyBhcmUgbm90IGJsb2NrZWQgYnkgYW55IGZpcmV3YWxsIG9yIG90aGVyIHNlY3VyaXR5IG1lYXN1cmUuPC9saT48bGkgdHJhbnNsYXRlPkdvRGFkZHkncyBjZXJ0aWZpY2F0ZXMgYXJlIHRydXN0ZWQgb24geW91ciBjb21wdXRlciBhbmQgYnJvd3Nlci48L2xpPjwvdWw+PC9wPjwvZGl2PjwvZGl2PjwvZGl2PlwiXHJcblxyXG4vKioqLyB9KSxcclxuXHJcbi8qKiovIFwiLi9zcmMvU2VsZlNlcnZpY2UvQ29ubmVjdGl2aXR5VGVzdC9GYWlsdXJlSW5mb3JtYXRpb24vaW5kZXguZGVwbG95LmpzXCI6XHJcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxyXG4gICEqKiogLi9zcmMvU2VsZlNlcnZpY2UvQ29ubmVjdGl2aXR5VGVzdC9GYWlsdXJlSW5mb3JtYXRpb24vaW5kZXguZGVwbG95LmpzICoqKiFcclxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4vKiEgZXhwb3J0cyBwcm92aWRlZDogZGlyZWN0aXZlRnVuY3Rpb24gKi9cclxuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgX193ZWJwYWNrX2V4cG9ydHNfXywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcbl9fd2VicGFja19yZXF1aXJlX18ucihfX3dlYnBhY2tfZXhwb3J0c19fKTtcclxuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb25uZWN0aXZpdHlUZXN0X2ZhaWx1cmVJbmZvcm1hdGlvbl9kaXJlY3RpdmVfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzBfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29ubmVjdGl2aXR5VGVzdC5mYWlsdXJlSW5mb3JtYXRpb24uZGlyZWN0aXZlICovIFwiLi9zcmMvU2VsZlNlcnZpY2UvQ29ubmVjdGl2aXR5VGVzdC9GYWlsdXJlSW5mb3JtYXRpb24vY29ubmVjdGl2aXR5VGVzdC5mYWlsdXJlSW5mb3JtYXRpb24uZGlyZWN0aXZlLmpzXCIpO1xyXG4vKiBoYXJtb255IHJlZXhwb3J0IChzYWZlKSAqLyBfX3dlYnBhY2tfcmVxdWlyZV9fLmQoX193ZWJwYWNrX2V4cG9ydHNfXywgXCJkaXJlY3RpdmVGdW5jdGlvblwiLCBmdW5jdGlvbigpIHsgcmV0dXJuIF9jb25uZWN0aXZpdHlUZXN0X2ZhaWx1cmVJbmZvcm1hdGlvbl9kaXJlY3RpdmVfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzBfX1tcImRlZmF1bHRcIl07IH0pO1xyXG5cclxuXHJcblxyXG5cclxuLyoqKi8gfSlcclxuXHJcbi8qKioqKiovIH0pO1xyXG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0aXZpdHktdGVzdC1mYWlsdXJlLWluZm9ybWF0aW9uLmpzLm1hcFxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nvbm5lY3Rpdml0eS10ZXN0LWZhaWx1cmUtaW5mb3JtYXRpb24uanNcbi8vIG1vZHVsZSBpZCA9IDQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBib3R0bGUgPSByZXF1aXJlKCcuL2JvdHRsZScpO1xyXG5cclxud2luZG93LmNzID0gd2luZG93LmNzIHx8IHt9O1xyXG53aW5kb3cuY3MuZ3VhY2NsaWVudCA9IGJvdHRsZS5jb250YWluZXIuQ2xvdWRTaGFyZUd1YWNhbW9sZTtcclxubW9kdWxlLmV4cG9ydHMgPSBib3R0bGUuY29udGFpbmVyLkNsb3VkU2hhcmVHdWFjYW1vbGU7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2d1YWNhbW9sZS1jbGllbnQvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInRyeSB7XHJcbiAgICB2YXIgXyA9IHJlcXVpcmUoXCJ1bmRlcnNjb3JlXCIpO1xyXG4gICAgdmFyICQgPSByZXF1aXJlKFwialF1ZXJ5XCIpO1xyXG4gICAgdmFyIGNzd3MgPSByZXF1aXJlKFwiLi4vY3N3c1wiKS5jc3dzO1xyXG4gICAgdmFyIEhlYXJ0QmVhdHNEaXNwYXRjaGVyXyA9IHJlcXVpcmUoJy4vaGVhcnRiZWF0cy1kaXNwYXRjaGVyJyk7XHJcbiAgICB2YXIgV2Vic29ja2V0c0Nvbm5lY3RvciA9IHJlcXVpcmUoJy4vd2Vic29ja2V0cy1jb25uZWN0b3InKTtcclxuXHJcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEhlYXJ0QmVhdHNEaXNwYXRjaGVyKCkge1xyXG4gICAgICAgIHZhciB3ZWJzb2NrZXRzQ29ubmVjdG9yID0gbmV3IFdlYnNvY2tldHNDb25uZWN0b3IoY3N3cywgJy9hcGkvdjMvV2ViU29ja2V0cycsICdoZWFydGJlYXQnKTtcclxuICAgICAgICByZXR1cm4gbmV3IEhlYXJ0QmVhdHNEaXNwYXRjaGVyXyh3ZWJzb2NrZXRzQ29ubmVjdG9yKTtcclxuICAgIH07ICAgIFxyXG59IGNhdGNoIChfKSB7XHJcbiAgICBjb25zb2xlLmxvZyhcImhlYXJ0YmVhdC1vdmVyLXdzIHBhY2thZ2UgaXMgbm90IGF2YWlsYWJsZSBiZWNhdXNlIG9mIG1pc3NpbmcgZXh0ZXJuYWxzXCIpO1xyXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBudWxsO1xyXG59XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2hlYXJ0YmVhdC1vdmVyLXdzL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSA0NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgc2FuaXRpemVIdG1sTW9kdWxlID0gcmVxdWlyZSgnc2FuaXRpemUtaHRtbCcpO1xyXG5cclxudmFyIENvbmZpZ3VyYXRpb25zID0ge1xyXG4gICAgZW52Vmlld2VyOiB7XHJcbiAgICAgICAgYWxsb3dlZFRhZ3M6IFtcInNwYW5cIiwgXCJpbWdcIiwgXCJoMVwiLCBcImgyXCIsIFwiaDNcIiwgXCJoNFwiLCBcImNzLXZpZXdlci1zdGFydC1idXR0b25cIiwgXCJjb3VudGRvd24tY2xvY2tcIiwgXCJhbHRlcnl4LXN0YXJ0LWJ1dHRvblwiXSxcclxuICAgICAgICBhbGxvd2VkQXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICBcIipcIjogW1wic3R5bGVcIixcclxuICAgICAgICAgICAgICAgIFwiY2xhc3NcIixcclxuICAgICAgICAgICAgICAgIFwiY3Mtdmlld2VyLW1vZGFsLXZpZGVvXCIsXHJcbiAgICAgICAgICAgICAgICBcImNzLXZpZXdlci12aWRlby11cmxcIixcclxuICAgICAgICAgICAgICAgIFwiY3Mtdmlld2VyLXZpZGVvLWF1dG9wbGF5XCIsXHJcbiAgICAgICAgICAgICAgICBcImNzLXZpZXdlci12aWRlby13aWR0aFwiLFxyXG4gICAgICAgICAgICAgICAgXCJjcy12aWV3ZXItdmlkZW8taGVpZ2h0XCIsXHJcbiAgICAgICAgICAgICAgICBcImNzLXZpZXdlci12aWRlby10aXRsZVwiLFxyXG4gICAgICAgICAgICAgICAgXCJjcy12aWV3ZXItbGlua1wiLFxyXG4gICAgICAgICAgICAgICAgXCJ0aW1lLW1pbnV0ZXNcIlxyXG4gICAgICAgICAgICBdXHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHRvcE1vc3RUb29sdGlwOiB7XHJcbiAgICAgICAgYWxsb3dlZFRhZ3M6IFtcInNwYW5cIiwgXCJpbWdcIiwgXCJoMVwiLCBcImgyXCIgXSxcclxuICAgICAgICBhbGxvd2VkQXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICBcIipcIjogW1wic3R5bGVcIiwgXCJjbGFzc1wiXVxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICB2aWV3ZXJSZXNvdXJjZXM6IHtcclxuICAgICAgICBhbGxvd2VkVGFnczogW1wic3BhblwiLCBcImltZ1wiLCBcImgxXCIsIFwiaDJcIiBdLFxyXG4gICAgICAgIGFsbG93ZWRBdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgIFwiKlwiOiBbXCJzdHlsZVwiXVxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBwZXJtaXNzaXZlOiB7XHJcbiAgICAgICAgYWxsb3dlZFRhZ3M6IFtcImltZ1wiLCBcImgxXCIsIFwiaDJcIiwgXCJzcGFuXCIsIFwidVwiLCBcImZvbnRcIl0sXHJcbiAgICAgICAgYWxsb3dlZEF0dHJpYnV0ZXM6IHtcclxuICAgICAgICAgICAgXCIqXCI6IFtcImFsdFwiLCBcImRpclwiLCBcInNyY1wiLCBcInN0eWxlXCIsIFwiaHJlZlwiLCBcInRhcmdldFwiLCBcImNlbGxwYWRkaW5nXCIsIFwiY2VsbHNwYWNpbmdcIiwgXCJpZFwiLCBcImNvbHNwYW5cIixcclxuICAgICAgICAgICAgICAgIFwiY2xhc3NcIiwgXCJmYWNlXCIsIFwiY29sb3JcIiwgXCJyZWZcIiwgXCJhbGlnblwiLCBcImxhbmdcIiwgXCJib3JkZXJcIiwgXCJzY29wZVwiLCBcImhlaWdodFwiLCBcInRpdGxlXCIsIFwid2lkdGhcIl1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcblxyXG5mdW5jdGlvbiBIdG1sU2FuaXRpemVyKCkge1xyXG4gICAgdmFyIHRoYXQgPSB0aGlzO1xyXG5cclxuICAgIHRoYXQuX2NvbmZpZ3VyYXRpb25zID0ge307XHJcbiAgICBPYmplY3Qua2V5cyhDb25maWd1cmF0aW9ucykuZm9yRWFjaChmdW5jdGlvbihjb25maWd1cmF0aW9uTmFtZSkge1xyXG4gICAgICAgIHRoYXQuX2NvbmZpZ3VyYXRpb25zW2NvbmZpZ3VyYXRpb25OYW1lXSA9IHRoYXQuX2NyZWF0ZUNvbmZpZyhDb25maWd1cmF0aW9uc1tjb25maWd1cmF0aW9uTmFtZV0pO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbkh0bWxTYW5pdGl6ZXIucHJvdG90eXBlLnNhbml0aXplID0gZnVuY3Rpb24oaHRtbCwgY29uZmlnTmFtZSkge1xyXG4gICAgdmFyIHRoYXQgPSB0aGlzO1xyXG5cclxuICAgIHZhciBjb25maWcgPSB0aGF0Ll9jb25maWd1cmF0aW9uc1tjb25maWdOYW1lXTtcclxuICAgIGlmICghdGhhdC5fY29uZmlndXJhdGlvbnNbY29uZmlnTmFtZV0pXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSHRtbFNhbml0aXplcjogTm8gc3VjaCBjb25maWd1cmF0aW9uICdcIiArIGNvbmZpZ05hbWUgKyBcIidcIik7XHJcbiAgICByZXR1cm4gc2FuaXRpemVIdG1sTW9kdWxlKGh0bWwsIGNvbmZpZyk7XHJcbn07XHJcblxyXG5IdG1sU2FuaXRpemVyLnByb3RvdHlwZS5fY3JlYXRlQ29uZmlnID0gZnVuY3Rpb24oY29uZmlnKSB7XHJcbiAgICB2YXIgdGhhdCA9IHRoaXM7XHJcblxyXG4gICAgdmFyIGRlZmF1bHRDb25maWcgPSB0aGF0Ll9nZXREZWZhdWx0Q29uZmlndXJhdGlvbkNvcHkoKTtcclxuXHJcbiAgICBpZiAoIWNvbmZpZylcclxuICAgICAgICByZXR1cm4gZGVmYXVsdENvbmZpZztcclxuXHJcbiAgICBpZiAoY29uZmlnLmFsbG93ZWRUYWdzKVxyXG4gICAgICAgIGRlZmF1bHRDb25maWcuYWxsb3dlZFRhZ3MgPSBkZWZhdWx0Q29uZmlnLmFsbG93ZWRUYWdzLmNvbmNhdChjb25maWcuYWxsb3dlZFRhZ3MpO1xyXG5cclxuICAgIGlmIChjb25maWcuYWxsb3dlZEF0dHJpYnV0ZXMpIHtcclxuICAgICAgICBPYmplY3Qua2V5cyhjb25maWcuYWxsb3dlZEF0dHJpYnV0ZXMpLmZvckVhY2goZnVuY3Rpb24odGFnKSB7XHJcbiAgICAgICAgICAgIGlmICghZGVmYXVsdENvbmZpZy5hbGxvd2VkQXR0cmlidXRlc1t0YWddKVxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdENvbmZpZy5hbGxvd2VkQXR0cmlidXRlc1t0YWddID0gY29uZmlnLmFsbG93ZWRBdHRyaWJ1dGVzW3RhZ107XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIGRlZmF1bHRDb25maWcuYWxsb3dlZEF0dHJpYnV0ZXNbdGFnXSA9IGRlZmF1bHRDb25maWcuYWxsb3dlZEF0dHJpYnV0ZXNbdGFnXS5jb25jYXQoY29uZmlnLmFsbG93ZWRBdHRyaWJ1dGVzW3RhZ10pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkZWZhdWx0Q29uZmlnO1xyXG59O1xyXG5cclxuSHRtbFNhbml0aXplci5wcm90b3R5cGUuX2dldERlZmF1bHRDb25maWd1cmF0aW9uQ29weSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVIdG1sTW9kdWxlLmRlZmF1bHRzKSk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEh0bWxTYW5pdGl6ZXI7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvaHRtbC1zYW5pdGl6ZXIvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQ1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBib3R0bGUgPSByZXF1aXJlKCcuL2JvdHRsZScpO1xyXG5cclxud2luZG93LmNzID0gd2luZG93LmNzIHx8IHt9O1xyXG53aW5kb3cuY3MuZ3VhY2NsaWVudCA9IGJvdHRsZS5jb250YWluZXIuQ2xvdWRTaGFyZVNwYXJrO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGJvdHRsZS5jb250YWluZXIuQ2xvdWRTaGFyZVNwYXJrO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9zcGFyay1jbGllbnQvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQ2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0J1xuXG5leHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5leHBvcnRzLnRvQnl0ZUFycmF5ID0gdG9CeXRlQXJyYXlcbmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IGZyb21CeXRlQXJyYXlcblxudmFyIGxvb2t1cCA9IFtdXG52YXIgcmV2TG9va3VwID0gW11cbnZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBVaW50OEFycmF5IDogQXJyYXlcblxudmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbmZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG59XG5cbnJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxucmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG5cbmZ1bmN0aW9uIHBsYWNlSG9sZGVyc0NvdW50IChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG4gIC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcbiAgLy8gcmVwcmVzZW50IG9uZSBieXRlXG4gIC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuICAvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG4gIHJldHVybiBiNjRbbGVuIC0gMl0gPT09ICc9JyA/IDIgOiBiNjRbbGVuIC0gMV0gPT09ICc9JyA/IDEgOiAwXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKGI2NCkge1xuICAvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbiAgcmV0dXJuIGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVyc0NvdW50KGI2NClcbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgaSwgaiwgbCwgdG1wLCBwbGFjZUhvbGRlcnMsIGFyclxuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuICBwbGFjZUhvbGRlcnMgPSBwbGFjZUhvbGRlcnNDb3VudChiNjQpXG5cbiAgYXJyID0gbmV3IEFycihsZW4gKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gbGVuIC0gNCA6IGxlblxuXG4gIHZhciBMID0gMFxuXG4gIGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcbiAgICB0bXAgPSAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxOCkgfCAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHwgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHwgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAzKV1cbiAgICBhcnJbTCsrXSA9ICh0bXAgPj4gMTYpICYgMHhGRlxuICAgIGFycltMKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbTCsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcbiAgICB0bXAgPSAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltMKytdID0gdG1wICYgMHhGRlxuICB9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuICAgIHRtcCA9IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDEwKSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8IChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltMKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbTCsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICsgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcbiAgICBvdXRwdXQucHVzaCh0cmlwbGV0VG9CYXNlNjQodG1wKSlcbiAgfVxuICByZXR1cm4gb3V0cHV0LmpvaW4oJycpXG59XG5cbmZ1bmN0aW9uIGZyb21CeXRlQXJyYXkgKHVpbnQ4KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbiA9IHVpbnQ4Lmxlbmd0aFxuICB2YXIgZXh0cmFCeXRlcyA9IGxlbiAlIDMgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcbiAgdmFyIG91dHB1dCA9ICcnXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsodWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKSkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBvdXRwdXQgKz0gbG9va3VwW3RtcCA+PiAyXVxuICAgIG91dHB1dCArPSBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdXG4gICAgb3V0cHV0ICs9ICc9PSdcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgKHVpbnQ4W2xlbiAtIDFdKVxuICAgIG91dHB1dCArPSBsb29rdXBbdG1wID4+IDEwXVxuICAgIG91dHB1dCArPSBsb29rdXBbKHRtcCA+PiA0KSAmIDB4M0ZdXG4gICAgb3V0cHV0ICs9IGxvb2t1cFsodG1wIDw8IDIpICYgMHgzRl1cbiAgICBvdXRwdXQgKz0gJz0nXG4gIH1cblxuICBwYXJ0cy5wdXNoKG91dHB1dClcblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9iYXNlNjQtanMvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDQ3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJDOlxcXFxCdWlsZEFnZW50XFxcXHdvcmtcXFxcN2E0YTBmZTQ1YjI2MDIyNlxcXFxjbG91ZHNoYXJlXFxcXHNyY1xcXFxqYXZhc2NyaXB0XFxcXGNzXFxcXG5vZGVfbW9kdWxlc1xcXFxjc3MtbG9hZGVyXFxcXGNzc1RvU3RyaW5nLmpzXCIpKCk7XG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCIuY2hvY29sYXRleS1jbGllbnQgIHtcXHJcXG5cXHRmb250LWZhbWlseTogJ29wZW4tc2FucycsIHNhbnMtc2VyaWY7XFxyXFxuXFx0dGV4dC1hbGlnbjogY2VudGVyO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgPiAuc3BhY2VyIHtcXHJcXG5cXHRkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuXFx0d2lkdGg6IDIwcHg7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAgYSB7XFxyXFxuXFx0Y29sb3I6IHJnYigwLCAxNjAsIDE5OCk7XFxyXFxuXFx0dGV4dC1kZWNvcmF0aW9uOiBub25lO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtbGlzdCB7XFxyXFxuXFx0bWFyZ2luLXJpZ2h0OiAxNXB4O1xcclxcbn1cXHRcXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtbGlzdCAuZW1wdHktbm90aWNlIHtcXHJcXG5cXHRwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuXFx0aGVpZ2h0OiAxMDAlO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtbGlzdCAuZW1wdHktbm90aWNlIHNwYW4ge1xcclxcblxcdGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG5cXHRwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuXFx0dG9wOiAzMCU7XFxyXFxuXFx0bGVmdDogNTAlO1xcclxcblxcdC1tcy10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XFxyXFxuXFx0LW1vei10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XFxyXFxuXFx0LXdlYmtpdC10cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XFxyXFxuXFx0dHJhbnNmb3JtOiB0cmFuc2xhdGVYKC01MCUpO1xcclxcbn1cXHJcXG5cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2VzLXBhbmUge1xcclxcblxcdHZlcnRpY2FsLWFsaWduOiB0b3A7XFxyXFxuXFx0d2lkdGg6IDQ1JTtcXHJcXG5cXHRkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuXFx0dGV4dC1hbGlnbjogbGVmdDtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5wYWNrYWdlcy1wYW5lID4gLnRpdGxlIHtcXHJcXG5cXHRoZWlnaHQ6IDgwcHg7XFxyXFxuXFx0dGV4dC1hbGlnbjogY2VudGVyO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2VzLXBhbmUgLnRpdGxlIC50aXRsZS10ZXh0IHtcXHJcXG5cXHRkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuXFx0Zm9udC1zaXplOiAyM3B4O1xcclxcblxcdG1hcmdpbjogMjYuNXB4IDA7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAuZGV0YWlscy1wYW5lIHtcXHJcXG5cXHR2ZXJ0aWNhbC1hbGlnbjogdG9wO1xcclxcblxcdHdpZHRoOiAxMDAlO1xcclxcblxcdGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG59XFxyXFxuXFxyXFxuXFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5wYWNrYWdlLWl0ZW0ge1xcclxcblxcdHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG5cXHRib3JkZXItYm90dG9tOiAxcHggc29saWQgcmdiKDIwOCwgMjA4LCAyMDgpO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtaXRlbSB0YWJsZSB7XFxyXFxuXFx0d2lkdGg6IDEwMCU7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAucGFja2FnZS1pdGVtIC5pY29uIHtcXHJcXG5cXHR2ZXJ0aWNhbC1hbGlnbjogdG9wO1xcclxcblxcdHdpZHRoOiA0NHB4O1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtaXRlbSAuaW5mbyB7XFxyXFxuXFx0dmVydGljYWwtYWxpZ246IHRvcDtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5wYWNrYWdlLWl0ZW0gLmluZm8gLnRpdGxlIHtcXHJcXG5cXHRoZWlnaHQ6IGF1dG87XFxyXFxuXFx0bWFyZ2luLXRvcDogN3B4O1xcclxcblxcdGZvbnQtc2l6ZTogMjJweDtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5wYWNrYWdlLWl0ZW0gLmluZm8gLmF1dGhvcnMge1xcclxcblxcdG1hcmdpbjogN3B4IDA7XFxyXFxuXFx0Zm9udC1zaXplOiAxNHB4O1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtaXRlbSAuaW5mbyAuZGVzY3JpcHRpb24ge1xcclxcblxcdGZvbnQtc2l6ZTogMTNweDtcXHJcXG5cXHRtYXJnaW46IDEwcHggMDtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5wYWNrYWdlLWl0ZW0gLmFjdGlvbnMge1xcclxcblxcdHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxyXFxuXFx0dGV4dC1hbGlnbjogcmlnaHQ7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCBidXR0b24ge1xcclxcblxcdGJhY2tncm91bmQtY29sb3I6IHJnYigxMjIsIDEyMiwgMTIyKTtcXHJcXG5cXHRib3JkZXI6IDFweCBzb2xpZCByZ2IoMTIyLCAxMjIsIDEyMik7XFxyXFxuXFx0Ym9yZGVyLXJhZGl1czogMnB4O1xcclxcblxcdGNvbG9yOiB3aGl0ZTtcXHJcXG5cXHR3aGl0ZS1zcGFjZTogbm93cmFwO1xcclxcblxcdHBhZGRpbmc6IDNweCA1cHg7XFxyXFxuXFx0b3V0bGluZTogbm9uZTtcXHJcXG5cXHRjdXJzb3I6IHBvaW50ZXI7XFxyXFxuXFx0Zm9udC1zaXplOiAxMnB4O1xcclxcbn1cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgYnV0dG9uOmhvdmVyIHtcXHJcXG5cXHRiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMjUsIDE2NiwgMjA2KTtcXHJcXG5cXHRib3JkZXI6IDFweCBzb2xpZCByZ2IoMjUsIDE2NiwgMjA2KTtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IGJ1dHRvbltkaXNhYmxlZF0ge1xcclxcblxcdGJhY2tncm91bmQtY29sb3I6IHJnYigxMjIsIDEyMiwgMTIyKTtcXHJcXG5cXHRib3JkZXI6IDFweCBzb2xpZCByZ2IoMTIyLCAxMjIsIDEyMik7XFxyXFxuXFx0Y3Vyc29yOiBkZWZhdWx0O1xcclxcblxcdG9wYWNpdHk6IDAuNTtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5wYWNrYWdlLWl0ZW0gLmljb24gaW1nIHtcXHJcXG5cXHR3aWR0aDogMzBweDtcXHJcXG5cXHRtYXJnaW46IDZweCA3cHg7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAuc2VhcmNoLWlucHV0IHtcXHJcXG5cXHRwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuXFx0d2lkdGg6IDEwMCU7XFxyXFxuXFx0dGV4dC1hbGlnbjogY2VudGVyO1xcclxcblxcdGhlaWdodDogODBweDtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5zZWFyY2gtaW5wdXQgaW5wdXRbdHlwZT10ZXh0XSB7XFxyXFxuXFx0d2lkdGg6IDkwJTtcXHJcXG5cXHRib3JkZXI6IDFweCBzb2xpZCByZ2IoMTYxLCAxNjEsIDE2MSk7XFxyXFxuXFx0Ym9yZGVyLXJhZGl1czogMnB4O1xcclxcblxcdHBhZGRpbmctbGVmdDogMTZweDtcXHJcXG5cXHRwYWRkaW5nLXRvcDogOHB4O1xcclxcblxcdHBhZGRpbmctYm90dG9tOiA4cHg7XFxyXFxuXFx0Zm9udC1zaXplOiAxN3B4O1xcclxcblxcdG1hcmdpbjogMjFweCAwO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtZGV0YWlsZWQtaXRlbSB7XFxyXFxuXFx0dGV4dC1hbGlnbjogY2VudGVyO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnNjcm9sbGVkIHtcXHJcXG5cXHQtbW96LWJveC1zaGFkb3c6IGluc2V0IDAgMTNweCAxNXB4IC0xM3B4IHJnYmEoMTgsIDE0NiwgMTkyLCAwLjIxKTtcXHJcXG5cXHQtd2Via2l0LWJveC1zaGFkb3c6IGluc2V0IDAgMTNweCAxNXB4IC0xM3B4IHJnYmEoMTgsIDE0NiwgMTkyLCAwLjIxKTtcXHJcXG5cXHRib3gtc2hhZG93OiBpbnNldCAwIDEzcHggMTVweCAtMTNweCByZ2JhKDE4LCAxNDYsIDE5MiwgMC4yMSk7XFxyXFxufVxcclxcblxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAucGFja2FnZS1kZXRhaWxlZC1pdGVtIC5jb250ZW50IHtcXHJcXG5cXHRkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuXFx0d2lkdGg6IDkwJTtcXHJcXG5cXHR0ZXh0LWFsaWduOiBsZWZ0O1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLmRldGFpbHMtcGFuZSAuaGVhZGVyIHtcXHJcXG5cXHRwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuXFx0bWFyZ2luOiAxNXB4IDA7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAuZGV0YWlscy1wYW5lIC5oZWFkZXIgLmJhY2sge1xcclxcblxcdG1hcmdpbjogNnB4IDA7XFxyXFxuXFx0cG9zaXRpb246IGFic29sdXRlOyBcXHJcXG5cXHR0b3A6IDA7IFxcclxcblxcdGxlZnQ6IDA7XFxyXFxufVxcclxcblxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAuZGV0YWlscy1wYW5lIC5oZWFkZXIgLmhlYWRlci1jb250ZW50IHtcXHJcXG5cXHR0ZXh0LWFsaWduOiBjZW50ZXI7IFxcclxcblxcdHRleHQtYWxpZ246IGNlbnRlcjsgXFxyXFxuXFx0bWF4LXdpZHRoOiA4NSU7IFxcclxcblxcdG1hcmdpbjogYXV0bztcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5kZXRhaWxzLXBhbmUgLmhlYWRlciAuaGVhZGVyLWNvbnRlbnQgLnRpdGxlIHtcXHJcXG5cXHRkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuXFx0Zm9udC1zaXplOiAyMHB4O1xcclxcblxcdHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAuZGV0YWlscy1wYW5lIC5oZWFkZXIgLmhlYWRlci1jb250ZW50IC5pY29uIHtcXHJcXG5cXHRkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuXFx0aGVpZ2h0OiAxMDAlO1xcclxcblxcdHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAuZGV0YWlscy1wYW5lIC5oZWFkZXIgLmhlYWRlci1jb250ZW50IC5pY29uIGltZyB7XFxyXFxuXFx0d2lkdGg6IDMwcHg7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWNsaWVudCAuZGV0YWlscy1wYW5lIC5oZWFkZXIgLmhlYWRlci1jb250ZW50IC5hY3Rpb24ge1xcclxcblxcdGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG5cXHRtYXJnaW4tbGVmdDogMTBweDtcXHJcXG5cXHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtZGV0YWlsZWQtaXRlbSAuc2VjdGlvbiB7XFxyXFxuXFx0Ym9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNjY2M7XFxyXFxuXFx0Zm9udC13ZWlnaHQ6IGJvbGQ7XFxyXFxuXFx0Y29sb3I6ICM1NTU7XFxyXFxuXFx0bWFyZ2luLXRvcDogMTBweDtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5wYWNrYWdlLWRldGFpbGVkLWl0ZW0gLmxhYmVsIHtcXHJcXG5cXHR2ZXJ0aWNhbC1hbGlnbjogdG9wO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1jbGllbnQgLnBhY2thZ2UtZGV0YWlsZWQtaXRlbSAudmVyc2lvbiB7XFxyXFxuXFx0Zm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktY2xpZW50IC5zcGlubmVyIHtcXHJcXG5cXHR0ZXh0LWFsaWduOiBjZW50ZXI7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWJ1dHRvbiB7XFxyXFxuXFx0cG9zaXRpb246IHJlbGF0aXZlO1xcclxcblxcdGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG5cXHR3aWR0aDogMTZweDtcXHJcXG5cXHRoZWlnaHQ6IDE2cHg7XFxyXFxufVxcclxcblxcclxcbi5jaG9jb2xhdGV5LWJ1dHRvbiA+IGJ1dHRvbiB7XFxyXFxuXFx0cG9zaXRpb246IGFic29sdXRlO1xcclxcblxcdHRvcDogMDtcXHJcXG5cXHRsZWZ0OiAwO1xcclxcblxcdHdpZHRoOiAxNnB4O1xcclxcblxcdGhlaWdodDogMTZweDtcXHJcXG4gICAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcXHJcXG4gICAgYmFja2dyb3VuZC1zaXplOiAxM3B4IDEzcHg7XFxyXFxuICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6ICM3YTdhN2E7XFxyXFxuICAgIG91dGxpbmU6IG5vbmU7XFxyXFxuICAgIHBhZGRpbmc6IDA7XFxyXFxuICAgIGN1cnNvcjogcG9pbnRlcjtcXHJcXG59XFxyXFxuXFxyXFxuLmNob2NvbGF0ZXktYnV0dG9uID4gYnV0dG9uOmhvdmVyIHtcXHJcXG5cXHRiYWNrZ3JvdW5kLWNvbG9yOiAjMDA5YWNlO1xcclxcbn1cXHJcXG5cXHJcXG4uY2hvY29sYXRleS1idXR0b24gPiAuY2hvY29sYXRleS1idXR0b24tb3ZlcmxheSB7XFxyXFxuXFx0ZGlzcGxheTogbm9uZTtcXHJcXG5cXHRwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuXFx0dG9wOiAwO1xcclxcblxcdGxlZnQ6IDA7XFxyXFxuXFx0d2lkdGg6IDE2cHg7XFxyXFxuXFx0aGVpZ2h0OiAxNnB4O1xcclxcblxcdGJhY2tncm91bmQtY29sb3I6ICMwMDlhY2U7XFxyXFxuXFx0b3BhY2l0eTogMC41O1xcclxcblxcdGN1cnNvcjogcG9pbnRlcjtcXHJcXG5cXHRib3JkZXItcmFkaXVzOiAzcHg7XFxyXFxufVwiLCBcIlwiXSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzcy1sb2FkZXIhLi9zcmMvY2hvY29sYXRleS1jbGllbnQvc3R5bGVzL3N0eWxlLmNzc1xuLy8gbW9kdWxlIGlkID0gNDhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkM6XFxcXEJ1aWxkQWdlbnRcXFxcd29ya1xcXFw3YTRhMGZlNDViMjYwMjI2XFxcXGNsb3Vkc2hhcmVcXFxcc3JjXFxcXGphdmFzY3JpcHRcXFxcY3NcXFxcbm9kZV9tb2R1bGVzXFxcXGNzcy1sb2FkZXJcXFxcY3NzVG9TdHJpbmcuanNcIikoKTtcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcclxcbiAqIGJvb3RzdHJhcC10b3VyIC0gdjAuMTAuMlxcclxcbiAqIGh0dHA6Ly9ib290c3RyYXB0b3VyLmNvbVxcclxcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcclxcbiAqIENvcHlyaWdodCAyMDEyLTIwMTUgVWxyaWNoIFNvc3NvdVxcclxcbiAqXFxyXFxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XFxyXFxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlICh0aGUgXFxcIkxpY2Vuc2VcXFwiKTtcXHJcXG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXFxyXFxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XFxyXFxuICpcXHJcXG4gKiAgICAgaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVRcXHJcXG4gKlxcclxcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcXHJcXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcXFwiQVMgSVNcXFwiIEJBU0lTLFxcclxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxcclxcbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcXHJcXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cXHJcXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cXHJcXG4gKi9cXHJcXG5cXHJcXG4udG91ci1iYWNrZHJvcCB7XFxyXFxuICBwb3NpdGlvbjogZml4ZWQ7XFxyXFxuICB0b3A6IDA7XFxyXFxuICByaWdodDogMDtcXHJcXG4gIGJvdHRvbTogMDtcXHJcXG4gIGxlZnQ6IDA7XFxyXFxuICB6LWluZGV4OiAxO1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDtcXHJcXG4gIG9wYWNpdHk6IDAuODtcXHJcXG4gIGZpbHRlcjogYWxwaGEob3BhY2l0eT04MCk7XFxyXFxufVxcclxcbi50b3VyLXN0ZXAtYmFja2Ryb3Age1xcclxcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcclxcbiAgei1pbmRleDogMjtcXHJcXG59XFxyXFxuLnRvdXItc3RlcC1iYWNrZHJvcCA+IHRkIHtcXHJcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXHJcXG4gIHotaW5kZXg6IDI7XFxyXFxufVxcclxcbi50b3VyLXN0ZXAtYmFja2Ryb3AtZGlzYWJsZS1jbGlja3tcXHJcXG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xcclxcbn1cXHJcXG4udG91ci1zdGVwLWJhY2tncm91bmQge1xcclxcbiAgcG9zaXRpb246IGFic29sdXRlICFpbXBvcnRhbnQ7XFxyXFxuICB6LWluZGV4OiAxO1xcclxcbiAgYmFja2dyb3VuZDogaW5oZXJpdDtcXHJcXG4gIGJvcmRlci1yYWRpdXM6IDNweDtcXHJcXG59XFxyXFxuLnBvcG92ZXJbY2xhc3MqPVxcXCJ0b3VyLVxcXCJdIHtcXHJcXG4gIHotaW5kZXg6IDEwMDtcXHJcXG59XFxyXFxuLnBvcG92ZXJbY2xhc3MqPVxcXCJ0b3VyLVxcXCJdIC5wb3BvdmVyLW5hdmlnYXRpb24ge1xcclxcbiAgcGFkZGluZzogOXB4IDE0cHg7XFxyXFxufVxcclxcbi5wb3BvdmVyW2NsYXNzKj1cXFwidG91ci1cXFwiXSAucG9wb3Zlci1uYXZpZ2F0aW9uICpbZGF0YS1yb2xlPVxcXCJlbmRcXFwiXSB7XFxyXFxuICBmbG9hdDogcmlnaHQ7XFxyXFxufVxcclxcbi5wb3BvdmVyW2NsYXNzKj1cXFwidG91ci1cXFwiXSAucG9wb3Zlci1uYXZpZ2F0aW9uICpbZGF0YS1yb2xlPVxcXCJwcmV2XFxcIl0sXFxyXFxuLnBvcG92ZXJbY2xhc3MqPVxcXCJ0b3VyLVxcXCJdIC5wb3BvdmVyLW5hdmlnYXRpb24gKltkYXRhLXJvbGU9XFxcIm5leHRcXFwiXSxcXHJcXG4ucG9wb3ZlcltjbGFzcyo9XFxcInRvdXItXFxcIl0gLnBvcG92ZXItbmF2aWdhdGlvbiAqW2RhdGEtcm9sZT1cXFwiZW5kXFxcIl0ge1xcclxcbiAgY3Vyc29yOiBwb2ludGVyO1xcclxcbn1cXHJcXG4ucG9wb3ZlcltjbGFzcyo9XFxcInRvdXItXFxcIl0gLnBvcG92ZXItbmF2aWdhdGlvbiAqW2RhdGEtcm9sZT1cXFwicHJldlxcXCJdLmRpc2FibGVkLFxcclxcbi5wb3BvdmVyW2NsYXNzKj1cXFwidG91ci1cXFwiXSAucG9wb3Zlci1uYXZpZ2F0aW9uICpbZGF0YS1yb2xlPVxcXCJuZXh0XFxcIl0uZGlzYWJsZWQsXFxyXFxuLnBvcG92ZXJbY2xhc3MqPVxcXCJ0b3VyLVxcXCJdIC5wb3BvdmVyLW5hdmlnYXRpb24gKltkYXRhLXJvbGU9XFxcImVuZFxcXCJdLmRpc2FibGVkIHtcXHJcXG4gIGN1cnNvcjogZGVmYXVsdDtcXHJcXG59XFxyXFxuLnBvcG92ZXJbY2xhc3MqPVxcXCJ0b3VyLVxcXCJdLm9ycGhhbiB7XFxyXFxuICBwb3NpdGlvbjogZml4ZWQ7XFxyXFxuICBtYXJnaW4tdG9wOiAwO1xcclxcbn1cXHJcXG4ucG9wb3ZlcltjbGFzcyo9XFxcInRvdXItXFxcIl0ub3JwaGFuIC5hcnJvdyB7XFxyXFxuICBkaXNwbGF5OiBub25lO1xcclxcbn1cXHJcXG4ucG9wb3ZlciBhIHtcXHJcXG4gIGN1cnNvcjogcG9pbnRlcjtcXHJcXG59XCIsIFwiXCJdKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlciEuL3NyYy9jbG91ZHNoYXJlLXRvdXIvYm9vdHN0cmFwLXRvdXIvYm9vdHN0cmFwLXRvdXIuY3NzXG4vLyBtb2R1bGUgaWQgPSA0OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQzpcXFxcQnVpbGRBZ2VudFxcXFx3b3JrXFxcXDdhNGEwZmU0NWIyNjAyMjZcXFxcY2xvdWRzaGFyZVxcXFxzcmNcXFxcamF2YXNjcmlwdFxcXFxjc1xcXFxub2RlX21vZHVsZXNcXFxcY3NzLWxvYWRlclxcXFxjc3NUb1N0cmluZy5qc1wiKSgpO1xuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiLnBvcG92ZXIudG91ciAuY2xvc2UtYnV0dG9uIHtcXHJcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgICB0b3A6IDdweDtcXHJcXG4gICAgcmlnaHQ6IDhweDtcXHJcXG4gICAgZm9udC1zaXplOiAxNnB4O1xcclxcbiAgICBjb2xvcjogIzY2NjtcXHJcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcclxcbn1cXHJcXG5cXHJcXG4ucG9wb3Zlci50b3VyIC5jbG9zZS1idXR0b246aG92ZXIge1xcclxcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XFxyXFxufVxcclxcblxcclxcbi5wb3BvdmVyLnRvdXIgLnBvcG92ZXItdGl0bGUge1xcclxcbiAgICBwYWRkaW5nLXJpZ2h0OiAyNXB4O1xcclxcbn1cIiwgXCJcIl0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyIS4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvRmxvd1RlbXBsYXRlLmNzc1xuLy8gbW9kdWxlIGlkID0gNTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkM6XFxcXEJ1aWxkQWdlbnRcXFxcd29ya1xcXFw3YTRhMGZlNDViMjYwMjI2XFxcXGNsb3Vkc2hhcmVcXFxcc3JjXFxcXGphdmFzY3JpcHRcXFxcY3NcXFxcbm9kZV9tb2R1bGVzXFxcXGNzcy1sb2FkZXJcXFxcY3NzVG9TdHJpbmcuanNcIikoKTtcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5jcy1pbWFnZS1mbG93LW1vZGFsIHtcXHJcXG4gICAgcG9zaXRpb246IGZpeGVkO1xcclxcbiAgICB0b3A6IDA7XFxyXFxuICAgIGxlZnQ6IDA7XFxyXFxuICAgIHdpZHRoOiAxMDAlO1xcclxcbiAgICBoZWlnaHQ6IDEwMCU7XFxyXFxuICAgIHotaW5kZXg6IDI7XFxyXFxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG59XFxyXFxuXFxyXFxuLmNzLWltYWdlLWZsb3ctbW9kYWwgLnZlcnRpY2FsLWFsaWduZXIge1xcclxcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxyXFxuICAgIGhlaWdodDogMTAwJTtcXHJcXG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcXHJcXG59XFxyXFxuXFxyXFxuLmNzLWltYWdlLWZsb3ctbW9kYWwgLm1vZGFsLWJhY2tkcm9wIHtcXHJcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcclxcbiAgICB0b3A6IDA7XFxyXFxuICAgIGxlZnQ6IDA7XFxyXFxuICAgIHdpZHRoOiAxMDAlO1xcclxcbiAgICBoZWlnaHQ6IDEwMCU7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6IGJsYWNrO1xcclxcbiAgICBvcGFjaXR5OiAwLjU7XFxyXFxuICAgIHotaW5kZXg6IDA7XFxyXFxufVxcclxcblxcclxcbi5jcy1pbWFnZS1mbG93LW1vZGFsIC5tb2RhbC1jb250YWluZXIge1xcclxcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXHJcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XFxyXFxuICAgIGJvcmRlci1yYWRpdXM6IDRweDtcXHJcXG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcXHJcXG4gICAgYm94LXNoYWRvdzogMCAwIDMwcHggLTZweCBibGFjaztcXHJcXG4gICAgbWF4LXdpZHRoOiAxMDAlO1xcclxcbiAgICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcclxcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXHJcXG4gICAgLW1vei10cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTUwJSk7XFxyXFxuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcXHJcXG4gICAgdG9wOiA0MCU7XFxyXFxufVxcclxcblxcclxcbi5jcy1pbWFnZS1mbG93LW1vZGFsIC5mbG93LW1vZGFsLWhlYWRlciB7XFxyXFxuICAgIGJhY2tncm91bmQtY29sb3I6ICNmN2Y3Zjc7XFxyXFxuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWJlYmViO1xcclxcbiAgICBmb250LWZhbWlseTogXFxcIm9wZW4gc2Fuc1xcXCIsIHNhbnMtc2VyaWY7XFxyXFxuICAgIGZvbnQtc2l6ZTogMTdweDtcXHJcXG4gICAgY29sb3I6ICM2NzY3Njc7XFxyXFxuICAgIHBhZGRpbmc6IDVweCAwO1xcclxcbn1cXHJcXG5cXHJcXG4uY3MtaW1hZ2UtZmxvdy1tb2RhbCAuZmxvdy1tb2RhbC1pbWFnZS1jb250YWluZXIge1xcclxcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICAgIHdpZHRoOiAxMDAlO1xcclxcbiAgICBoZWlnaHQ6IDEwMCU7XFxyXFxufVxcclxcblxcclxcbi5jcy1pbWFnZS1mbG93LW1vZGFsIC5mbG93LW1vZGFsLWltYWdlLWNvbnRhaW5lciBpbWcge1xcclxcbiAgICBtYXgtd2lkdGg6IDEwMCU7XFxyXFxufVxcclxcblxcclxcbi5jcy1pbWFnZS1mbG93LW1vZGFsIC5mbG93LW1vZGFsLWltYWdlLWNvbnRhaW5lciBbaW1hZ2UtZmxvdy1zcG90XSB7XFxyXFxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcclxcbiAgICB3aWR0aDogMTBweDtcXHJcXG4gICAgaGVpZ2h0OiAxMHB4O1xcclxcbn1cIiwgXCJcIl0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyIS4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvSW1hZ2VGbG93TW9kYWwuY3NzXG4vLyBtb2R1bGUgaWQgPSA1MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKlxuICBNb2R1bGUgZGVwZW5kZW5jaWVzXG4qL1xudmFyIEVsZW1lbnRUeXBlID0gcmVxdWlyZSgnZG9tZWxlbWVudHR5cGUnKTtcbnZhciBlbnRpdGllcyA9IHJlcXVpcmUoJ2VudGl0aWVzJyk7XG5cbi8qXG4gIEJvb2xlYW4gQXR0cmlidXRlc1xuKi9cbnZhciBib29sZWFuQXR0cmlidXRlcyA9IHtcbiAgX19wcm90b19fOiBudWxsLFxuICBhbGxvd2Z1bGxzY3JlZW46IHRydWUsXG4gIGFzeW5jOiB0cnVlLFxuICBhdXRvZm9jdXM6IHRydWUsXG4gIGF1dG9wbGF5OiB0cnVlLFxuICBjaGVja2VkOiB0cnVlLFxuICBjb250cm9sczogdHJ1ZSxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgZGVmZXI6IHRydWUsXG4gIGRpc2FibGVkOiB0cnVlLFxuICBoaWRkZW46IHRydWUsXG4gIGlzbWFwOiB0cnVlLFxuICBsb29wOiB0cnVlLFxuICBtdWx0aXBsZTogdHJ1ZSxcbiAgbXV0ZWQ6IHRydWUsXG4gIG9wZW46IHRydWUsXG4gIHJlYWRvbmx5OiB0cnVlLFxuICByZXF1aXJlZDogdHJ1ZSxcbiAgcmV2ZXJzZWQ6IHRydWUsXG4gIHNjb3BlZDogdHJ1ZSxcbiAgc2VhbWxlc3M6IHRydWUsXG4gIHNlbGVjdGVkOiB0cnVlLFxuICB0eXBlbXVzdG1hdGNoOiB0cnVlXG59O1xuXG52YXIgdW5lbmNvZGVkRWxlbWVudHMgPSB7XG4gIF9fcHJvdG9fXzogbnVsbCxcbiAgc3R5bGU6IHRydWUsXG4gIHNjcmlwdDogdHJ1ZSxcbiAgeG1wOiB0cnVlLFxuICBpZnJhbWU6IHRydWUsXG4gIG5vZW1iZWQ6IHRydWUsXG4gIG5vZnJhbWVzOiB0cnVlLFxuICBwbGFpbnRleHQ6IHRydWUsXG4gIG5vc2NyaXB0OiB0cnVlXG59O1xuXG4vKlxuICBGb3JtYXQgYXR0cmlidXRlc1xuKi9cbmZ1bmN0aW9uIGZvcm1hdEF0dHJzKGF0dHJpYnV0ZXMsIG9wdHMpIHtcbiAgaWYgKCFhdHRyaWJ1dGVzKSByZXR1cm47XG5cbiAgdmFyIG91dHB1dCA9ICcnLFxuICAgICAgdmFsdWU7XG5cbiAgLy8gTG9vcCB0aHJvdWdoIHRoZSBhdHRyaWJ1dGVzXG4gIGZvciAodmFyIGtleSBpbiBhdHRyaWJ1dGVzKSB7XG4gICAgdmFsdWUgPSBhdHRyaWJ1dGVzW2tleV07XG4gICAgaWYgKG91dHB1dCkge1xuICAgICAgb3V0cHV0ICs9ICcgJztcbiAgICB9XG5cbiAgICBpZiAoIXZhbHVlICYmIGJvb2xlYW5BdHRyaWJ1dGVzW2tleV0pIHtcbiAgICAgIG91dHB1dCArPSBrZXk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dCArPSBrZXkgKyAnPVwiJyArIChvcHRzLmRlY29kZUVudGl0aWVzID8gZW50aXRpZXMuZW5jb2RlWE1MKHZhbHVlKSA6IHZhbHVlKSArICdcIic7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLypcbiAgU2VsZi1lbmNsb3NpbmcgdGFncyAoc3RvbGVuIGZyb20gbm9kZS1odG1scGFyc2VyKVxuKi9cbnZhciBzaW5nbGVUYWcgPSB7XG4gIF9fcHJvdG9fXzogbnVsbCxcbiAgYXJlYTogdHJ1ZSxcbiAgYmFzZTogdHJ1ZSxcbiAgYmFzZWZvbnQ6IHRydWUsXG4gIGJyOiB0cnVlLFxuICBjb2w6IHRydWUsXG4gIGNvbW1hbmQ6IHRydWUsXG4gIGVtYmVkOiB0cnVlLFxuICBmcmFtZTogdHJ1ZSxcbiAgaHI6IHRydWUsXG4gIGltZzogdHJ1ZSxcbiAgaW5wdXQ6IHRydWUsXG4gIGlzaW5kZXg6IHRydWUsXG4gIGtleWdlbjogdHJ1ZSxcbiAgbGluazogdHJ1ZSxcbiAgbWV0YTogdHJ1ZSxcbiAgcGFyYW06IHRydWUsXG4gIHNvdXJjZTogdHJ1ZSxcbiAgdHJhY2s6IHRydWUsXG4gIHdicjogdHJ1ZSxcbn07XG5cblxudmFyIHJlbmRlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZG9tLCBvcHRzKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShkb20pICYmICFkb20uY2hlZXJpbykgZG9tID0gW2RvbV07XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gIHZhciBvdXRwdXQgPSAnJztcblxuICBmb3IodmFyIGkgPSAwOyBpIDwgZG9tLmxlbmd0aDsgaSsrKXtcbiAgICB2YXIgZWxlbSA9IGRvbVtpXTtcblxuICAgIGlmIChlbGVtLnR5cGUgPT09ICdyb290JylcbiAgICAgIG91dHB1dCArPSByZW5kZXIoZWxlbS5jaGlsZHJlbiwgb3B0cyk7XG4gICAgZWxzZSBpZiAoRWxlbWVudFR5cGUuaXNUYWcoZWxlbSkpXG4gICAgICBvdXRwdXQgKz0gcmVuZGVyVGFnKGVsZW0sIG9wdHMpO1xuICAgIGVsc2UgaWYgKGVsZW0udHlwZSA9PT0gRWxlbWVudFR5cGUuRGlyZWN0aXZlKVxuICAgICAgb3V0cHV0ICs9IHJlbmRlckRpcmVjdGl2ZShlbGVtKTtcbiAgICBlbHNlIGlmIChlbGVtLnR5cGUgPT09IEVsZW1lbnRUeXBlLkNvbW1lbnQpXG4gICAgICBvdXRwdXQgKz0gcmVuZGVyQ29tbWVudChlbGVtKTtcbiAgICBlbHNlIGlmIChlbGVtLnR5cGUgPT09IEVsZW1lbnRUeXBlLkNEQVRBKVxuICAgICAgb3V0cHV0ICs9IHJlbmRlckNkYXRhKGVsZW0pO1xuICAgIGVsc2VcbiAgICAgIG91dHB1dCArPSByZW5kZXJUZXh0KGVsZW0sIG9wdHMpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbmZ1bmN0aW9uIHJlbmRlclRhZyhlbGVtLCBvcHRzKSB7XG4gIC8vIEhhbmRsZSBTVkdcbiAgaWYgKGVsZW0ubmFtZSA9PT0gXCJzdmdcIikgb3B0cyA9IHtkZWNvZGVFbnRpdGllczogb3B0cy5kZWNvZGVFbnRpdGllcywgeG1sTW9kZTogdHJ1ZX07XG5cbiAgdmFyIHRhZyA9ICc8JyArIGVsZW0ubmFtZSxcbiAgICAgIGF0dHJpYnMgPSBmb3JtYXRBdHRycyhlbGVtLmF0dHJpYnMsIG9wdHMpO1xuXG4gIGlmIChhdHRyaWJzKSB7XG4gICAgdGFnICs9ICcgJyArIGF0dHJpYnM7XG4gIH1cblxuICBpZiAoXG4gICAgb3B0cy54bWxNb2RlXG4gICAgJiYgKCFlbGVtLmNoaWxkcmVuIHx8IGVsZW0uY2hpbGRyZW4ubGVuZ3RoID09PSAwKVxuICApIHtcbiAgICB0YWcgKz0gJy8+JztcbiAgfSBlbHNlIHtcbiAgICB0YWcgKz0gJz4nO1xuICAgIGlmIChlbGVtLmNoaWxkcmVuKSB7XG4gICAgICB0YWcgKz0gcmVuZGVyKGVsZW0uY2hpbGRyZW4sIG9wdHMpO1xuICAgIH1cblxuICAgIGlmICghc2luZ2xlVGFnW2VsZW0ubmFtZV0gfHwgb3B0cy54bWxNb2RlKSB7XG4gICAgICB0YWcgKz0gJzwvJyArIGVsZW0ubmFtZSArICc+JztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFnO1xufVxuXG5mdW5jdGlvbiByZW5kZXJEaXJlY3RpdmUoZWxlbSkge1xuICByZXR1cm4gJzwnICsgZWxlbS5kYXRhICsgJz4nO1xufVxuXG5mdW5jdGlvbiByZW5kZXJUZXh0KGVsZW0sIG9wdHMpIHtcbiAgdmFyIGRhdGEgPSBlbGVtLmRhdGEgfHwgJyc7XG5cbiAgLy8gaWYgZW50aXRpZXMgd2VyZW4ndCBkZWNvZGVkLCBubyBuZWVkIHRvIGVuY29kZSB0aGVtIGJhY2tcbiAgaWYgKG9wdHMuZGVjb2RlRW50aXRpZXMgJiYgIShlbGVtLnBhcmVudCAmJiBlbGVtLnBhcmVudC5uYW1lIGluIHVuZW5jb2RlZEVsZW1lbnRzKSkge1xuICAgIGRhdGEgPSBlbnRpdGllcy5lbmNvZGVYTUwoZGF0YSk7XG4gIH1cblxuICByZXR1cm4gZGF0YTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyQ2RhdGEoZWxlbSkge1xuICByZXR1cm4gJzwhW0NEQVRBWycgKyBlbGVtLmNoaWxkcmVuWzBdLmRhdGEgKyAnXV0+Jztcbn1cblxuZnVuY3Rpb24gcmVuZGVyQ29tbWVudChlbGVtKSB7XG4gIHJldHVybiAnPCEtLScgKyBlbGVtLmRhdGEgKyAnLS0+Jztcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9kb20tc2VyaWFsaXplci9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gNTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy9UeXBlcyBvZiBlbGVtZW50cyBmb3VuZCBpbiB0aGUgRE9NXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0VGV4dDogXCJ0ZXh0XCIsIC8vVGV4dFxuXHREaXJlY3RpdmU6IFwiZGlyZWN0aXZlXCIsIC8vPD8gLi4uID8+XG5cdENvbW1lbnQ6IFwiY29tbWVudFwiLCAvLzwhLS0gLi4uIC0tPlxuXHRTY3JpcHQ6IFwic2NyaXB0XCIsIC8vPHNjcmlwdD4gdGFnc1xuXHRTdHlsZTogXCJzdHlsZVwiLCAvLzxzdHlsZT4gdGFnc1xuXHRUYWc6IFwidGFnXCIsIC8vQW55IHRhZ1xuXHRDREFUQTogXCJjZGF0YVwiLCAvLzwhW0NEQVRBWyAuLi4gXV0+XG5cblx0aXNUYWc6IGZ1bmN0aW9uKGVsZW0pe1xuXHRcdHJldHVybiBlbGVtLnR5cGUgPT09IFwidGFnXCIgfHwgZWxlbS50eXBlID09PSBcInNjcmlwdFwiIHx8IGVsZW0udHlwZSA9PT0gXCJzdHlsZVwiO1xuXHR9XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9kb20tc2VyaWFsaXplci9+L2RvbWVsZW1lbnR0eXBlL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSA1M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgRWxlbWVudFR5cGUgPSByZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIik7XG5cbnZhciByZV93aGl0ZXNwYWNlID0gL1xccysvZztcbnZhciBOb2RlUHJvdG90eXBlID0gcmVxdWlyZShcIi4vbGliL25vZGVcIik7XG52YXIgRWxlbWVudFByb3RvdHlwZSA9IHJlcXVpcmUoXCIuL2xpYi9lbGVtZW50XCIpO1xuXG5mdW5jdGlvbiBEb21IYW5kbGVyKGNhbGxiYWNrLCBvcHRpb25zLCBlbGVtZW50Q0Ipe1xuXHRpZih0eXBlb2YgY2FsbGJhY2sgPT09IFwib2JqZWN0XCIpe1xuXHRcdGVsZW1lbnRDQiA9IG9wdGlvbnM7XG5cdFx0b3B0aW9ucyA9IGNhbGxiYWNrO1xuXHRcdGNhbGxiYWNrID0gbnVsbDtcblx0fSBlbHNlIGlmKHR5cGVvZiBvcHRpb25zID09PSBcImZ1bmN0aW9uXCIpe1xuXHRcdGVsZW1lbnRDQiA9IG9wdGlvbnM7XG5cdFx0b3B0aW9ucyA9IGRlZmF1bHRPcHRzO1xuXHR9XG5cdHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XG5cdHRoaXMuX29wdGlvbnMgPSBvcHRpb25zIHx8IGRlZmF1bHRPcHRzO1xuXHR0aGlzLl9lbGVtZW50Q0IgPSBlbGVtZW50Q0I7XG5cdHRoaXMuZG9tID0gW107XG5cdHRoaXMuX2RvbmUgPSBmYWxzZTtcblx0dGhpcy5fdGFnU3RhY2sgPSBbXTtcblx0dGhpcy5fcGFyc2VyID0gdGhpcy5fcGFyc2VyIHx8IG51bGw7XG59XG5cbi8vZGVmYXVsdCBvcHRpb25zXG52YXIgZGVmYXVsdE9wdHMgPSB7XG5cdG5vcm1hbGl6ZVdoaXRlc3BhY2U6IGZhbHNlLCAvL1JlcGxhY2UgYWxsIHdoaXRlc3BhY2Ugd2l0aCBzaW5nbGUgc3BhY2VzXG5cdHdpdGhTdGFydEluZGljZXM6IGZhbHNlLCAvL0FkZCBzdGFydEluZGV4IHByb3BlcnRpZXMgdG8gbm9kZXNcbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9ucGFyc2VyaW5pdCA9IGZ1bmN0aW9uKHBhcnNlcil7XG5cdHRoaXMuX3BhcnNlciA9IHBhcnNlcjtcbn07XG5cbi8vUmVzZXRzIHRoZSBoYW5kbGVyIGJhY2sgdG8gc3RhcnRpbmcgc3RhdGVcbkRvbUhhbmRsZXIucHJvdG90eXBlLm9ucmVzZXQgPSBmdW5jdGlvbigpe1xuXHREb21IYW5kbGVyLmNhbGwodGhpcywgdGhpcy5fY2FsbGJhY2ssIHRoaXMuX29wdGlvbnMsIHRoaXMuX2VsZW1lbnRDQik7XG59O1xuXG4vL1NpZ25hbHMgdGhlIGhhbmRsZXIgdGhhdCBwYXJzaW5nIGlzIGRvbmVcbkRvbUhhbmRsZXIucHJvdG90eXBlLm9uZW5kID0gZnVuY3Rpb24oKXtcblx0aWYodGhpcy5fZG9uZSkgcmV0dXJuO1xuXHR0aGlzLl9kb25lID0gdHJ1ZTtcblx0dGhpcy5fcGFyc2VyID0gbnVsbDtcblx0dGhpcy5faGFuZGxlQ2FsbGJhY2sobnVsbCk7XG59O1xuXG5Eb21IYW5kbGVyLnByb3RvdHlwZS5faGFuZGxlQ2FsbGJhY2sgPVxuRG9tSGFuZGxlci5wcm90b3R5cGUub25lcnJvciA9IGZ1bmN0aW9uKGVycm9yKXtcblx0aWYodHlwZW9mIHRoaXMuX2NhbGxiYWNrID09PSBcImZ1bmN0aW9uXCIpe1xuXHRcdHRoaXMuX2NhbGxiYWNrKGVycm9yLCB0aGlzLmRvbSk7XG5cdH0gZWxzZSB7XG5cdFx0aWYoZXJyb3IpIHRocm93IGVycm9yO1xuXHR9XG59O1xuXG5Eb21IYW5kbGVyLnByb3RvdHlwZS5vbmNsb3NldGFnID0gZnVuY3Rpb24oKXtcblx0Ly9pZih0aGlzLl90YWdTdGFjay5wb3AoKS5uYW1lICE9PSBuYW1lKSB0aGlzLl9oYW5kbGVDYWxsYmFjayhFcnJvcihcIlRhZ25hbWUgZGlkbid0IG1hdGNoIVwiKSk7XG5cdHZhciBlbGVtID0gdGhpcy5fdGFnU3RhY2sucG9wKCk7XG5cdGlmKHRoaXMuX2VsZW1lbnRDQikgdGhpcy5fZWxlbWVudENCKGVsZW0pO1xufTtcblxuRG9tSGFuZGxlci5wcm90b3R5cGUuX2FkZERvbUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50KXtcblx0dmFyIHBhcmVudCA9IHRoaXMuX3RhZ1N0YWNrW3RoaXMuX3RhZ1N0YWNrLmxlbmd0aCAtIDFdO1xuXHR2YXIgc2libGluZ3MgPSBwYXJlbnQgPyBwYXJlbnQuY2hpbGRyZW4gOiB0aGlzLmRvbTtcblx0dmFyIHByZXZpb3VzU2libGluZyA9IHNpYmxpbmdzW3NpYmxpbmdzLmxlbmd0aCAtIDFdO1xuXG5cdGVsZW1lbnQubmV4dCA9IG51bGw7XG5cblx0aWYodGhpcy5fb3B0aW9ucy53aXRoU3RhcnRJbmRpY2VzKXtcblx0XHRlbGVtZW50LnN0YXJ0SW5kZXggPSB0aGlzLl9wYXJzZXIuc3RhcnRJbmRleDtcblx0fVxuXG5cdGlmICh0aGlzLl9vcHRpb25zLndpdGhEb21MdmwxKSB7XG5cdFx0ZWxlbWVudC5fX3Byb3RvX18gPSBlbGVtZW50LnR5cGUgPT09IFwidGFnXCIgPyBFbGVtZW50UHJvdG90eXBlIDogTm9kZVByb3RvdHlwZTtcblx0fVxuXG5cdGlmKHByZXZpb3VzU2libGluZyl7XG5cdFx0ZWxlbWVudC5wcmV2ID0gcHJldmlvdXNTaWJsaW5nO1xuXHRcdHByZXZpb3VzU2libGluZy5uZXh0ID0gZWxlbWVudDtcblx0fSBlbHNlIHtcblx0XHRlbGVtZW50LnByZXYgPSBudWxsO1xuXHR9XG5cblx0c2libGluZ3MucHVzaChlbGVtZW50KTtcblx0ZWxlbWVudC5wYXJlbnQgPSBwYXJlbnQgfHwgbnVsbDtcbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9ub3BlbnRhZyA9IGZ1bmN0aW9uKG5hbWUsIGF0dHJpYnMpe1xuXHR2YXIgZWxlbWVudCA9IHtcblx0XHR0eXBlOiBuYW1lID09PSBcInNjcmlwdFwiID8gRWxlbWVudFR5cGUuU2NyaXB0IDogbmFtZSA9PT0gXCJzdHlsZVwiID8gRWxlbWVudFR5cGUuU3R5bGUgOiBFbGVtZW50VHlwZS5UYWcsXG5cdFx0bmFtZTogbmFtZSxcblx0XHRhdHRyaWJzOiBhdHRyaWJzLFxuXHRcdGNoaWxkcmVuOiBbXVxuXHR9O1xuXG5cdHRoaXMuX2FkZERvbUVsZW1lbnQoZWxlbWVudCk7XG5cblx0dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KTtcbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9udGV4dCA9IGZ1bmN0aW9uKGRhdGEpe1xuXHQvL3RoZSBpZ25vcmVXaGl0ZXNwYWNlIGlzIG9mZmljaWFsbHkgZHJvcHBlZCwgYnV0IGZvciBub3csXG5cdC8vaXQncyBhbiBhbGlhcyBmb3Igbm9ybWFsaXplV2hpdGVzcGFjZVxuXHR2YXIgbm9ybWFsaXplID0gdGhpcy5fb3B0aW9ucy5ub3JtYWxpemVXaGl0ZXNwYWNlIHx8IHRoaXMuX29wdGlvbnMuaWdub3JlV2hpdGVzcGFjZTtcblxuXHR2YXIgbGFzdFRhZztcblxuXHRpZighdGhpcy5fdGFnU3RhY2subGVuZ3RoICYmIHRoaXMuZG9tLmxlbmd0aCAmJiAobGFzdFRhZyA9IHRoaXMuZG9tW3RoaXMuZG9tLmxlbmd0aC0xXSkudHlwZSA9PT0gRWxlbWVudFR5cGUuVGV4dCl7XG5cdFx0aWYobm9ybWFsaXplKXtcblx0XHRcdGxhc3RUYWcuZGF0YSA9IChsYXN0VGFnLmRhdGEgKyBkYXRhKS5yZXBsYWNlKHJlX3doaXRlc3BhY2UsIFwiIFwiKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGFzdFRhZy5kYXRhICs9IGRhdGE7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGlmKFxuXHRcdFx0dGhpcy5fdGFnU3RhY2subGVuZ3RoICYmXG5cdFx0XHQobGFzdFRhZyA9IHRoaXMuX3RhZ1N0YWNrW3RoaXMuX3RhZ1N0YWNrLmxlbmd0aCAtIDFdKSAmJlxuXHRcdFx0KGxhc3RUYWcgPSBsYXN0VGFnLmNoaWxkcmVuW2xhc3RUYWcuY2hpbGRyZW4ubGVuZ3RoIC0gMV0pICYmXG5cdFx0XHRsYXN0VGFnLnR5cGUgPT09IEVsZW1lbnRUeXBlLlRleHRcblx0XHQpe1xuXHRcdFx0aWYobm9ybWFsaXplKXtcblx0XHRcdFx0bGFzdFRhZy5kYXRhID0gKGxhc3RUYWcuZGF0YSArIGRhdGEpLnJlcGxhY2UocmVfd2hpdGVzcGFjZSwgXCIgXCIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGFzdFRhZy5kYXRhICs9IGRhdGE7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmKG5vcm1hbGl6ZSl7XG5cdFx0XHRcdGRhdGEgPSBkYXRhLnJlcGxhY2UocmVfd2hpdGVzcGFjZSwgXCIgXCIpO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9hZGREb21FbGVtZW50KHtcblx0XHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdFx0dHlwZTogRWxlbWVudFR5cGUuVGV4dFxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59O1xuXG5Eb21IYW5kbGVyLnByb3RvdHlwZS5vbmNvbW1lbnQgPSBmdW5jdGlvbihkYXRhKXtcblx0dmFyIGxhc3RUYWcgPSB0aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGggLSAxXTtcblxuXHRpZihsYXN0VGFnICYmIGxhc3RUYWcudHlwZSA9PT0gRWxlbWVudFR5cGUuQ29tbWVudCl7XG5cdFx0bGFzdFRhZy5kYXRhICs9IGRhdGE7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0dmFyIGVsZW1lbnQgPSB7XG5cdFx0ZGF0YTogZGF0YSxcblx0XHR0eXBlOiBFbGVtZW50VHlwZS5Db21tZW50XG5cdH07XG5cblx0dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTtcblx0dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KTtcbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9uY2RhdGFzdGFydCA9IGZ1bmN0aW9uKCl7XG5cdHZhciBlbGVtZW50ID0ge1xuXHRcdGNoaWxkcmVuOiBbe1xuXHRcdFx0ZGF0YTogXCJcIixcblx0XHRcdHR5cGU6IEVsZW1lbnRUeXBlLlRleHRcblx0XHR9XSxcblx0XHR0eXBlOiBFbGVtZW50VHlwZS5DREFUQVxuXHR9O1xuXG5cdHRoaXMuX2FkZERvbUVsZW1lbnQoZWxlbWVudCk7XG5cdHRoaXMuX3RhZ1N0YWNrLnB1c2goZWxlbWVudCk7XG59O1xuXG5Eb21IYW5kbGVyLnByb3RvdHlwZS5vbmNvbW1lbnRlbmQgPSBEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNkYXRhZW5kID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fdGFnU3RhY2sucG9wKCk7XG59O1xuXG5Eb21IYW5kbGVyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKG5hbWUsIGRhdGEpe1xuXHR0aGlzLl9hZGREb21FbGVtZW50KHtcblx0XHRuYW1lOiBuYW1lLFxuXHRcdGRhdGE6IGRhdGEsXG5cdFx0dHlwZTogRWxlbWVudFR5cGUuRGlyZWN0aXZlXG5cdH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBEb21IYW5kbGVyO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2RvbWhhbmRsZXIvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDU0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIERPTS1MZXZlbC0xLWNvbXBsaWFudCBzdHJ1Y3R1cmVcbnZhciBOb2RlUHJvdG90eXBlID0gcmVxdWlyZSgnLi9ub2RlJyk7XG52YXIgRWxlbWVudFByb3RvdHlwZSA9IG1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZShOb2RlUHJvdG90eXBlKTtcblxudmFyIGRvbUx2bDEgPSB7XG5cdHRhZ05hbWU6IFwibmFtZVwiXG59O1xuXG5PYmplY3Qua2V5cyhkb21MdmwxKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuXHR2YXIgc2hvcnRoYW5kID0gZG9tTHZsMVtrZXldO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoRWxlbWVudFByb3RvdHlwZSwga2V5LCB7XG5cdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzW3Nob3J0aGFuZF0gfHwgbnVsbDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24odmFsKSB7XG5cdFx0XHR0aGlzW3Nob3J0aGFuZF0gPSB2YWw7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0fSk7XG59KTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9kb21oYW5kbGVyL2xpYi9lbGVtZW50LmpzXG4vLyBtb2R1bGUgaWQgPSA1NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgRG9tVXRpbHMgPSBtb2R1bGUuZXhwb3J0cztcblxuW1xuXHRyZXF1aXJlKFwiLi9saWIvc3RyaW5naWZ5XCIpLFxuXHRyZXF1aXJlKFwiLi9saWIvdHJhdmVyc2FsXCIpLFxuXHRyZXF1aXJlKFwiLi9saWIvbWFuaXB1bGF0aW9uXCIpLFxuXHRyZXF1aXJlKFwiLi9saWIvcXVlcnlpbmdcIiksXG5cdHJlcXVpcmUoXCIuL2xpYi9sZWdhY3lcIiksXG5cdHJlcXVpcmUoXCIuL2xpYi9oZWxwZXJzXCIpXG5dLmZvckVhY2goZnVuY3Rpb24oZXh0KXtcblx0T2JqZWN0LmtleXMoZXh0KS5mb3JFYWNoKGZ1bmN0aW9uKGtleSl7XG5cdFx0RG9tVXRpbHNba2V5XSA9IGV4dFtrZXldLmJpbmQoRG9tVXRpbHMpO1xuXHR9KTtcbn0pO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2RvbXV0aWxzL2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSA1NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyByZW1vdmVTdWJzZXRzXG4vLyBHaXZlbiBhbiBhcnJheSBvZiBub2RlcywgcmVtb3ZlIGFueSBtZW1iZXIgdGhhdCBpcyBjb250YWluZWQgYnkgYW5vdGhlci5cbmV4cG9ydHMucmVtb3ZlU3Vic2V0cyA9IGZ1bmN0aW9uKG5vZGVzKSB7XG5cdHZhciBpZHggPSBub2Rlcy5sZW5ndGgsIG5vZGUsIGFuY2VzdG9yLCByZXBsYWNlO1xuXG5cdC8vIENoZWNrIGlmIGVhY2ggbm9kZSAob3Igb25lIG9mIGl0cyBhbmNlc3RvcnMpIGlzIGFscmVhZHkgY29udGFpbmVkIGluIHRoZVxuXHQvLyBhcnJheS5cblx0d2hpbGUgKC0taWR4ID4gLTEpIHtcblx0XHRub2RlID0gYW5jZXN0b3IgPSBub2Rlc1tpZHhdO1xuXG5cdFx0Ly8gVGVtcG9yYXJpbHkgcmVtb3ZlIHRoZSBub2RlIHVuZGVyIGNvbnNpZGVyYXRpb25cblx0XHRub2Rlc1tpZHhdID0gbnVsbDtcblx0XHRyZXBsYWNlID0gdHJ1ZTtcblxuXHRcdHdoaWxlIChhbmNlc3Rvcikge1xuXHRcdFx0aWYgKG5vZGVzLmluZGV4T2YoYW5jZXN0b3IpID4gLTEpIHtcblx0XHRcdFx0cmVwbGFjZSA9IGZhbHNlO1xuXHRcdFx0XHRub2Rlcy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudDtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGUgbm9kZSBoYXMgYmVlbiBmb3VuZCB0byBiZSB1bmlxdWUsIHJlLWluc2VydCBpdC5cblx0XHRpZiAocmVwbGFjZSkge1xuXHRcdFx0bm9kZXNbaWR4XSA9IG5vZGU7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG5vZGVzO1xufTtcblxuLy8gU291cmNlOiBodHRwOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jZG9tLW5vZGUtY29tcGFyZWRvY3VtZW50cG9zaXRpb25cbnZhciBQT1NJVElPTiA9IHtcblx0RElTQ09OTkVDVEVEOiAxLFxuXHRQUkVDRURJTkc6IDIsXG5cdEZPTExPV0lORzogNCxcblx0Q09OVEFJTlM6IDgsXG5cdENPTlRBSU5FRF9CWTogMTZcbn07XG5cbi8vIENvbXBhcmUgdGhlIHBvc2l0aW9uIG9mIG9uZSBub2RlIGFnYWluc3QgYW5vdGhlciBub2RlIGluIGFueSBvdGhlciBkb2N1bWVudC5cbi8vIFRoZSByZXR1cm4gdmFsdWUgaXMgYSBiaXRtYXNrIHdpdGggdGhlIGZvbGxvd2luZyB2YWx1ZXM6XG4vL1xuLy8gZG9jdW1lbnQgb3JkZXI6XG4vLyA+IFRoZXJlIGlzIGFuIG9yZGVyaW5nLCBkb2N1bWVudCBvcmRlciwgZGVmaW5lZCBvbiBhbGwgdGhlIG5vZGVzIGluIHRoZVxuLy8gPiBkb2N1bWVudCBjb3JyZXNwb25kaW5nIHRvIHRoZSBvcmRlciBpbiB3aGljaCB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZVxuLy8gPiBYTUwgcmVwcmVzZW50YXRpb24gb2YgZWFjaCBub2RlIG9jY3VycyBpbiB0aGUgWE1MIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuLy8gPiBkb2N1bWVudCBhZnRlciBleHBhbnNpb24gb2YgZ2VuZXJhbCBlbnRpdGllcy4gVGh1cywgdGhlIGRvY3VtZW50IGVsZW1lbnRcbi8vID4gbm9kZSB3aWxsIGJlIHRoZSBmaXJzdCBub2RlLiBFbGVtZW50IG5vZGVzIG9jY3VyIGJlZm9yZSB0aGVpciBjaGlsZHJlbi5cbi8vID4gVGh1cywgZG9jdW1lbnQgb3JkZXIgb3JkZXJzIGVsZW1lbnQgbm9kZXMgaW4gb3JkZXIgb2YgdGhlIG9jY3VycmVuY2Ugb2Zcbi8vID4gdGhlaXIgc3RhcnQtdGFnIGluIHRoZSBYTUwgKGFmdGVyIGV4cGFuc2lvbiBvZiBlbnRpdGllcykuIFRoZSBhdHRyaWJ1dGVcbi8vID4gbm9kZXMgb2YgYW4gZWxlbWVudCBvY2N1ciBhZnRlciB0aGUgZWxlbWVudCBhbmQgYmVmb3JlIGl0cyBjaGlsZHJlbi4gVGhlXG4vLyA+IHJlbGF0aXZlIG9yZGVyIG9mIGF0dHJpYnV0ZSBub2RlcyBpcyBpbXBsZW1lbnRhdGlvbi1kZXBlbmRlbnQuL1xuLy8gU291cmNlOlxuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtQ29yZS9nbG9zc2FyeS5odG1sI2R0LWRvY3VtZW50LW9yZGVyXG4vL1xuLy8gQGFyZ3VtZW50IHtOb2RlfSBub2RhQSBUaGUgZmlyc3Qgbm9kZSB0byB1c2UgaW4gdGhlIGNvbXBhcmlzb25cbi8vIEBhcmd1bWVudCB7Tm9kZX0gbm9kZUIgVGhlIHNlY29uZCBub2RlIHRvIHVzZSBpbiB0aGUgY29tcGFyaXNvblxuLy9cbi8vIEByZXR1cm4ge051bWJlcn0gQSBiaXRtYXNrIGRlc2NyaWJpbmcgdGhlIGlucHV0IG5vZGVzJyByZWxhdGl2ZSBwb3NpdGlvbi5cbi8vICAgICAgICAgU2VlIGh0dHA6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNkb20tbm9kZS1jb21wYXJlZG9jdW1lbnRwb3NpdGlvbiBmb3Jcbi8vICAgICAgICAgYSBkZXNjcmlwdGlvbiBvZiB0aGVzZSB2YWx1ZXMuXG52YXIgY29tcGFyZVBvcyA9IGV4cG9ydHMuY29tcGFyZURvY3VtZW50UG9zaXRpb24gPSBmdW5jdGlvbihub2RlQSwgbm9kZUIpIHtcblx0dmFyIGFQYXJlbnRzID0gW107XG5cdHZhciBiUGFyZW50cyA9IFtdO1xuXHR2YXIgY3VycmVudCwgc2hhcmVkUGFyZW50LCBzaWJsaW5ncywgYVNpYmxpbmcsIGJTaWJsaW5nLCBpZHg7XG5cblx0aWYgKG5vZGVBID09PSBub2RlQikge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0Y3VycmVudCA9IG5vZGVBO1xuXHR3aGlsZSAoY3VycmVudCkge1xuXHRcdGFQYXJlbnRzLnVuc2hpZnQoY3VycmVudCk7XG5cdFx0Y3VycmVudCA9IGN1cnJlbnQucGFyZW50O1xuXHR9XG5cdGN1cnJlbnQgPSBub2RlQjtcblx0d2hpbGUgKGN1cnJlbnQpIHtcblx0XHRiUGFyZW50cy51bnNoaWZ0KGN1cnJlbnQpO1xuXHRcdGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDtcblx0fVxuXG5cdGlkeCA9IDA7XG5cdHdoaWxlIChhUGFyZW50c1tpZHhdID09PSBiUGFyZW50c1tpZHhdKSB7XG5cdFx0aWR4Kys7XG5cdH1cblxuXHRpZiAoaWR4ID09PSAwKSB7XG5cdFx0cmV0dXJuIFBPU0lUSU9OLkRJU0NPTk5FQ1RFRDtcblx0fVxuXG5cdHNoYXJlZFBhcmVudCA9IGFQYXJlbnRzW2lkeCAtIDFdO1xuXHRzaWJsaW5ncyA9IHNoYXJlZFBhcmVudC5jaGlsZHJlbjtcblx0YVNpYmxpbmcgPSBhUGFyZW50c1tpZHhdO1xuXHRiU2libGluZyA9IGJQYXJlbnRzW2lkeF07XG5cblx0aWYgKHNpYmxpbmdzLmluZGV4T2YoYVNpYmxpbmcpID4gc2libGluZ3MuaW5kZXhPZihiU2libGluZykpIHtcblx0XHRpZiAoc2hhcmVkUGFyZW50ID09PSBub2RlQikge1xuXHRcdFx0cmV0dXJuIFBPU0lUSU9OLkZPTExPV0lORyB8IFBPU0lUSU9OLkNPTlRBSU5FRF9CWTtcblx0XHR9XG5cdFx0cmV0dXJuIFBPU0lUSU9OLkZPTExPV0lORztcblx0fSBlbHNlIHtcblx0XHRpZiAoc2hhcmVkUGFyZW50ID09PSBub2RlQSkge1xuXHRcdFx0cmV0dXJuIFBPU0lUSU9OLlBSRUNFRElORyB8IFBPU0lUSU9OLkNPTlRBSU5TO1xuXHRcdH1cblx0XHRyZXR1cm4gUE9TSVRJT04uUFJFQ0VESU5HO1xuXHR9XG59O1xuXG4vLyBTb3J0IGFuIGFycmF5IG9mIG5vZGVzIGJhc2VkIG9uIHRoZWlyIHJlbGF0aXZlIHBvc2l0aW9uIGluIHRoZSBkb2N1bWVudCBhbmRcbi8vIHJlbW92ZSBhbnkgZHVwbGljYXRlIG5vZGVzLiBJZiB0aGUgYXJyYXkgY29udGFpbnMgbm9kZXMgdGhhdCBkbyBub3QgYmVsb25nXG4vLyB0byB0aGUgc2FtZSBkb2N1bWVudCwgc29ydCBvcmRlciBpcyB1bnNwZWNpZmllZC5cbi8vXG4vLyBAYXJndW1lbnQge0FycmF5fSBub2RlcyBBcnJheSBvZiBET00gbm9kZXNcbi8vXG4vLyBAcmV0dXJucyB7QXJyYXl9IGNvbGxlY3Rpb24gb2YgdW5pcXVlIG5vZGVzLCBzb3J0ZWQgaW4gZG9jdW1lbnQgb3JkZXJcbmV4cG9ydHMudW5pcXVlU29ydCA9IGZ1bmN0aW9uKG5vZGVzKSB7XG5cdHZhciBpZHggPSBub2Rlcy5sZW5ndGgsIG5vZGUsIHBvc2l0aW9uO1xuXG5cdG5vZGVzID0gbm9kZXMuc2xpY2UoKTtcblxuXHR3aGlsZSAoLS1pZHggPiAtMSkge1xuXHRcdG5vZGUgPSBub2Rlc1tpZHhdO1xuXHRcdHBvc2l0aW9uID0gbm9kZXMuaW5kZXhPZihub2RlKTtcblx0XHRpZiAocG9zaXRpb24gPiAtMSAmJiBwb3NpdGlvbiA8IGlkeCkge1xuXHRcdFx0bm9kZXMuc3BsaWNlKGlkeCwgMSk7XG5cdFx0fVxuXHR9XG5cdG5vZGVzLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuXHRcdHZhciByZWxhdGl2ZSA9IGNvbXBhcmVQb3MoYSwgYik7XG5cdFx0aWYgKHJlbGF0aXZlICYgUE9TSVRJT04uUFJFQ0VESU5HKSB7XG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0fSBlbHNlIGlmIChyZWxhdGl2ZSAmIFBPU0lUSU9OLkZPTExPV0lORykge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9KTtcblxuXHRyZXR1cm4gbm9kZXM7XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2RvbXV0aWxzL2xpYi9oZWxwZXJzLmpzXG4vLyBtb2R1bGUgaWQgPSA1N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgRWxlbWVudFR5cGUgPSByZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIik7XG52YXIgaXNUYWcgPSBleHBvcnRzLmlzVGFnID0gRWxlbWVudFR5cGUuaXNUYWc7XG5cbmV4cG9ydHMudGVzdEVsZW1lbnQgPSBmdW5jdGlvbihvcHRpb25zLCBlbGVtZW50KXtcblx0Zm9yKHZhciBrZXkgaW4gb3B0aW9ucyl7XG5cdFx0aWYoIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSk7XG5cdFx0ZWxzZSBpZihrZXkgPT09IFwidGFnX25hbWVcIil7XG5cdFx0XHRpZighaXNUYWcoZWxlbWVudCkgfHwgIW9wdGlvbnMudGFnX25hbWUoZWxlbWVudC5uYW1lKSl7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYoa2V5ID09PSBcInRhZ190eXBlXCIpe1xuXHRcdFx0aWYoIW9wdGlvbnMudGFnX3R5cGUoZWxlbWVudC50eXBlKSkgcmV0dXJuIGZhbHNlO1xuXHRcdH0gZWxzZSBpZihrZXkgPT09IFwidGFnX2NvbnRhaW5zXCIpe1xuXHRcdFx0aWYoaXNUYWcoZWxlbWVudCkgfHwgIW9wdGlvbnMudGFnX2NvbnRhaW5zKGVsZW1lbnQuZGF0YSkpe1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmKCFlbGVtZW50LmF0dHJpYnMgfHwgIW9wdGlvbnNba2V5XShlbGVtZW50LmF0dHJpYnNba2V5XSkpe1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn07XG5cbnZhciBDaGVja3MgPSB7XG5cdHRhZ19uYW1lOiBmdW5jdGlvbihuYW1lKXtcblx0XHRpZih0eXBlb2YgbmFtZSA9PT0gXCJmdW5jdGlvblwiKXtcblx0XHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuIGlzVGFnKGVsZW0pICYmIG5hbWUoZWxlbS5uYW1lKTsgfTtcblx0XHR9IGVsc2UgaWYobmFtZSA9PT0gXCIqXCIpe1xuXHRcdFx0cmV0dXJuIGlzVGFnO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oZWxlbSl7IHJldHVybiBpc1RhZyhlbGVtKSAmJiBlbGVtLm5hbWUgPT09IG5hbWU7IH07XG5cdFx0fVxuXHR9LFxuXHR0YWdfdHlwZTogZnVuY3Rpb24odHlwZSl7XG5cdFx0aWYodHlwZW9mIHR5cGUgPT09IFwiZnVuY3Rpb25cIil7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oZWxlbSl7IHJldHVybiB0eXBlKGVsZW0udHlwZSk7IH07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuIGVsZW0udHlwZSA9PT0gdHlwZTsgfTtcblx0XHR9XG5cdH0sXG5cdHRhZ19jb250YWluczogZnVuY3Rpb24oZGF0YSl7XG5cdFx0aWYodHlwZW9mIGRhdGEgPT09IFwiZnVuY3Rpb25cIil7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oZWxlbSl7IHJldHVybiAhaXNUYWcoZWxlbSkgJiYgZGF0YShlbGVtLmRhdGEpOyB9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oZWxlbSl7IHJldHVybiAhaXNUYWcoZWxlbSkgJiYgZWxlbS5kYXRhID09PSBkYXRhOyB9O1xuXHRcdH1cblx0fVxufTtcblxuZnVuY3Rpb24gZ2V0QXR0cmliQ2hlY2soYXR0cmliLCB2YWx1ZSl7XG5cdGlmKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKXtcblx0XHRyZXR1cm4gZnVuY3Rpb24oZWxlbSl7IHJldHVybiBlbGVtLmF0dHJpYnMgJiYgdmFsdWUoZWxlbS5hdHRyaWJzW2F0dHJpYl0pOyB9O1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuIGVsZW0uYXR0cmlicyAmJiBlbGVtLmF0dHJpYnNbYXR0cmliXSA9PT0gdmFsdWU7IH07XG5cdH1cbn1cblxuZnVuY3Rpb24gY29tYmluZUZ1bmNzKGEsIGIpe1xuXHRyZXR1cm4gZnVuY3Rpb24oZWxlbSl7XG5cdFx0cmV0dXJuIGEoZWxlbSkgfHwgYihlbGVtKTtcblx0fTtcbn1cblxuZXhwb3J0cy5nZXRFbGVtZW50cyA9IGZ1bmN0aW9uKG9wdGlvbnMsIGVsZW1lbnQsIHJlY3Vyc2UsIGxpbWl0KXtcblx0dmFyIGZ1bmNzID0gT2JqZWN0LmtleXMob3B0aW9ucykubWFwKGZ1bmN0aW9uKGtleSl7XG5cdFx0dmFyIHZhbHVlID0gb3B0aW9uc1trZXldO1xuXHRcdHJldHVybiBrZXkgaW4gQ2hlY2tzID8gQ2hlY2tzW2tleV0odmFsdWUpIDogZ2V0QXR0cmliQ2hlY2soa2V5LCB2YWx1ZSk7XG5cdH0pO1xuXG5cdHJldHVybiBmdW5jcy5sZW5ndGggPT09IDAgPyBbXSA6IHRoaXMuZmlsdGVyKFxuXHRcdGZ1bmNzLnJlZHVjZShjb21iaW5lRnVuY3MpLFxuXHRcdGVsZW1lbnQsIHJlY3Vyc2UsIGxpbWl0XG5cdCk7XG59O1xuXG5leHBvcnRzLmdldEVsZW1lbnRCeUlkID0gZnVuY3Rpb24oaWQsIGVsZW1lbnQsIHJlY3Vyc2Upe1xuXHRpZighQXJyYXkuaXNBcnJheShlbGVtZW50KSkgZWxlbWVudCA9IFtlbGVtZW50XTtcblx0cmV0dXJuIHRoaXMuZmluZE9uZShnZXRBdHRyaWJDaGVjayhcImlkXCIsIGlkKSwgZWxlbWVudCwgcmVjdXJzZSAhPT0gZmFsc2UpO1xufTtcblxuZXhwb3J0cy5nZXRFbGVtZW50c0J5VGFnTmFtZSA9IGZ1bmN0aW9uKG5hbWUsIGVsZW1lbnQsIHJlY3Vyc2UsIGxpbWl0KXtcblx0cmV0dXJuIHRoaXMuZmlsdGVyKENoZWNrcy50YWdfbmFtZShuYW1lKSwgZWxlbWVudCwgcmVjdXJzZSwgbGltaXQpO1xufTtcblxuZXhwb3J0cy5nZXRFbGVtZW50c0J5VGFnVHlwZSA9IGZ1bmN0aW9uKHR5cGUsIGVsZW1lbnQsIHJlY3Vyc2UsIGxpbWl0KXtcblx0cmV0dXJuIHRoaXMuZmlsdGVyKENoZWNrcy50YWdfdHlwZSh0eXBlKSwgZWxlbWVudCwgcmVjdXJzZSwgbGltaXQpO1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9kb211dGlscy9saWIvbGVnYWN5LmpzXG4vLyBtb2R1bGUgaWQgPSA1OFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJleHBvcnRzLnJlbW92ZUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtKXtcblx0aWYoZWxlbS5wcmV2KSBlbGVtLnByZXYubmV4dCA9IGVsZW0ubmV4dDtcblx0aWYoZWxlbS5uZXh0KSBlbGVtLm5leHQucHJldiA9IGVsZW0ucHJldjtcblxuXHRpZihlbGVtLnBhcmVudCl7XG5cdFx0dmFyIGNoaWxkcyA9IGVsZW0ucGFyZW50LmNoaWxkcmVuO1xuXHRcdGNoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLCAxKTtcblx0fVxufTtcblxuZXhwb3J0cy5yZXBsYWNlRWxlbWVudCA9IGZ1bmN0aW9uKGVsZW0sIHJlcGxhY2VtZW50KXtcblx0dmFyIHByZXYgPSByZXBsYWNlbWVudC5wcmV2ID0gZWxlbS5wcmV2O1xuXHRpZihwcmV2KXtcblx0XHRwcmV2Lm5leHQgPSByZXBsYWNlbWVudDtcblx0fVxuXG5cdHZhciBuZXh0ID0gcmVwbGFjZW1lbnQubmV4dCA9IGVsZW0ubmV4dDtcblx0aWYobmV4dCl7XG5cdFx0bmV4dC5wcmV2ID0gcmVwbGFjZW1lbnQ7XG5cdH1cblxuXHR2YXIgcGFyZW50ID0gcmVwbGFjZW1lbnQucGFyZW50ID0gZWxlbS5wYXJlbnQ7XG5cdGlmKHBhcmVudCl7XG5cdFx0dmFyIGNoaWxkcyA9IHBhcmVudC5jaGlsZHJlbjtcblx0XHRjaGlsZHNbY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pXSA9IHJlcGxhY2VtZW50O1xuXHR9XG59O1xuXG5leHBvcnRzLmFwcGVuZENoaWxkID0gZnVuY3Rpb24oZWxlbSwgY2hpbGQpe1xuXHRjaGlsZC5wYXJlbnQgPSBlbGVtO1xuXG5cdGlmKGVsZW0uY2hpbGRyZW4ucHVzaChjaGlsZCkgIT09IDEpe1xuXHRcdHZhciBzaWJsaW5nID0gZWxlbS5jaGlsZHJlbltlbGVtLmNoaWxkcmVuLmxlbmd0aCAtIDJdO1xuXHRcdHNpYmxpbmcubmV4dCA9IGNoaWxkO1xuXHRcdGNoaWxkLnByZXYgPSBzaWJsaW5nO1xuXHRcdGNoaWxkLm5leHQgPSBudWxsO1xuXHR9XG59O1xuXG5leHBvcnRzLmFwcGVuZCA9IGZ1bmN0aW9uKGVsZW0sIG5leHQpe1xuXHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnQsXG5cdFx0Y3Vyck5leHQgPSBlbGVtLm5leHQ7XG5cblx0bmV4dC5uZXh0ID0gY3Vyck5leHQ7XG5cdG5leHQucHJldiA9IGVsZW07XG5cdGVsZW0ubmV4dCA9IG5leHQ7XG5cdG5leHQucGFyZW50ID0gcGFyZW50O1xuXG5cdGlmKGN1cnJOZXh0KXtcblx0XHRjdXJyTmV4dC5wcmV2ID0gbmV4dDtcblx0XHRpZihwYXJlbnQpe1xuXHRcdFx0dmFyIGNoaWxkcyA9IHBhcmVudC5jaGlsZHJlbjtcblx0XHRcdGNoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGN1cnJOZXh0KSwgMCwgbmV4dCk7XG5cdFx0fVxuXHR9IGVsc2UgaWYocGFyZW50KXtcblx0XHRwYXJlbnQuY2hpbGRyZW4ucHVzaChuZXh0KTtcblx0fVxufTtcblxuZXhwb3J0cy5wcmVwZW5kID0gZnVuY3Rpb24oZWxlbSwgcHJldil7XG5cdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudDtcblx0aWYocGFyZW50KXtcblx0XHR2YXIgY2hpbGRzID0gcGFyZW50LmNoaWxkcmVuO1xuXHRcdGNoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLCAwLCBwcmV2KTtcblx0fVxuXG5cdGlmKGVsZW0ucHJldil7XG5cdFx0ZWxlbS5wcmV2Lm5leHQgPSBwcmV2O1xuXHR9XG5cdFxuXHRwcmV2LnBhcmVudCA9IHBhcmVudDtcblx0cHJldi5wcmV2ID0gZWxlbS5wcmV2O1xuXHRwcmV2Lm5leHQgPSBlbGVtO1xuXHRlbGVtLnByZXYgPSBwcmV2O1xufTtcblxuXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZG9tdXRpbHMvbGliL21hbmlwdWxhdGlvbi5qc1xuLy8gbW9kdWxlIGlkID0gNTlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGlzVGFnID0gcmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLmlzVGFnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0ZmlsdGVyOiBmaWx0ZXIsXG5cdGZpbmQ6IGZpbmQsXG5cdGZpbmRPbmVDaGlsZDogZmluZE9uZUNoaWxkLFxuXHRmaW5kT25lOiBmaW5kT25lLFxuXHRleGlzdHNPbmU6IGV4aXN0c09uZSxcblx0ZmluZEFsbDogZmluZEFsbFxufTtcblxuZnVuY3Rpb24gZmlsdGVyKHRlc3QsIGVsZW1lbnQsIHJlY3Vyc2UsIGxpbWl0KXtcblx0aWYoIUFycmF5LmlzQXJyYXkoZWxlbWVudCkpIGVsZW1lbnQgPSBbZWxlbWVudF07XG5cblx0aWYodHlwZW9mIGxpbWl0ICE9PSBcIm51bWJlclwiIHx8ICFpc0Zpbml0ZShsaW1pdCkpe1xuXHRcdGxpbWl0ID0gSW5maW5pdHk7XG5cdH1cblx0cmV0dXJuIGZpbmQodGVzdCwgZWxlbWVudCwgcmVjdXJzZSAhPT0gZmFsc2UsIGxpbWl0KTtcbn1cblxuZnVuY3Rpb24gZmluZCh0ZXN0LCBlbGVtcywgcmVjdXJzZSwgbGltaXQpe1xuXHR2YXIgcmVzdWx0ID0gW10sIGNoaWxkcztcblxuXHRmb3IodmFyIGkgPSAwLCBqID0gZWxlbXMubGVuZ3RoOyBpIDwgajsgaSsrKXtcblx0XHRpZih0ZXN0KGVsZW1zW2ldKSl7XG5cdFx0XHRyZXN1bHQucHVzaChlbGVtc1tpXSk7XG5cdFx0XHRpZigtLWxpbWl0IDw9IDApIGJyZWFrO1xuXHRcdH1cblxuXHRcdGNoaWxkcyA9IGVsZW1zW2ldLmNoaWxkcmVuO1xuXHRcdGlmKHJlY3Vyc2UgJiYgY2hpbGRzICYmIGNoaWxkcy5sZW5ndGggPiAwKXtcblx0XHRcdGNoaWxkcyA9IGZpbmQodGVzdCwgY2hpbGRzLCByZWN1cnNlLCBsaW1pdCk7XG5cdFx0XHRyZXN1bHQgPSByZXN1bHQuY29uY2F0KGNoaWxkcyk7XG5cdFx0XHRsaW1pdCAtPSBjaGlsZHMubGVuZ3RoO1xuXHRcdFx0aWYobGltaXQgPD0gMCkgYnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZmluZE9uZUNoaWxkKHRlc3QsIGVsZW1zKXtcblx0Zm9yKHZhciBpID0gMCwgbCA9IGVsZW1zLmxlbmd0aDsgaSA8IGw7IGkrKyl7XG5cdFx0aWYodGVzdChlbGVtc1tpXSkpIHJldHVybiBlbGVtc1tpXTtcblx0fVxuXG5cdHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaW5kT25lKHRlc3QsIGVsZW1zKXtcblx0dmFyIGVsZW0gPSBudWxsO1xuXG5cdGZvcih2YXIgaSA9IDAsIGwgPSBlbGVtcy5sZW5ndGg7IGkgPCBsICYmICFlbGVtOyBpKyspe1xuXHRcdGlmKCFpc1RhZyhlbGVtc1tpXSkpe1xuXHRcdFx0Y29udGludWU7XG5cdFx0fSBlbHNlIGlmKHRlc3QoZWxlbXNbaV0pKXtcblx0XHRcdGVsZW0gPSBlbGVtc1tpXTtcblx0XHR9IGVsc2UgaWYoZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoID4gMCl7XG5cdFx0XHRlbGVtID0gZmluZE9uZSh0ZXN0LCBlbGVtc1tpXS5jaGlsZHJlbik7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmZ1bmN0aW9uIGV4aXN0c09uZSh0ZXN0LCBlbGVtcyl7XG5cdGZvcih2YXIgaSA9IDAsIGwgPSBlbGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspe1xuXHRcdGlmKFxuXHRcdFx0aXNUYWcoZWxlbXNbaV0pICYmIChcblx0XHRcdFx0dGVzdChlbGVtc1tpXSkgfHwgKFxuXHRcdFx0XHRcdGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aCA+IDAgJiZcblx0XHRcdFx0XHRleGlzdHNPbmUodGVzdCwgZWxlbXNbaV0uY2hpbGRyZW4pXG5cdFx0XHRcdClcblx0XHRcdClcblx0XHQpe1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBmaW5kQWxsKHRlc3QsIGVsZW1zKXtcblx0dmFyIHJlc3VsdCA9IFtdO1xuXHRmb3IodmFyIGkgPSAwLCBqID0gZWxlbXMubGVuZ3RoOyBpIDwgajsgaSsrKXtcblx0XHRpZighaXNUYWcoZWxlbXNbaV0pKSBjb250aW51ZTtcblx0XHRpZih0ZXN0KGVsZW1zW2ldKSkgcmVzdWx0LnB1c2goZWxlbXNbaV0pO1xuXG5cdFx0aWYoZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoID4gMCl7XG5cdFx0XHRyZXN1bHQgPSByZXN1bHQuY29uY2F0KGZpbmRBbGwodGVzdCwgZWxlbXNbaV0uY2hpbGRyZW4pKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9kb211dGlscy9saWIvcXVlcnlpbmcuanNcbi8vIG1vZHVsZSBpZCA9IDYwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBFbGVtZW50VHlwZSA9IHJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKSxcbiAgICBnZXRPdXRlckhUTUwgPSByZXF1aXJlKFwiZG9tLXNlcmlhbGl6ZXJcIiksXG4gICAgaXNUYWcgPSBFbGVtZW50VHlwZS5pc1RhZztcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGdldElubmVySFRNTDogZ2V0SW5uZXJIVE1MLFxuXHRnZXRPdXRlckhUTUw6IGdldE91dGVySFRNTCxcblx0Z2V0VGV4dDogZ2V0VGV4dFxufTtcblxuZnVuY3Rpb24gZ2V0SW5uZXJIVE1MKGVsZW0sIG9wdHMpe1xuXHRyZXR1cm4gZWxlbS5jaGlsZHJlbiA/IGVsZW0uY2hpbGRyZW4ubWFwKGZ1bmN0aW9uKGVsZW0pe1xuXHRcdHJldHVybiBnZXRPdXRlckhUTUwoZWxlbSwgb3B0cyk7XG5cdH0pLmpvaW4oXCJcIikgOiBcIlwiO1xufVxuXG5mdW5jdGlvbiBnZXRUZXh0KGVsZW0pe1xuXHRpZihBcnJheS5pc0FycmF5KGVsZW0pKSByZXR1cm4gZWxlbS5tYXAoZ2V0VGV4dCkuam9pbihcIlwiKTtcblx0aWYoaXNUYWcoZWxlbSkgfHwgZWxlbS50eXBlID09PSBFbGVtZW50VHlwZS5DREFUQSkgcmV0dXJuIGdldFRleHQoZWxlbS5jaGlsZHJlbik7XG5cdGlmKGVsZW0udHlwZSA9PT0gRWxlbWVudFR5cGUuVGV4dCkgcmV0dXJuIGVsZW0uZGF0YTtcblx0cmV0dXJuIFwiXCI7XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZG9tdXRpbHMvbGliL3N0cmluZ2lmeS5qc1xuLy8gbW9kdWxlIGlkID0gNjFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGdldENoaWxkcmVuID0gZXhwb3J0cy5nZXRDaGlsZHJlbiA9IGZ1bmN0aW9uKGVsZW0pe1xuXHRyZXR1cm4gZWxlbS5jaGlsZHJlbjtcbn07XG5cbnZhciBnZXRQYXJlbnQgPSBleHBvcnRzLmdldFBhcmVudCA9IGZ1bmN0aW9uKGVsZW0pe1xuXHRyZXR1cm4gZWxlbS5wYXJlbnQ7XG59O1xuXG5leHBvcnRzLmdldFNpYmxpbmdzID0gZnVuY3Rpb24oZWxlbSl7XG5cdHZhciBwYXJlbnQgPSBnZXRQYXJlbnQoZWxlbSk7XG5cdHJldHVybiBwYXJlbnQgPyBnZXRDaGlsZHJlbihwYXJlbnQpIDogW2VsZW1dO1xufTtcblxuZXhwb3J0cy5nZXRBdHRyaWJ1dGVWYWx1ZSA9IGZ1bmN0aW9uKGVsZW0sIG5hbWUpe1xuXHRyZXR1cm4gZWxlbS5hdHRyaWJzICYmIGVsZW0uYXR0cmlic1tuYW1lXTtcbn07XG5cbmV4cG9ydHMuaGFzQXR0cmliID0gZnVuY3Rpb24oZWxlbSwgbmFtZSl7XG5cdHJldHVybiAhIWVsZW0uYXR0cmlicyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGVsZW0uYXR0cmlicywgbmFtZSk7XG59O1xuXG5leHBvcnRzLmdldE5hbWUgPSBmdW5jdGlvbihlbGVtKXtcblx0cmV0dXJuIGVsZW0ubmFtZTtcbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZG9tdXRpbHMvbGliL3RyYXZlcnNhbC5qc1xuLy8gbW9kdWxlIGlkID0gNjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGVuY29kZSA9IHJlcXVpcmUoXCIuL2xpYi9lbmNvZGUuanNcIiksXG4gICAgZGVjb2RlID0gcmVxdWlyZShcIi4vbGliL2RlY29kZS5qc1wiKTtcblxuZXhwb3J0cy5kZWNvZGUgPSBmdW5jdGlvbihkYXRhLCBsZXZlbCl7XG5cdHJldHVybiAoIWxldmVsIHx8IGxldmVsIDw9IDAgPyBkZWNvZGUuWE1MIDogZGVjb2RlLkhUTUwpKGRhdGEpO1xufTtcblxuZXhwb3J0cy5kZWNvZGVTdHJpY3QgPSBmdW5jdGlvbihkYXRhLCBsZXZlbCl7XG5cdHJldHVybiAoIWxldmVsIHx8IGxldmVsIDw9IDAgPyBkZWNvZGUuWE1MIDogZGVjb2RlLkhUTUxTdHJpY3QpKGRhdGEpO1xufTtcblxuZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbihkYXRhLCBsZXZlbCl7XG5cdHJldHVybiAoIWxldmVsIHx8IGxldmVsIDw9IDAgPyBlbmNvZGUuWE1MIDogZW5jb2RlLkhUTUwpKGRhdGEpO1xufTtcblxuZXhwb3J0cy5lbmNvZGVYTUwgPSBlbmNvZGUuWE1MO1xuXG5leHBvcnRzLmVuY29kZUhUTUw0ID1cbmV4cG9ydHMuZW5jb2RlSFRNTDUgPVxuZXhwb3J0cy5lbmNvZGVIVE1MICA9IGVuY29kZS5IVE1MO1xuXG5leHBvcnRzLmRlY29kZVhNTCA9XG5leHBvcnRzLmRlY29kZVhNTFN0cmljdCA9IGRlY29kZS5YTUw7XG5cbmV4cG9ydHMuZGVjb2RlSFRNTDQgPVxuZXhwb3J0cy5kZWNvZGVIVE1MNSA9XG5leHBvcnRzLmRlY29kZUhUTUwgPSBkZWNvZGUuSFRNTDtcblxuZXhwb3J0cy5kZWNvZGVIVE1MNFN0cmljdCA9XG5leHBvcnRzLmRlY29kZUhUTUw1U3RyaWN0ID1cbmV4cG9ydHMuZGVjb2RlSFRNTFN0cmljdCA9IGRlY29kZS5IVE1MU3RyaWN0O1xuXG5leHBvcnRzLmVzY2FwZSA9IGVuY29kZS5lc2NhcGU7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vZW50aXRpZXMvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDYzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBlbnRpdHlNYXAgPSByZXF1aXJlKFwiLi4vbWFwcy9lbnRpdGllcy5qc29uXCIpLFxuICAgIGxlZ2FjeU1hcCA9IHJlcXVpcmUoXCIuLi9tYXBzL2xlZ2FjeS5qc29uXCIpLFxuICAgIHhtbE1hcCAgICA9IHJlcXVpcmUoXCIuLi9tYXBzL3htbC5qc29uXCIpLFxuICAgIGRlY29kZUNvZGVQb2ludCA9IHJlcXVpcmUoXCIuL2RlY29kZV9jb2RlcG9pbnQuanNcIik7XG5cbnZhciBkZWNvZGVYTUxTdHJpY3QgID0gZ2V0U3RyaWN0RGVjb2Rlcih4bWxNYXApLFxuICAgIGRlY29kZUhUTUxTdHJpY3QgPSBnZXRTdHJpY3REZWNvZGVyKGVudGl0eU1hcCk7XG5cbmZ1bmN0aW9uIGdldFN0cmljdERlY29kZXIobWFwKXtcblx0dmFyIGtleXMgPSBPYmplY3Qua2V5cyhtYXApLmpvaW4oXCJ8XCIpLFxuXHQgICAgcmVwbGFjZSA9IGdldFJlcGxhY2VyKG1hcCk7XG5cblx0a2V5cyArPSBcInwjW3hYXVtcXFxcZGEtZkEtRl0rfCNcXFxcZCtcIjtcblxuXHR2YXIgcmUgPSBuZXcgUmVnRXhwKFwiJig/OlwiICsga2V5cyArIFwiKTtcIiwgXCJnXCIpO1xuXG5cdHJldHVybiBmdW5jdGlvbihzdHIpe1xuXHRcdHJldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKHJlLCByZXBsYWNlKTtcblx0fTtcbn1cblxudmFyIGRlY29kZUhUTUwgPSAoZnVuY3Rpb24oKXtcblx0dmFyIGxlZ2FjeSA9IE9iamVjdC5rZXlzKGxlZ2FjeU1hcClcblx0XHQuc29ydChzb3J0ZXIpO1xuXG5cdHZhciBrZXlzID0gT2JqZWN0LmtleXMoZW50aXR5TWFwKVxuXHRcdC5zb3J0KHNvcnRlcik7XG5cblx0Zm9yKHZhciBpID0gMCwgaiA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKXtcblx0XHRpZihsZWdhY3lbal0gPT09IGtleXNbaV0pe1xuXHRcdFx0a2V5c1tpXSArPSBcIjs/XCI7XG5cdFx0XHRqKys7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGtleXNbaV0gKz0gXCI7XCI7XG5cdFx0fVxuXHR9XG5cblx0dmFyIHJlID0gbmV3IFJlZ0V4cChcIiYoPzpcIiArIGtleXMuam9pbihcInxcIikgKyBcInwjW3hYXVtcXFxcZGEtZkEtRl0rOz98I1xcXFxkKzs/KVwiLCBcImdcIiksXG5cdCAgICByZXBsYWNlID0gZ2V0UmVwbGFjZXIoZW50aXR5TWFwKTtcblxuXHRmdW5jdGlvbiByZXBsYWNlcihzdHIpe1xuXHRcdGlmKHN0ci5zdWJzdHIoLTEpICE9PSBcIjtcIikgc3RyICs9IFwiO1wiO1xuXHRcdHJldHVybiByZXBsYWNlKHN0cik7XG5cdH1cblxuXHQvL1RPRE8gY29uc2lkZXIgY3JlYXRpbmcgYSBtZXJnZWQgbWFwXG5cdHJldHVybiBmdW5jdGlvbihzdHIpe1xuXHRcdHJldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKHJlLCByZXBsYWNlcik7XG5cdH07XG59KCkpO1xuXG5mdW5jdGlvbiBzb3J0ZXIoYSwgYil7XG5cdHJldHVybiBhIDwgYiA/IDEgOiAtMTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVwbGFjZXIobWFwKXtcblx0cmV0dXJuIGZ1bmN0aW9uIHJlcGxhY2Uoc3RyKXtcblx0XHRpZihzdHIuY2hhckF0KDEpID09PSBcIiNcIil7XG5cdFx0XHRpZihzdHIuY2hhckF0KDIpID09PSBcIlhcIiB8fCBzdHIuY2hhckF0KDIpID09PSBcInhcIil7XG5cdFx0XHRcdHJldHVybiBkZWNvZGVDb2RlUG9pbnQocGFyc2VJbnQoc3RyLnN1YnN0cigzKSwgMTYpKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBkZWNvZGVDb2RlUG9pbnQocGFyc2VJbnQoc3RyLnN1YnN0cigyKSwgMTApKTtcblx0XHR9XG5cdFx0cmV0dXJuIG1hcFtzdHIuc2xpY2UoMSwgLTEpXTtcblx0fTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdFhNTDogZGVjb2RlWE1MU3RyaWN0LFxuXHRIVE1MOiBkZWNvZGVIVE1MLFxuXHRIVE1MU3RyaWN0OiBkZWNvZGVIVE1MU3RyaWN0XG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9lbnRpdGllcy9saWIvZGVjb2RlLmpzXG4vLyBtb2R1bGUgaWQgPSA2NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgaW52ZXJzZVhNTCA9IGdldEludmVyc2VPYmoocmVxdWlyZShcIi4uL21hcHMveG1sLmpzb25cIikpLFxuICAgIHhtbFJlcGxhY2VyID0gZ2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2VYTUwpO1xuXG5leHBvcnRzLlhNTCA9IGdldEludmVyc2UoaW52ZXJzZVhNTCwgeG1sUmVwbGFjZXIpO1xuXG52YXIgaW52ZXJzZUhUTUwgPSBnZXRJbnZlcnNlT2JqKHJlcXVpcmUoXCIuLi9tYXBzL2VudGl0aWVzLmpzb25cIikpLFxuICAgIGh0bWxSZXBsYWNlciA9IGdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlSFRNTCk7XG5cbmV4cG9ydHMuSFRNTCA9IGdldEludmVyc2UoaW52ZXJzZUhUTUwsIGh0bWxSZXBsYWNlcik7XG5cbmZ1bmN0aW9uIGdldEludmVyc2VPYmoob2JqKXtcblx0cmV0dXJuIE9iamVjdC5rZXlzKG9iaikuc29ydCgpLnJlZHVjZShmdW5jdGlvbihpbnZlcnNlLCBuYW1lKXtcblx0XHRpbnZlcnNlW29ialtuYW1lXV0gPSBcIiZcIiArIG5hbWUgKyBcIjtcIjtcblx0XHRyZXR1cm4gaW52ZXJzZTtcblx0fSwge30pO1xufVxuXG5mdW5jdGlvbiBnZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZSl7XG5cdHZhciBzaW5nbGUgPSBbXSxcblx0ICAgIG11bHRpcGxlID0gW107XG5cblx0T2JqZWN0LmtleXMoaW52ZXJzZSkuZm9yRWFjaChmdW5jdGlvbihrKXtcblx0XHRpZihrLmxlbmd0aCA9PT0gMSl7XG5cdFx0XHRzaW5nbGUucHVzaChcIlxcXFxcIiArIGspO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtdWx0aXBsZS5wdXNoKGspO1xuXHRcdH1cblx0fSk7XG5cblx0Ly9UT0RPIGFkZCByYW5nZXNcblx0bXVsdGlwbGUudW5zaGlmdChcIltcIiArIHNpbmdsZS5qb2luKFwiXCIpICsgXCJdXCIpO1xuXG5cdHJldHVybiBuZXcgUmVnRXhwKG11bHRpcGxlLmpvaW4oXCJ8XCIpLCBcImdcIik7XG59XG5cbnZhciByZV9ub25BU0NJSSA9IC9bXlxcMC1cXHg3Rl0vZyxcbiAgICByZV9hc3RyYWxTeW1ib2xzID0gL1tcXHVEODAwLVxcdURCRkZdW1xcdURDMDAtXFx1REZGRl0vZztcblxuZnVuY3Rpb24gc2luZ2xlQ2hhclJlcGxhY2VyKGMpe1xuXHRyZXR1cm4gXCImI3hcIiArIGMuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSArIFwiO1wiO1xufVxuXG5mdW5jdGlvbiBhc3RyYWxSZXBsYWNlcihjKXtcblx0Ly8gaHR0cDovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC1lbmNvZGluZyNzdXJyb2dhdGUtZm9ybXVsYWVcblx0dmFyIGhpZ2ggPSBjLmNoYXJDb2RlQXQoMCk7XG5cdHZhciBsb3cgID0gYy5jaGFyQ29kZUF0KDEpO1xuXHR2YXIgY29kZVBvaW50ID0gKGhpZ2ggLSAweEQ4MDApICogMHg0MDAgKyBsb3cgLSAweERDMDAgKyAweDEwMDAwO1xuXHRyZXR1cm4gXCImI3hcIiArIGNvZGVQb2ludC50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSArIFwiO1wiO1xufVxuXG5mdW5jdGlvbiBnZXRJbnZlcnNlKGludmVyc2UsIHJlKXtcblx0ZnVuY3Rpb24gZnVuYyhuYW1lKXtcblx0XHRyZXR1cm4gaW52ZXJzZVtuYW1lXTtcblx0fVxuXG5cdHJldHVybiBmdW5jdGlvbihkYXRhKXtcblx0XHRyZXR1cm4gZGF0YVxuXHRcdFx0XHQucmVwbGFjZShyZSwgZnVuYylcblx0XHRcdFx0LnJlcGxhY2UocmVfYXN0cmFsU3ltYm9scywgYXN0cmFsUmVwbGFjZXIpXG5cdFx0XHRcdC5yZXBsYWNlKHJlX25vbkFTQ0lJLCBzaW5nbGVDaGFyUmVwbGFjZXIpO1xuXHR9O1xufVxuXG52YXIgcmVfeG1sQ2hhcnMgPSBnZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZVhNTCk7XG5cbmZ1bmN0aW9uIGVzY2FwZVhNTChkYXRhKXtcblx0cmV0dXJuIGRhdGFcblx0XHRcdC5yZXBsYWNlKHJlX3htbENoYXJzLCBzaW5nbGVDaGFyUmVwbGFjZXIpXG5cdFx0XHQucmVwbGFjZShyZV9hc3RyYWxTeW1ib2xzLCBhc3RyYWxSZXBsYWNlcilcblx0XHRcdC5yZXBsYWNlKHJlX25vbkFTQ0lJLCBzaW5nbGVDaGFyUmVwbGFjZXIpO1xufVxuXG5leHBvcnRzLmVzY2FwZSA9IGVzY2FwZVhNTDtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9lbnRpdGllcy9saWIvZW5jb2RlLmpzXG4vLyBtb2R1bGUgaWQgPSA2NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHtcblx0XCIwXCI6IDY1NTMzLFxuXHRcIjEyOFwiOiA4MzY0LFxuXHRcIjEzMFwiOiA4MjE4LFxuXHRcIjEzMVwiOiA0MDIsXG5cdFwiMTMyXCI6IDgyMjIsXG5cdFwiMTMzXCI6IDgyMzAsXG5cdFwiMTM0XCI6IDgyMjQsXG5cdFwiMTM1XCI6IDgyMjUsXG5cdFwiMTM2XCI6IDcxMCxcblx0XCIxMzdcIjogODI0MCxcblx0XCIxMzhcIjogMzUyLFxuXHRcIjEzOVwiOiA4MjQ5LFxuXHRcIjE0MFwiOiAzMzgsXG5cdFwiMTQyXCI6IDM4MSxcblx0XCIxNDVcIjogODIxNixcblx0XCIxNDZcIjogODIxNyxcblx0XCIxNDdcIjogODIyMCxcblx0XCIxNDhcIjogODIyMSxcblx0XCIxNDlcIjogODIyNixcblx0XCIxNTBcIjogODIxMSxcblx0XCIxNTFcIjogODIxMixcblx0XCIxNTJcIjogNzMyLFxuXHRcIjE1M1wiOiA4NDgyLFxuXHRcIjE1NFwiOiAzNTMsXG5cdFwiMTU1XCI6IDgyNTAsXG5cdFwiMTU2XCI6IDMzOSxcblx0XCIxNThcIjogMzgyLFxuXHRcIjE1OVwiOiAzNzZcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2VudGl0aWVzL21hcHMvZGVjb2RlLmpzb25cbi8vIG1vZHVsZSBpZCA9IDY2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKiBib290c3RyYXAtdG91ciAtIHYwLjEwLjJcclxuICogaHR0cDovL2Jvb3RzdHJhcHRvdXIuY29tXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE1IFVscmljaCBTb3Nzb3VcclxuICpcclxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZSAodGhlIFwiTGljZW5zZVwiKTtcclxuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxyXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICpcclxuICogICAgIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXHJcbiAqXHJcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcclxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxyXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cclxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxyXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cclxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqL1xyXG5cclxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqIFRoaXMgaXMgYSBtb2RpZmllZCB2ZXJzaW9uIGZvciBDbG91ZFNoYXJlXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKi9cclxuXHJcbihmdW5jdGlvbigkLCB3aW5kb3cpIHtcclxuICAgIHZhciBUb3VyLCBkb2N1bWVudDtcclxuICAgIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xyXG4gICAgVG91ciA9IChmdW5jdGlvbigpIHtcclxuICAgICAgICBmdW5jdGlvbiBUb3VyKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdmFyIHN0b3JhZ2U7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBzdG9yYWdlID0gd2luZG93LmxvY2FsU3RvcmFnZTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoX2Vycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBzdG9yYWdlID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9ICQuZXh0ZW5kKHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICd0b3VyJyxcclxuICAgICAgICAgICAgICAgIHN0ZXBzOiBbXSxcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogJ2JvZHknLFxyXG4gICAgICAgICAgICAgICAgYXV0b3Njcm9sbDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGF1dG9zY3JvbGxFbGVtZW50OiAnYm9keScsXHJcbiAgICAgICAgICAgICAgICBrZXlib2FyZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHN0b3JhZ2U6IHN0b3JhZ2UsXHJcbiAgICAgICAgICAgICAgICBkZWJ1ZzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBiYWNrZHJvcDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBiYWNrZHJvcENvbnRhaW5lcjogJ2JvZHknLFxyXG4gICAgICAgICAgICAgICAgYmFja2Ryb3BQYWRkaW5nOiAwLFxyXG4gICAgICAgICAgICAgICAgcmVkaXJlY3Q6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBvcnBoYW46IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZHVyYXRpb246IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZGVsYXk6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgYmFzZVBhdGg6ICcnLFxyXG4gICAgICAgICAgICAgICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwicG9wb3ZlclwiIHJvbGU9XCJ0b29sdGlwXCI+IDxkaXYgY2xhc3M9XCJhcnJvd1wiPjwvZGl2PiA8aDMgY2xhc3M9XCJwb3BvdmVyLXRpdGxlXCI+PC9oMz4gPGRpdiBjbGFzcz1cInBvcG92ZXItY29udGVudFwiPjwvZGl2PiA8ZGl2IGNsYXNzPVwicG9wb3Zlci1uYXZpZ2F0aW9uXCI+IDxkaXYgY2xhc3M9XCJidG4tZ3JvdXBcIj4gPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc20gYnRuLWRlZmF1bHRcIiBkYXRhLXJvbGU9XCJwcmV2XCI+JmxhcXVvOyBQcmV2PC9idXR0b24+IDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1kZWZhdWx0XCIgZGF0YS1yb2xlPVwibmV4dFwiPk5leHQgJnJhcXVvOzwvYnV0dG9uPiA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tZGVmYXVsdFwiIGRhdGEtcm9sZT1cInBhdXNlLXJlc3VtZVwiIGRhdGEtcGF1c2UtdGV4dD1cIlBhdXNlXCIgZGF0YS1yZXN1bWUtdGV4dD1cIlJlc3VtZVwiPlBhdXNlPC9idXR0b24+IDwvZGl2PiA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tZGVmYXVsdFwiIGRhdGEtcm9sZT1cImVuZFwiPkVuZCB0b3VyPC9idXR0b24+IDwvZGl2PiA8L2Rpdj4nLFxyXG4gICAgICAgICAgICAgICAgYWZ0ZXJTZXRTdGF0ZTogZnVuY3Rpb24oa2V5LCB2YWx1ZSkge30sXHJcbiAgICAgICAgICAgICAgICBhZnRlckdldFN0YXRlOiBmdW5jdGlvbihrZXksIHZhbHVlKSB7fSxcclxuICAgICAgICAgICAgICAgIGFmdGVyUmVtb3ZlU3RhdGU6IGZ1bmN0aW9uKGtleSkge30sXHJcbiAgICAgICAgICAgICAgICBvblN0YXJ0OiBmdW5jdGlvbih0b3VyKSB7fSxcclxuICAgICAgICAgICAgICAgIG9uRW5kOiBmdW5jdGlvbih0b3VyKSB7fSxcclxuICAgICAgICAgICAgICAgIG9uU2hvdzogZnVuY3Rpb24odG91cikge30sXHJcbiAgICAgICAgICAgICAgICBvblNob3duOiBmdW5jdGlvbih0b3VyKSB7fSxcclxuICAgICAgICAgICAgICAgIG9uSGlkZTogZnVuY3Rpb24odG91cikge30sXHJcbiAgICAgICAgICAgICAgICBvbkhpZGRlbjogZnVuY3Rpb24odG91cikge30sXHJcbiAgICAgICAgICAgICAgICBvbk5leHQ6IGZ1bmN0aW9uKHRvdXIpIHt9LFxyXG4gICAgICAgICAgICAgICAgb25QcmV2OiBmdW5jdGlvbih0b3VyKSB7fSxcclxuICAgICAgICAgICAgICAgIG9uUGF1c2U6IGZ1bmN0aW9uKHRvdXIsIGR1cmF0aW9uKSB7fSxcclxuICAgICAgICAgICAgICAgIG9uUmVzdW1lOiBmdW5jdGlvbih0b3VyLCBkdXJhdGlvbikge30sXHJcbiAgICAgICAgICAgICAgICBvblJlZGlyZWN0RXJyb3I6IGZ1bmN0aW9uKHRvdXIpIHt9XHJcbiAgICAgICAgICAgIH0sIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICB0aGlzLl9mb3JjZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLl9pbml0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5fY3VycmVudCA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuYmFja2Ryb3AgPSB7XHJcbiAgICAgICAgICAgICAgICBvdmVybGF5OiBudWxsLFxyXG4gICAgICAgICAgICAgICAgJGVsZW1lbnQ6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAkYmFja2dyb3VuZDogbnVsbCxcclxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRTaG93bjogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBvdmVybGF5RWxlbWVudFNob3duOiBmYWxzZVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB0aGlzLl9zY3JvbGxDYWxsYmFjayA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5hZGRTdGVwcyA9IGZ1bmN0aW9uKHN0ZXBzKSB7XHJcbiAgICAgICAgICAgIHZhciBzdGVwLCBfaSwgX2xlbjtcclxuICAgICAgICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBzdGVwcy5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgc3RlcCA9IHN0ZXBzW19pXTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWRkU3RlcChzdGVwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5hZGRTdGVwID0gZnVuY3Rpb24oc3RlcCkge1xyXG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLnN0ZXBzLnB1c2goc3RlcCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLmdldFN0ZXAgPSBmdW5jdGlvbihpKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9vcHRpb25zLnN0ZXBzW2ldICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7XHJcbiAgICAgICAgICAgICAgICAgICAgaWQ6IFwic3RlcC1cIiArIGksXHJcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogJycsXHJcbiAgICAgICAgICAgICAgICAgICAgaG9zdDogJycsXHJcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50OiAncmlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnJyxcclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiAnPHA+PC9wPicsXHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dDogaSA9PT0gdGhpcy5fb3B0aW9ucy5zdGVwcy5sZW5ndGggLSAxID8gLTEgOiBpICsgMSxcclxuICAgICAgICAgICAgICAgICAgICBwcmV2OiBpIC0gMSxcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb246IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyOiB0aGlzLl9vcHRpb25zLmNvbnRhaW5lcixcclxuICAgICAgICAgICAgICAgICAgICBhdXRvc2Nyb2xsOiB0aGlzLl9vcHRpb25zLmF1dG9zY3JvbGwsXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b3Njcm9sbEVsZW1lbnQ6IHRoaXMuX29wdGlvbnMuYXV0b3Njcm9sbEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgYmFja2Ryb3A6IHRoaXMuX29wdGlvbnMuYmFja2Ryb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgYmFja2Ryb3BDb250YWluZXI6IHRoaXMuX29wdGlvbnMuYmFja2Ryb3BDb250YWluZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgYmFja2Ryb3BQYWRkaW5nOiB0aGlzLl9vcHRpb25zLmJhY2tkcm9wUGFkZGluZyxcclxuICAgICAgICAgICAgICAgICAgICByZWRpcmVjdDogdGhpcy5fb3B0aW9ucy5yZWRpcmVjdCxcclxuICAgICAgICAgICAgICAgICAgICByZWZsZXhFbGVtZW50OiB0aGlzLl9vcHRpb25zLnN0ZXBzW2ldLmVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgb3JwaGFuOiB0aGlzLl9vcHRpb25zLm9ycGhhbixcclxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogdGhpcy5fb3B0aW9ucy5kdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICBkZWxheTogdGhpcy5fb3B0aW9ucy5kZWxheSxcclxuICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZTogdGhpcy5fb3B0aW9ucy50ZW1wbGF0ZSxcclxuICAgICAgICAgICAgICAgICAgICBvblNob3c6IHRoaXMuX29wdGlvbnMub25TaG93LFxyXG4gICAgICAgICAgICAgICAgICAgIG9uU2hvd246IHRoaXMuX29wdGlvbnMub25TaG93bixcclxuICAgICAgICAgICAgICAgICAgICBvbkhpZGU6IHRoaXMuX29wdGlvbnMub25IaWRlLFxyXG4gICAgICAgICAgICAgICAgICAgIG9uSGlkZGVuOiB0aGlzLl9vcHRpb25zLm9uSGlkZGVuLFxyXG4gICAgICAgICAgICAgICAgICAgIG9uTmV4dDogdGhpcy5fb3B0aW9ucy5vbk5leHQsXHJcbiAgICAgICAgICAgICAgICAgICAgb25QcmV2OiB0aGlzLl9vcHRpb25zLm9uUHJldixcclxuICAgICAgICAgICAgICAgICAgICBvblBhdXNlOiB0aGlzLl9vcHRpb25zLm9uUGF1c2UsXHJcbiAgICAgICAgICAgICAgICAgICAgb25SZXN1bWU6IHRoaXMuX29wdGlvbnMub25SZXN1bWUsXHJcbiAgICAgICAgICAgICAgICAgICAgb25SZWRpcmVjdEVycm9yOiB0aGlzLl9vcHRpb25zLm9uUmVkaXJlY3RFcnJvclxyXG4gICAgICAgICAgICAgICAgfSwgdGhpcy5fb3B0aW9ucy5zdGVwc1tpXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oZm9yY2UpIHtcclxuICAgICAgICAgICAgdGhpcy5fZm9yY2UgPSBmb3JjZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZW5kZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZGVidWcoJ1RvdXIgZW5kZWQsIGluaXQgcHJldmVudGVkLicpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5zZXRDdXJyZW50U3RlcCgpO1xyXG4gICAgICAgICAgICB0aGlzLnNldE5leHRTdGVwKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2luaXRNb3VzZU5hdmlnYXRpb24oKTtcclxuICAgICAgICAgICAgdGhpcy5faW5pdEtleWJvYXJkTmF2aWdhdGlvbigpO1xyXG4gICAgICAgICAgICB0aGlzLl9vblJlc2l6ZSgoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuc2hvd1N0ZXAoX3RoaXMuX2N1cnJlbnQpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSkodGhpcykpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zaG93U3RlcCh0aGlzLl9jdXJyZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9pbml0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5pc0luaXRpYWxpemVkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbml0ZWQ7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihmb3JjZSkge1xyXG4gICAgICAgICAgICB2YXIgcHJvbWlzZTtcclxuICAgICAgICAgICAgaWYgKGZvcmNlID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGZvcmNlID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9pbml0ZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdChmb3JjZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnQgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHByb21pc2UgPSB0aGlzLl9tYWtlUHJvbWlzZSh0aGlzLl9vcHRpb25zLm9uU3RhcnQgIT0gbnVsbCA/IHRoaXMuX29wdGlvbnMub25TdGFydCh0aGlzKSA6IHZvaWQgMCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9jYWxsT25Qcm9taXNlRG9uZShwcm9taXNlLCB0aGlzLnNob3dTdGVwLCAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciBwcm9taXNlO1xyXG4gICAgICAgICAgICBwcm9taXNlID0gdGhpcy5oaWRlU3RlcCh0aGlzLl9jdXJyZW50KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGxPblByb21pc2VEb25lKHByb21pc2UsIHRoaXMuX3Nob3dOZXh0U3RlcCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUucHJldiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICB2YXIgcHJvbWlzZTtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHRoaXMuaGlkZVN0ZXAodGhpcy5fY3VycmVudCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYWxsT25Qcm9taXNlRG9uZShwcm9taXNlLCB0aGlzLl9zaG93UHJldlN0ZXApO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLmdvVG8gPSBmdW5jdGlvbihpKSB7XHJcbiAgICAgICAgICAgIHZhciBwcm9taXNlO1xyXG4gICAgICAgICAgICBwcm9taXNlID0gdGhpcy5oaWRlU3RlcCh0aGlzLl9jdXJyZW50KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGxPblByb21pc2VEb25lKHByb21pc2UsIHRoaXMuc2hvd1N0ZXAsIGkpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICB2YXIgZW5kSGVscGVyLCBwcm9taXNlO1xyXG4gICAgICAgICAgICBlbmRIZWxwZXIgPSAoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgJChkb2N1bWVudCkub2ZmKFwiY2xpY2sudG91ci1cIiArIF90aGlzLl9vcHRpb25zLm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICQoZG9jdW1lbnQpLm9mZihcImtleXVwLnRvdXItXCIgKyBfdGhpcy5fb3B0aW9ucy5uYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAkKHdpbmRvdykub2ZmKFwicmVzaXplLnRvdXItXCIgKyBfdGhpcy5fb3B0aW9ucy5uYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3NldFN0YXRlKCdlbmQnLCAneWVzJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2luaXRlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9mb3JjZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9jbGVhclRpbWVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLl9vcHRpb25zLm9uRW5kICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLl9vcHRpb25zLm9uRW5kKF90aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9KSh0aGlzKTtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHRoaXMuaGlkZVN0ZXAodGhpcy5fY3VycmVudCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYWxsT25Qcm9taXNlRG9uZShwcm9taXNlLCBlbmRIZWxwZXIpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLmVuZGVkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAhdGhpcy5fZm9yY2UgJiYgISF0aGlzLl9nZXRTdGF0ZSgnZW5kJyk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUucmVzdGFydCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVTdGF0ZSgnY3VycmVudF9zdGVwJyk7XHJcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZVN0YXRlKCdlbmQnKTtcclxuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlU3RhdGUoJ3JlZGlyZWN0X3RvJyk7XHJcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydCgpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciBzdGVwO1xyXG4gICAgICAgICAgICBzdGVwID0gdGhpcy5nZXRTdGVwKHRoaXMuX2N1cnJlbnQpO1xyXG4gICAgICAgICAgICBpZiAoIShzdGVwICYmIHN0ZXAuZHVyYXRpb24pKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9wYXVzZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLl9kdXJhdGlvbiAtPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuX3N0YXJ0O1xyXG4gICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcclxuICAgICAgICAgICAgdGhpcy5fZGVidWcoXCJQYXVzZWQvU3RvcHBlZCBzdGVwIFwiICsgKHRoaXMuX2N1cnJlbnQgKyAxKSArIFwiIHRpbWVyIChcIiArIHRoaXMuX2R1cmF0aW9uICsgXCIgcmVtYWluaW5nKS5cIik7XHJcbiAgICAgICAgICAgIGlmIChzdGVwLm9uUGF1c2UgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0ZXAub25QYXVzZSh0aGlzLCB0aGlzLl9kdXJhdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdmFyIHN0ZXA7XHJcbiAgICAgICAgICAgIHN0ZXAgPSB0aGlzLmdldFN0ZXAodGhpcy5fY3VycmVudCk7XHJcbiAgICAgICAgICAgIGlmICghKHN0ZXAgJiYgc3RlcC5kdXJhdGlvbikpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3BhdXNlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGFydCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICAgICAgICB0aGlzLl9kdXJhdGlvbiA9IHRoaXMuX2R1cmF0aW9uIHx8IHN0ZXAuZHVyYXRpb247XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldFRpbWVvdXQoKGZ1bmN0aW9uKF90aGlzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLl9pc0xhc3QoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMubmV4dCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbmQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9KSh0aGlzKSwgdGhpcy5fZHVyYXRpb24pO1xyXG4gICAgICAgICAgICB0aGlzLl9kZWJ1ZyhcIlN0YXJ0ZWQgc3RlcCBcIiArICh0aGlzLl9jdXJyZW50ICsgMSkgKyBcIiB0aW1lciB3aXRoIGR1cmF0aW9uIFwiICsgdGhpcy5fZHVyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoKHN0ZXAub25SZXN1bWUgIT0gbnVsbCkgJiYgdGhpcy5fZHVyYXRpb24gIT09IHN0ZXAuZHVyYXRpb24pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzdGVwLm9uUmVzdW1lKHRoaXMsIHRoaXMuX2R1cmF0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLmhpZGVTdGVwID0gZnVuY3Rpb24oaSkge1xyXG4gICAgICAgICAgICB2YXIgaGlkZVN0ZXBIZWxwZXIsIHByb21pc2UsIHN0ZXA7XHJcbiAgICAgICAgICAgIHN0ZXAgPSB0aGlzLmdldFN0ZXAoaSk7XHJcbiAgICAgICAgICAgIGlmICghc3RlcCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZU9uU2Nyb2xsKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX2NsZWFyVGltZXIoKTtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHRoaXMuX21ha2VQcm9taXNlKHN0ZXAub25IaWRlICE9IG51bGwgPyBzdGVwLm9uSGlkZSh0aGlzLCBpKSA6IHZvaWQgMCk7XHJcbiAgICAgICAgICAgIGhpZGVTdGVwSGVscGVyID0gKGZ1bmN0aW9uKF90aGlzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciAkZWxlbWVudDtcclxuICAgICAgICAgICAgICAgICAgICAkZWxlbWVudCA9IHN0ZXAub3JwaGFuID8gJChcImJvZHlcIikgOiAkKHN0ZXAuZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoJGVsZW1lbnQuZGF0YSgnYnMucG9wb3ZlcicpIHx8ICRlbGVtZW50LmRhdGEoJ3BvcG92ZXInKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnQgPSAkKFwiLnRvdXItXCIgKyBfdGhpcy5fb3B0aW9ucy5uYW1lICsgXCIudG91ci1cIiArIF90aGlzLl9vcHRpb25zLm5hbWUgKyBcIi1cIiArIGkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5yZW1vdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnQucG9wb3ZlcignZGVzdHJveScpLnJlbW92ZUNsYXNzKFwidG91ci1cIiArIF90aGlzLl9vcHRpb25zLm5hbWUgKyBcIi1lbGVtZW50IHRvdXItXCIgKyBfdGhpcy5fb3B0aW9ucy5uYW1lICsgXCItXCIgKyBpICsgXCItZWxlbWVudFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5yZW1vdmVEYXRhKCdicy5wb3BvdmVyJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0ZXAucmVmbGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICQoc3RlcC5yZWZsZXhFbGVtZW50KS5yZW1vdmVDbGFzcygndG91ci1zdGVwLWVsZW1lbnQtcmVmbGV4Jykub2ZmKFwiXCIgKyAoX3RoaXMuX3JlZmxleEV2ZW50KHN0ZXAucmVmbGV4KSkgKyBcIi50b3VyLVwiICsgX3RoaXMuX29wdGlvbnMubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGVwLmJhY2tkcm9wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLl9oaWRlQmFja2Ryb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0ZXAub25IaWRkZW4gIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RlcC5vbkhpZGRlbihfdGhpcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSkodGhpcyk7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxPblByb21pc2VEb25lKHByb21pc2UsIGhpZGVTdGVwSGVscGVyKTtcclxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuc2hvd1N0ZXAgPSBmdW5jdGlvbihpLCBkaXNhYmxlQXV0b1Njcm9sbCkge1xyXG4gICAgICAgICAgICB2YXIgcHJvbWlzZSwgc2hvd1N0ZXBIZWxwZXIsIHNraXBUb1ByZXZpb3VzLCBzdGVwO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5lbmRlZCgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9kZWJ1ZygnVG91ciBlbmRlZCwgc2hvd1N0ZXAgcHJldmVudGVkLicpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc3RlcCA9IHRoaXMuZ2V0U3RlcChpKTtcclxuICAgICAgICAgICAgaWYgKCFzdGVwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzT3JwaGFuKHN0ZXApICYmIHN0ZXAub3B0aW9uYWwgJiYgIXN0ZXAub3JwaGFuKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaG93U3RlcChpICsgMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2tpcFRvUHJldmlvdXMgPSBpIDwgdGhpcy5fY3VycmVudDtcclxuICAgICAgICAgICAgdGhpcy5zZXROZXh0U3RlcChpKTtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHRoaXMuX21ha2VQcm9taXNlKHN0ZXAub25TaG93ICE9IG51bGwgPyBzdGVwLm9uU2hvdyh0aGlzLCBpKSA6IHZvaWQgMCk7XHJcbiAgICAgICAgICAgIHNob3dTdGVwSGVscGVyID0gKGZ1bmN0aW9uKF90aGlzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXRoLCBzaG93UG9wb3ZlckFuZE92ZXJsYXk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0Q3VycmVudFN0ZXAoaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcGF0aCA9IChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh7fS50b1N0cmluZy5jYWxsKHN0ZXAucGF0aCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1tvYmplY3QgRnVuY3Rpb25dJzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RlcC5wYXRoKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdbb2JqZWN0IFN0cmluZ10nOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcHRpb25zLmJhc2VQYXRoICsgc3RlcC5wYXRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RlcC5wYXRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSkuY2FsbChfdGhpcyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy5faXNSZWRpcmVjdChzdGVwLmhvc3QsIHBhdGgsIGRvY3VtZW50LmxvY2F0aW9uKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5fcmVkaXJlY3Qoc3RlcCwgaSwgcGF0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3RoaXMuX2lzSnVzdFBhdGhIYXNoRGlmZmVyZW50KHN0ZXAuaG9zdCwgcGF0aCwgZG9jdW1lbnQubG9jYXRpb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLl9pc09ycGhhbihzdGVwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RlcC5vcnBoYW4gPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5fZGVidWcoXCJTdG9wIGF0IG9ycGhhbiBzdGVwIFwiICsgKF90aGlzLl9jdXJyZW50ICsgMSkgKyBcIi5cXG5PcnBoYW4gb3B0aW9uIGlzIGZhbHNlIGFuZCB0aGUgZWxlbWVudCBkb2VzIG5vdCBleGlzdCBvciBpcyBoaWRkZW4uXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLl9kZWJ1ZyhcIlNob3cgdGhlIG9ycGhhbiBzdGVwIFwiICsgKF90aGlzLl9jdXJyZW50ICsgMSkgKyBcIi4gT3JwaGFuIG9wdGlvbiBpcyB0cnVlLlwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0ZXAuYmFja2Ryb3ApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3Nob3dCYWNrZHJvcChzdGVwKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgc2hvd1BvcG92ZXJBbmRPdmVybGF5ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy5nZXRDdXJyZW50U3RlcCgpICE9PSBpIHx8IF90aGlzLmVuZGVkKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHN0ZXAuZWxlbWVudCAhPSBudWxsKSAmJiBzdGVwLmJhY2tkcm9wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5fc2hvd092ZXJsYXlFbGVtZW50KHN0ZXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLl9zaG93UG9wb3ZlcihzdGVwLCBpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3NldFNob3dTdGVwT25TY3JvbGwoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0ZXAub25TaG93biAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwLm9uU2hvd24oX3RoaXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5fZGVidWcoXCJTdGVwIFwiICsgKF90aGlzLl9jdXJyZW50ICsgMSkgKyBcIiBvZiBcIiArIF90aGlzLl9vcHRpb25zLnN0ZXBzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWRpc2FibGVBdXRvU2Nyb2xsICYmIHN0ZXAuYXV0b3Njcm9sbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5fc2Nyb2xsSW50b1ZpZXcoc3RlcC5lbGVtZW50LCBzaG93UG9wb3ZlckFuZE92ZXJsYXksIHN0ZXAuYXV0b3Njcm9sbEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dQb3BvdmVyQW5kT3ZlcmxheSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RlcC5kdXJhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMucmVzdW1lKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSkodGhpcyk7XHJcbiAgICAgICAgICAgIGlmIChzdGVwLmRlbGF5KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9kZWJ1ZyhcIldhaXQgXCIgKyBzdGVwLmRlbGF5ICsgXCIgbWlsbGlzZWNvbmRzIHRvIHNob3cgdGhlIHN0ZXAgXCIgKyAodGhpcy5fY3VycmVudCArIDEpKTtcclxuICAgICAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KChmdW5jdGlvbihfdGhpcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLl9jYWxsT25Qcm9taXNlRG9uZShwcm9taXNlLCBzaG93U3RlcEhlbHBlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH0pKHRoaXMpLCBzdGVwLmRlbGF5KTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxPblByb21pc2VEb25lKHByb21pc2UsIHNob3dTdGVwSGVscGVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5nZXRDdXJyZW50U3RlcCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudCA9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDdXJyZW50U3RlcCgpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5zZXRDdXJyZW50U3RlcCA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9jdXJyZW50ID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdGF0ZSgnY3VycmVudF9zdGVwJywgdmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY3VycmVudCA9IHRoaXMuX2dldFN0YXRlKCdjdXJyZW50X3N0ZXAnKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9jdXJyZW50ID09PSBudWxsID8gbnVsbCA6IHBhcnNlSW50KHRoaXMuX2N1cnJlbnQsIDEwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5nZXROZXh0U3RlcCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fbmV4dCA9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXROZXh0U3RlcCgpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmV4dDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5zZXROZXh0U3RlcCA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9uZXh0ID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdGF0ZSgnbmV4dF9zdGVwJywgdmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbmV4dCA9IHRoaXMuX2dldFN0YXRlKCduZXh0X3N0ZXAnKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX25leHQgPSB0aGlzLl9uZXh0ID09PSBudWxsID8gbnVsbCA6IHBhcnNlSW50KHRoaXMuX25leHQsIDEwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5yZWRyYXcgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Nob3dPdmVybGF5RWxlbWVudCh0aGlzLmdldFN0ZXAodGhpcy5nZXRDdXJyZW50U3RlcCgpKS5lbGVtZW50LCB0cnVlKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fc2V0U3RhdGUgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHZhciBlLCBrZXlOYW1lO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5zdG9yYWdlKSB7XHJcbiAgICAgICAgICAgICAgICBrZXlOYW1lID0gXCJcIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiX1wiICsga2V5O1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcHRpb25zLnN0b3JhZ2Uuc2V0SXRlbShrZXlOYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChfZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBlID0gX2Vycm9yO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlLmNvZGUgPT09IERPTUV4Y2VwdGlvbi5RVU9UQV9FWENFRURFRF9FUlIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGVidWcoJ0xvY2FsU3RvcmFnZSBxdW90YSBleGNlZWRlZC4gU3RhdGUgc3RvcmFnZSBmYWlsZWQuJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuYWZ0ZXJTZXRTdGF0ZShrZXlOYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0ge307XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGVba2V5XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX3JlbW92ZVN0YXRlID0gZnVuY3Rpb24oa2V5KSB7XHJcbiAgICAgICAgICAgIHZhciBrZXlOYW1lO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5zdG9yYWdlKSB7XHJcbiAgICAgICAgICAgICAgICBrZXlOYW1lID0gXCJcIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiX1wiICsga2V5O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5zdG9yYWdlLnJlbW92ZUl0ZW0oa2V5TmFtZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fb3B0aW9ucy5hZnRlclJlbW92ZVN0YXRlKGtleU5hbWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsZXRlIHRoaXMuX3N0YXRlW2tleV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fZ2V0U3RhdGUgPSBmdW5jdGlvbihrZXkpIHtcclxuICAgICAgICAgICAgdmFyIGtleU5hbWUsIHZhbHVlO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5zdG9yYWdlKSB7XHJcbiAgICAgICAgICAgICAgICBrZXlOYW1lID0gXCJcIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiX1wiICsga2V5O1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9vcHRpb25zLnN0b3JhZ2UuZ2V0SXRlbShrZXlOYW1lKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9zdGF0ZVtrZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdm9pZCAwIHx8IHZhbHVlID09PSAnbnVsbCcpIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLmFmdGVyR2V0U3RhdGUoa2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fc2hvd05leHRTdGVwID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciBwcm9taXNlLCBzaG93TmV4dFN0ZXBIZWxwZXIsIHN0ZXA7XHJcbiAgICAgICAgICAgIHN0ZXAgPSB0aGlzLmdldFN0ZXAodGhpcy5fY3VycmVudCk7XHJcbiAgICAgICAgICAgIHNob3dOZXh0U3RlcEhlbHBlciA9IChmdW5jdGlvbihfdGhpcykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuc2hvd1N0ZXAoc3RlcC5uZXh0KTtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0pKHRoaXMpO1xyXG4gICAgICAgICAgICBwcm9taXNlID0gdGhpcy5fbWFrZVByb21pc2Uoc3RlcC5vbk5leHQgIT0gbnVsbCA/IHN0ZXAub25OZXh0KHRoaXMpIDogdm9pZCAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGxPblByb21pc2VEb25lKHByb21pc2UsIHNob3dOZXh0U3RlcEhlbHBlcik7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX3Nob3dQcmV2U3RlcCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICB2YXIgcHJvbWlzZSwgc2hvd1ByZXZTdGVwSGVscGVyLCBzdGVwO1xyXG4gICAgICAgICAgICBzdGVwID0gdGhpcy5nZXRTdGVwKHRoaXMuX2N1cnJlbnQpO1xyXG4gICAgICAgICAgICBzaG93UHJldlN0ZXBIZWxwZXIgPSAoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLnNob3dTdGVwKHN0ZXAucHJldik7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9KSh0aGlzKTtcclxuICAgICAgICAgICAgcHJvbWlzZSA9IHRoaXMuX21ha2VQcm9taXNlKHN0ZXAub25QcmV2ICE9IG51bGwgPyBzdGVwLm9uUHJldih0aGlzKSA6IHZvaWQgMCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jYWxsT25Qcm9taXNlRG9uZShwcm9taXNlLCBzaG93UHJldlN0ZXBIZWxwZXIpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKHRleHQpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuZGVidWcpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB3aW5kb3cuY29uc29sZS5sb2coXCJCb290c3RyYXAgVG91ciAnXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUgKyBcIicgfCBcIiArIHRleHQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2lzUmVkaXJlY3QgPSBmdW5jdGlvbihob3N0LCBwYXRoLCBsb2NhdGlvbikge1xyXG4gICAgICAgICAgICB2YXIgY3VycmVudFBhdGg7XHJcbiAgICAgICAgICAgIGlmIChob3N0ICE9PSAnJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzSG9zdERpZmZlcmVudChob3N0LCBsb2NhdGlvbi5ocmVmKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGN1cnJlbnRQYXRoID0gW2xvY2F0aW9uLnBhdGhuYW1lLCBsb2NhdGlvbi5zZWFyY2gsIGxvY2F0aW9uLmhhc2hdLmpvaW4oJycpO1xyXG4gICAgICAgICAgICByZXR1cm4gKHBhdGggIT0gbnVsbCkgJiYgcGF0aCAhPT0gJycgJiYgKCh7fS50b1N0cmluZy5jYWxsKHBhdGgpID09PSAnW29iamVjdCBSZWdFeHBdJyAmJiAhcGF0aC50ZXN0KGN1cnJlbnRQYXRoKSkgfHwgKHt9LnRvU3RyaW5nLmNhbGwocGF0aCkgPT09ICdbb2JqZWN0IFN0cmluZ10nICYmIHRoaXMuX2lzUGF0aERpZmZlcmVudChwYXRoLCBjdXJyZW50UGF0aCkpKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5faXNIb3N0RGlmZmVyZW50ID0gZnVuY3Rpb24oaG9zdCwgY3VycmVudFVSTCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UHJvdG9jb2woaG9zdCkgIT09IHRoaXMuX2dldFByb3RvY29sKGN1cnJlbnRVUkwpIHx8IHRoaXMuX2dldEhvc3QoaG9zdCkgIT09IHRoaXMuX2dldEhvc3QoY3VycmVudFVSTCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2lzUGF0aERpZmZlcmVudCA9IGZ1bmN0aW9uKHBhdGgsIGN1cnJlbnRQYXRoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRQYXRoKHBhdGgpICE9PSB0aGlzLl9nZXRQYXRoKGN1cnJlbnRQYXRoKSB8fCAhdGhpcy5fZXF1YWwodGhpcy5fZ2V0UXVlcnkocGF0aCksIHRoaXMuX2dldFF1ZXJ5KGN1cnJlbnRQYXRoKSkgfHwgIXRoaXMuX2VxdWFsKHRoaXMuX2dldEhhc2gocGF0aCksIHRoaXMuX2dldEhhc2goY3VycmVudFBhdGgpKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5faXNKdXN0UGF0aEhhc2hEaWZmZXJlbnQgPSBmdW5jdGlvbihob3N0LCBwYXRoLCBsb2NhdGlvbikge1xyXG4gICAgICAgICAgICB2YXIgY3VycmVudFBhdGg7XHJcbiAgICAgICAgICAgIGlmIChob3N0ICE9PSAnJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzSG9zdERpZmZlcmVudChob3N0LCBsb2NhdGlvbi5ocmVmKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjdXJyZW50UGF0aCA9IFtsb2NhdGlvbi5wYXRobmFtZSwgbG9jYXRpb24uc2VhcmNoLCBsb2NhdGlvbi5oYXNoXS5qb2luKCcnKTtcclxuICAgICAgICAgICAgaWYgKHt9LnRvU3RyaW5nLmNhbGwocGF0aCkgPT09ICdbb2JqZWN0IFN0cmluZ10nKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UGF0aChwYXRoKSA9PT0gdGhpcy5fZ2V0UGF0aChjdXJyZW50UGF0aCkgJiYgdGhpcy5fZXF1YWwodGhpcy5fZ2V0UXVlcnkocGF0aCksIHRoaXMuX2dldFF1ZXJ5KGN1cnJlbnRQYXRoKSkgJiYgIXRoaXMuX2VxdWFsKHRoaXMuX2dldEhhc2gocGF0aCksIHRoaXMuX2dldEhhc2goY3VycmVudFBhdGgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX3JlZGlyZWN0ID0gZnVuY3Rpb24oc3RlcCwgaSwgcGF0aCkge1xyXG4gICAgICAgICAgICBpZiAoJC5pc0Z1bmN0aW9uKHN0ZXAucmVkaXJlY3QpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RlcC5yZWRpcmVjdC5jYWxsKHRoaXMsIHBhdGgpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0ZXAucmVkaXJlY3QgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2RlYnVnKFwiUmVkaXJlY3QgdG8gXCIgKyBzdGVwLmhvc3QgKyBwYXRoKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9nZXRTdGF0ZSgncmVkaXJlY3RfdG8nKSA9PT0gKFwiXCIgKyBpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2RlYnVnKFwiRXJyb3IgcmVkaXJlY3Rpb24gbG9vcCB0byBcIiArIHBhdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZVN0YXRlKCdyZWRpcmVjdF90bycpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGVwLm9uUmVkaXJlY3RFcnJvciAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGVwLm9uUmVkaXJlY3RFcnJvcih0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFN0YXRlKCdyZWRpcmVjdF90bycsIFwiXCIgKyBpKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQubG9jYXRpb24uaHJlZiA9IFwiXCIgKyBzdGVwLmhvc3QgKyBwYXRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2lzT3JwaGFuID0gZnVuY3Rpb24oc3RlcCkge1xyXG4gICAgICAgICAgICByZXR1cm4gKHN0ZXAuZWxlbWVudCA9PSBudWxsKSB8fCAhJChzdGVwLmVsZW1lbnQpLmxlbmd0aCB8fCAkKHN0ZXAuZWxlbWVudCkuaXMoJzpoaWRkZW4nKSAmJiAoJChzdGVwLmVsZW1lbnQpWzBdLm5hbWVzcGFjZVVSSSAhPT0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2lzTGFzdCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudCA8IHRoaXMuX29wdGlvbnMuc3RlcHMubGVuZ3RoIC0gMTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fc2hvd1BvcG92ZXIgPSBmdW5jdGlvbihzdGVwLCBpKSB7XHJcbiAgICAgICAgICAgIHZhciAkZWxlbWVudCwgJHRpcCwgaXNPcnBoYW4sIG9wdGlvbnMsIHNob3VsZEFkZFNtYXJ0O1xyXG4gICAgICAgICAgICAkKFwiLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUpLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICBvcHRpb25zID0gJC5leHRlbmQoe30sIHRoaXMuX29wdGlvbnMpO1xyXG4gICAgICAgICAgICBpZiAoc3RlcC5vcnBoYW4gJiYgc3RlcC5lbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoJChzdGVwLmVsZW1lbnQpLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpc09ycGhhbiA9IHN0ZXAub3JwaGFuIHx8IHRoaXMuX2lzT3JwaGFuKHN0ZXApO1xyXG4gICAgICAgICAgICBzdGVwLnRlbXBsYXRlID0gdGhpcy5fdGVtcGxhdGUoc3RlcCwgaSk7XHJcbiAgICAgICAgICAgIGlmIChpc09ycGhhbikge1xyXG4gICAgICAgICAgICAgICAgc3RlcC5lbGVtZW50ID0gJ2JvZHknO1xyXG4gICAgICAgICAgICAgICAgc3RlcC5wbGFjZW1lbnQgPSAndG9wJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAkZWxlbWVudCA9ICQoc3RlcC5lbGVtZW50KTtcclxuICAgICAgICAgICAgJGVsZW1lbnQuYWRkQ2xhc3MoXCJ0b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lICsgXCItZWxlbWVudCB0b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lICsgXCItXCIgKyBpICsgXCItZWxlbWVudFwiKTtcclxuICAgICAgICAgICAgaWYgKHN0ZXAub3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgJC5leHRlbmQob3B0aW9ucywgc3RlcC5vcHRpb25zKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc3RlcC5yZWZsZXggJiYgIWlzT3JwaGFuKSB7XHJcbiAgICAgICAgICAgICAgICAkKHN0ZXAucmVmbGV4RWxlbWVudCkuYWRkQ2xhc3MoJ3RvdXItc3RlcC1lbGVtZW50LXJlZmxleCcpLm9mZihcIlwiICsgKHRoaXMuX3JlZmxleEV2ZW50KHN0ZXAucmVmbGV4KSkgKyBcIi50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lKS5vbihcIlwiICsgKHRoaXMuX3JlZmxleEV2ZW50KHN0ZXAucmVmbGV4KSkgKyBcIi50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lLCAoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy5faXNMYXN0KCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5uZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuZW5kKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSkodGhpcykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHNob3VsZEFkZFNtYXJ0ID0gc3RlcC5zbWFydFBsYWNlbWVudCA9PT0gdHJ1ZSAmJiBzdGVwLnBsYWNlbWVudC5zZWFyY2goL2F1dG8vaSkgPT09IC0xO1xyXG4gICAgICAgICAgICAkZWxlbWVudC5wb3BvdmVyKHtcclxuICAgICAgICAgICAgICAgIHBsYWNlbWVudDogc2hvdWxkQWRkU21hcnQgPyBcImF1dG8gXCIgKyBzdGVwLnBsYWNlbWVudCA6IHN0ZXAucGxhY2VtZW50LFxyXG4gICAgICAgICAgICAgICAgdHJpZ2dlcjogJ21hbnVhbCcsXHJcbiAgICAgICAgICAgICAgICB0aXRsZTogc3RlcC50aXRsZSxcclxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHN0ZXAuY29udGVudCxcclxuICAgICAgICAgICAgICAgIGh0bWw6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBhbmltYXRpb246IHN0ZXAuYW5pbWF0aW9uLFxyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyOiBzdGVwLmNvbnRhaW5lcixcclxuICAgICAgICAgICAgICAgIHRlbXBsYXRlOiBzdGVwLnRlbXBsYXRlLFxyXG4gICAgICAgICAgICAgICAgc2VsZWN0b3I6IHN0ZXAuZWxlbWVudFxyXG4gICAgICAgICAgICB9KS5wb3BvdmVyKCdzaG93Jyk7XHJcbiAgICAgICAgICAgICR0aXAgPSAkZWxlbWVudC5kYXRhKCdicy5wb3BvdmVyJykgPyAkZWxlbWVudC5kYXRhKCdicy5wb3BvdmVyJykudGlwKCkgOiAkZWxlbWVudC5kYXRhKCdwb3BvdmVyJykudGlwKCk7XHJcbiAgICAgICAgICAgICR0aXAuYXR0cignaWQnLCBzdGVwLmlkKTtcclxuICAgICAgICAgICAgaWYgKHN0ZXAud2lkdGgpXHJcbiAgICAgICAgICAgICAgICAkdGlwLmNzcyhcIm1heC13aWR0aFwiLCBzdGVwLndpZHRoKTtcclxuICAgICAgICAgICAgdGhpcy5fcmVwb3NpdGlvbigkdGlwLCBzdGVwKTtcclxuICAgICAgICAgICAgaWYgKGlzT3JwaGFuKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2VudGVyKCR0aXApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX3RlbXBsYXRlID0gZnVuY3Rpb24oc3RlcCwgaSkge1xyXG4gICAgICAgICAgICB2YXIgJG5hdmlnYXRpb24sICRuZXh0LCAkcHJldiwgJHJlc3VtZSwgJHRlbXBsYXRlLCB0ZW1wbGF0ZSwgaXNPcnBoYW47XHJcbiAgICAgICAgICAgIGlzT3JwaGFuID0gc3RlcC5vcnBoYW4gfHwgdGhpcy5faXNPcnBoYW4oc3RlcCk7XHJcbiAgICAgICAgICAgIHRlbXBsYXRlID0gc3RlcC50ZW1wbGF0ZTtcclxuICAgICAgICAgICAgaWYgKGlzT3JwaGFuICYmIHt9LnRvU3RyaW5nLmNhbGwoc3RlcC5vcnBoYW4pICE9PSAnW29iamVjdCBCb29sZWFuXScpIHtcclxuICAgICAgICAgICAgICAgIHRlbXBsYXRlID0gc3RlcC5vcnBoYW47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgJHRlbXBsYXRlID0gJC5pc0Z1bmN0aW9uKHRlbXBsYXRlKSA/ICQodGVtcGxhdGUoaSwgc3RlcCkpIDogJCh0ZW1wbGF0ZSk7XHJcbiAgICAgICAgICAgICRuYXZpZ2F0aW9uID0gJHRlbXBsYXRlLmZpbmQoJy5wb3BvdmVyLW5hdmlnYXRpb24nKTtcclxuICAgICAgICAgICAgJHByZXYgPSAkbmF2aWdhdGlvbi5maW5kKCdbZGF0YS1yb2xlPVwicHJldlwiXScpO1xyXG4gICAgICAgICAgICAkbmV4dCA9ICRuYXZpZ2F0aW9uLmZpbmQoJ1tkYXRhLXJvbGU9XCJuZXh0XCJdJyk7XHJcbiAgICAgICAgICAgICRyZXN1bWUgPSAkbmF2aWdhdGlvbi5maW5kKCdbZGF0YS1yb2xlPVwicGF1c2UtcmVzdW1lXCJdJyk7XHJcbiAgICAgICAgICAgIGlmIChpc09ycGhhbikge1xyXG4gICAgICAgICAgICAgICAgJHRlbXBsYXRlLmFkZENsYXNzKCdvcnBoYW4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAkdGVtcGxhdGUuYWRkQ2xhc3MoXCJ0b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lICsgXCIgdG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiLVwiICsgaSk7XHJcbiAgICAgICAgICAgIGlmIChzdGVwLnJlZmxleCkge1xyXG4gICAgICAgICAgICAgICAgJHRlbXBsYXRlLmFkZENsYXNzKFwidG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiLXJlZmxleFwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc3RlcC5wcmV2IDwgMCkge1xyXG4gICAgICAgICAgICAgICAgJHByZXYuYWRkQ2xhc3MoJ2Rpc2FibGVkJyk7XHJcbiAgICAgICAgICAgICAgICAkcHJldi5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzdGVwLm5leHQgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAkbmV4dC5hZGRDbGFzcygnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgICAgICRuZXh0LnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFzdGVwLmR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAkcmVzdW1lLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiAkdGVtcGxhdGUuY2xvbmUoKS53cmFwKCc8ZGl2PicpLnBhcmVudCgpLmh0bWwoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fcmVmbGV4RXZlbnQgPSBmdW5jdGlvbihyZWZsZXgpIHtcclxuICAgICAgICAgICAgaWYgKHt9LnRvU3RyaW5nLmNhbGwocmVmbGV4KSA9PT0gJ1tvYmplY3QgQm9vbGVhbl0nKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2NsaWNrJztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZWZsZXg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fcmVwb3NpdGlvbiA9IGZ1bmN0aW9uKCR0aXAsIHN0ZXApIHtcclxuICAgICAgICAgICAgdmFyIG9mZnNldEJvdHRvbSwgb2Zmc2V0SGVpZ2h0LCBvZmZzZXRSaWdodCwgb2Zmc2V0V2lkdGgsIG9yaWdpbmFsTGVmdCwgb3JpZ2luYWxUb3AsIHRpcE9mZnNldCwgc3RlcE9mZnNldDtcclxuICAgICAgICAgICAgc3RlcE9mZnNldCA9IHtcclxuICAgICAgICAgICAgICAgIGxlZnQ6IHBhcnNlSW50KHN0ZXAub2Zmc2V0WCkgfHwgMCxcclxuICAgICAgICAgICAgICAgIHRvcDogcGFyc2VJbnQoc3RlcC5vZmZzZXRZKSB8fCAwXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIG9mZnNldFdpZHRoID0gJHRpcFswXS5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgb2Zmc2V0SGVpZ2h0ID0gJHRpcFswXS5vZmZzZXRIZWlnaHQ7XHJcbiAgICAgICAgICAgIHRpcE9mZnNldCA9ICR0aXAub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgIHRpcE9mZnNldC5sZWZ0ICs9IHN0ZXBPZmZzZXQubGVmdDtcclxuICAgICAgICAgICAgdGlwT2Zmc2V0LnRvcCArPSBzdGVwT2Zmc2V0LnRvcDtcclxuICAgICAgICAgICAgb3JpZ2luYWxMZWZ0ID0gdGlwT2Zmc2V0LmxlZnQ7XHJcbiAgICAgICAgICAgIG9yaWdpbmFsVG9wID0gdGlwT2Zmc2V0LnRvcDtcclxuICAgICAgICAgICAgb2Zmc2V0Qm90dG9tID0gJChkb2N1bWVudCkub3V0ZXJIZWlnaHQoKSAtIHRpcE9mZnNldC50b3AgLSAkdGlwLm91dGVySGVpZ2h0KCk7XHJcbiAgICAgICAgICAgIGlmIChvZmZzZXRCb3R0b20gPCAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aXBPZmZzZXQudG9wID0gdGlwT2Zmc2V0LnRvcCArIG9mZnNldEJvdHRvbTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvZmZzZXRSaWdodCA9ICQoJ2h0bWwnKS5vdXRlcldpZHRoKCkgLSB0aXBPZmZzZXQubGVmdCAtICR0aXAub3V0ZXJXaWR0aCgpO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0UmlnaHQgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aXBPZmZzZXQubGVmdCA9IHRpcE9mZnNldC5sZWZ0ICsgb2Zmc2V0UmlnaHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRpcE9mZnNldC50b3AgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aXBPZmZzZXQudG9wID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGlwT2Zmc2V0LmxlZnQgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aXBPZmZzZXQubGVmdCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgJHRpcC5vZmZzZXQodGlwT2Zmc2V0KTtcclxuICAgICAgICAgICAgaWYgKHN0ZXAucGxhY2VtZW50ID09PSAnYm90dG9tJyB8fCBzdGVwLnBsYWNlbWVudCA9PT0gJ3RvcCcpIHtcclxuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbExlZnQgIT09IHRpcE9mZnNldC5sZWZ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlcGxhY2VBcnJvdygkdGlwLCAodGlwT2Zmc2V0LmxlZnQgLSBvcmlnaW5hbExlZnQpICogMiwgb2Zmc2V0V2lkdGgsICdsZWZ0Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxUb3AgIT09IHRpcE9mZnNldC50b3ApIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVwbGFjZUFycm93KCR0aXAsICh0aXBPZmZzZXQudG9wIC0gb3JpZ2luYWxUb3ApICogMiwgb2Zmc2V0SGVpZ2h0LCAndG9wJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fY2VudGVyID0gZnVuY3Rpb24oJHRpcCkge1xyXG4gICAgICAgICAgICByZXR1cm4gJHRpcC5jc3MoJ3RvcCcsICQod2luZG93KS5vdXRlckhlaWdodCgpIC8gMiAtICR0aXAub3V0ZXJIZWlnaHQoKSAvIDIpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9yZXBsYWNlQXJyb3cgPSBmdW5jdGlvbigkdGlwLCBkZWx0YSwgZGltZW5zaW9uLCBwb3NpdGlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gJHRpcC5maW5kKCcuYXJyb3cnKS5jc3MocG9zaXRpb24sIGRlbHRhID8gNTAgKiAoMSAtIGRlbHRhIC8gZGltZW5zaW9uKSArICclJyA6ICcnKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fc2Nyb2xsSW50b1ZpZXcgPSBmdW5jdGlvbihlbGVtZW50LCBjYWxsYmFjaywgYXV0b3Njcm9sbEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdmFyICRlbGVtZW50LCAkd2luZG93LCBjb3VudGVyLCBvZmZzZXRUb3AsIHNjcm9sbFRvcCwgd2luZG93SGVpZ2h0LCAkYXV0b3Njcm9sbEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICRlbGVtZW50ID0gJChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgIGlmICghJGVsZW1lbnQubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAkYXV0b3Njcm9sbEVsZW1lbnQgPSAkKGF1dG9zY3JvbGxFbGVtZW50IHx8IFwiYm9keSwgaHRtbFwiKTtcclxuICAgICAgICAgICAgJHdpbmRvdyA9ICQod2luZG93KTtcclxuICAgICAgICAgICAgb2Zmc2V0VG9wID0gdGhpcy5fY2FsY3VsYXRlT2Zmc2V0VG9wKCRlbGVtZW50WzBdKTtcclxuICAgICAgICAgICAgd2luZG93SGVpZ2h0ID0gJHdpbmRvdy5oZWlnaHQoKTtcclxuICAgICAgICAgICAgc2Nyb2xsVG9wID0gTWF0aC5tYXgoMCwgb2Zmc2V0VG9wIC0gKHdpbmRvd0hlaWdodCAvIDIpKTtcclxuICAgICAgICAgICAgdGhpcy5fZGVidWcoXCJTY3JvbGwgaW50byB2aWV3LiBTY3JvbGxUb3A6IFwiICsgc2Nyb2xsVG9wICsgXCIuIEVsZW1lbnQgb2Zmc2V0OiBcIiArIG9mZnNldFRvcCArIFwiLiBXaW5kb3cgaGVpZ2h0OiBcIiArIHdpbmRvd0hlaWdodCArIFwiLlwiKTtcclxuICAgICAgICAgICAgY291bnRlciA9IDA7XHJcbiAgICAgICAgICAgIHJldHVybiAkYXV0b3Njcm9sbEVsZW1lbnQuc3RvcCh0cnVlLCB0cnVlKS5hbmltYXRlKHtcclxuICAgICAgICAgICAgICAgIHNjcm9sbFRvcDogTWF0aC5jZWlsKHNjcm9sbFRvcClcclxuICAgICAgICAgICAgfSwgKGZ1bmN0aW9uKF90aGlzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY291bnRlciArPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb3VudGVyID49ICRhdXRvc2Nyb2xsRWxlbWVudC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLl9kZWJ1ZyhcIlNjcm9sbCBpbnRvIHZpZXcuXFxuQW5pbWF0aW9uIGVuZCBlbGVtZW50IG9mZnNldDogXCIgKyAoJGVsZW1lbnQub2Zmc2V0KCkudG9wKSArIFwiLlxcbldpbmRvdyBoZWlnaHQ6IFwiICsgKCR3aW5kb3cuaGVpZ2h0KCkpICsgXCIuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0pKHRoaXMpKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fY2FsY3VsYXRlT2Zmc2V0VG9wID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICAgICAgICB2YXIgdG9wID0gMDtcclxuICAgICAgICAgICAgd2hpbGUgKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIHRvcCArPSBlbGVtZW50Lm9mZnNldFRvcDtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdG9wO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9vblJlc2l6ZSA9IGZ1bmN0aW9uKGNhbGxiYWNrLCB0aW1lb3V0KSB7XHJcbiAgICAgICAgICAgICQod2luZG93KS5vbihcInJlc2l6ZS50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lLCByZXNpemVDYWxsYmFjayk7XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiByZXNpemVDYWxsYmFjaygpIHtcclxuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aW1lb3V0ID0gc2V0VGltZW91dChjYWxsYmFjaywgMTAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9zZXRTaG93U3RlcE9uU2Nyb2xsID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldE9uU2Nyb2xsKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2hvd1N0ZXAoX3RoaXMuZ2V0Q3VycmVudFN0ZXAoKSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9zZXRPblNjcm9sbCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHZhciB0aW1lb3V0O1xyXG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVPblNjcm9sbCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9zY3JvbGxDYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xyXG4gICAgICAgICAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMuX3Njcm9sbENhbGxiYWNrLCB0cnVlKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fcmVtb3ZlT25TY3JvbGwgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3Njcm9sbENhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLl9zY3JvbGxDYWxsYmFjaywgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zY3JvbGxDYWxsYmFjayA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5faW5pdE1vdXNlTmF2aWdhdGlvbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICB2YXIgX3RoaXM7XHJcbiAgICAgICAgICAgIF90aGlzID0gdGhpcztcclxuICAgICAgICAgICAgcmV0dXJuICQoZG9jdW1lbnQpLm9mZihcImNsaWNrLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUsIFwiLnBvcG92ZXIudG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiICpbZGF0YS1yb2xlPSdwcmV2J11cIikub2ZmKFwiY2xpY2sudG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSwgXCIucG9wb3Zlci50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lICsgXCIgKltkYXRhLXJvbGU9J25leHQnXVwiKS5vZmYoXCJjbGljay50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lLCBcIi5wb3BvdmVyLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUgKyBcIiAqW2RhdGEtcm9sZT0nZW5kJ11cIikub2ZmKFwiY2xpY2sudG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSwgXCIucG9wb3Zlci50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lICsgXCIgKltkYXRhLXJvbGU9J3BhdXNlLXJlc3VtZSddXCIpLm9uKFwiY2xpY2sudG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSwgXCIucG9wb3Zlci50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lICsgXCIgKltkYXRhLXJvbGU9J25leHQnXVwiLCAoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5uZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9KSh0aGlzKSkub24oXCJjbGljay50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lLCBcIi5wb3BvdmVyLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUgKyBcIiAqW2RhdGEtcm9sZT0ncHJldiddXCIsIChmdW5jdGlvbihfdGhpcykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLnByZXYoKTtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0pKHRoaXMpKS5vbihcImNsaWNrLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUsIFwiLnBvcG92ZXIudG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiICpbZGF0YS1yb2xlPSdlbmQnXVwiLCAoZnVuY3Rpb24oX3RoaXMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbmQoKTtcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0pKHRoaXMpKS5vbihcImNsaWNrLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUsIFwiLnBvcG92ZXIudG91ci1cIiArIHRoaXMuX29wdGlvbnMubmFtZSArIFwiICpbZGF0YS1yb2xlPSdoaWRlJ11cIiwgKGZ1bmN0aW9uKF90aGlzKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuaGlkZVN0ZXAoX3RoaXMuZ2V0Q3VycmVudFN0ZXAoKSk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9KSh0aGlzKSkub24oXCJjbGljay50b3VyLVwiICsgdGhpcy5fb3B0aW9ucy5uYW1lLCBcIi5wb3BvdmVyLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUgKyBcIiAqW2RhdGEtcm9sZT0ncGF1c2UtcmVzdW1lJ11cIiwgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyICR0aGlzO1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgJHRoaXMgPSAkKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgJHRoaXMudGV4dChfdGhpcy5fcGF1c2VkID8gJHRoaXMuZGF0YSgncGF1c2UtdGV4dCcpIDogJHRoaXMuZGF0YSgncmVzdW1lLXRleHQnKSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuX3BhdXNlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5yZXN1bWUoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLnBhdXNlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9pbml0S2V5Ym9hcmROYXZpZ2F0aW9uID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5fb3B0aW9ucy5rZXlib2FyZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiAkKGRvY3VtZW50KS5vbihcImtleXVwLnRvdXItXCIgKyB0aGlzLl9vcHRpb25zLm5hbWUsIChmdW5jdGlvbihfdGhpcykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWUud2hpY2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGUud2hpY2gpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy5faXNMYXN0KCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMubmV4dCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuZW5kKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMuX2N1cnJlbnQgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLnByZXYoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI3OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVuZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0pKHRoaXMpKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fbWFrZVByb21pc2UgPSBmdW5jdGlvbihyZXN1bHQpIHtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiAkLmlzRnVuY3Rpb24ocmVzdWx0LnRoZW4pKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fY2FsbE9uUHJvbWlzZURvbmUgPSBmdW5jdGlvbihwcm9taXNlLCBjYiwgYXJnKSB7XHJcbiAgICAgICAgICAgIGlmIChwcm9taXNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKChmdW5jdGlvbihfdGhpcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjYi5jYWxsKF90aGlzLCBhcmcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9KSh0aGlzKSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY2IuY2FsbCh0aGlzLCBhcmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX3Nob3dCYWNrZHJvcCA9IGZ1bmN0aW9uKHN0ZXApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYmFja2Ryb3AuYmFja2dyb3VuZFNob3duKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5iYWNrZHJvcCA9ICQoJzxkaXY+Jywge1xyXG4gICAgICAgICAgICAgICAgXCJjbGFzc1wiOiAndG91ci1iYWNrZHJvcCdcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuYmFja2Ryb3AuYmFja2dyb3VuZFNob3duID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuICQoc3RlcC5iYWNrZHJvcENvbnRhaW5lcikuYXBwZW5kKHRoaXMuYmFja2Ryb3ApO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9oaWRlQmFja2Ryb3AgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdGhpcy5faGlkZU92ZXJsYXlFbGVtZW50KCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oaWRlQmFja2dyb3VuZCgpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9oaWRlQmFja2dyb3VuZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5iYWNrZHJvcCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYmFja2Ryb3AucmVtb3ZlKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmFja2Ryb3AucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJhY2tkcm9wLm92ZXJsYXkgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYmFja2Ryb3AuYmFja2dyb3VuZFNob3duID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fc2hvd092ZXJsYXlFbGVtZW50ID0gZnVuY3Rpb24oc3RlcCwgZm9yY2UpIHtcclxuICAgICAgICAgICAgdmFyICRlbGVtZW50LCBlbGVtZW50RGF0YTtcclxuICAgICAgICAgICAgJGVsZW1lbnQgPSAkKHN0ZXAuZWxlbWVudCk7XHJcbiAgICAgICAgICAgIGlmICghJGVsZW1lbnQgfHwgJGVsZW1lbnQubGVuZ3RoID09PSAwIHx8IHRoaXMuYmFja2Ryb3Aub3ZlcmxheUVsZW1lbnRTaG93biAmJiAhZm9yY2UpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuYmFja2Ryb3Aub3ZlcmxheUVsZW1lbnRTaG93bikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5iYWNrZHJvcC4kZWxlbWVudCA9ICRlbGVtZW50LmFkZENsYXNzKCd0b3VyLXN0ZXAtYmFja2Ryb3AnKTtcclxuICAgICAgICAgICAgICAgIGlmIChzdGVwLmRpc2FibGVDbGljaylcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJhY2tkcm9wLiRlbGVtZW50ID0gJGVsZW1lbnQuYWRkQ2xhc3MoJ3RvdXItc3RlcC1iYWNrZHJvcC1kaXNhYmxlLWNsaWNrJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJhY2tkcm9wLiRiYWNrZ3JvdW5kID0gJCgnPGRpdj4nLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgXCJjbGFzc1wiOiAndG91ci1zdGVwLWJhY2tncm91bmQnXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGlmIChzdGVwLmJhY2tkcm9wQmFja2dyb3VuZENzc0NsYXNzKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmFja2Ryb3AuJGJhY2tncm91bmQuYWRkQ2xhc3Moc3RlcC5iYWNrZHJvcEJhY2tncm91bmRDc3NDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RlcC5iYWNrZHJvcEVsZW1lbnRDc3NDbGFzcylcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJhY2tkcm9wLiRlbGVtZW50LmFkZENsYXNzKHN0ZXAuYmFja2Ryb3BFbGVtZW50Q3NzQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5iYWNrZHJvcC4kYmFja2dyb3VuZC5hcHBlbmRUbyhzdGVwLmJhY2tkcm9wQ29udGFpbmVyKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYmFja2Ryb3Aub3ZlcmxheUVsZW1lbnRTaG93biA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxlbWVudERhdGEgPSB7XHJcbiAgICAgICAgICAgICAgICB3aWR0aDogJGVsZW1lbnQuaW5uZXJXaWR0aCgpLFxyXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAkZWxlbWVudC5pbm5lckhlaWdodCgpLFxyXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiAkZWxlbWVudC5vZmZzZXQoKVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoc3RlcC5iYWNrZHJvcFBhZGRpbmcpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnREYXRhID0gdGhpcy5fYXBwbHlCYWNrZHJvcFBhZGRpbmcoc3RlcC5iYWNrZHJvcFBhZGRpbmcsIGVsZW1lbnREYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5iYWNrZHJvcC4kYmFja2dyb3VuZC53aWR0aChlbGVtZW50RGF0YS53aWR0aCkuaGVpZ2h0KGVsZW1lbnREYXRhLmhlaWdodCkub2Zmc2V0KGVsZW1lbnREYXRhLm9mZnNldCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2hpZGVPdmVybGF5RWxlbWVudCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuYmFja2Ryb3Aub3ZlcmxheUVsZW1lbnRTaG93bikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuYmFja2Ryb3AuJGVsZW1lbnQucmVtb3ZlQ2xhc3MoJ3RvdXItc3RlcC1iYWNrZHJvcCcpO1xyXG4gICAgICAgICAgICB0aGlzLmJhY2tkcm9wLiRlbGVtZW50LnJlbW92ZUNsYXNzKCd0b3VyLXN0ZXAtYmFja2Ryb3AtZGlzYWJsZS1jbGljaycpO1xyXG4gICAgICAgICAgICB0aGlzLmJhY2tkcm9wLiRiYWNrZ3JvdW5kLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB0aGlzLmJhY2tkcm9wLiRlbGVtZW50ID0gbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5iYWNrZHJvcC4kYmFja2dyb3VuZCA9IG51bGw7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmJhY2tkcm9wLm92ZXJsYXlFbGVtZW50U2hvd24gPSBmYWxzZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fYXBwbHlCYWNrZHJvcFBhZGRpbmcgPSBmdW5jdGlvbihwYWRkaW5nLCBkYXRhKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFkZGluZyA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwYWRkaW5nLnRvcCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZy50b3AgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHBhZGRpbmcucmlnaHQgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmcucmlnaHQgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHBhZGRpbmcuYm90dG9tID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nLmJvdHRvbSA9IDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGFkZGluZy5sZWZ0ID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nLmxlZnQgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZGF0YS5vZmZzZXQudG9wID0gZGF0YS5vZmZzZXQudG9wIC0gcGFkZGluZy50b3A7XHJcbiAgICAgICAgICAgICAgICBkYXRhLm9mZnNldC5sZWZ0ID0gZGF0YS5vZmZzZXQubGVmdCAtIHBhZGRpbmcubGVmdDtcclxuICAgICAgICAgICAgICAgIGRhdGEud2lkdGggPSBkYXRhLndpZHRoICsgcGFkZGluZy5sZWZ0ICsgcGFkZGluZy5yaWdodDtcclxuICAgICAgICAgICAgICAgIGRhdGEuaGVpZ2h0ID0gZGF0YS5oZWlnaHQgKyBwYWRkaW5nLnRvcCArIHBhZGRpbmcuYm90dG9tO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZGF0YS5vZmZzZXQudG9wID0gZGF0YS5vZmZzZXQudG9wIC0gcGFkZGluZztcclxuICAgICAgICAgICAgICAgIGRhdGEub2Zmc2V0LmxlZnQgPSBkYXRhLm9mZnNldC5sZWZ0IC0gcGFkZGluZztcclxuICAgICAgICAgICAgICAgIGRhdGEud2lkdGggPSBkYXRhLndpZHRoICsgKHBhZGRpbmcgKiAyKTtcclxuICAgICAgICAgICAgICAgIGRhdGEuaGVpZ2h0ID0gZGF0YS5oZWlnaHQgKyAocGFkZGluZyAqIDIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9jbGVhclRpbWVyID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kdXJhdGlvbiA9IG51bGw7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2dldFByb3RvY29sID0gZnVuY3Rpb24odXJsKSB7XHJcbiAgICAgICAgICAgIHVybCA9IHVybC5zcGxpdCgnOi8vJyk7XHJcbiAgICAgICAgICAgIGlmICh1cmwubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVybFswXTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAnaHR0cCc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fZ2V0SG9zdCA9IGZ1bmN0aW9uKHVybCkge1xyXG4gICAgICAgICAgICB1cmwgPSB1cmwuc3BsaXQoJy8vJyk7XHJcbiAgICAgICAgICAgIHVybCA9IHVybC5sZW5ndGggPiAxID8gdXJsWzFdIDogdXJsWzBdO1xyXG4gICAgICAgICAgICByZXR1cm4gdXJsLnNwbGl0KCcvJylbMF07XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2dldFBhdGggPSBmdW5jdGlvbihwYXRoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBwYXRoLnJlcGxhY2UoL1xcLz8kLywgJycpLnNwbGl0KCc/JylbMF0uc3BsaXQoJyMnKVswXTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fZ2V0UXVlcnkgPSBmdW5jdGlvbihwYXRoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRQYXJhbXMocGF0aCwgJz8nKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBUb3VyLnByb3RvdHlwZS5fZ2V0SGFzaCA9IGZ1bmN0aW9uKHBhdGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFBhcmFtcyhwYXRoLCAnIycpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFRvdXIucHJvdG90eXBlLl9nZXRQYXJhbXMgPSBmdW5jdGlvbihwYXRoLCBzdGFydCkge1xyXG4gICAgICAgICAgICB2YXIgcGFyYW0sIHBhcmFtcywgcGFyYW1zT2JqZWN0LCBfaSwgX2xlbjtcclxuICAgICAgICAgICAgcGFyYW1zID0gcGF0aC5zcGxpdChzdGFydCk7XHJcbiAgICAgICAgICAgIGlmIChwYXJhbXMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge307XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGFyYW1zID0gcGFyYW1zWzFdLnNwbGl0KCcmJyk7XHJcbiAgICAgICAgICAgIHBhcmFtc09iamVjdCA9IHt9O1xyXG4gICAgICAgICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IHBhcmFtcy5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgcGFyYW0gPSBwYXJhbXNbX2ldO1xyXG4gICAgICAgICAgICAgICAgcGFyYW0gPSBwYXJhbS5zcGxpdCgnPScpO1xyXG4gICAgICAgICAgICAgICAgcGFyYW1zT2JqZWN0W3BhcmFtWzBdXSA9IHBhcmFtWzFdIHx8ICcnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBwYXJhbXNPYmplY3Q7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgVG91ci5wcm90b3R5cGUuX2VxdWFsID0gZnVuY3Rpb24ob2JqMSwgb2JqMikge1xyXG4gICAgICAgICAgICB2YXIgaywgdjtcclxuICAgICAgICAgICAgaWYgKHt9LnRvU3RyaW5nLmNhbGwob2JqMSkgPT09ICdbb2JqZWN0IE9iamVjdF0nICYmIHt9LnRvU3RyaW5nLmNhbGwob2JqMikgPT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gb2JqMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHYgPSBvYmoxW2tdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmoyW2tdICE9PSB2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gb2JqMikge1xyXG4gICAgICAgICAgICAgICAgICAgIHYgPSBvYmoyW2tdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmoxW2tdICE9PSB2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gb2JqMSA9PT0gb2JqMjtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gVG91cjtcclxuXHJcbiAgICB9KSgpO1xyXG4gICAgcmV0dXJuIHdpbmRvdy5Ub3VyID0gVG91cjtcclxufSkoalF1ZXJ5LCB3aW5kb3cpO1xuXG4vKioqIEVYUE9SVFMgRlJPTSBleHBvcnRzLWxvYWRlciAqKiovXG5tb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5Ub3VyO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nsb3Vkc2hhcmUtdG91ci9ib290c3RyYXAtdG91ci9ib290c3RyYXAtdG91ci5qc1xuLy8gbW9kdWxlIGlkID0gNjdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBcIjxkaXYgY2xhc3M9XFxcImNob2NvbGF0ZXktYnV0dG9uXFxcIiB0b3VyLXRhZy1uYW1lPVxcXCJjaG9jb2xhdGV5LWJ1dHRvblxcXCI+XFxyXFxuXFx0PGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIG5nLWNsaWNrPVxcXCJuZ0NsaWNrXFxcIj48L2J1dHRvbj5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL2Nob2NvbGF0ZXktYnV0dG9uLmh0bWxcbi8vIG1vZHVsZSBpZCA9IDY4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPVxcXCJjaG9jb2xhdGV5LWNsaWVudFxcXCI+XFxyXFxuXFx0PHBhY2thZ2VzLXBhbmUgc2hvdy1zZWFyY2g9XFxcInRydWVcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgIGZpcnN0LXZpZXc9XFxcInBvcHVsYXJcXFwiXFxyXFxuXFx0XFx0XFx0XFx0ICAgc2VsZWN0ZWQtcGFja2FnZXM9XFxcInNlbGVjdGVkUGFja2FnZXNcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgIG9uLXNlbGVjdC1wYWNrYWdlPVxcXCJzZWxlY3RQYWNrYWdlXFxcIj48L3BhY2thZ2VzLXBhbmU+XFxyXFxuXFx0XFx0XFx0XFx0ICAgXFxyXFxuXFx0PHBhY2thZ2VzLXBhbmUgc2hvdy1zZWFyY2g9XFxcImZhbHNlXFxcIlxcclxcblxcdFxcdFxcdFxcdCAgIHRpdGxlPVxcXCJTZWxlY3RlZCBQYWNrYWdlc1xcXCIgXFxyXFxuXFx0XFx0XFx0XFx0ICAgZmlyc3Qtdmlldz1cXFwic2VsZWN0ZWQtcGFja2FnZXNcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgIHNlbGVjdGVkLXBhY2thZ2VzPVxcXCJzZWxlY3RlZFBhY2thZ2VzXFxcIiBcXHJcXG5cXHRcXHRcXHRcXHQgICBvbi11bnNlbGVjdC1wYWNrYWdlPVxcXCJ1bnNlbGVjdFBhY2thZ2VcXFwiPjwvcGFja2FnZXMtcGFuZT5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL2Nob2NvbGF0ZXktY2xpZW50Lmh0bWxcbi8vIG1vZHVsZSBpZCA9IDY5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPVxcXCJkZXRhaWxzLXBhbmVcXFwiPlxcclxcblxcdDxkaXYgY2xhc3M9XFxcImhlYWRlclxcXCI+XFxyXFxuXFx0XFx0PGRpdiBjbGFzcz1cXFwiYmFja1xcXCI+XFxyXFxuXFx0XFx0XFx0PGEgaHJlZj1cXFwiamF2YXNjcmlwdDo7XFxcIiBuZy1jbGljaz1cXFwiYmFjaygpXFxcIj4mbHQ7IGJhY2s8L2E+XFxyXFxuXFx0XFx0PC9kaXY+XFxyXFxuXFx0XFx0PGRpdiBjbGFzcz1cXFwiaGVhZGVyLWNvbnRlbnRcXFwiIHN0eWxlPVxcXCJcXFwiPlxcclxcblxcdFxcdFxcdDxkaXYgY2xhc3M9XFxcImljb25cXFwiPlxcclxcblxcdFxcdFxcdFxcdDxpbWcgbmctc3JjPVxcXCJ7e3BhY2thZ2UuaWNvblVybH19XFxcIiAvPlxcclxcblxcdFxcdFxcdDwvZGl2PlxcclxcblxcdFxcdFxcdDxkaXYgY2xhc3M9XFxcInRpdGxlXFxcIj5cXHJcXG5cXHRcXHRcXHRcXHQ8c3BhbiBuZy1iaW5kPVxcXCJwYWNrYWdlLnRpdGxlIHx8IHBhY2thZ2UuaWROYW1lXFxcIj48L3NwYW4+IFxcclxcblxcdFxcdFxcdFxcdDxzcGFuIG5nLWJpbmQ9XFxcInBhY2thZ2UudmVyc2lvblxcXCI+PC9zcGFuPlxcclxcblxcdFxcdFxcdDwvZGl2PlxcclxcblxcdFxcdFxcdDxkaXYgY2xhc3M9XFxcImFjdGlvblxcXCI+XFxyXFxuXFx0XFx0XFx0XFx0PGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIG5nLXNob3c9XFxcIm9uU2VsZWN0UGFja2FnZVxcXCIgbmctY2xpY2s9XFxcIm9uU2VsZWN0UGFja2FnZShwYWNrYWdlKVxcXCIgbmctZGlzYWJsZWQ9XFxcImlzU2VsZWN0ZWQoKVxcXCI+QWRkICZndDs8L2J1dHRvbj5cXHJcXG5cXHRcXHRcXHRcXHQ8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgbmctc2hvdz1cXFwib25VbnNlbGVjdFBhY2thZ2VcXFwiIG5nLWNsaWNrPVxcXCJ1bnNlbGVjdEFuZEdvQmFjaygpXFxcIj4mbHQ7IFJlbW92ZTwvYnV0dG9uPlxcclxcblxcdFxcdFxcdDwvZGl2PlxcclxcblxcdFxcdDwvZGl2PlxcclxcblxcdDwvZGl2PlxcclxcblxcdDxwYWNrYWdlLWRldGFpbGVkLWl0ZW0gcGFja2FnZT1cXFwicGFja2FnZVxcXCIgXFxyXFxuXFx0XFx0XFx0XFx0XFx0XFx0ICAgb24tc2VsZWN0LXBhY2thZ2U9XFxcIm9uU2VsZWN0UGFja2FnZVxcXCIgXFxyXFxuXFx0XFx0XFx0XFx0XFx0XFx0ICAgb24tdW5zZWxlY3QtcGFja2FnZT1cXFwidW5zZWxlY3RBbmRHb0JhY2tcXFwiXFxyXFxuXFx0XFx0XFx0XFx0XFx0XFx0ICAgc2VsZWN0ZWQtcGFja2FnZXM9XFxcInNlbGVjdGVkUGFja2FnZXNcXFwiPjwvcGFja2FnZS1kZXRhaWxzLWl0ZW0+XFxyXFxuPC9kaXY+XCI7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9kZXRhaWxzLXBhbmUuaHRtbFxuLy8gbW9kdWxlIGlkID0gNzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBcIjxkaXYgY2xhc3M9XFxcIm1hcmtkb3duXFxcIiBuZy1iaW5kLWh0bWw9XFxcInBhcnNlZENvbnRlbnRcXFwiPlxcclxcbjwvZGl2PlwiO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nob2NvbGF0ZXktY2xpZW50L2RpcmVjdGl2ZXMvbWFya2Rvd24uaHRtbFxuLy8gbW9kdWxlIGlkID0gNzFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBcIjxkaXYgY2xhc3M9XFxcInBhY2thZ2UtZGV0YWlsZWQtaXRlbVxcXCIgbmctY2xhc3M9XFxcInsnc2Nyb2xsZWQnOiBzY3JvbGxlZH1cXFwiPlxcclxcblxcdDxkaXYgY2xhc3M9XFxcImNvbnRlbnRcXFwiPlxcclxcblxcdFxcdDxkaXYgY2xhc3M9XFxcInNlY3Rpb25cXFwiPkRlc2NyaXB0aW9uPC9kaXY+XFxyXFxuXFx0XFx0PGRpdiBjbGFzcz1cXFwiZGVzY3JpcHRpb25cXFwiPlxcclxcblxcdFxcdFxcdDxtYXJrZG93biBjb250ZW50PVxcXCJwYWNrYWdlLmRlc2NyaXB0aW9uXFxcIj48L21hcmtkb3duPlxcclxcblxcdFxcdDwvZGl2PlxcclxcblxcdFxcdFxcclxcblxcdFxcdDxkaXYgY2xhc3M9XFxcInNlY3Rpb25cXFwiPkV4dHJhIGRldGFpbHM6PC9kaXY+XFxyXFxuXFx0XFx0PHRhYmxlPlxcclxcblxcdFxcdFxcdDx0cj5cXHJcXG5cXHRcXHRcXHRcXHQ8dGQgY2xhc3M9XFxcImxhYmVsXFxcIj5BdXRob3JzOjwvdGQ+XFxyXFxuXFx0XFx0XFx0XFx0PHRkPjxzcGFuIG5nLWJpbmQ9XFxcInBhY2thZ2UuYXV0aG9yc1xcXCI+PC9zcGFuPjwvdGQ+XFxyXFxuXFx0XFx0XFx0PC90cj5cXHJcXG5cXHRcXHRcXHQ8dHI+XFxyXFxuXFx0XFx0XFx0XFx0PHRkIGNsYXNzPVxcXCJsYWJlbFxcXCI+RG93bmxvYWRzOjwvdGQ+XFxyXFxuXFx0XFx0XFx0XFx0PHRkPjxzcGFuIG5nLWJpbmQ9XFxcInBhY2thZ2UuZG93bmxvYWRDb3VudFxcXCI+PC9zcGFuPjwvdGQ+XFxyXFxuXFx0XFx0XFx0PC90cj5cXHJcXG5cXHRcXHRcXHQ8dHI+XFxyXFxuXFx0XFx0XFx0XFx0PHRkIGNsYXNzPVxcXCJsYWJlbFxcXCI+Q2hvY29sYXRleSBsaW5rOjwvdGQ+XFxyXFxuXFx0XFx0XFx0XFx0PHRkPlxcclxcblxcdFxcdFxcdFxcdFxcdDxkaXYgY2xhc3M9XFxcImxpbmtcXFwiPlxcclxcblxcdFxcdFxcdFxcdFxcdFxcdDxhIG5nLWhyZWY9XFxcInt7cGFja2FnZS5nYWxsZXJ5RGV0YWlsc1VybH19XFxcIiBuZy1iaW5kPVxcXCJwYWNrYWdlLmdhbGxlcnlEZXRhaWxzVXJsXFxcIiB0YXJnZXQ9XFxcIl9ibGFua1xcXCI+PC9hPlxcclxcblxcdFxcdFxcdFxcdFxcdDwvZGl2PlxcclxcblxcdFxcdFxcdFxcdDwvdGQ+XFxyXFxuXFx0XFx0XFx0PC90cj5cXHJcXG5cXHRcXHRcXHQ8dHI+XFxyXFxuXFx0XFx0XFx0XFx0PHRkIGNsYXNzPVxcXCJsYWJlbFxcXCI+UHJvamVjdCBzaXRlOjwvdGQ+XFxyXFxuXFx0XFx0XFx0XFx0PHRkPlxcclxcblxcdFxcdFxcdFxcdFxcdDxkaXYgY2xhc3M9XFxcImxpbmtcXFwiPlxcclxcblxcdFxcdFxcdFxcdFxcdFxcdDxhIG5nLWhyZWY9XFxcInt7cGFja2FnZS5wcm9qZWN0VXJsfX1cXFwiIG5nLWJpbmQ9XFxcInBhY2thZ2UucHJvamVjdFVybFxcXCIgdGFyZ2V0PVxcXCJfYmxhbmtcXFwiPjwvYT5cXHJcXG5cXHRcXHRcXHRcXHRcXHQ8L2Rpdj5cXHJcXG5cXHRcXHRcXHRcXHQ8L3RkPlxcclxcblxcdFxcdFxcdDwvdHI+XFxyXFxuXFx0XFx0XFx0PHRyPlxcclxcblxcdFxcdFxcdFxcdDx0ZCBjbGFzcz1cXFwibGFiZWxcXFwiPlRhZ3M6PC90ZD5cXHJcXG5cXHRcXHRcXHRcXHQ8dGQ+PHNwYW4gbmctYmluZD1cXFwicGFja2FnZS50YWdzXFxcIj48L3NwYW4+PC90ZD5cXHJcXG5cXHRcXHRcXHQ8L3RyPlxcclxcblxcdFxcdDwvdGFibGU+XFxyXFxuXFx0XFx0PGRpdiBuZy1zaG93PVxcXCJvblNlbGVjdFBhY2thZ2VcXFwiIGNsYXNzPVxcXCJzZWN0aW9uXFxcIj5DaG9vc2UgYW5vdGhlciB2ZXJzaW9uPC9kaXY+XFxyXFxuXFx0XFx0PHRhYmxlIG5nLXNob3c9XFxcIm9uU2VsZWN0UGFja2FnZVxcXCI+XFxyXFxuXFx0XFx0XFx0PHRyIG5nLXJlcGVhdD1cXFwidmVyc2lvbiBpbiB2ZXJzaW9uc1xcXCI+XFxyXFxuXFx0XFx0XFx0XFx0PHRkIGNsYXNzPVxcXCJ2ZXJzaW9uXFxcIj5cXHJcXG5cXHRcXHRcXHRcXHRcXHQ8c3BhbiBuZy1iaW5kPVxcXCJ2ZXJzaW9uXFxcIj48L3NwYW4+XFxyXFxuXFx0XFx0XFx0XFx0PC90ZD5cXHJcXG5cXHRcXHRcXHRcXHQ8dGQ+XFxyXFxuXFx0XFx0XFx0XFx0XFx0PGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIG5nLWNsaWNrPVxcXCJzZWxlY3RWZXJzaW9uKHZlcnNpb24pXFxcIiBuZy1kaXNhYmxlZD1cXFwiaXNTZWxlY3RlZCh2ZXJzaW9uKVxcXCI+QWRkICZndDs8L2J1dHRvbj5cXHJcXG5cXHRcXHRcXHRcXHQ8L3RkPlxcclxcblxcdFxcdFxcdDwvdHI+XFxyXFxuXFx0XFx0PC90YWJsZT5cXHJcXG5cXHRcXHQ8c3Bpbm5lciBuZy1zaG93PVxcXCJvblNlbGVjdFBhY2thZ2UgJiYgc2hvd1ZlcnNpb25TcGlubmVyXFxcIj48L3NwaW5uZXI+XFxyXFxuXFx0XFx0PGRpdiBuZy1zaG93PVxcXCJvblNlbGVjdFBhY2thZ2UgJiYgbm9Nb3JlICYmIHZlcnNpb25zLmxlbmd0aCA9PSAwXFxcIj5cXHJcXG5cXHRcXHRcXHRObyBvdGhlciB2ZXJzaW9ucyBmb3VuZC5cXHJcXG5cXHRcXHQ8L2Rpdj5cXHJcXG5cXHQ8L2Rpdj5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2UtZGV0YWlsZWQtaXRlbS5odG1sXG4vLyBtb2R1bGUgaWQgPSA3MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IFwiPGRpdiBjbGFzcz1cXFwicGFja2FnZS1pdGVtXFxcIj5cXHJcXG5cXHQ8dGFibGU+XFxyXFxuXFx0XFx0PHRyPlxcclxcblxcdFxcdFxcdDx0ZCBjbGFzcz1cXFwiaWNvblxcXCI+XFxyXFxuXFx0XFx0XFx0XFx0PGltZyBuZy1zcmM9XFxcInt7cGFja2FnZS5pY29uVXJsfX1cXFwiIC8+XFxyXFxuXFx0XFx0XFx0PC90ZD5cXHJcXG5cXHRcXHRcXHQ8dGQgY2xhc3M9XFxcImluZm9cXFwiPlxcclxcblxcdFxcdFxcdFxcdDxkaXYgY2xhc3M9XFxcInRpdGxlXFxcIj48c3BhbiBuZy1iaW5kPVxcXCJwYWNrYWdlLnRpdGxlIHx8IHBhY2thZ2UuaWROYW1lXFxcIj48L3NwYW4+IDxzcGFuIG5nLWJpbmQ9XFxcInBhY2thZ2UudmVyc2lvblxcXCI+PC9zcGFuPjwvZGl2PlxcclxcblxcdFxcdFxcdFxcdDxkaXYgY2xhc3M9XFxcImF1dGhvcnNcXFwiPkJ5OiA8c3BhbiBuZy1iaW5kPVxcXCJwYWNrYWdlLmF1dGhvcnNcXFwiPjwvc3Bhbj48L2Rpdj5cXHJcXG5cXHRcXHRcXHRcXHQ8ZGl2IGNsYXNzPVxcXCJkZXNjcmlwdGlvblxcXCI+XFxyXFxuXFx0XFx0XFx0XFx0XFx0PHNwYW4gbmctYmluZD1cXFwic2hvcnREZXNjcmlwdGlvblxcXCI+PC9zcGFuPlxcclxcblxcdFxcdFxcdFxcdFxcdDxhIGhyZWY9XFxcImphdmFzY3JpcHQ6O1xcXCIgbmctY2xpY2s9XFxcIm9uVmlld0RldGFpbHMocGFja2FnZSlcXFwiPm1vcmUgaW5mb3JtYXRpb248L2E+XFxyXFxuXFx0XFx0XFx0XFx0PC9kaXY+XFxyXFxuXFx0XFx0XFx0PC90ZD5cXHJcXG5cXHRcXHRcXHQ8dGQgY2xhc3M9XFxcImFjdGlvbnNcXFwiPlxcclxcblxcdFxcdFxcdFxcdDxkaXYgbmctc2hvdz1cXFwib25TZWxlY3RQYWNrYWdlXFxcIj5cXHJcXG5cXHRcXHRcXHRcXHRcXHQ8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgbmctY2xpY2s9XFxcIm9uU2VsZWN0UGFja2FnZShwYWNrYWdlKVxcXCIgbmctZGlzYWJsZWQ9XFxcImlzU2VsZWN0ZWQoKVxcXCI+QWRkICZndDs8L2J1dHRvbj5cXHJcXG5cXHRcXHRcXHRcXHQ8L2Rpdj5cXHJcXG5cXHRcXHRcXHRcXHQ8ZGl2IG5nLXNob3c9XFxcIm9uVW5zZWxlY3RQYWNrYWdlXFxcIj5cXHJcXG5cXHRcXHRcXHRcXHRcXHQ8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgbmctY2xpY2s9XFxcIm9uVW5zZWxlY3RQYWNrYWdlKHBhY2thZ2UpXFxcIj4mbHQ7IFJlbW92ZTwvYnV0dG9uPlxcclxcblxcdFxcdFxcdFxcdDwvZGl2PlxcclxcblxcdFxcdFxcdDwvdGQ+XFxyXFxuXFx0XFx0PC90cj5cXHJcXG5cXHQ8L3RhYmxlPlxcclxcbjwvZGl2PlwiO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nob2NvbGF0ZXktY2xpZW50L2RpcmVjdGl2ZXMvcGFja2FnZS1pdGVtLmh0bWxcbi8vIG1vZHVsZSBpZCA9IDczXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPVxcXCJwYWNrYWdlLWxpc3RcXFwiIG5nLWNsYXNzPVxcXCJ7J3Njcm9sbGVkJzogc2Nyb2xsZWR9XFxcIj5cXHJcXG5cXHQ8cGFja2FnZS1pdGVtIG5nLXJlcGVhdD1cXFwicCBpbiBwYWNrYWdlc1xcXCIgXFxyXFxuXFx0XFx0XFx0XFx0ICBwYWNrYWdlPVxcXCJwXFxcIiBcXHJcXG5cXHRcXHRcXHRcXHQgIG9uLXZpZXctZGV0YWlscz1cXFwib25WaWV3RGV0YWlsc1xcXCIgXFxyXFxuXFx0XFx0XFx0XFx0ICBvbi12aWV3LXZlcnNpb25zPVxcXCJvblZpZXdWZXJzaW9uc1xcXCJcXHJcXG5cXHRcXHRcXHRcXHQgIG9uLXNlbGVjdC1wYWNrYWdlPVxcXCJvblNlbGVjdFBhY2thZ2VcXFwiXFxyXFxuXFx0XFx0XFx0XFx0ICBvbi11bnNlbGVjdC1wYWNrYWdlPVxcXCJvblVuc2VsZWN0UGFja2FnZVxcXCIsXFxyXFxuXFx0XFx0XFx0XFx0ICBzZWxlY3RlZC1wYWNrYWdlcz1cXFwic2VsZWN0ZWRQYWNrYWdlc1xcXCI+PC9wYWNrYWdlLWl0ZW0+XFxyXFxuXFx0PGRpdiBjbGFzcz1cXFwiZW1wdHktbm90aWNlXFxcIiBuZy1zaG93PVxcXCIhc2hvd1NwaW5uZXIgJiYgcGFja2FnZXMubGVuZ3RoID09IDBcXFwiPlxcclxcblxcdFxcdDxzcGFuIG5nLWJpbmQ9XFxcImVtcHR5UGhyYXNlXFxcIj48L3NwYW4+XFxyXFxuXFx0PC9kaXY+XFxyXFxuXFx0PHNwaW5uZXIgbmctc2hvdz1cXFwic2hvd1NwaW5uZXJcXFwiPjwvc3Bpbm5lcj5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2UtbGlzdC5odG1sXG4vLyBtb2R1bGUgaWQgPSA3NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IFwiPGRpdiBjbGFzcz1cXFwicGFja2FnZXMtcGFuZVxcXCI+XFxyXFxuXFx0PHNlYXJjaC1pbnB1dCBuZy1zaG93PVxcXCJzaG93U2VhcmNoXFxcIiBvbi1zZWFyY2g9XFxcInNlYXJjaFBhY2thZ2VzXFxcIj48L3NlYXJjaC1pbnB1dD5cXHJcXG5cXHQ8ZGl2IGNsYXNzPVxcXCJ0aXRsZVxcXCIgbmctc2hvdz1cXFwidGl0bGVcXFwiPlxcclxcblxcdFxcdDxkaXYgY2xhc3M9XFxcInRpdGxlLXRleHRcXFwiPlxcclxcblxcdFxcdFxcdDxzcGFuIG5nLWJpbmQ9XFxcInRpdGxlXFxcIj48L3NwYW4+XFxyXFxuXFx0XFx0PC9kaXY+XFxyXFxuXFx0PC9kaXY+XFxyXFxuXFx0XFxyXFxuXFx0PHBhY2thZ2UtbGlzdCBuZy1zaG93PVxcXCJzZWxlY3RlZFZpZXc9PSdzZWFyY2gnXFxcIiBcXHJcXG5cXHRcXHRcXHRcXHQgcGFja2FnZXM9XFxcInBhY2thZ2VzXFxcIlxcclxcblxcdFxcdFxcdFxcdCBlbXB0eS1waHJhc2U9XFxcIk5vIFBhY2thZ2VzIEZvdW5kXFxcIlxcclxcblxcdFxcdFxcdFxcdCBvbi12aWV3LWRldGFpbHM9XFxcInZpZXdEZXRhaWxzXFxcIiBcXHJcXG5cXHRcXHRcXHRcXHQgc2VsZWN0ZWQtcGFja2FnZXM9XFxcInNlbGVjdGVkUGFja2FnZXNcXFwiIFxcclxcblxcdFxcdFxcdFxcdCBvbi1zZWxlY3QtcGFja2FnZT1cXFwib25TZWxlY3RQYWNrYWdlXFxcIlxcclxcblxcdFxcdFxcdFxcdCBvbi1uZWVkLW1vcmU9XFxcImZldGNoTW9yZVNlYXJjaFxcXCJcXHJcXG5cXHRcXHRcXHRcXHQgc2hvdy1zcGlubmVyPVxcXCJzaG93U3Bpbm5lclxcXCJcXHJcXG5cXHRcXHRcXHRcXHQgc2VsZWN0ZWQtcGFja2FnZXM9XFxcInNlbGVjdGVkUGFja2FnZXNcXFwiPjwvcGFja2FnZS1saXN0PlxcclxcblxcclxcblxcdDxwYWNrYWdlLWxpc3Qgbmctc2hvdz1cXFwic2VsZWN0ZWRWaWV3PT0ncG9wdWxhcidcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgcGFja2FnZXM9XFxcInBhY2thZ2VzXFxcIlxcclxcblxcdFxcdFxcdFxcdCAgZW1wdHktcGhyYXNlPVxcXCJObyBQYWNrYWdlcyBGb3VuZFxcXCJcXHJcXG5cXHRcXHRcXHRcXHQgIG9uLXZpZXctZGV0YWlscz1cXFwidmlld0RldGFpbHNcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgc2VsZWN0ZWQtcGFja2FnZXM9XFxcInNlbGVjdGVkUGFja2FnZXNcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgb24tc2VsZWN0LXBhY2thZ2U9XFxcIm9uU2VsZWN0UGFja2FnZVxcXCJcXHJcXG5cXHRcXHRcXHRcXHQgIG9uLW5lZWQtbW9yZT1cXFwiZmV0Y2hNb3JlUG9wdWxhclxcXCJcXHJcXG5cXHRcXHRcXHRcXHQgIHNob3ctc3Bpbm5lcj1cXFwic2hvd1NwaW5uZXJcXFwiXFxyXFxuXFx0XFx0XFx0XFx0ICBzZWxlY3RlZC1wYWNrYWdlcz1cXFwic2VsZWN0ZWRQYWNrYWdlc1xcXCI+PC9wYWNrYWdlLWxpc3Q+XFxyXFxuXFxyXFxuXFx0PHBhY2thZ2UtbGlzdCBuZy1zaG93PVxcXCJzZWxlY3RlZFZpZXc9PSdzZWxlY3RlZC1wYWNrYWdlcydcXFwiXFxyXFxuXFx0XFx0XFx0XFx0ICBwYWNrYWdlcz1cXFwic2VsZWN0ZWRQYWNrYWdlc1xcXCJcXHJcXG5cXHRcXHRcXHRcXHQgIGVtcHR5LXBocmFzZT1cXFwiTm8gUGFja2FnZXMgU2VsZWN0ZWRcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgc2hvdy1zcGlubmVyPVxcXCJzaG93U3Bpbm5lclxcXCIgXFxyXFxuXFx0XFx0XFx0XFx0ICBvbi12aWV3LWRldGFpbHM9XFxcInZpZXdEZXRhaWxzXFxcIiBcXHJcXG5cXHRcXHRcXHRcXHQgIG9uLXVuc2VsZWN0LXBhY2thZ2U9XFxcIm9uVW5zZWxlY3RQYWNrYWdlXFxcIlxcclxcblxcdFxcdFxcdFxcdCAgc2VsZWN0ZWQtcGFja2FnZXM9XFxcInNlbGVjdGVkUGFja2FnZXNcXFwiPjwvcGFja2FnZS1saXN0PlxcclxcblxcclxcblxcdDxkZXRhaWxzLXBhbmUgbmctc2hvdz1cXFwic2VsZWN0ZWRWaWV3PT0nZGV0YWlscydcXFwiIFxcclxcblxcdFxcdFxcdFxcdCAgYmFjaz1cXFwiYmFja1xcXCIgXFxyXFxuXFx0XFx0XFx0XFx0ICBwYWNrYWdlPVxcXCJ2aWV3UGFja2FnZVxcXCJcXHJcXG5cXHRcXHRcXHRcXHQgIG9uLXNlbGVjdC1wYWNrYWdlPVxcXCJvblNlbGVjdFBhY2thZ2VcXFwiXFxyXFxuXFx0XFx0XFx0XFx0ICBvbi11bnNlbGVjdC1wYWNrYWdlPVxcXCJvblVuc2VsZWN0UGFja2FnZVxcXCJcXHJcXG5cXHRcXHRcXHRcXHQgIHNlbGVjdGVkLXBhY2thZ2VzPVxcXCJzZWxlY3RlZFBhY2thZ2VzXFxcIj48L2RldGFpbHMtcGFuZT5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2VzLXBhbmUuaHRtbFxuLy8gbW9kdWxlIGlkID0gNzVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBcIjxkaXYgY2xhc3M9XFxcInNlYXJjaC1pbnB1dFxcXCI+XFxyXFxuXFx0PGlucHV0IHR5cGU9XFxcInRleHRcXFwiIHBsYWNlaG9sZGVyPVxcXCJTZWFyY2ggZm9yIHBhY2thZ2VzLCB0cnkgJ2dpdCcgb3IgJy5uZXQnXFxcIiAvPlxcclxcbjwvZGl2PlwiO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nob2NvbGF0ZXktY2xpZW50L2RpcmVjdGl2ZXMvc2VhcmNoLWlucHV0Lmh0bWxcbi8vIG1vZHVsZSBpZCA9IDc2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPVxcXCJzcGlubmVyXFxcIj5cXHJcXG5cXHQ8aW1nIC8+XFxyXFxuPC9kaXY+XCI7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9zcGlubmVyLmh0bWxcbi8vIG1vZHVsZSBpZCA9IDc3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPVxcXCJwb3BvdmVyIHRvdXJcXFwiIHN0eWxlPVxcXCJwYWRkaW5nLWJvdHRvbTogMTVweDtcXFwiPlxcclxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcnJvd1xcXCI+PC9kaXY+XFxyXFxuICAgIDxoMyBjbGFzcz1cXFwicG9wb3Zlci10aXRsZVxcXCI+PC9oMz5cXHJcXG4gICAgPGEgZGF0YS1yb2xlPSdoaWRlJyBjbGFzcz1cXFwiY2xvc2UtYnV0dG9uXFxcIj4mdGltZXM7PC9hPlxcclxcbiAgICA8ZGl2IGNsYXNzPVxcXCJwb3BvdmVyLWNvbnRlbnRcXFwiPjwvZGl2PlxcclxcbjwvZGl2PlwiO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvRmxvd1RlbXBsYXRlLmh0bWxcbi8vIG1vZHVsZSBpZCA9IDc4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPVxcXCJwb3BvdmVyIHRvdXJcXFwiIHN0eWxlPVxcXCJwYWRkaW5nLWJvdHRvbTogMTVweDtcXFwiPlxcclxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcnJvd1xcXCI+PC9kaXY+XFxyXFxuICAgIDxoMyBjbGFzcz1cXFwicG9wb3Zlci10aXRsZVxcXCI+PC9oMz5cXHJcXG4gICAgPGRpdiBjbGFzcz1cXFwicG9wb3Zlci1jb250ZW50XFxcIj48L2Rpdj5cXHJcXG4gICAgPHNwYW4gY2xhc3M9J3BvcG92ZXItbmF2aWdhdGlvbicgc3R5bGU9XFxcInBhZGRpbmc6IDEwcHhcXFwiPlxcclxcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz0nYnRuIGJ0bi1kZWZhdWx0JyBkYXRhLXJvbGU9J2VuZCcgc3R5bGU9XFxcIm1hcmdpbi1yaWdodDogMTVweDtcXFwiPkVuZCB0b3VyPC9idXR0b24+XFxyXFxuICAgIDwvc3Bhbj5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jbG91ZHNoYXJlLXRvdXIvdGVtcGxhdGVzL0Zsb3dUZW1wbGF0ZVdpdGhFbmQuaHRtbFxuLy8gbW9kdWxlIGlkID0gNzlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBcIjxkaXYgY2xhc3M9XFxcInBvcG92ZXIgdG91clxcXCIgc3R5bGU9XFxcInBhZGRpbmctYm90dG9tOiAxNXB4O1xcXCI+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcImFycm93XFxcIj48L2Rpdj5cXHJcXG4gICAgPGgzIGNsYXNzPVxcXCJwb3BvdmVyLXRpdGxlXFxcIj48L2gzPlxcclxcbiAgICA8YSBkYXRhLXJvbGU9J2hpZGUnIGNsYXNzPVxcXCJjbG9zZS1idXR0b25cXFwiPiZ0aW1lczs8L2E+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcInBvcG92ZXItY29udGVudFxcXCI+PC9kaXY+XFxyXFxuICAgIDxzcGFuIGNsYXNzPSdwb3BvdmVyLW5hdmlnYXRpb24nIHN0eWxlPVxcXCJwYWRkaW5nOiAxMHB4XFxcIj5cXHJcXG4gICAgICAgIDxidXR0b24gY2xhc3M9J2J0biBidG4tZGVmYXVsdCcgZGF0YS1yb2xlPSduZXh0Jz5OZXh0PC9idXR0b24+XFxyXFxuICAgIDwvc3Bhbj5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jbG91ZHNoYXJlLXRvdXIvdGVtcGxhdGVzL0Zsb3dUZW1wbGF0ZVdpdGhOZXh0Lmh0bWxcbi8vIG1vZHVsZSBpZCA9IDgwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gXCI8ZGl2IGNsYXNzPVxcXCJwb3BvdmVyIHRvdXJcXFwiIHN0eWxlPVxcXCJwYWRkaW5nLWJvdHRvbTogMTVweDtcXFwiPlxcclxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcnJvd1xcXCI+PC9kaXY+XFxyXFxuICAgIDxoMyBjbGFzcz1cXFwicG9wb3Zlci10aXRsZVxcXCI+PC9oMz5cXHJcXG4gICAgPGRpdiBjbGFzcz1cXFwicG9wb3Zlci1jb250ZW50XFxcIj48L2Rpdj5cXHJcXG4gICAgPHNwYW4gY2xhc3M9J3BvcG92ZXItbmF2aWdhdGlvbicgc3R5bGU9XFxcInBhZGRpbmc6IDEwcHhcXFwiPlxcclxcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz0nYnRuIGJ0bi1kZWZhdWx0JyBkYXRhLXJvbGU9J25leHQnPk5leHQ8L2J1dHRvbj5cXHJcXG4gICAgICAgIDxidXR0b24gY2xhc3M9J2J0biBidG4tbGluaycgZGF0YS1yb2xlPSdlbmQnIHN0eWxlPVxcXCJtYXJnaW4tcmlnaHQ6IDE1cHg7XFxcIj5FbmQgdG91cjwvYnV0dG9uPlxcclxcbiAgICA8L3NwYW4+XFxyXFxuPC9kaXY+XCI7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9GbG93VGVtcGxhdGVXaXRoTmV4dEFuZEVuZC5odG1sXG4vLyBtb2R1bGUgaWQgPSA4MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IFwiPGRpdiBjbGFzcz1cXFwicG9wb3ZlciB0b3VyXFxcIiBzdHlsZT1cXFwicGFkZGluZy1ib3R0b206IDE1cHg7XFxcIj5cXHJcXG4gICAgPGRpdiBjbGFzcz1cXFwiYXJyb3dcXFwiPjwvZGl2PlxcclxcbiAgICA8aDMgY2xhc3M9XFxcInBvcG92ZXItdGl0bGVcXFwiPjwvaDM+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcInBvcG92ZXItY29udGVudFxcXCI+PC9kaXY+XFxyXFxuPC9kaXY+XCI7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9GbG93V2l0aG91dEV4aXRUZW1wbGF0ZS5odG1sXG4vLyBtb2R1bGUgaWQgPSA4MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IFwiPGRpdiBjbGFzcz1cXFwiY3MtaW1hZ2UtZmxvdy1tb2RhbFxcXCI+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcIm1vZGFsLWJhY2tkcm9wXFxcIj48L2Rpdj5cXHJcXG4gICAgPGRpdiBjbGFzcz1cXFwibW9kYWwtY29udGFpbmVyXFxcIj5cXHJcXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImZsb3ctbW9kYWwtaGVhZGVyXFxcIj5cXHJcXG4gICAgICAgIDwvZGl2PlxcclxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwiZmxvdy1tb2RhbC1pbWFnZS1jb250YWluZXJcXFwiPlxcclxcbiAgICAgICAgPC9kaXY+XFxyXFxuICAgIDwvZGl2PlxcclxcbjwvZGl2PlwiO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nsb3Vkc2hhcmUtdG91ci90ZW1wbGF0ZXMvSW1hZ2VGbG93TW9kYWwuaHRtbFxuLy8gbW9kdWxlIGlkID0gODNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBcIjxkaXYgY2xhc3M9XFxcInBvcG92ZXIgdG91clxcXCIgc3R5bGU9XFxcInBhZGRpbmctYm90dG9tOiAxNXB4O1xcXCI+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcImFycm93XFxcIj48L2Rpdj5cXHJcXG4gICAgPGgzIGNsYXNzPVxcXCJwb3BvdmVyLXRpdGxlXFxcIj48L2gzPlxcclxcbiAgICA8ZGl2IGNsYXNzPVxcXCJwb3BvdmVyLWNvbnRlbnRcXFwiPjwvZGl2PlxcclxcbiAgICA8c3BhbiBjbGFzcz0ncG9wb3Zlci1uYXZpZ2F0aW9uJyBzdHlsZT1cXFwicGFkZGluZzogMTBweFxcXCI+XFxyXFxuICAgICAgICA8YnV0dG9uIGNsYXNzPSdidG4gYnRuLWRlZmF1bHQnIGRhdGEtcm9sZT0nZW5kJyBzdHlsZT1cXFwibWFyZ2luLXJpZ2h0OiAxNXB4O1xcXCI+R290IEl0ITwvYnV0dG9uPlxcclxcbiAgICA8L3NwYW4+XFxyXFxuPC9kaXY+XCI7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9TaG93T25jZUZsb3dUZW1wbGF0ZS5odG1sXG4vLyBtb2R1bGUgaWQgPSA4NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IFwiPGRpdiBjbGFzcz1cXFwicG9wb3ZlciB0b3VyXFxcIiBzdHlsZT1cXFwicGFkZGluZy1ib3R0b206IDE1cHg7XFxcIj5cXHJcXG4gICAgPGRpdiBjbGFzcz1cXFwiYXJyb3dcXFwiPjwvZGl2PlxcclxcbiAgICA8aDMgY2xhc3M9XFxcInBvcG92ZXItdGl0bGVcXFwiPjwvaDM+XFxyXFxuICAgIDxkaXYgY2xhc3M9XFxcInBvcG92ZXItY29udGVudFxcXCI+PC9kaXY+XFxyXFxuICAgIDxzcGFuIGNsYXNzPSdwb3BvdmVyLW5hdmlnYXRpb24nIHN0eWxlPVxcXCJwYWRkaW5nOiAxMHB4XFxcIj5cXHJcXG4gICAgICAgIDxidXR0b24gY2xhc3M9J2J0biBidG4tZGVmYXVsdCcgZGF0YS1yb2xlPSdlbmQnIHN0eWxlPVxcXCJmbG9hdDogbm9uZTtcXFwiPkdvdCBJdCE8L2J1dHRvbj5cXHJcXG4gICAgICAgIDxidXR0b24gY2xhc3M9J2J0biBidG4tZGVmYXVsdCcgZGF0YS1yb2xlPSduZXh0JyBzdHlsZT1cXFwiZmxvYXQ6IHJpZ2h0OyBtYXJnaW4tcmlnaHQ6IDE1cHg7XFxcIj5OZXh0PC9idXR0b24+XFxyXFxuICAgIDwvc3Bhbj5cXHJcXG48L2Rpdj5cIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jbG91ZHNoYXJlLXRvdXIvdGVtcGxhdGVzL1Nob3dPbmNlRmxvd1RlbXBsYXRlV2l0aE5leHQuaHRtbFxuLy8gbW9kdWxlIGlkID0gODVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBDb2xsZWN0aW5nSGFuZGxlcjtcblxuZnVuY3Rpb24gQ29sbGVjdGluZ0hhbmRsZXIoY2JzKXtcblx0dGhpcy5fY2JzID0gY2JzIHx8IHt9O1xuXHR0aGlzLmV2ZW50cyA9IFtdO1xufVxuXG52YXIgRVZFTlRTID0gcmVxdWlyZShcIi4vXCIpLkVWRU5UUztcbk9iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtcblx0aWYoRVZFTlRTW25hbWVdID09PSAwKXtcblx0XHRuYW1lID0gXCJvblwiICsgbmFtZTtcblx0XHRDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpe1xuXHRcdFx0dGhpcy5ldmVudHMucHVzaChbbmFtZV0pO1xuXHRcdFx0aWYodGhpcy5fY2JzW25hbWVdKSB0aGlzLl9jYnNbbmFtZV0oKTtcblx0XHR9O1xuXHR9IGVsc2UgaWYoRVZFTlRTW25hbWVdID09PSAxKXtcblx0XHRuYW1lID0gXCJvblwiICsgbmFtZTtcblx0XHRDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbihhKXtcblx0XHRcdHRoaXMuZXZlbnRzLnB1c2goW25hbWUsIGFdKTtcblx0XHRcdGlmKHRoaXMuX2Nic1tuYW1lXSkgdGhpcy5fY2JzW25hbWVdKGEpO1xuXHRcdH07XG5cdH0gZWxzZSBpZihFVkVOVFNbbmFtZV0gPT09IDIpe1xuXHRcdG5hbWUgPSBcIm9uXCIgKyBuYW1lO1xuXHRcdENvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKGEsIGIpe1xuXHRcdFx0dGhpcy5ldmVudHMucHVzaChbbmFtZSwgYSwgYl0pO1xuXHRcdFx0aWYodGhpcy5fY2JzW25hbWVdKSB0aGlzLl9jYnNbbmFtZV0oYSwgYik7XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHR0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHNcIik7XG5cdH1cbn0pO1xuXG5Db2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGUub25yZXNldCA9IGZ1bmN0aW9uKCl7XG5cdHRoaXMuZXZlbnRzID0gW107XG5cdGlmKHRoaXMuX2Nicy5vbnJlc2V0KSB0aGlzLl9jYnMub25yZXNldCgpO1xufTtcblxuQ29sbGVjdGluZ0hhbmRsZXIucHJvdG90eXBlLnJlc3RhcnQgPSBmdW5jdGlvbigpe1xuXHRpZih0aGlzLl9jYnMub25yZXNldCkgdGhpcy5fY2JzLm9ucmVzZXQoKTtcblxuXHRmb3IodmFyIGkgPSAwLCBsZW4gPSB0aGlzLmV2ZW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKyl7XG5cdFx0aWYodGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSl7XG5cblx0XHRcdHZhciBudW0gPSB0aGlzLmV2ZW50c1tpXS5sZW5ndGg7XG5cblx0XHRcdGlmKG51bSA9PT0gMSl7XG5cdFx0XHRcdHRoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0oKTtcblx0XHRcdH0gZWxzZSBpZihudW0gPT09IDIpe1xuXHRcdFx0XHR0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKHRoaXMuZXZlbnRzW2ldWzFdKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0odGhpcy5ldmVudHNbaV1bMV0sIHRoaXMuZXZlbnRzW2ldWzJdKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vaHRtbHBhcnNlcjIvbGliL0NvbGxlY3RpbmdIYW5kbGVyLmpzXG4vLyBtb2R1bGUgaWQgPSA4NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgaW5kZXggPSByZXF1aXJlKFwiLi9pbmRleC5qc1wiKSxcbiAgICBEb21IYW5kbGVyID0gaW5kZXguRG9tSGFuZGxlcixcbiAgICBEb21VdGlscyA9IGluZGV4LkRvbVV0aWxzO1xuXG4vL1RPRE86IG1ha2UgdGhpcyBhIHN0cmVhbWFibGUgaGFuZGxlclxuZnVuY3Rpb24gRmVlZEhhbmRsZXIoY2FsbGJhY2ssIG9wdGlvbnMpe1xuXHR0aGlzLmluaXQoY2FsbGJhY2ssIG9wdGlvbnMpO1xufVxuXG5yZXF1aXJlKFwiaW5oZXJpdHNcIikoRmVlZEhhbmRsZXIsIERvbUhhbmRsZXIpO1xuXG5GZWVkSGFuZGxlci5wcm90b3R5cGUuaW5pdCA9IERvbUhhbmRsZXI7XG5cbmZ1bmN0aW9uIGdldEVsZW1lbnRzKHdoYXQsIHdoZXJlKXtcblx0cmV0dXJuIERvbVV0aWxzLmdldEVsZW1lbnRzQnlUYWdOYW1lKHdoYXQsIHdoZXJlLCB0cnVlKTtcbn1cbmZ1bmN0aW9uIGdldE9uZUVsZW1lbnQod2hhdCwgd2hlcmUpe1xuXHRyZXR1cm4gRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCwgd2hlcmUsIHRydWUsIDEpWzBdO1xufVxuZnVuY3Rpb24gZmV0Y2god2hhdCwgd2hlcmUsIHJlY3Vyc2Upe1xuXHRyZXR1cm4gRG9tVXRpbHMuZ2V0VGV4dChcblx0XHREb21VdGlscy5nZXRFbGVtZW50c0J5VGFnTmFtZSh3aGF0LCB3aGVyZSwgcmVjdXJzZSwgMSlcblx0KS50cmltKCk7XG59XG5cbmZ1bmN0aW9uIGFkZENvbmRpdGlvbmFsbHkob2JqLCBwcm9wLCB3aGF0LCB3aGVyZSwgcmVjdXJzZSl7XG5cdHZhciB0bXAgPSBmZXRjaCh3aGF0LCB3aGVyZSwgcmVjdXJzZSk7XG5cdGlmKHRtcCkgb2JqW3Byb3BdID0gdG1wO1xufVxuXG52YXIgaXNWYWxpZEZlZWQgPSBmdW5jdGlvbih2YWx1ZSl7XG5cdHJldHVybiB2YWx1ZSA9PT0gXCJyc3NcIiB8fCB2YWx1ZSA9PT0gXCJmZWVkXCIgfHwgdmFsdWUgPT09IFwicmRmOlJERlwiO1xufTtcblxuRmVlZEhhbmRsZXIucHJvdG90eXBlLm9uZW5kID0gZnVuY3Rpb24oKXtcblx0dmFyIGZlZWQgPSB7fSxcblx0ICAgIGZlZWRSb290ID0gZ2V0T25lRWxlbWVudChpc1ZhbGlkRmVlZCwgdGhpcy5kb20pLFxuXHQgICAgdG1wLCBjaGlsZHM7XG5cblx0aWYoZmVlZFJvb3Qpe1xuXHRcdGlmKGZlZWRSb290Lm5hbWUgPT09IFwiZmVlZFwiKXtcblx0XHRcdGNoaWxkcyA9IGZlZWRSb290LmNoaWxkcmVuO1xuXG5cdFx0XHRmZWVkLnR5cGUgPSBcImF0b21cIjtcblx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZmVlZCwgXCJpZFwiLCBcImlkXCIsIGNoaWxkcyk7XG5cdFx0XHRhZGRDb25kaXRpb25hbGx5KGZlZWQsIFwidGl0bGVcIiwgXCJ0aXRsZVwiLCBjaGlsZHMpO1xuXHRcdFx0aWYoKHRtcCA9IGdldE9uZUVsZW1lbnQoXCJsaW5rXCIsIGNoaWxkcykpICYmICh0bXAgPSB0bXAuYXR0cmlicykgJiYgKHRtcCA9IHRtcC5ocmVmKSkgZmVlZC5saW5rID0gdG1wO1xuXHRcdFx0YWRkQ29uZGl0aW9uYWxseShmZWVkLCBcImRlc2NyaXB0aW9uXCIsIFwic3VidGl0bGVcIiwgY2hpbGRzKTtcblx0XHRcdGlmKCh0bXAgPSBmZXRjaChcInVwZGF0ZWRcIiwgY2hpbGRzKSkpIGZlZWQudXBkYXRlZCA9IG5ldyBEYXRlKHRtcCk7XG5cdFx0XHRhZGRDb25kaXRpb25hbGx5KGZlZWQsIFwiYXV0aG9yXCIsIFwiZW1haWxcIiwgY2hpbGRzLCB0cnVlKTtcblxuXHRcdFx0ZmVlZC5pdGVtcyA9IGdldEVsZW1lbnRzKFwiZW50cnlcIiwgY2hpbGRzKS5tYXAoZnVuY3Rpb24oaXRlbSl7XG5cdFx0XHRcdHZhciBlbnRyeSA9IHt9LCB0bXA7XG5cblx0XHRcdFx0aXRlbSA9IGl0ZW0uY2hpbGRyZW47XG5cblx0XHRcdFx0YWRkQ29uZGl0aW9uYWxseShlbnRyeSwgXCJpZFwiLCBcImlkXCIsIGl0ZW0pO1xuXHRcdFx0XHRhZGRDb25kaXRpb25hbGx5KGVudHJ5LCBcInRpdGxlXCIsIFwidGl0bGVcIiwgaXRlbSk7XG5cdFx0XHRcdGlmKCh0bXAgPSBnZXRPbmVFbGVtZW50KFwibGlua1wiLCBpdGVtKSkgJiYgKHRtcCA9IHRtcC5hdHRyaWJzKSAmJiAodG1wID0gdG1wLmhyZWYpKSBlbnRyeS5saW5rID0gdG1wO1xuXHRcdFx0XHRpZigodG1wID0gZmV0Y2goXCJzdW1tYXJ5XCIsIGl0ZW0pIHx8IGZldGNoKFwiY29udGVudFwiLCBpdGVtKSkpIGVudHJ5LmRlc2NyaXB0aW9uID0gdG1wO1xuXHRcdFx0XHRpZigodG1wID0gZmV0Y2goXCJ1cGRhdGVkXCIsIGl0ZW0pKSkgZW50cnkucHViRGF0ZSA9IG5ldyBEYXRlKHRtcCk7XG5cdFx0XHRcdHJldHVybiBlbnRyeTtcblx0XHRcdH0pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjaGlsZHMgPSBnZXRPbmVFbGVtZW50KFwiY2hhbm5lbFwiLCBmZWVkUm9vdC5jaGlsZHJlbikuY2hpbGRyZW47XG5cblx0XHRcdGZlZWQudHlwZSA9IGZlZWRSb290Lm5hbWUuc3Vic3RyKDAsIDMpO1xuXHRcdFx0ZmVlZC5pZCA9IFwiXCI7XG5cdFx0XHRhZGRDb25kaXRpb25hbGx5KGZlZWQsIFwidGl0bGVcIiwgXCJ0aXRsZVwiLCBjaGlsZHMpO1xuXHRcdFx0YWRkQ29uZGl0aW9uYWxseShmZWVkLCBcImxpbmtcIiwgXCJsaW5rXCIsIGNoaWxkcyk7XG5cdFx0XHRhZGRDb25kaXRpb25hbGx5KGZlZWQsIFwiZGVzY3JpcHRpb25cIiwgXCJkZXNjcmlwdGlvblwiLCBjaGlsZHMpO1xuXHRcdFx0aWYoKHRtcCA9IGZldGNoKFwibGFzdEJ1aWxkRGF0ZVwiLCBjaGlsZHMpKSkgZmVlZC51cGRhdGVkID0gbmV3IERhdGUodG1wKTtcblx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZmVlZCwgXCJhdXRob3JcIiwgXCJtYW5hZ2luZ0VkaXRvclwiLCBjaGlsZHMsIHRydWUpO1xuXG5cdFx0XHRmZWVkLml0ZW1zID0gZ2V0RWxlbWVudHMoXCJpdGVtXCIsIGZlZWRSb290LmNoaWxkcmVuKS5tYXAoZnVuY3Rpb24oaXRlbSl7XG5cdFx0XHRcdHZhciBlbnRyeSA9IHt9LCB0bXA7XG5cblx0XHRcdFx0aXRlbSA9IGl0ZW0uY2hpbGRyZW47XG5cblx0XHRcdFx0YWRkQ29uZGl0aW9uYWxseShlbnRyeSwgXCJpZFwiLCBcImd1aWRcIiwgaXRlbSk7XG5cdFx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZW50cnksIFwidGl0bGVcIiwgXCJ0aXRsZVwiLCBpdGVtKTtcblx0XHRcdFx0YWRkQ29uZGl0aW9uYWxseShlbnRyeSwgXCJsaW5rXCIsIFwibGlua1wiLCBpdGVtKTtcblx0XHRcdFx0YWRkQ29uZGl0aW9uYWxseShlbnRyeSwgXCJkZXNjcmlwdGlvblwiLCBcImRlc2NyaXB0aW9uXCIsIGl0ZW0pO1xuXHRcdFx0XHRpZigodG1wID0gZmV0Y2goXCJwdWJEYXRlXCIsIGl0ZW0pKSkgZW50cnkucHViRGF0ZSA9IG5ldyBEYXRlKHRtcCk7XG5cdFx0XHRcdHJldHVybiBlbnRyeTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXHR0aGlzLmRvbSA9IGZlZWQ7XG5cdERvbUhhbmRsZXIucHJvdG90eXBlLl9oYW5kbGVDYWxsYmFjay5jYWxsKFxuXHRcdHRoaXMsIGZlZWRSb290ID8gbnVsbCA6IEVycm9yKFwiY291bGRuJ3QgZmluZCByb290IG9mIGZlZWRcIilcblx0KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRmVlZEhhbmRsZXI7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vaHRtbHBhcnNlcjIvbGliL0ZlZWRIYW5kbGVyLmpzXG4vLyBtb2R1bGUgaWQgPSA4N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IFByb3h5SGFuZGxlcjtcblxuZnVuY3Rpb24gUHJveHlIYW5kbGVyKGNicyl7XG5cdHRoaXMuX2NicyA9IGNicyB8fCB7fTtcbn1cblxudmFyIEVWRU5UUyA9IHJlcXVpcmUoXCIuL1wiKS5FVkVOVFM7XG5PYmplY3Qua2V5cyhFVkVOVFMpLmZvckVhY2goZnVuY3Rpb24obmFtZSl7XG5cdGlmKEVWRU5UU1tuYW1lXSA9PT0gMCl7XG5cdFx0bmFtZSA9IFwib25cIiArIG5hbWU7XG5cdFx0UHJveHlIYW5kbGVyLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCl7XG5cdFx0XHRpZih0aGlzLl9jYnNbbmFtZV0pIHRoaXMuX2Nic1tuYW1lXSgpO1xuXHRcdH07XG5cdH0gZWxzZSBpZihFVkVOVFNbbmFtZV0gPT09IDEpe1xuXHRcdG5hbWUgPSBcIm9uXCIgKyBuYW1lO1xuXHRcdFByb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbihhKXtcblx0XHRcdGlmKHRoaXMuX2Nic1tuYW1lXSkgdGhpcy5fY2JzW25hbWVdKGEpO1xuXHRcdH07XG5cdH0gZWxzZSBpZihFVkVOVFNbbmFtZV0gPT09IDIpe1xuXHRcdG5hbWUgPSBcIm9uXCIgKyBuYW1lO1xuXHRcdFByb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbihhLCBiKXtcblx0XHRcdGlmKHRoaXMuX2Nic1tuYW1lXSkgdGhpcy5fY2JzW25hbWVdKGEsIGIpO1xuXHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0dGhyb3cgRXJyb3IoXCJ3cm9uZyBudW1iZXIgb2YgYXJndW1lbnRzXCIpO1xuXHR9XG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vaHRtbHBhcnNlcjIvbGliL1Byb3h5SGFuZGxlci5qc1xuLy8gbW9kdWxlIGlkID0gODhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBQYXJzZXIgPSByZXF1aXJlKFwiLi9Xcml0YWJsZVN0cmVhbS5qc1wiKTtcblxuZnVuY3Rpb24gU3RyZWFtKG9wdGlvbnMpe1xuXHRQYXJzZXIuY2FsbCh0aGlzLCBuZXcgQ2JzKHRoaXMpLCBvcHRpb25zKTtcbn1cblxucmVxdWlyZShcImluaGVyaXRzXCIpKFN0cmVhbSwgUGFyc2VyKTtcblxuU3RyZWFtLnByb3RvdHlwZS5yZWFkYWJsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIENicyhzY29wZSl7XG5cdHRoaXMuc2NvcGUgPSBzY29wZTtcbn1cblxudmFyIEVWRU5UUyA9IHJlcXVpcmUoXCIuLi9cIikuRVZFTlRTO1xuXG5PYmplY3Qua2V5cyhFVkVOVFMpLmZvckVhY2goZnVuY3Rpb24obmFtZSl7XG5cdGlmKEVWRU5UU1tuYW1lXSA9PT0gMCl7XG5cdFx0Q2JzLnByb3RvdHlwZVtcIm9uXCIgKyBuYW1lXSA9IGZ1bmN0aW9uKCl7XG5cdFx0XHR0aGlzLnNjb3BlLmVtaXQobmFtZSk7XG5cdFx0fTtcblx0fSBlbHNlIGlmKEVWRU5UU1tuYW1lXSA9PT0gMSl7XG5cdFx0Q2JzLnByb3RvdHlwZVtcIm9uXCIgKyBuYW1lXSA9IGZ1bmN0aW9uKGEpe1xuXHRcdFx0dGhpcy5zY29wZS5lbWl0KG5hbWUsIGEpO1xuXHRcdH07XG5cdH0gZWxzZSBpZihFVkVOVFNbbmFtZV0gPT09IDIpe1xuXHRcdENicy5wcm90b3R5cGVbXCJvblwiICsgbmFtZV0gPSBmdW5jdGlvbihhLCBiKXtcblx0XHRcdHRoaXMuc2NvcGUuZW1pdChuYW1lLCBhLCBiKTtcblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdHRocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50cyFcIik7XG5cdH1cbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9odG1scGFyc2VyMi9saWIvU3RyZWFtLmpzXG4vLyBtb2R1bGUgaWQgPSA4OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9pZWVlNzU0L2luZGV4LmpzXG4vLyBtb2R1bGUgaWQgPSA5MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKlxuIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU0hBIGZhbWlseSBvZiBoYXNoZXMsIGFzXG4gZGVmaW5lZCBpbiBGSVBTIFBVQiAxODAtMiBhcyB3ZWxsIGFzIHRoZSBjb3JyZXNwb25kaW5nIEhNQUMgaW1wbGVtZW50YXRpb25cbiBhcyBkZWZpbmVkIGluIEZJUFMgUFVCIDE5OGFcblxuIENvcHlyaWdodCBCcmlhbiBUdXJlayAyMDA4LTIwMTZcbiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiBTZWUgaHR0cDovL2NhbGlnYXRpby5naXRodWIuY29tL2pzU0hBLyBmb3IgbW9yZSBpbmZvcm1hdGlvblxuXG4gU2V2ZXJhbCBmdW5jdGlvbnMgdGFrZW4gZnJvbSBQYXVsIEpvaG5zdG9uXG4qL1xuJ3VzZSBzdHJpY3QnOyhmdW5jdGlvbihWKXtmdW5jdGlvbiBBKGEsYixjKXt2YXIgZT0wLGY9WzBdLGs9XCJcIixoPW51bGwsaz1jfHxcIlVURjhcIjtpZihcIlVURjhcIiE9PWsmJlwiVVRGMTZCRVwiIT09ayYmXCJVVEYxNkxFXCIhPT1rKXRocm93XCJlbmNvZGluZyBtdXN0IGJlIFVURjgsIFVURjE2QkUsIG9yIFVURjE2TEVcIjtpZihcIkhFWFwiPT09Yil7aWYoMCE9PWEubGVuZ3RoJTIpdGhyb3dcInNyY1N0cmluZyBvZiBIRVggdHlwZSBtdXN0IGJlIGluIGJ5dGUgaW5jcmVtZW50c1wiO2g9RShhKTtlPWguYmluTGVuO2Y9aC52YWx1ZX1lbHNlIGlmKFwiVEVYVFwiPT09Ynx8XCJBU0NJSVwiPT09YiloPU0oYSxrKSxlPWguYmluTGVuLGY9aC52YWx1ZTtlbHNlIGlmKFwiQjY0XCI9PT1iKWg9TihhKSxlPWguYmluTGVuLGY9aC52YWx1ZTtlbHNlIGlmKFwiQllURVNcIj09PWIpaD1PKGEpLGU9aC5iaW5MZW4sZj1oLnZhbHVlO2Vsc2UgdGhyb3dcImlucHV0Rm9ybWF0IG11c3QgYmUgSEVYLCBURVhULCBBU0NJSSwgQjY0LCBvciBCWVRFU1wiO1xudGhpcy5nZXRIYXNoPWZ1bmN0aW9uKGEsYixjLGspe3ZhciBoPW51bGwsZD1mLnNsaWNlKCksbj1lLG07Mz09PWFyZ3VtZW50cy5sZW5ndGg/XCJudW1iZXJcIiE9PXR5cGVvZiBjJiYoaz1jLGM9MSk6Mj09PWFyZ3VtZW50cy5sZW5ndGgmJihjPTEpO2lmKGMhPT1wYXJzZUludChjLDEwKXx8MT5jKXRocm93XCJudW1Sb3VuZHMgbXVzdCBhIGludGVnZXIgPj0gMVwiO3N3aXRjaChiKXtjYXNlIFwiSEVYXCI6aD1QO2JyZWFrO2Nhc2UgXCJCNjRcIjpoPVE7YnJlYWs7Y2FzZSBcIkJZVEVTXCI6aD1SO2JyZWFrO2RlZmF1bHQ6dGhyb3dcImZvcm1hdCBtdXN0IGJlIEhFWCwgQjY0LCBvciBCWVRFU1wiO31pZihcIlNIQS0xXCI9PT1hKWZvcihtPTA7bTxjO20rPTEpZD1CKGQsbiksbj0xNjA7ZWxzZSBpZihcIlNIQS0yMjRcIj09PWEpZm9yKG09MDttPGM7bSs9MSlkPXgoZCxuLGEpLG49MjI0O2Vsc2UgaWYoXCJTSEEtMjU2XCI9PT1hKWZvcihtPTA7bTxjO20rPTEpZD14KGQsbixhKSxuPTI1NjtlbHNlIGlmKFwiU0hBLTM4NFwiPT09XG5hKWZvcihtPTA7bTxjO20rPTEpZD14KGQsbixhKSxuPTM4NDtlbHNlIGlmKFwiU0hBLTUxMlwiPT09YSlmb3IobT0wO208YzttKz0xKWQ9eChkLG4sYSksbj01MTI7ZWxzZSB0aHJvd1wiQ2hvc2VuIFNIQSB2YXJpYW50IGlzIG5vdCBzdXBwb3J0ZWRcIjtyZXR1cm4gaChkLFMoaykpfTt0aGlzLmdldEhNQUM9ZnVuY3Rpb24oYSxiLGMsaCxxKXt2YXIgZCxuLG0sdSxyPVtdLHY9W107ZD1udWxsO3N3aXRjaChoKXtjYXNlIFwiSEVYXCI6aD1QO2JyZWFrO2Nhc2UgXCJCNjRcIjpoPVE7YnJlYWs7Y2FzZSBcIkJZVEVTXCI6aD1SO2JyZWFrO2RlZmF1bHQ6dGhyb3dcIm91dHB1dEZvcm1hdCBtdXN0IGJlIEhFWCwgQjY0LCBvciBCWVRFU1wiO31pZihcIlNIQS0xXCI9PT1jKW49NjQsdT0xNjA7ZWxzZSBpZihcIlNIQS0yMjRcIj09PWMpbj02NCx1PTIyNDtlbHNlIGlmKFwiU0hBLTI1NlwiPT09YyluPTY0LHU9MjU2O2Vsc2UgaWYoXCJTSEEtMzg0XCI9PT1jKW49MTI4LHU9Mzg0O2Vsc2UgaWYoXCJTSEEtNTEyXCI9PT1jKW49XG4xMjgsdT01MTI7ZWxzZSB0aHJvd1wiQ2hvc2VuIFNIQSB2YXJpYW50IGlzIG5vdCBzdXBwb3J0ZWRcIjtpZihcIkhFWFwiPT09YilkPUUoYSksbT1kLmJpbkxlbixkPWQudmFsdWU7ZWxzZSBpZihcIlRFWFRcIj09PWJ8fFwiQVNDSUlcIj09PWIpZD1NKGEsayksbT1kLmJpbkxlbixkPWQudmFsdWU7ZWxzZSBpZihcIkI2NFwiPT09YilkPU4oYSksbT1kLmJpbkxlbixkPWQudmFsdWU7ZWxzZSBpZihcIkJZVEVTXCI9PT1iKWQ9TyhhKSxtPWQuYmluTGVuLGQ9ZC52YWx1ZTtlbHNlIHRocm93XCJpbnB1dEZvcm1hdCBtdXN0IGJlIEhFWCwgVEVYVCwgQVNDSUksIEI2NCwgb3IgQllURVNcIjthPTgqbjtiPW4vNC0xO2lmKG48bS84KXtmb3IoZD1cIlNIQS0xXCI9PT1jP0IoZCxtKTp4KGQsbSxjKTtkLmxlbmd0aDw9YjspZC5wdXNoKDApO2RbYl0mPTQyOTQ5NjcwNDB9ZWxzZSBpZihuPm0vOCl7Zm9yKDtkLmxlbmd0aDw9YjspZC5wdXNoKDApO2RbYl0mPTQyOTQ5NjcwNDB9Zm9yKG49MDtuPD1iO24rPTEpcltuXT1kW25dXlxuOTA5NTIyNDg2LHZbbl09ZFtuXV4xNTQ5NTU2ODI4O2M9XCJTSEEtMVwiPT09Yz9CKHYuY29uY2F0KEIoci5jb25jYXQoZiksYStlKSksYSt1KTp4KHYuY29uY2F0KHgoci5jb25jYXQoZiksYStlLGMpKSxhK3UsYyk7cmV0dXJuIGgoYyxTKHEpKX19ZnVuY3Rpb24gcShhLGIpe3RoaXMuYT1hO3RoaXMuYj1ifWZ1bmN0aW9uIE0oYSxiKXt2YXIgYz1bXSxlLGY9W10saz0wLGgscCxxO2lmKFwiVVRGOFwiPT09Yilmb3IoaD0wO2g8YS5sZW5ndGg7aCs9MSlmb3IoZT1hLmNoYXJDb2RlQXQoaCksZj1bXSwxMjg+ZT9mLnB1c2goZSk6MjA0OD5lPyhmLnB1c2goMTkyfGU+Pj42KSxmLnB1c2goMTI4fGUmNjMpKTo1NTI5Nj5lfHw1NzM0NDw9ZT9mLnB1c2goMjI0fGU+Pj4xMiwxMjh8ZT4+PjYmNjMsMTI4fGUmNjMpOihoKz0xLGU9NjU1MzYrKChlJjEwMjMpPDwxMHxhLmNoYXJDb2RlQXQoaCkmMTAyMyksZi5wdXNoKDI0MHxlPj4+MTgsMTI4fGU+Pj4xMiY2MywxMjh8ZT4+PjYmNjMsMTI4fGUmNjMpKSxcbnA9MDtwPGYubGVuZ3RoO3ArPTEpe2ZvcihxPWs+Pj4yO2MubGVuZ3RoPD1xOyljLnB1c2goMCk7Y1txXXw9ZltwXTw8MjQtayU0Kjg7ays9MX1lbHNlIGlmKFwiVVRGMTZCRVwiPT09Ynx8XCJVVEYxNkxFXCI9PT1iKWZvcihoPTA7aDxhLmxlbmd0aDtoKz0xKXtlPWEuY2hhckNvZGVBdChoKTtcIlVURjE2TEVcIj09PWImJihwPWUmMjU1LGU9cDw8OHxlPj44KTtmb3IocT1rPj4+MjtjLmxlbmd0aDw9cTspYy5wdXNoKDApO2NbcV18PWU8PDE2LWslNCo4O2srPTJ9cmV0dXJue3ZhbHVlOmMsYmluTGVuOjgqa319ZnVuY3Rpb24gRShhKXt2YXIgYj1bXSxjPWEubGVuZ3RoLGUsZixrO2lmKDAhPT1jJTIpdGhyb3dcIlN0cmluZyBvZiBIRVggdHlwZSBtdXN0IGJlIGluIGJ5dGUgaW5jcmVtZW50c1wiO2ZvcihlPTA7ZTxjO2UrPTIpe2Y9cGFyc2VJbnQoYS5zdWJzdHIoZSwyKSwxNik7aWYoaXNOYU4oZikpdGhyb3dcIlN0cmluZyBvZiBIRVggdHlwZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnNcIjtcbmZvcihrPWU+Pj4zO2IubGVuZ3RoPD1rOyliLnB1c2goMCk7YltlPj4+M118PWY8PDI0LWUlOCo0fXJldHVybnt2YWx1ZTpiLGJpbkxlbjo0KmN9fWZ1bmN0aW9uIE8oYSl7dmFyIGI9W10sYyxlLGY7Zm9yKGU9MDtlPGEubGVuZ3RoO2UrPTEpYz1hLmNoYXJDb2RlQXQoZSksZj1lPj4+MixiLmxlbmd0aDw9ZiYmYi5wdXNoKDApLGJbZl18PWM8PDI0LWUlNCo4O3JldHVybnt2YWx1ZTpiLGJpbkxlbjo4KmEubGVuZ3RofX1mdW5jdGlvbiBOKGEpe3ZhciBiPVtdLGM9MCxlLGYsayxoLHA7aWYoLTE9PT1hLnNlYXJjaCgvXlthLXpBLVowLTk9K1xcL10rJC8pKXRocm93XCJJbnZhbGlkIGNoYXJhY3RlciBpbiBiYXNlLTY0IHN0cmluZ1wiO2Y9YS5pbmRleE9mKFwiPVwiKTthPWEucmVwbGFjZSgvXFw9L2csXCJcIik7aWYoLTEhPT1mJiZmPGEubGVuZ3RoKXRocm93XCJJbnZhbGlkICc9JyBmb3VuZCBpbiBiYXNlLTY0IHN0cmluZ1wiO2ZvcihmPTA7ZjxhLmxlbmd0aDtmKz00KXtwPWEuc3Vic3RyKGYsNCk7XG5mb3Ioaz1oPTA7azxwLmxlbmd0aDtrKz0xKWU9XCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvXCIuaW5kZXhPZihwW2tdKSxofD1lPDwxOC02Kms7Zm9yKGs9MDtrPHAubGVuZ3RoLTE7ays9MSl7Zm9yKGU9Yz4+PjI7Yi5sZW5ndGg8PWU7KWIucHVzaCgwKTtiW2VdfD0oaD4+PjE2LTgqayYyNTUpPDwyNC1jJTQqODtjKz0xfX1yZXR1cm57dmFsdWU6YixiaW5MZW46OCpjfX1mdW5jdGlvbiBQKGEsYil7dmFyIGM9XCJcIixlPTQqYS5sZW5ndGgsZixrO2ZvcihmPTA7ZjxlO2YrPTEpaz1hW2Y+Pj4yXT4+PjgqKDMtZiU0KSxjKz1cIjAxMjM0NTY3ODlhYmNkZWZcIi5jaGFyQXQoaz4+PjQmMTUpK1wiMDEyMzQ1Njc4OWFiY2RlZlwiLmNoYXJBdChrJjE1KTtyZXR1cm4gYi5vdXRwdXRVcHBlcj9jLnRvVXBwZXJDYXNlKCk6Y31mdW5jdGlvbiBRKGEsYil7dmFyIGM9XCJcIixlPTQqYS5sZW5ndGgsZixrLGg7Zm9yKGY9MDtmPGU7Zis9XG4zKWZvcihoPWYrMT4+PjIsaz1hLmxlbmd0aDw9aD8wOmFbaF0saD1mKzI+Pj4yLGg9YS5sZW5ndGg8PWg/MDphW2hdLGg9KGFbZj4+PjJdPj4+OCooMy1mJTQpJjI1NSk8PDE2fChrPj4+OCooMy0oZisxKSU0KSYyNTUpPDw4fGg+Pj44KigzLShmKzIpJTQpJjI1NSxrPTA7ND5rO2srPTEpOCpmKzYqazw9MzIqYS5sZW5ndGg/Yys9XCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvXCIuY2hhckF0KGg+Pj42KigzLWspJjYzKTpjKz1iLmI2NFBhZDtyZXR1cm4gY31mdW5jdGlvbiBSKGEpe3ZhciBiPVwiXCIsYz00KmEubGVuZ3RoLGUsZjtmb3IoZT0wO2U8YztlKz0xKWY9YVtlPj4+Ml0+Pj44KigzLWUlNCkmMjU1LGIrPVN0cmluZy5mcm9tQ2hhckNvZGUoZik7cmV0dXJuIGJ9ZnVuY3Rpb24gUyhhKXt2YXIgYj17b3V0cHV0VXBwZXI6ITEsYjY0UGFkOlwiPVwifTt0cnl7YS5oYXNPd25Qcm9wZXJ0eShcIm91dHB1dFVwcGVyXCIpJiZcbihiLm91dHB1dFVwcGVyPWEub3V0cHV0VXBwZXIpLGEuaGFzT3duUHJvcGVydHkoXCJiNjRQYWRcIikmJihiLmI2NFBhZD1hLmI2NFBhZCl9Y2F0Y2goYyl7fWlmKFwiYm9vbGVhblwiIT09dHlwZW9mIGIub3V0cHV0VXBwZXIpdGhyb3dcIkludmFsaWQgb3V0cHV0VXBwZXIgZm9ybWF0dGluZyBvcHRpb25cIjtpZihcInN0cmluZ1wiIT09dHlwZW9mIGIuYjY0UGFkKXRocm93XCJJbnZhbGlkIGI2NFBhZCBmb3JtYXR0aW5nIG9wdGlvblwiO3JldHVybiBifWZ1bmN0aW9uIHkoYSxiKXtyZXR1cm4gYTw8YnxhPj4+MzItYn1mdW5jdGlvbiByKGEsYil7cmV0dXJuIGE+Pj5ifGE8PDMyLWJ9ZnVuY3Rpb24gdihhLGIpe3ZhciBjPW51bGwsYz1uZXcgcShhLmEsYS5iKTtyZXR1cm4gYz0zMj49Yj9uZXcgcShjLmE+Pj5ifGMuYjw8MzItYiY0Mjk0OTY3Mjk1LGMuYj4+PmJ8Yy5hPDwzMi1iJjQyOTQ5NjcyOTUpOm5ldyBxKGMuYj4+PmItMzJ8Yy5hPDw2NC1iJjQyOTQ5NjcyOTUsYy5hPj4+Yi0zMnxjLmI8PDY0LVxuYiY0Mjk0OTY3Mjk1KX1mdW5jdGlvbiBUKGEsYil7dmFyIGM9bnVsbDtyZXR1cm4gYz0zMj49Yj9uZXcgcShhLmE+Pj5iLGEuYj4+PmJ8YS5hPDwzMi1iJjQyOTQ5NjcyOTUpOm5ldyBxKDAsYS5hPj4+Yi0zMil9ZnVuY3Rpb24gVyhhLGIsYyl7cmV0dXJuIGEmYl5+YSZjfWZ1bmN0aW9uIFgoYSxiLGMpe3JldHVybiBuZXcgcShhLmEmYi5hXn5hLmEmYy5hLGEuYiZiLmJefmEuYiZjLmIpfWZ1bmN0aW9uIFUoYSxiLGMpe3JldHVybiBhJmJeYSZjXmImY31mdW5jdGlvbiBZKGEsYixjKXtyZXR1cm4gbmV3IHEoYS5hJmIuYV5hLmEmYy5hXmIuYSZjLmEsYS5iJmIuYl5hLmImYy5iXmIuYiZjLmIpfWZ1bmN0aW9uIFooYSl7cmV0dXJuIHIoYSwyKV5yKGEsMTMpXnIoYSwyMil9ZnVuY3Rpb24gYWEoYSl7dmFyIGI9dihhLDI4KSxjPXYoYSwzNCk7YT12KGEsMzkpO3JldHVybiBuZXcgcShiLmFeYy5hXmEuYSxiLmJeYy5iXmEuYil9ZnVuY3Rpb24gYmEoYSl7cmV0dXJuIHIoYSw2KV5yKGEsXG4xMSlecihhLDI1KX1mdW5jdGlvbiBjYShhKXt2YXIgYj12KGEsMTQpLGM9dihhLDE4KTthPXYoYSw0MSk7cmV0dXJuIG5ldyBxKGIuYV5jLmFeYS5hLGIuYl5jLmJeYS5iKX1mdW5jdGlvbiBkYShhKXtyZXR1cm4gcihhLDcpXnIoYSwxOCleYT4+PjN9ZnVuY3Rpb24gZWEoYSl7dmFyIGI9dihhLDEpLGM9dihhLDgpO2E9VChhLDcpO3JldHVybiBuZXcgcShiLmFeYy5hXmEuYSxiLmJeYy5iXmEuYil9ZnVuY3Rpb24gZmEoYSl7cmV0dXJuIHIoYSwxNylecihhLDE5KV5hPj4+MTB9ZnVuY3Rpb24gZ2EoYSl7dmFyIGI9dihhLDE5KSxjPXYoYSw2MSk7YT1UKGEsNik7cmV0dXJuIG5ldyBxKGIuYV5jLmFeYS5hLGIuYl5jLmJeYS5iKX1mdW5jdGlvbiBEKGEsYil7dmFyIGM9KGEmNjU1MzUpKyhiJjY1NTM1KTtyZXR1cm4oKGE+Pj4xNikrKGI+Pj4xNikrKGM+Pj4xNikmNjU1MzUpPDwxNnxjJjY1NTM1fWZ1bmN0aW9uIGhhKGEsYixjLGUpe3ZhciBmPShhJjY1NTM1KSsoYiY2NTUzNSkrKGMmXG42NTUzNSkrKGUmNjU1MzUpO3JldHVybigoYT4+PjE2KSsoYj4+PjE2KSsoYz4+PjE2KSsoZT4+PjE2KSsoZj4+PjE2KSY2NTUzNSk8PDE2fGYmNjU1MzV9ZnVuY3Rpb24gRihhLGIsYyxlLGYpe3ZhciBrPShhJjY1NTM1KSsoYiY2NTUzNSkrKGMmNjU1MzUpKyhlJjY1NTM1KSsoZiY2NTUzNSk7cmV0dXJuKChhPj4+MTYpKyhiPj4+MTYpKyhjPj4+MTYpKyhlPj4+MTYpKyhmPj4+MTYpKyhrPj4+MTYpJjY1NTM1KTw8MTZ8ayY2NTUzNX1mdW5jdGlvbiBpYShhLGIpe3ZhciBjLGUsZjtjPShhLmImNjU1MzUpKyhiLmImNjU1MzUpO2U9KGEuYj4+PjE2KSsoYi5iPj4+MTYpKyhjPj4+MTYpO2Y9KGUmNjU1MzUpPDwxNnxjJjY1NTM1O2M9KGEuYSY2NTUzNSkrKGIuYSY2NTUzNSkrKGU+Pj4xNik7ZT0oYS5hPj4+MTYpKyhiLmE+Pj4xNikrKGM+Pj4xNik7cmV0dXJuIG5ldyBxKChlJjY1NTM1KTw8MTZ8YyY2NTUzNSxmKX1mdW5jdGlvbiBqYShhLGIsYyxlKXt2YXIgZixrLGg7Zj0oYS5iJjY1NTM1KStcbihiLmImNjU1MzUpKyhjLmImNjU1MzUpKyhlLmImNjU1MzUpO2s9KGEuYj4+PjE2KSsoYi5iPj4+MTYpKyhjLmI+Pj4xNikrKGUuYj4+PjE2KSsoZj4+PjE2KTtoPShrJjY1NTM1KTw8MTZ8ZiY2NTUzNTtmPShhLmEmNjU1MzUpKyhiLmEmNjU1MzUpKyhjLmEmNjU1MzUpKyhlLmEmNjU1MzUpKyhrPj4+MTYpO2s9KGEuYT4+PjE2KSsoYi5hPj4+MTYpKyhjLmE+Pj4xNikrKGUuYT4+PjE2KSsoZj4+PjE2KTtyZXR1cm4gbmV3IHEoKGsmNjU1MzUpPDwxNnxmJjY1NTM1LGgpfWZ1bmN0aW9uIGthKGEsYixjLGUsZil7dmFyIGssaCxwO2s9KGEuYiY2NTUzNSkrKGIuYiY2NTUzNSkrKGMuYiY2NTUzNSkrKGUuYiY2NTUzNSkrKGYuYiY2NTUzNSk7aD0oYS5iPj4+MTYpKyhiLmI+Pj4xNikrKGMuYj4+PjE2KSsoZS5iPj4+MTYpKyhmLmI+Pj4xNikrKGs+Pj4xNik7cD0oaCY2NTUzNSk8PDE2fGsmNjU1MzU7az0oYS5hJjY1NTM1KSsoYi5hJjY1NTM1KSsoYy5hJjY1NTM1KSsoZS5hJjY1NTM1KStcbihmLmEmNjU1MzUpKyhoPj4+MTYpO2g9KGEuYT4+PjE2KSsoYi5hPj4+MTYpKyhjLmE+Pj4xNikrKGUuYT4+PjE2KSsoZi5hPj4+MTYpKyhrPj4+MTYpO3JldHVybiBuZXcgcSgoaCY2NTUzNSk8PDE2fGsmNjU1MzUscCl9ZnVuY3Rpb24gQihhLGIpe3ZhciBjPVtdLGUsZixrLGgscCxxLHIsdCx2LGQ9WzE3MzI1ODQxOTMsNDAyMzIzMzQxNywyNTYyMzgzMTAyLDI3MTczMzg3OCwzMjg1Mzc3NTIwXTtmb3IoZT0oYis2NT4+Pjk8PDQpKzE1O2EubGVuZ3RoPD1lOylhLnB1c2goMCk7YVtiPj4+NV18PTEyODw8MjQtYiUzMjthW2VdPWImNDI5NDk2NzI5NTthW2UtMV09Yi80Mjk0OTY3Mjk2fDA7dj1hLmxlbmd0aDtmb3Iocj0wO3I8djtyKz0xNil7ZT1kWzBdO2Y9ZFsxXTtrPWRbMl07aD1kWzNdO3A9ZFs0XTtmb3IodD0wOzgwPnQ7dCs9MSljW3RdPTE2PnQ/YVt0K3JdOnkoY1t0LTNdXmNbdC04XV5jW3QtMTRdXmNbdC0xNl0sMSkscT0yMD50P0YoeShlLDUpLGYma15+ZiZoLHAsMTUxODUwMDI0OSxcbmNbdF0pOjQwPnQ/Rih5KGUsNSksZl5rXmgscCwxODU5Nzc1MzkzLGNbdF0pOjYwPnQ/Rih5KGUsNSksVShmLGssaCkscCwyNDAwOTU5NzA4LGNbdF0pOkYoeShlLDUpLGZea15oLHAsMzM5NTQ2OTc4MixjW3RdKSxwPWgsaD1rLGs9eShmLDMwKSxmPWUsZT1xO2RbMF09RChlLGRbMF0pO2RbMV09RChmLGRbMV0pO2RbMl09RChrLGRbMl0pO2RbM109RChoLGRbM10pO2RbNF09RChwLGRbNF0pfXJldHVybiBkfWZ1bmN0aW9uIHgoYSxiLGMpe3ZhciBlLGYsayxoLHAscix2LHQseixkLG4sbSx1LHgseSx3LEEsQixHLEgsSSxKLEssTCxnLEM9W10sRSxsPVsxMTE2MzUyNDA4LDE4OTk0NDc0NDEsMzA0OTMyMzQ3MSwzOTIxMDA5NTczLDk2MTk4NzE2MywxNTA4OTcwOTkzLDI0NTM2MzU3NDgsMjg3MDc2MzIyMSwzNjI0MzgxMDgwLDMxMDU5ODQwMSw2MDcyMjUyNzgsMTQyNjg4MTk4NywxOTI1MDc4Mzg4LDIxNjIwNzgyMDYsMjYxNDg4ODEwMywzMjQ4MjIyNTgwLDM4MzUzOTA0MDEsNDAyMjIyNDc3NCxcbjI2NDM0NzA3OCw2MDQ4MDc2MjgsNzcwMjU1OTgzLDEyNDkxNTAxMjIsMTU1NTA4MTY5MiwxOTk2MDY0OTg2LDI1NTQyMjA4ODIsMjgyMTgzNDM0OSwyOTUyOTk2ODA4LDMyMTAzMTM2NzEsMzMzNjU3MTg5MSwzNTg0NTI4NzExLDExMzkyNjk5MywzMzgyNDE4OTUsNjY2MzA3MjA1LDc3MzUyOTkxMiwxMjk0NzU3MzcyLDEzOTYxODIyOTEsMTY5NTE4MzcwMCwxOTg2NjYxMDUxLDIxNzcwMjYzNTAsMjQ1Njk1NjAzNywyNzMwNDg1OTIxLDI4MjAzMDI0MTEsMzI1OTczMDgwMCwzMzQ1NzY0NzcxLDM1MTYwNjU4MTcsMzYwMDM1MjgwNCw0MDk0NTcxOTA5LDI3NTQyMzM0NCw0MzAyMjc3MzQsNTA2OTQ4NjE2LDY1OTA2MDU1Niw4ODM5OTc4NzcsOTU4MTM5NTcxLDEzMjI4MjIyMTgsMTUzNzAwMjA2MywxNzQ3ODczNzc5LDE5NTU1NjIyMjIsMjAyNDEwNDgxNSwyMjI3NzMwNDUyLDIzNjE4NTI0MjQsMjQyODQzNjQ3NCwyNzU2NzM0MTg3LDMyMDQwMzE0NzksMzMyOTMyNTI5OF07ZD1bMzIzODM3MTAzMixcbjkxNDE1MDY2Myw4MTI3MDI5OTksNDE0NDkxMjY5Nyw0MjkwNzc1ODU3LDE3NTA2MDMwMjUsMTY5NDA3NjgzOSwzMjA0MDc1NDI4XTtmPVsxNzc5MDMzNzAzLDMxNDQxMzQyNzcsMTAxMzkwNDI0MiwyNzczNDgwNzYyLDEzNTk4OTMxMTksMjYwMDgyMjkyNCw1Mjg3MzQ2MzUsMTU0MTQ1OTIyNV07aWYoXCJTSEEtMjI0XCI9PT1jfHxcIlNIQS0yNTZcIj09PWMpbj02NCxlPShiKzY1Pj4+OTw8NCkrMTUseD0xNix5PTEsZz1OdW1iZXIsdz1ELEE9aGEsQj1GLEc9ZGEsSD1mYSxJPVosSj1iYSxMPVUsSz1XLGQ9XCJTSEEtMjI0XCI9PT1jP2Q6ZjtlbHNlIGlmKFwiU0hBLTM4NFwiPT09Y3x8XCJTSEEtNTEyXCI9PT1jKW49ODAsZT0oYisxMjk+Pj4xMDw8NSkrMzEseD0zMix5PTIsZz1xLHc9aWEsQT1qYSxCPWthLEc9ZWEsSD1nYSxJPWFhLEo9Y2EsTD1ZLEs9WCxsPVtuZXcgZyhsWzBdLDM2MDk3Njc0NTgpLG5ldyBnKGxbMV0sNjAyODkxNzI1KSxuZXcgZyhsWzJdLDM5NjQ0ODQzOTkpLG5ldyBnKGxbM10sXG4yMTczMjk1NTQ4KSxuZXcgZyhsWzRdLDQwODE2Mjg0NzIpLG5ldyBnKGxbNV0sMzA1MzgzNDI2NSksbmV3IGcobFs2XSwyOTM3NjcxNTc5KSxuZXcgZyhsWzddLDM2NjQ2MDk1NjApLG5ldyBnKGxbOF0sMjczNDg4MzM5NCksbmV3IGcobFs5XSwxMTY0OTk2NTQyKSxuZXcgZyhsWzEwXSwxMzIzNjEwNzY0KSxuZXcgZyhsWzExXSwzNTkwMzA0OTk0KSxuZXcgZyhsWzEyXSw0MDY4MTgyMzgzKSxuZXcgZyhsWzEzXSw5OTEzMzYxMTMpLG5ldyBnKGxbMTRdLDYzMzgwMzMxNyksbmV3IGcobFsxNV0sMzQ3OTc3NDg2OCksbmV3IGcobFsxNl0sMjY2NjYxMzQ1OCksbmV3IGcobFsxN10sOTQ0NzExMTM5KSxuZXcgZyhsWzE4XSwyMzQxMjYyNzczKSxuZXcgZyhsWzE5XSwyMDA3ODAwOTMzKSxuZXcgZyhsWzIwXSwxNDk1OTkwOTAxKSxuZXcgZyhsWzIxXSwxODU2NDMxMjM1KSxuZXcgZyhsWzIyXSwzMTc1MjE4MTMyKSxuZXcgZyhsWzIzXSwyMTk4OTUwODM3KSxuZXcgZyhsWzI0XSwzOTk5NzE5MzM5KSxcbm5ldyBnKGxbMjVdLDc2Njc4NDAxNiksbmV3IGcobFsyNl0sMjU2NjU5NDg3OSksbmV3IGcobFsyN10sMzIwMzMzNzk1NiksbmV3IGcobFsyOF0sMTAzNDQ1NzAyNiksbmV3IGcobFsyOV0sMjQ2Njk0ODkwMSksbmV3IGcobFszMF0sMzc1ODMyNjM4MyksbmV3IGcobFszMV0sMTY4NzE3OTM2KSxuZXcgZyhsWzMyXSwxMTg4MTc5OTY0KSxuZXcgZyhsWzMzXSwxNTQ2MDQ1NzM0KSxuZXcgZyhsWzM0XSwxNTIyODA1NDg1KSxuZXcgZyhsWzM1XSwyNjQzODMzODIzKSxuZXcgZyhsWzM2XSwyMzQzNTI3MzkwKSxuZXcgZyhsWzM3XSwxMDE0NDc3NDgwKSxuZXcgZyhsWzM4XSwxMjA2NzU5MTQyKSxuZXcgZyhsWzM5XSwzNDQwNzc2MjcpLG5ldyBnKGxbNDBdLDEyOTA4NjM0NjApLG5ldyBnKGxbNDFdLDMxNTg0NTQyNzMpLG5ldyBnKGxbNDJdLDM1MDU5NTI2NTcpLG5ldyBnKGxbNDNdLDEwNjIxNzAwOCksbmV3IGcobFs0NF0sMzYwNjAwODM0NCksbmV3IGcobFs0NV0sMTQzMjcyNTc3NiksbmV3IGcobFs0Nl0sXG4xNDY3MDMxNTk0KSxuZXcgZyhsWzQ3XSw4NTExNjk3MjApLG5ldyBnKGxbNDhdLDMxMDA4MjM3NTIpLG5ldyBnKGxbNDldLDEzNjMyNTgxOTUpLG5ldyBnKGxbNTBdLDM3NTA2ODU1OTMpLG5ldyBnKGxbNTFdLDM3ODUwNTAyODApLG5ldyBnKGxbNTJdLDMzMTgzMDc0MjcpLG5ldyBnKGxbNTNdLDM4MTI3MjM0MDMpLG5ldyBnKGxbNTRdLDIwMDMwMzQ5OTUpLG5ldyBnKGxbNTVdLDM2MDIwMzY4OTkpLG5ldyBnKGxbNTZdLDE1NzU5OTAwMTIpLG5ldyBnKGxbNTddLDExMjU1OTI5MjgpLG5ldyBnKGxbNThdLDI3MTY5MDQzMDYpLG5ldyBnKGxbNTldLDQ0Mjc3NjA0NCksbmV3IGcobFs2MF0sNTkzNjk4MzQ0KSxuZXcgZyhsWzYxXSwzNzMzMTEwMjQ5KSxuZXcgZyhsWzYyXSwyOTk5MzUxNTczKSxuZXcgZyhsWzYzXSwzODE1OTIwNDI3KSxuZXcgZygzMzkxNTY5NjE0LDM5MjgzODM5MDApLG5ldyBnKDM1MTUyNjcyNzEsNTY2MjgwNzExKSxuZXcgZygzOTQwMTg3NjA2LDM0NTQwNjk1MzQpLFxubmV3IGcoNDExODYzMDI3MSw0MDAwMjM5OTkyKSxuZXcgZygxMTY0MTg0NzQsMTkxNDEzODU1NCksbmV3IGcoMTc0MjkyNDIxLDI3MzEwNTUyNzApLG5ldyBnKDI4OTM4MDM1NiwzMjAzOTkzMDA2KSxuZXcgZyg0NjAzOTMyNjksMzIwNjIwMzE1KSxuZXcgZyg2ODU0NzE3MzMsNTg3NDk2ODM2KSxuZXcgZyg4NTIxNDI5NzEsMTA4Njc5Mjg1MSksbmV3IGcoMTAxNzAzNjI5OCwzNjU1NDMxMDApLG5ldyBnKDExMjYwMDA1ODAsMjYxODI5NzY3NiksbmV3IGcoMTI4ODAzMzQ3MCwzNDA5ODU1MTU4KSxuZXcgZygxNTAxNTA1OTQ4LDQyMzQ1MDk4NjYpLG5ldyBnKDE2MDcxNjc5MTUsOTg3MTY3NDY4KSxuZXcgZygxODE2NDAyMzE2LDEyNDYxODk1OTEpXSxkPVwiU0hBLTM4NFwiPT09Yz9bbmV3IGcoMzQxODA3MDM2NSxkWzBdKSxuZXcgZygxNjU0MjcwMjUwLGRbMV0pLG5ldyBnKDI0Mzg1MjkzNzAsZFsyXSksbmV3IGcoMzU1NDYyMzYwLGRbM10pLG5ldyBnKDE3MzE0MDU0MTUsZFs0XSksbmV3IGcoNDEwNDg4ODU4OTUsXG5kWzVdKSxuZXcgZygzNjc1MDA4NTI1LGRbNl0pLG5ldyBnKDEyMDMwNjI4MTMsZFs3XSldOltuZXcgZyhmWzBdLDQwODkyMzU3MjApLG5ldyBnKGZbMV0sMjIyNzg3MzU5NSksbmV3IGcoZlsyXSw0MjcxMTc1NzIzKSxuZXcgZyhmWzNdLDE1OTU3NTAxMjkpLG5ldyBnKGZbNF0sMjkxNzU2NTEzNyksbmV3IGcoZls1XSw3MjU1MTExOTkpLG5ldyBnKGZbNl0sNDIxNTM4OTU0NyksbmV3IGcoZls3XSwzMjcwMzMyMDkpXTtlbHNlIHRocm93XCJVbmV4cGVjdGVkIGVycm9yIGluIFNIQS0yIGltcGxlbWVudGF0aW9uXCI7Zm9yKDthLmxlbmd0aDw9ZTspYS5wdXNoKDApO2FbYj4+PjVdfD0xMjg8PDI0LWIlMzI7YVtlXT1iJjQyOTQ5NjcyOTU7YVtlLTFdPWIvNDI5NDk2NzI5NnwwO0U9YS5sZW5ndGg7Zm9yKG09MDttPEU7bSs9eCl7Yj1kWzBdO2U9ZFsxXTtmPWRbMl07az1kWzNdO2g9ZFs0XTtwPWRbNV07cj1kWzZdO3Y9ZFs3XTtmb3IodT0wO3U8bjt1Kz0xKTE2PnU/KHo9dSp5K20sdD1hLmxlbmd0aDw9XG56PzA6YVt6XSx6PWEubGVuZ3RoPD16KzE/MDphW3orMV0sQ1t1XT1uZXcgZyh0LHopKTpDW3VdPUEoSChDW3UtMl0pLENbdS03XSxHKENbdS0xNV0pLENbdS0xNl0pLHQ9Qih2LEooaCksSyhoLHAsciksbFt1XSxDW3VdKSx6PXcoSShiKSxMKGIsZSxmKSksdj1yLHI9cCxwPWgsaD13KGssdCksaz1mLGY9ZSxlPWIsYj13KHQseik7ZFswXT13KGIsZFswXSk7ZFsxXT13KGUsZFsxXSk7ZFsyXT13KGYsZFsyXSk7ZFszXT13KGssZFszXSk7ZFs0XT13KGgsZFs0XSk7ZFs1XT13KHAsZFs1XSk7ZFs2XT13KHIsZFs2XSk7ZFs3XT13KHYsZFs3XSl9aWYoXCJTSEEtMjI0XCI9PT1jKWE9W2RbMF0sZFsxXSxkWzJdLGRbM10sZFs0XSxkWzVdLGRbNl1dO2Vsc2UgaWYoXCJTSEEtMjU2XCI9PT1jKWE9ZDtlbHNlIGlmKFwiU0hBLTM4NFwiPT09YylhPVtkWzBdLmEsZFswXS5iLGRbMV0uYSxkWzFdLmIsZFsyXS5hLGRbMl0uYixkWzNdLmEsZFszXS5iLGRbNF0uYSxkWzRdLmIsZFs1XS5hLGRbNV0uYl07ZWxzZSBpZihcIlNIQS01MTJcIj09PVxuYylhPVtkWzBdLmEsZFswXS5iLGRbMV0uYSxkWzFdLmIsZFsyXS5hLGRbMl0uYixkWzNdLmEsZFszXS5iLGRbNF0uYSxkWzRdLmIsZFs1XS5hLGRbNV0uYixkWzZdLmEsZFs2XS5iLGRbN10uYSxkWzddLmJdO2Vsc2UgdGhyb3dcIlVuZXhwZWN0ZWQgZXJyb3IgaW4gU0hBLTIgaW1wbGVtZW50YXRpb25cIjtyZXR1cm4gYX1cImZ1bmN0aW9uXCI9PT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShmdW5jdGlvbigpe3JldHVybiBBfSk6XCJ1bmRlZmluZWRcIiE9PXR5cGVvZiBleHBvcnRzP1widW5kZWZpbmVkXCIhPT10eXBlb2YgbW9kdWxlJiZtb2R1bGUuZXhwb3J0cz9tb2R1bGUuZXhwb3J0cz1leHBvcnRzPUE6ZXhwb3J0cz1BOlYuanNTSEE9QX0pKHRoaXMpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2pzc2hhL3NyYy9zaGEuanNcbi8vIG1vZHVsZSBpZCA9IDkxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qKlxuICogbWFya2VkIC0gYSBtYXJrZG93biBwYXJzZXJcbiAqIENvcHlyaWdodCAoYykgMjAxMS0yMDE0LCBDaHJpc3RvcGhlciBKZWZmcmV5LiAoTUlUIExpY2Vuc2VkKVxuICogaHR0cHM6Ly9naXRodWIuY29tL2NoamovbWFya2VkXG4gKi9cblxuOyhmdW5jdGlvbigpIHtcblxuLyoqXG4gKiBCbG9jay1MZXZlbCBHcmFtbWFyXG4gKi9cblxudmFyIGJsb2NrID0ge1xuICBuZXdsaW5lOiAvXlxcbisvLFxuICBjb2RlOiAvXiggezR9W15cXG5dK1xcbiopKy8sXG4gIGZlbmNlczogbm9vcCxcbiAgaHI6IC9eKCAqWy0qX10pezMsfSAqKD86XFxuK3wkKS8sXG4gIGhlYWRpbmc6IC9eICooI3sxLDZ9KSAqKFteXFxuXSs/KSAqIyogKig/Olxcbit8JCkvLFxuICBucHRhYmxlOiBub29wLFxuICBsaGVhZGluZzogL14oW15cXG5dKylcXG4gKig9fC0pezIsfSAqKD86XFxuK3wkKS8sXG4gIGJsb2NrcXVvdGU6IC9eKCAqPlteXFxuXSsoXFxuKD8hZGVmKVteXFxuXSspKlxcbiopKy8sXG4gIGxpc3Q6IC9eKCAqKShidWxsKSBbXFxzXFxTXSs/KD86aHJ8ZGVmfFxcbnsyLH0oPyEgKSg/IVxcMWJ1bGwgKVxcbip8XFxzKiQpLyxcbiAgaHRtbDogL14gKig/OmNvbW1lbnQgKig/OlxcbnxcXHMqJCl8Y2xvc2VkICooPzpcXG57Mix9fFxccyokKXxjbG9zaW5nICooPzpcXG57Mix9fFxccyokKSkvLFxuICBkZWY6IC9eICpcXFsoW15cXF1dKylcXF06ICo8PyhbXlxccz5dKyk+Pyg/OiArW1wiKF0oW15cXG5dKylbXCIpXSk/ICooPzpcXG4rfCQpLyxcbiAgdGFibGU6IG5vb3AsXG4gIHBhcmFncmFwaDogL14oKD86W15cXG5dK1xcbj8oPyFocnxoZWFkaW5nfGxoZWFkaW5nfGJsb2NrcXVvdGV8dGFnfGRlZikpKylcXG4qLyxcbiAgdGV4dDogL15bXlxcbl0rL1xufTtcblxuYmxvY2suYnVsbGV0ID0gLyg/OlsqKy1dfFxcZCtcXC4pLztcbmJsb2NrLml0ZW0gPSAvXiggKikoYnVsbCkgW15cXG5dKig/Olxcbig/IVxcMWJ1bGwgKVteXFxuXSopKi87XG5ibG9jay5pdGVtID0gcmVwbGFjZShibG9jay5pdGVtLCAnZ20nKVxuICAoL2J1bGwvZywgYmxvY2suYnVsbGV0KVxuICAoKTtcblxuYmxvY2subGlzdCA9IHJlcGxhY2UoYmxvY2subGlzdClcbiAgKC9idWxsL2csIGJsb2NrLmJ1bGxldClcbiAgKCdocicsICdcXFxcbisoPz1cXFxcMT8oPzpbLSpfXSAqKXszLH0oPzpcXFxcbit8JCkpJylcbiAgKCdkZWYnLCAnXFxcXG4rKD89JyArIGJsb2NrLmRlZi5zb3VyY2UgKyAnKScpXG4gICgpO1xuXG5ibG9jay5ibG9ja3F1b3RlID0gcmVwbGFjZShibG9jay5ibG9ja3F1b3RlKVxuICAoJ2RlZicsIGJsb2NrLmRlZilcbiAgKCk7XG5cbmJsb2NrLl90YWcgPSAnKD8hKD86J1xuICArICdhfGVtfHN0cm9uZ3xzbWFsbHxzfGNpdGV8cXxkZm58YWJicnxkYXRhfHRpbWV8Y29kZSdcbiAgKyAnfHZhcnxzYW1wfGtiZHxzdWJ8c3VwfGl8Ynx1fG1hcmt8cnVieXxydHxycHxiZGl8YmRvJ1xuICArICd8c3Bhbnxicnx3YnJ8aW5zfGRlbHxpbWcpXFxcXGIpXFxcXHcrKD8hOi98W15cXFxcd1xcXFxzQF0qQClcXFxcYic7XG5cbmJsb2NrLmh0bWwgPSByZXBsYWNlKGJsb2NrLmh0bWwpXG4gICgnY29tbWVudCcsIC88IS0tW1xcc1xcU10qPy0tPi8pXG4gICgnY2xvc2VkJywgLzwodGFnKVtcXHNcXFNdKz88XFwvXFwxPi8pXG4gICgnY2xvc2luZycsIC88dGFnKD86XCJbXlwiXSpcInwnW14nXSonfFteJ1wiPl0pKj8+LylcbiAgKC90YWcvZywgYmxvY2suX3RhZylcbiAgKCk7XG5cbmJsb2NrLnBhcmFncmFwaCA9IHJlcGxhY2UoYmxvY2sucGFyYWdyYXBoKVxuICAoJ2hyJywgYmxvY2suaHIpXG4gICgnaGVhZGluZycsIGJsb2NrLmhlYWRpbmcpXG4gICgnbGhlYWRpbmcnLCBibG9jay5saGVhZGluZylcbiAgKCdibG9ja3F1b3RlJywgYmxvY2suYmxvY2txdW90ZSlcbiAgKCd0YWcnLCAnPCcgKyBibG9jay5fdGFnKVxuICAoJ2RlZicsIGJsb2NrLmRlZilcbiAgKCk7XG5cbi8qKlxuICogTm9ybWFsIEJsb2NrIEdyYW1tYXJcbiAqL1xuXG5ibG9jay5ub3JtYWwgPSBtZXJnZSh7fSwgYmxvY2spO1xuXG4vKipcbiAqIEdGTSBCbG9jayBHcmFtbWFyXG4gKi9cblxuYmxvY2suZ2ZtID0gbWVyZ2Uoe30sIGJsb2NrLm5vcm1hbCwge1xuICBmZW5jZXM6IC9eICooYHszLH18fnszLH0pWyBcXC5dKihcXFMrKT8gKlxcbihbXFxzXFxTXSo/KVxccypcXDEgKig/Olxcbit8JCkvLFxuICBwYXJhZ3JhcGg6IC9eLyxcbiAgaGVhZGluZzogL14gKigjezEsNn0pICsoW15cXG5dKz8pICojKiAqKD86XFxuK3wkKS9cbn0pO1xuXG5ibG9jay5nZm0ucGFyYWdyYXBoID0gcmVwbGFjZShibG9jay5wYXJhZ3JhcGgpXG4gICgnKD8hJywgJyg/ISdcbiAgICArIGJsb2NrLmdmbS5mZW5jZXMuc291cmNlLnJlcGxhY2UoJ1xcXFwxJywgJ1xcXFwyJykgKyAnfCdcbiAgICArIGJsb2NrLmxpc3Quc291cmNlLnJlcGxhY2UoJ1xcXFwxJywgJ1xcXFwzJykgKyAnfCcpXG4gICgpO1xuXG4vKipcbiAqIEdGTSArIFRhYmxlcyBCbG9jayBHcmFtbWFyXG4gKi9cblxuYmxvY2sudGFibGVzID0gbWVyZ2Uoe30sIGJsb2NrLmdmbSwge1xuICBucHRhYmxlOiAvXiAqKFxcUy4qXFx8LiopXFxuICooWy06XSsgKlxcfFstfCA6XSopXFxuKCg/Oi4qXFx8LiooPzpcXG58JCkpKilcXG4qLyxcbiAgdGFibGU6IC9eICpcXHwoLispXFxuICpcXHwoICpbLTpdK1stfCA6XSopXFxuKCg/OiAqXFx8LiooPzpcXG58JCkpKilcXG4qL1xufSk7XG5cbi8qKlxuICogQmxvY2sgTGV4ZXJcbiAqL1xuXG5mdW5jdGlvbiBMZXhlcihvcHRpb25zKSB7XG4gIHRoaXMudG9rZW5zID0gW107XG4gIHRoaXMudG9rZW5zLmxpbmtzID0ge307XG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwgbWFya2VkLmRlZmF1bHRzO1xuICB0aGlzLnJ1bGVzID0gYmxvY2subm9ybWFsO1xuXG4gIGlmICh0aGlzLm9wdGlvbnMuZ2ZtKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy50YWJsZXMpIHtcbiAgICAgIHRoaXMucnVsZXMgPSBibG9jay50YWJsZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucnVsZXMgPSBibG9jay5nZm07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRXhwb3NlIEJsb2NrIFJ1bGVzXG4gKi9cblxuTGV4ZXIucnVsZXMgPSBibG9jaztcblxuLyoqXG4gKiBTdGF0aWMgTGV4IE1ldGhvZFxuICovXG5cbkxleGVyLmxleCA9IGZ1bmN0aW9uKHNyYywgb3B0aW9ucykge1xuICB2YXIgbGV4ZXIgPSBuZXcgTGV4ZXIob3B0aW9ucyk7XG4gIHJldHVybiBsZXhlci5sZXgoc3JjKTtcbn07XG5cbi8qKlxuICogUHJlcHJvY2Vzc2luZ1xuICovXG5cbkxleGVyLnByb3RvdHlwZS5sZXggPSBmdW5jdGlvbihzcmMpIHtcbiAgc3JjID0gc3JjXG4gICAgLnJlcGxhY2UoL1xcclxcbnxcXHIvZywgJ1xcbicpXG4gICAgLnJlcGxhY2UoL1xcdC9nLCAnICAgICcpXG4gICAgLnJlcGxhY2UoL1xcdTAwYTAvZywgJyAnKVxuICAgIC5yZXBsYWNlKC9cXHUyNDI0L2csICdcXG4nKTtcblxuICByZXR1cm4gdGhpcy50b2tlbihzcmMsIHRydWUpO1xufTtcblxuLyoqXG4gKiBMZXhpbmdcbiAqL1xuXG5MZXhlci5wcm90b3R5cGUudG9rZW4gPSBmdW5jdGlvbihzcmMsIHRvcCwgYnEpIHtcbiAgdmFyIHNyYyA9IHNyYy5yZXBsYWNlKC9eICskL2dtLCAnJylcbiAgICAsIG5leHRcbiAgICAsIGxvb3NlXG4gICAgLCBjYXBcbiAgICAsIGJ1bGxcbiAgICAsIGJcbiAgICAsIGl0ZW1cbiAgICAsIHNwYWNlXG4gICAgLCBpXG4gICAgLCBsO1xuXG4gIHdoaWxlIChzcmMpIHtcbiAgICAvLyBuZXdsaW5lXG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMubmV3bGluZS5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICBpZiAoY2FwWzBdLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhpcy50b2tlbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ3NwYWNlJ1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjb2RlXG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMuY29kZS5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICBjYXAgPSBjYXBbMF0ucmVwbGFjZSgvXiB7NH0vZ20sICcnKTtcbiAgICAgIHRoaXMudG9rZW5zLnB1c2goe1xuICAgICAgICB0eXBlOiAnY29kZScsXG4gICAgICAgIHRleHQ6ICF0aGlzLm9wdGlvbnMucGVkYW50aWNcbiAgICAgICAgICA/IGNhcC5yZXBsYWNlKC9cXG4rJC8sICcnKVxuICAgICAgICAgIDogY2FwXG4gICAgICB9KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIGZlbmNlcyAoZ2ZtKVxuICAgIGlmIChjYXAgPSB0aGlzLnJ1bGVzLmZlbmNlcy5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICB0aGlzLnRva2Vucy5wdXNoKHtcbiAgICAgICAgdHlwZTogJ2NvZGUnLFxuICAgICAgICBsYW5nOiBjYXBbMl0sXG4gICAgICAgIHRleHQ6IGNhcFszXSB8fCAnJ1xuICAgICAgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBoZWFkaW5nXG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMuaGVhZGluZy5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICB0aGlzLnRva2Vucy5wdXNoKHtcbiAgICAgICAgdHlwZTogJ2hlYWRpbmcnLFxuICAgICAgICBkZXB0aDogY2FwWzFdLmxlbmd0aCxcbiAgICAgICAgdGV4dDogY2FwWzJdXG4gICAgICB9KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHRhYmxlIG5vIGxlYWRpbmcgcGlwZSAoZ2ZtKVxuICAgIGlmICh0b3AgJiYgKGNhcCA9IHRoaXMucnVsZXMubnB0YWJsZS5leGVjKHNyYykpKSB7XG4gICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKGNhcFswXS5sZW5ndGgpO1xuXG4gICAgICBpdGVtID0ge1xuICAgICAgICB0eXBlOiAndGFibGUnLFxuICAgICAgICBoZWFkZXI6IGNhcFsxXS5yZXBsYWNlKC9eICp8ICpcXHwgKiQvZywgJycpLnNwbGl0KC8gKlxcfCAqLyksXG4gICAgICAgIGFsaWduOiBjYXBbMl0ucmVwbGFjZSgvXiAqfFxcfCAqJC9nLCAnJykuc3BsaXQoLyAqXFx8ICovKSxcbiAgICAgICAgY2VsbHM6IGNhcFszXS5yZXBsYWNlKC9cXG4kLywgJycpLnNwbGl0KCdcXG4nKVxuICAgICAgfTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGl0ZW0uYWxpZ24ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKC9eICotKzogKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICBpdGVtLmFsaWduW2ldID0gJ3JpZ2h0JztcbiAgICAgICAgfSBlbHNlIGlmICgvXiAqOi0rOiAqJC8udGVzdChpdGVtLmFsaWduW2ldKSkge1xuICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAnY2VudGVyJztcbiAgICAgICAgfSBlbHNlIGlmICgvXiAqOi0rICokLy50ZXN0KGl0ZW0uYWxpZ25baV0pKSB7XG4gICAgICAgICAgaXRlbS5hbGlnbltpXSA9ICdsZWZ0JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpdGVtLmFsaWduW2ldID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgaXRlbS5jZWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpdGVtLmNlbGxzW2ldID0gaXRlbS5jZWxsc1tpXS5zcGxpdCgvICpcXHwgKi8pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRva2Vucy5wdXNoKGl0ZW0pO1xuXG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBsaGVhZGluZ1xuICAgIGlmIChjYXAgPSB0aGlzLnJ1bGVzLmxoZWFkaW5nLmV4ZWMoc3JjKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIHRoaXMudG9rZW5zLnB1c2goe1xuICAgICAgICB0eXBlOiAnaGVhZGluZycsXG4gICAgICAgIGRlcHRoOiBjYXBbMl0gPT09ICc9JyA/IDEgOiAyLFxuICAgICAgICB0ZXh0OiBjYXBbMV1cbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gaHJcbiAgICBpZiAoY2FwID0gdGhpcy5ydWxlcy5oci5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICB0aGlzLnRva2Vucy5wdXNoKHtcbiAgICAgICAgdHlwZTogJ2hyJ1xuICAgICAgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBibG9ja3F1b3RlXG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMuYmxvY2txdW90ZS5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG5cbiAgICAgIHRoaXMudG9rZW5zLnB1c2goe1xuICAgICAgICB0eXBlOiAnYmxvY2txdW90ZV9zdGFydCdcbiAgICAgIH0pO1xuXG4gICAgICBjYXAgPSBjYXBbMF0ucmVwbGFjZSgvXiAqPiA/L2dtLCAnJyk7XG5cbiAgICAgIC8vIFBhc3MgYHRvcGAgdG8ga2VlcCB0aGUgY3VycmVudFxuICAgICAgLy8gXCJ0b3BsZXZlbFwiIHN0YXRlLiBUaGlzIGlzIGV4YWN0bHlcbiAgICAgIC8vIGhvdyBtYXJrZG93bi5wbCB3b3Jrcy5cbiAgICAgIHRoaXMudG9rZW4oY2FwLCB0b3AsIHRydWUpO1xuXG4gICAgICB0aGlzLnRva2Vucy5wdXNoKHtcbiAgICAgICAgdHlwZTogJ2Jsb2NrcXVvdGVfZW5kJ1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIGxpc3RcbiAgICBpZiAoY2FwID0gdGhpcy5ydWxlcy5saXN0LmV4ZWMoc3JjKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIGJ1bGwgPSBjYXBbMl07XG5cbiAgICAgIHRoaXMudG9rZW5zLnB1c2goe1xuICAgICAgICB0eXBlOiAnbGlzdF9zdGFydCcsXG4gICAgICAgIG9yZGVyZWQ6IGJ1bGwubGVuZ3RoID4gMVxuICAgICAgfSk7XG5cbiAgICAgIC8vIEdldCBlYWNoIHRvcC1sZXZlbCBpdGVtLlxuICAgICAgY2FwID0gY2FwWzBdLm1hdGNoKHRoaXMucnVsZXMuaXRlbSk7XG5cbiAgICAgIG5leHQgPSBmYWxzZTtcbiAgICAgIGwgPSBjYXAubGVuZ3RoO1xuICAgICAgaSA9IDA7XG5cbiAgICAgIGZvciAoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGl0ZW0gPSBjYXBbaV07XG5cbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBsaXN0IGl0ZW0ncyBidWxsZXRcbiAgICAgICAgLy8gc28gaXQgaXMgc2VlbiBhcyB0aGUgbmV4dCB0b2tlbi5cbiAgICAgICAgc3BhY2UgPSBpdGVtLmxlbmd0aDtcbiAgICAgICAgaXRlbSA9IGl0ZW0ucmVwbGFjZSgvXiAqKFsqKy1dfFxcZCtcXC4pICsvLCAnJyk7XG5cbiAgICAgICAgLy8gT3V0ZGVudCB3aGF0ZXZlciB0aGVcbiAgICAgICAgLy8gbGlzdCBpdGVtIGNvbnRhaW5zLiBIYWNreS5cbiAgICAgICAgaWYgKH5pdGVtLmluZGV4T2YoJ1xcbiAnKSkge1xuICAgICAgICAgIHNwYWNlIC09IGl0ZW0ubGVuZ3RoO1xuICAgICAgICAgIGl0ZW0gPSAhdGhpcy5vcHRpb25zLnBlZGFudGljXG4gICAgICAgICAgICA/IGl0ZW0ucmVwbGFjZShuZXcgUmVnRXhwKCdeIHsxLCcgKyBzcGFjZSArICd9JywgJ2dtJyksICcnKVxuICAgICAgICAgICAgOiBpdGVtLnJlcGxhY2UoL14gezEsNH0vZ20sICcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERldGVybWluZSB3aGV0aGVyIHRoZSBuZXh0IGxpc3QgaXRlbSBiZWxvbmdzIGhlcmUuXG4gICAgICAgIC8vIEJhY2twZWRhbCBpZiBpdCBkb2VzIG5vdCBiZWxvbmcgaW4gdGhpcyBsaXN0LlxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNtYXJ0TGlzdHMgJiYgaSAhPT0gbCAtIDEpIHtcbiAgICAgICAgICBiID0gYmxvY2suYnVsbGV0LmV4ZWMoY2FwW2kgKyAxXSlbMF07XG4gICAgICAgICAgaWYgKGJ1bGwgIT09IGIgJiYgIShidWxsLmxlbmd0aCA+IDEgJiYgYi5sZW5ndGggPiAxKSkge1xuICAgICAgICAgICAgc3JjID0gY2FwLnNsaWNlKGkgKyAxKS5qb2luKCdcXG4nKSArIHNyYztcbiAgICAgICAgICAgIGkgPSBsIC0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEZXRlcm1pbmUgd2hldGhlciBpdGVtIGlzIGxvb3NlIG9yIG5vdC5cbiAgICAgICAgLy8gVXNlOiAvKF58XFxuKSg/ISApW15cXG5dK1xcblxcbig/IVxccyokKS9cbiAgICAgICAgLy8gZm9yIGRpc2NvdW50IGJlaGF2aW9yLlxuICAgICAgICBsb29zZSA9IG5leHQgfHwgL1xcblxcbig/IVxccyokKS8udGVzdChpdGVtKTtcbiAgICAgICAgaWYgKGkgIT09IGwgLSAxKSB7XG4gICAgICAgICAgbmV4dCA9IGl0ZW0uY2hhckF0KGl0ZW0ubGVuZ3RoIC0gMSkgPT09ICdcXG4nO1xuICAgICAgICAgIGlmICghbG9vc2UpIGxvb3NlID0gbmV4dDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudG9rZW5zLnB1c2goe1xuICAgICAgICAgIHR5cGU6IGxvb3NlXG4gICAgICAgICAgICA/ICdsb29zZV9pdGVtX3N0YXJ0J1xuICAgICAgICAgICAgOiAnbGlzdF9pdGVtX3N0YXJ0J1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBSZWN1cnNlLlxuICAgICAgICB0aGlzLnRva2VuKGl0ZW0sIGZhbHNlLCBicSk7XG5cbiAgICAgICAgdGhpcy50b2tlbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ2xpc3RfaXRlbV9lbmQnXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRva2Vucy5wdXNoKHtcbiAgICAgICAgdHlwZTogJ2xpc3RfZW5kJ1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIGh0bWxcbiAgICBpZiAoY2FwID0gdGhpcy5ydWxlcy5odG1sLmV4ZWMoc3JjKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIHRoaXMudG9rZW5zLnB1c2goe1xuICAgICAgICB0eXBlOiB0aGlzLm9wdGlvbnMuc2FuaXRpemVcbiAgICAgICAgICA/ICdwYXJhZ3JhcGgnXG4gICAgICAgICAgOiAnaHRtbCcsXG4gICAgICAgIHByZTogIXRoaXMub3B0aW9ucy5zYW5pdGl6ZXJcbiAgICAgICAgICAmJiAoY2FwWzFdID09PSAncHJlJyB8fCBjYXBbMV0gPT09ICdzY3JpcHQnIHx8IGNhcFsxXSA9PT0gJ3N0eWxlJyksXG4gICAgICAgIHRleHQ6IGNhcFswXVxuICAgICAgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBkZWZcbiAgICBpZiAoKCFicSAmJiB0b3ApICYmIChjYXAgPSB0aGlzLnJ1bGVzLmRlZi5leGVjKHNyYykpKSB7XG4gICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKGNhcFswXS5sZW5ndGgpO1xuICAgICAgdGhpcy50b2tlbnMubGlua3NbY2FwWzFdLnRvTG93ZXJDYXNlKCldID0ge1xuICAgICAgICBocmVmOiBjYXBbMl0sXG4gICAgICAgIHRpdGxlOiBjYXBbM11cbiAgICAgIH07XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyB0YWJsZSAoZ2ZtKVxuICAgIGlmICh0b3AgJiYgKGNhcCA9IHRoaXMucnVsZXMudGFibGUuZXhlYyhzcmMpKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcblxuICAgICAgaXRlbSA9IHtcbiAgICAgICAgdHlwZTogJ3RhYmxlJyxcbiAgICAgICAgaGVhZGVyOiBjYXBbMV0ucmVwbGFjZSgvXiAqfCAqXFx8ICokL2csICcnKS5zcGxpdCgvICpcXHwgKi8pLFxuICAgICAgICBhbGlnbjogY2FwWzJdLnJlcGxhY2UoL14gKnxcXHwgKiQvZywgJycpLnNwbGl0KC8gKlxcfCAqLyksXG4gICAgICAgIGNlbGxzOiBjYXBbM10ucmVwbGFjZSgvKD86ICpcXHwgKik/XFxuJC8sICcnKS5zcGxpdCgnXFxuJylcbiAgICAgIH07XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBpdGVtLmFsaWduLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICgvXiAqLSs6ICokLy50ZXN0KGl0ZW0uYWxpZ25baV0pKSB7XG4gICAgICAgICAgaXRlbS5hbGlnbltpXSA9ICdyaWdodCc7XG4gICAgICAgIH0gZWxzZSBpZiAoL14gKjotKzogKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICBpdGVtLmFsaWduW2ldID0gJ2NlbnRlcic7XG4gICAgICAgIH0gZWxzZSBpZiAoL14gKjotKyAqJC8udGVzdChpdGVtLmFsaWduW2ldKSkge1xuICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAnbGVmdCc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbS5hbGlnbltpXSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChpID0gMDsgaSA8IGl0ZW0uY2VsbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlbS5jZWxsc1tpXSA9IGl0ZW0uY2VsbHNbaV1cbiAgICAgICAgICAucmVwbGFjZSgvXiAqXFx8ICp8ICpcXHwgKiQvZywgJycpXG4gICAgICAgICAgLnNwbGl0KC8gKlxcfCAqLyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMudG9rZW5zLnB1c2goaXRlbSk7XG5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHRvcC1sZXZlbCBwYXJhZ3JhcGhcbiAgICBpZiAodG9wICYmIChjYXAgPSB0aGlzLnJ1bGVzLnBhcmFncmFwaC5leGVjKHNyYykpKSB7XG4gICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKGNhcFswXS5sZW5ndGgpO1xuICAgICAgdGhpcy50b2tlbnMucHVzaCh7XG4gICAgICAgIHR5cGU6ICdwYXJhZ3JhcGgnLFxuICAgICAgICB0ZXh0OiBjYXBbMV0uY2hhckF0KGNhcFsxXS5sZW5ndGggLSAxKSA9PT0gJ1xcbidcbiAgICAgICAgICA/IGNhcFsxXS5zbGljZSgwLCAtMSlcbiAgICAgICAgICA6IGNhcFsxXVxuICAgICAgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyB0ZXh0XG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMudGV4dC5leGVjKHNyYykpIHtcbiAgICAgIC8vIFRvcC1sZXZlbCBzaG91bGQgbmV2ZXIgcmVhY2ggaGVyZS5cbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICB0aGlzLnRva2Vucy5wdXNoKHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICB0ZXh0OiBjYXBbMF1cbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHNyYykge1xuICAgICAgdGhyb3cgbmV3XG4gICAgICAgIEVycm9yKCdJbmZpbml0ZSBsb29wIG9uIGJ5dGU6ICcgKyBzcmMuY2hhckNvZGVBdCgwKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXMudG9rZW5zO1xufTtcblxuLyoqXG4gKiBJbmxpbmUtTGV2ZWwgR3JhbW1hclxuICovXG5cbnZhciBpbmxpbmUgPSB7XG4gIGVzY2FwZTogL15cXFxcKFtcXFxcYCp7fVxcW1xcXSgpIytcXC0uIV8+XSkvLFxuICBhdXRvbGluazogL148KFteID5dKyhAfDpcXC8pW14gPl0rKT4vLFxuICB1cmw6IG5vb3AsXG4gIHRhZzogL148IS0tW1xcc1xcU10qPy0tPnxePFxcLz9cXHcrKD86XCJbXlwiXSpcInwnW14nXSonfFteJ1wiPl0pKj8+LyxcbiAgbGluazogL14hP1xcWyhpbnNpZGUpXFxdXFwoaHJlZlxcKS8sXG4gIHJlZmxpbms6IC9eIT9cXFsoaW5zaWRlKVxcXVxccypcXFsoW15cXF1dKilcXF0vLFxuICBub2xpbms6IC9eIT9cXFsoKD86XFxbW15cXF1dKlxcXXxbXlxcW1xcXV0pKilcXF0vLFxuICBzdHJvbmc6IC9eX18oW1xcc1xcU10rPylfXyg/IV8pfF5cXCpcXCooW1xcc1xcU10rPylcXCpcXCooPyFcXCopLyxcbiAgZW06IC9eXFxiXygoPzpbXl9dfF9fKSs/KV9cXGJ8XlxcKigoPzpcXCpcXCp8W1xcc1xcU10pKz8pXFwqKD8hXFwqKS8sXG4gIGNvZGU6IC9eKGArKVxccyooW1xcc1xcU10qP1teYF0pXFxzKlxcMSg/IWApLyxcbiAgYnI6IC9eIHsyLH1cXG4oPyFcXHMqJCkvLFxuICBkZWw6IG5vb3AsXG4gIHRleHQ6IC9eW1xcc1xcU10rPyg/PVtcXFxcPCFcXFtfKmBdfCB7Mix9XFxufCQpL1xufTtcblxuaW5saW5lLl9pbnNpZGUgPSAvKD86XFxbW15cXF1dKlxcXXxbXlxcW1xcXV18XFxdKD89W15cXFtdKlxcXSkpKi87XG5pbmxpbmUuX2hyZWYgPSAvXFxzKjw/KFtcXHNcXFNdKj8pPj8oPzpcXHMrWydcIl0oW1xcc1xcU10qPylbJ1wiXSk/XFxzKi87XG5cbmlubGluZS5saW5rID0gcmVwbGFjZShpbmxpbmUubGluaylcbiAgKCdpbnNpZGUnLCBpbmxpbmUuX2luc2lkZSlcbiAgKCdocmVmJywgaW5saW5lLl9ocmVmKVxuICAoKTtcblxuaW5saW5lLnJlZmxpbmsgPSByZXBsYWNlKGlubGluZS5yZWZsaW5rKVxuICAoJ2luc2lkZScsIGlubGluZS5faW5zaWRlKVxuICAoKTtcblxuLyoqXG4gKiBOb3JtYWwgSW5saW5lIEdyYW1tYXJcbiAqL1xuXG5pbmxpbmUubm9ybWFsID0gbWVyZ2Uoe30sIGlubGluZSk7XG5cbi8qKlxuICogUGVkYW50aWMgSW5saW5lIEdyYW1tYXJcbiAqL1xuXG5pbmxpbmUucGVkYW50aWMgPSBtZXJnZSh7fSwgaW5saW5lLm5vcm1hbCwge1xuICBzdHJvbmc6IC9eX18oPz1cXFMpKFtcXHNcXFNdKj9cXFMpX18oPyFfKXxeXFwqXFwqKD89XFxTKShbXFxzXFxTXSo/XFxTKVxcKlxcKig/IVxcKikvLFxuICBlbTogL15fKD89XFxTKShbXFxzXFxTXSo/XFxTKV8oPyFfKXxeXFwqKD89XFxTKShbXFxzXFxTXSo/XFxTKVxcKig/IVxcKikvXG59KTtcblxuLyoqXG4gKiBHRk0gSW5saW5lIEdyYW1tYXJcbiAqL1xuXG5pbmxpbmUuZ2ZtID0gbWVyZ2Uoe30sIGlubGluZS5ub3JtYWwsIHtcbiAgZXNjYXBlOiByZXBsYWNlKGlubGluZS5lc2NhcGUpKCddKScsICd+fF0pJykoKSxcbiAgdXJsOiAvXihodHRwcz86XFwvXFwvW15cXHM8XStbXjwuLDo7XCInKVxcXVxcc10pLyxcbiAgZGVsOiAvXn5+KD89XFxTKShbXFxzXFxTXSo/XFxTKX5+LyxcbiAgdGV4dDogcmVwbGFjZShpbmxpbmUudGV4dClcbiAgICAoJ118JywgJ35dfCcpXG4gICAgKCd8JywgJ3xodHRwcz86Ly98JylcbiAgICAoKVxufSk7XG5cbi8qKlxuICogR0ZNICsgTGluZSBCcmVha3MgSW5saW5lIEdyYW1tYXJcbiAqL1xuXG5pbmxpbmUuYnJlYWtzID0gbWVyZ2Uoe30sIGlubGluZS5nZm0sIHtcbiAgYnI6IHJlcGxhY2UoaW5saW5lLmJyKSgnezIsfScsICcqJykoKSxcbiAgdGV4dDogcmVwbGFjZShpbmxpbmUuZ2ZtLnRleHQpKCd7Mix9JywgJyonKSgpXG59KTtcblxuLyoqXG4gKiBJbmxpbmUgTGV4ZXIgJiBDb21waWxlclxuICovXG5cbmZ1bmN0aW9uIElubGluZUxleGVyKGxpbmtzLCBvcHRpb25zKSB7XG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwgbWFya2VkLmRlZmF1bHRzO1xuICB0aGlzLmxpbmtzID0gbGlua3M7XG4gIHRoaXMucnVsZXMgPSBpbmxpbmUubm9ybWFsO1xuICB0aGlzLnJlbmRlcmVyID0gdGhpcy5vcHRpb25zLnJlbmRlcmVyIHx8IG5ldyBSZW5kZXJlcjtcbiAgdGhpcy5yZW5kZXJlci5vcHRpb25zID0gdGhpcy5vcHRpb25zO1xuXG4gIGlmICghdGhpcy5saW5rcykge1xuICAgIHRocm93IG5ld1xuICAgICAgRXJyb3IoJ1Rva2VucyBhcnJheSByZXF1aXJlcyBhIGBsaW5rc2AgcHJvcGVydHkuJyk7XG4gIH1cblxuICBpZiAodGhpcy5vcHRpb25zLmdmbSkge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuYnJlYWtzKSB7XG4gICAgICB0aGlzLnJ1bGVzID0gaW5saW5lLmJyZWFrcztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ydWxlcyA9IGlubGluZS5nZm07XG4gICAgfVxuICB9IGVsc2UgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgIHRoaXMucnVsZXMgPSBpbmxpbmUucGVkYW50aWM7XG4gIH1cbn1cblxuLyoqXG4gKiBFeHBvc2UgSW5saW5lIFJ1bGVzXG4gKi9cblxuSW5saW5lTGV4ZXIucnVsZXMgPSBpbmxpbmU7XG5cbi8qKlxuICogU3RhdGljIExleGluZy9Db21waWxpbmcgTWV0aG9kXG4gKi9cblxuSW5saW5lTGV4ZXIub3V0cHV0ID0gZnVuY3Rpb24oc3JjLCBsaW5rcywgb3B0aW9ucykge1xuICB2YXIgaW5saW5lID0gbmV3IElubGluZUxleGVyKGxpbmtzLCBvcHRpb25zKTtcbiAgcmV0dXJuIGlubGluZS5vdXRwdXQoc3JjKTtcbn07XG5cbi8qKlxuICogTGV4aW5nL0NvbXBpbGluZ1xuICovXG5cbklubGluZUxleGVyLnByb3RvdHlwZS5vdXRwdXQgPSBmdW5jdGlvbihzcmMpIHtcbiAgdmFyIG91dCA9ICcnXG4gICAgLCBsaW5rXG4gICAgLCB0ZXh0XG4gICAgLCBocmVmXG4gICAgLCBjYXA7XG5cbiAgd2hpbGUgKHNyYykge1xuICAgIC8vIGVzY2FwZVxuICAgIGlmIChjYXAgPSB0aGlzLnJ1bGVzLmVzY2FwZS5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICBvdXQgKz0gY2FwWzFdO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gYXV0b2xpbmtcbiAgICBpZiAoY2FwID0gdGhpcy5ydWxlcy5hdXRvbGluay5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICBpZiAoY2FwWzJdID09PSAnQCcpIHtcbiAgICAgICAgdGV4dCA9IGNhcFsxXS5jaGFyQXQoNikgPT09ICc6J1xuICAgICAgICAgID8gdGhpcy5tYW5nbGUoY2FwWzFdLnN1YnN0cmluZyg3KSlcbiAgICAgICAgICA6IHRoaXMubWFuZ2xlKGNhcFsxXSk7XG4gICAgICAgIGhyZWYgPSB0aGlzLm1hbmdsZSgnbWFpbHRvOicpICsgdGV4dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRleHQgPSBlc2NhcGUoY2FwWzFdKTtcbiAgICAgICAgaHJlZiA9IHRleHQ7XG4gICAgICB9XG4gICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5saW5rKGhyZWYsIG51bGwsIHRleHQpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gdXJsIChnZm0pXG4gICAgaWYgKCF0aGlzLmluTGluayAmJiAoY2FwID0gdGhpcy5ydWxlcy51cmwuZXhlYyhzcmMpKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIHRleHQgPSBlc2NhcGUoY2FwWzFdKTtcbiAgICAgIGhyZWYgPSB0ZXh0O1xuICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIubGluayhocmVmLCBudWxsLCB0ZXh0KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHRhZ1xuICAgIGlmIChjYXAgPSB0aGlzLnJ1bGVzLnRhZy5leGVjKHNyYykpIHtcbiAgICAgIGlmICghdGhpcy5pbkxpbmsgJiYgL148YSAvaS50ZXN0KGNhcFswXSkpIHtcbiAgICAgICAgdGhpcy5pbkxpbmsgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmluTGluayAmJiAvXjxcXC9hPi9pLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmluTGluayA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIG91dCArPSB0aGlzLm9wdGlvbnMuc2FuaXRpemVcbiAgICAgICAgPyB0aGlzLm9wdGlvbnMuc2FuaXRpemVyXG4gICAgICAgICAgPyB0aGlzLm9wdGlvbnMuc2FuaXRpemVyKGNhcFswXSlcbiAgICAgICAgICA6IGVzY2FwZShjYXBbMF0pXG4gICAgICAgIDogY2FwWzBdXG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBsaW5rXG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMubGluay5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICB0aGlzLmluTGluayA9IHRydWU7XG4gICAgICBvdXQgKz0gdGhpcy5vdXRwdXRMaW5rKGNhcCwge1xuICAgICAgICBocmVmOiBjYXBbMl0sXG4gICAgICAgIHRpdGxlOiBjYXBbM11cbiAgICAgIH0pO1xuICAgICAgdGhpcy5pbkxpbmsgPSBmYWxzZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHJlZmxpbmssIG5vbGlua1xuICAgIGlmICgoY2FwID0gdGhpcy5ydWxlcy5yZWZsaW5rLmV4ZWMoc3JjKSlcbiAgICAgICAgfHwgKGNhcCA9IHRoaXMucnVsZXMubm9saW5rLmV4ZWMoc3JjKSkpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICBsaW5rID0gKGNhcFsyXSB8fCBjYXBbMV0pLnJlcGxhY2UoL1xccysvZywgJyAnKTtcbiAgICAgIGxpbmsgPSB0aGlzLmxpbmtzW2xpbmsudG9Mb3dlckNhc2UoKV07XG4gICAgICBpZiAoIWxpbmsgfHwgIWxpbmsuaHJlZikge1xuICAgICAgICBvdXQgKz0gY2FwWzBdLmNoYXJBdCgwKTtcbiAgICAgICAgc3JjID0gY2FwWzBdLnN1YnN0cmluZygxKSArIHNyYztcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0aGlzLmluTGluayA9IHRydWU7XG4gICAgICBvdXQgKz0gdGhpcy5vdXRwdXRMaW5rKGNhcCwgbGluayk7XG4gICAgICB0aGlzLmluTGluayA9IGZhbHNlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gc3Ryb25nXG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMuc3Ryb25nLmV4ZWMoc3JjKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIG91dCArPSB0aGlzLnJlbmRlcmVyLnN0cm9uZyh0aGlzLm91dHB1dChjYXBbMl0gfHwgY2FwWzFdKSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBlbVxuICAgIGlmIChjYXAgPSB0aGlzLnJ1bGVzLmVtLmV4ZWMoc3JjKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIG91dCArPSB0aGlzLnJlbmRlcmVyLmVtKHRoaXMub3V0cHV0KGNhcFsyXSB8fCBjYXBbMV0pKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIGNvZGVcbiAgICBpZiAoY2FwID0gdGhpcy5ydWxlcy5jb2RlLmV4ZWMoc3JjKSkge1xuICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhjYXBbMF0ubGVuZ3RoKTtcbiAgICAgIG91dCArPSB0aGlzLnJlbmRlcmVyLmNvZGVzcGFuKGVzY2FwZShjYXBbMl0sIHRydWUpKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIGJyXG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMuYnIuZXhlYyhzcmMpKSB7XG4gICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKGNhcFswXS5sZW5ndGgpO1xuICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuYnIoKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIGRlbCAoZ2ZtKVxuICAgIGlmIChjYXAgPSB0aGlzLnJ1bGVzLmRlbC5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5kZWwodGhpcy5vdXRwdXQoY2FwWzFdKSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyB0ZXh0XG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMudGV4dC5leGVjKHNyYykpIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcoY2FwWzBdLmxlbmd0aCk7XG4gICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci50ZXh0KGVzY2FwZSh0aGlzLnNtYXJ0eXBhbnRzKGNhcFswXSkpKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChzcmMpIHtcbiAgICAgIHRocm93IG5ld1xuICAgICAgICBFcnJvcignSW5maW5pdGUgbG9vcCBvbiBieXRlOiAnICsgc3JjLmNoYXJDb2RlQXQoMCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIENvbXBpbGUgTGlua1xuICovXG5cbklubGluZUxleGVyLnByb3RvdHlwZS5vdXRwdXRMaW5rID0gZnVuY3Rpb24oY2FwLCBsaW5rKSB7XG4gIHZhciBocmVmID0gZXNjYXBlKGxpbmsuaHJlZilcbiAgICAsIHRpdGxlID0gbGluay50aXRsZSA/IGVzY2FwZShsaW5rLnRpdGxlKSA6IG51bGw7XG5cbiAgcmV0dXJuIGNhcFswXS5jaGFyQXQoMCkgIT09ICchJ1xuICAgID8gdGhpcy5yZW5kZXJlci5saW5rKGhyZWYsIHRpdGxlLCB0aGlzLm91dHB1dChjYXBbMV0pKVxuICAgIDogdGhpcy5yZW5kZXJlci5pbWFnZShocmVmLCB0aXRsZSwgZXNjYXBlKGNhcFsxXSkpO1xufTtcblxuLyoqXG4gKiBTbWFydHlwYW50cyBUcmFuc2Zvcm1hdGlvbnNcbiAqL1xuXG5JbmxpbmVMZXhlci5wcm90b3R5cGUuc21hcnR5cGFudHMgPSBmdW5jdGlvbih0ZXh0KSB7XG4gIGlmICghdGhpcy5vcHRpb25zLnNtYXJ0eXBhbnRzKSByZXR1cm4gdGV4dDtcbiAgcmV0dXJuIHRleHRcbiAgICAvLyBlbS1kYXNoZXNcbiAgICAucmVwbGFjZSgvLS0tL2csICdcXHUyMDE0JylcbiAgICAvLyBlbi1kYXNoZXNcbiAgICAucmVwbGFjZSgvLS0vZywgJ1xcdTIwMTMnKVxuICAgIC8vIG9wZW5pbmcgc2luZ2xlc1xuICAgIC5yZXBsYWNlKC8oXnxbLVxcdTIwMTQvKFxcW3tcIlxcc10pJy9nLCAnJDFcXHUyMDE4JylcbiAgICAvLyBjbG9zaW5nIHNpbmdsZXMgJiBhcG9zdHJvcGhlc1xuICAgIC5yZXBsYWNlKC8nL2csICdcXHUyMDE5JylcbiAgICAvLyBvcGVuaW5nIGRvdWJsZXNcbiAgICAucmVwbGFjZSgvKF58Wy1cXHUyMDE0LyhcXFt7XFx1MjAxOFxcc10pXCIvZywgJyQxXFx1MjAxYycpXG4gICAgLy8gY2xvc2luZyBkb3VibGVzXG4gICAgLnJlcGxhY2UoL1wiL2csICdcXHUyMDFkJylcbiAgICAvLyBlbGxpcHNlc1xuICAgIC5yZXBsYWNlKC9cXC57M30vZywgJ1xcdTIwMjYnKTtcbn07XG5cbi8qKlxuICogTWFuZ2xlIExpbmtzXG4gKi9cblxuSW5saW5lTGV4ZXIucHJvdG90eXBlLm1hbmdsZSA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgaWYgKCF0aGlzLm9wdGlvbnMubWFuZ2xlKSByZXR1cm4gdGV4dDtcbiAgdmFyIG91dCA9ICcnXG4gICAgLCBsID0gdGV4dC5sZW5ndGhcbiAgICAsIGkgPSAwXG4gICAgLCBjaDtcblxuICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgIGNoID0gdGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChNYXRoLnJhbmRvbSgpID4gMC41KSB7XG4gICAgICBjaCA9ICd4JyArIGNoLnRvU3RyaW5nKDE2KTtcbiAgICB9XG4gICAgb3V0ICs9ICcmIycgKyBjaCArICc7JztcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFJlbmRlcmVyXG4gKi9cblxuZnVuY3Rpb24gUmVuZGVyZXIob3B0aW9ucykge1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xufVxuXG5SZW5kZXJlci5wcm90b3R5cGUuY29kZSA9IGZ1bmN0aW9uKGNvZGUsIGxhbmcsIGVzY2FwZWQpIHtcbiAgaWYgKHRoaXMub3B0aW9ucy5oaWdobGlnaHQpIHtcbiAgICB2YXIgb3V0ID0gdGhpcy5vcHRpb25zLmhpZ2hsaWdodChjb2RlLCBsYW5nKTtcbiAgICBpZiAob3V0ICE9IG51bGwgJiYgb3V0ICE9PSBjb2RlKSB7XG4gICAgICBlc2NhcGVkID0gdHJ1ZTtcbiAgICAgIGNvZGUgPSBvdXQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFsYW5nKSB7XG4gICAgcmV0dXJuICc8cHJlPjxjb2RlPidcbiAgICAgICsgKGVzY2FwZWQgPyBjb2RlIDogZXNjYXBlKGNvZGUsIHRydWUpKVxuICAgICAgKyAnXFxuPC9jb2RlPjwvcHJlPic7XG4gIH1cblxuICByZXR1cm4gJzxwcmU+PGNvZGUgY2xhc3M9XCInXG4gICAgKyB0aGlzLm9wdGlvbnMubGFuZ1ByZWZpeFxuICAgICsgZXNjYXBlKGxhbmcsIHRydWUpXG4gICAgKyAnXCI+J1xuICAgICsgKGVzY2FwZWQgPyBjb2RlIDogZXNjYXBlKGNvZGUsIHRydWUpKVxuICAgICsgJ1xcbjwvY29kZT48L3ByZT5cXG4nO1xufTtcblxuUmVuZGVyZXIucHJvdG90eXBlLmJsb2NrcXVvdGUgPSBmdW5jdGlvbihxdW90ZSkge1xuICByZXR1cm4gJzxibG9ja3F1b3RlPlxcbicgKyBxdW90ZSArICc8L2Jsb2NrcXVvdGU+XFxuJztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5odG1sID0gZnVuY3Rpb24oaHRtbCkge1xuICByZXR1cm4gaHRtbDtcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5oZWFkaW5nID0gZnVuY3Rpb24odGV4dCwgbGV2ZWwsIHJhdykge1xuICByZXR1cm4gJzxoJ1xuICAgICsgbGV2ZWxcbiAgICArICcgaWQ9XCInXG4gICAgKyB0aGlzLm9wdGlvbnMuaGVhZGVyUHJlZml4XG4gICAgKyByYXcudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bXlxcd10rL2csICctJylcbiAgICArICdcIj4nXG4gICAgKyB0ZXh0XG4gICAgKyAnPC9oJ1xuICAgICsgbGV2ZWxcbiAgICArICc+XFxuJztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5ociA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5vcHRpb25zLnhodG1sID8gJzxoci8+XFxuJyA6ICc8aHI+XFxuJztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5saXN0ID0gZnVuY3Rpb24oYm9keSwgb3JkZXJlZCkge1xuICB2YXIgdHlwZSA9IG9yZGVyZWQgPyAnb2wnIDogJ3VsJztcbiAgcmV0dXJuICc8JyArIHR5cGUgKyAnPlxcbicgKyBib2R5ICsgJzwvJyArIHR5cGUgKyAnPlxcbic7XG59O1xuXG5SZW5kZXJlci5wcm90b3R5cGUubGlzdGl0ZW0gPSBmdW5jdGlvbih0ZXh0KSB7XG4gIHJldHVybiAnPGxpPicgKyB0ZXh0ICsgJzwvbGk+XFxuJztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5wYXJhZ3JhcGggPSBmdW5jdGlvbih0ZXh0KSB7XG4gIHJldHVybiAnPHA+JyArIHRleHQgKyAnPC9wPlxcbic7XG59O1xuXG5SZW5kZXJlci5wcm90b3R5cGUudGFibGUgPSBmdW5jdGlvbihoZWFkZXIsIGJvZHkpIHtcbiAgcmV0dXJuICc8dGFibGU+XFxuJ1xuICAgICsgJzx0aGVhZD5cXG4nXG4gICAgKyBoZWFkZXJcbiAgICArICc8L3RoZWFkPlxcbidcbiAgICArICc8dGJvZHk+XFxuJ1xuICAgICsgYm9keVxuICAgICsgJzwvdGJvZHk+XFxuJ1xuICAgICsgJzwvdGFibGU+XFxuJztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS50YWJsZXJvdyA9IGZ1bmN0aW9uKGNvbnRlbnQpIHtcbiAgcmV0dXJuICc8dHI+XFxuJyArIGNvbnRlbnQgKyAnPC90cj5cXG4nO1xufTtcblxuUmVuZGVyZXIucHJvdG90eXBlLnRhYmxlY2VsbCA9IGZ1bmN0aW9uKGNvbnRlbnQsIGZsYWdzKSB7XG4gIHZhciB0eXBlID0gZmxhZ3MuaGVhZGVyID8gJ3RoJyA6ICd0ZCc7XG4gIHZhciB0YWcgPSBmbGFncy5hbGlnblxuICAgID8gJzwnICsgdHlwZSArICcgc3R5bGU9XCJ0ZXh0LWFsaWduOicgKyBmbGFncy5hbGlnbiArICdcIj4nXG4gICAgOiAnPCcgKyB0eXBlICsgJz4nO1xuICByZXR1cm4gdGFnICsgY29udGVudCArICc8LycgKyB0eXBlICsgJz5cXG4nO1xufTtcblxuLy8gc3BhbiBsZXZlbCByZW5kZXJlclxuUmVuZGVyZXIucHJvdG90eXBlLnN0cm9uZyA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgcmV0dXJuICc8c3Ryb25nPicgKyB0ZXh0ICsgJzwvc3Ryb25nPic7XG59O1xuXG5SZW5kZXJlci5wcm90b3R5cGUuZW0gPSBmdW5jdGlvbih0ZXh0KSB7XG4gIHJldHVybiAnPGVtPicgKyB0ZXh0ICsgJzwvZW0+Jztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5jb2Rlc3BhbiA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgcmV0dXJuICc8Y29kZT4nICsgdGV4dCArICc8L2NvZGU+Jztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5iciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5vcHRpb25zLnhodG1sID8gJzxici8+JyA6ICc8YnI+Jztcbn07XG5cblJlbmRlcmVyLnByb3RvdHlwZS5kZWwgPSBmdW5jdGlvbih0ZXh0KSB7XG4gIHJldHVybiAnPGRlbD4nICsgdGV4dCArICc8L2RlbD4nO1xufTtcblxuUmVuZGVyZXIucHJvdG90eXBlLmxpbmsgPSBmdW5jdGlvbihocmVmLCB0aXRsZSwgdGV4dCkge1xuICBpZiAodGhpcy5vcHRpb25zLnNhbml0aXplKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBwcm90ID0gZGVjb2RlVVJJQ29tcG9uZW50KHVuZXNjYXBlKGhyZWYpKVxuICAgICAgICAucmVwbGFjZSgvW15cXHc6XS9nLCAnJylcbiAgICAgICAgLnRvTG93ZXJDYXNlKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBpZiAocHJvdC5pbmRleE9mKCdqYXZhc2NyaXB0OicpID09PSAwIHx8IHByb3QuaW5kZXhPZigndmJzY3JpcHQ6JykgPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cbiAgdmFyIG91dCA9ICc8YSBocmVmPVwiJyArIGhyZWYgKyAnXCInO1xuICBpZiAodGl0bGUpIHtcbiAgICBvdXQgKz0gJyB0aXRsZT1cIicgKyB0aXRsZSArICdcIic7XG4gIH1cbiAgb3V0ICs9ICc+JyArIHRleHQgKyAnPC9hPic7XG4gIHJldHVybiBvdXQ7XG59O1xuXG5SZW5kZXJlci5wcm90b3R5cGUuaW1hZ2UgPSBmdW5jdGlvbihocmVmLCB0aXRsZSwgdGV4dCkge1xuICB2YXIgb3V0ID0gJzxpbWcgc3JjPVwiJyArIGhyZWYgKyAnXCIgYWx0PVwiJyArIHRleHQgKyAnXCInO1xuICBpZiAodGl0bGUpIHtcbiAgICBvdXQgKz0gJyB0aXRsZT1cIicgKyB0aXRsZSArICdcIic7XG4gIH1cbiAgb3V0ICs9IHRoaXMub3B0aW9ucy54aHRtbCA/ICcvPicgOiAnPic7XG4gIHJldHVybiBvdXQ7XG59O1xuXG5SZW5kZXJlci5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgcmV0dXJuIHRleHQ7XG59O1xuXG4vKipcbiAqIFBhcnNpbmcgJiBDb21waWxpbmdcbiAqL1xuXG5mdW5jdGlvbiBQYXJzZXIob3B0aW9ucykge1xuICB0aGlzLnRva2VucyA9IFtdO1xuICB0aGlzLnRva2VuID0gbnVsbDtcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCBtYXJrZWQuZGVmYXVsdHM7XG4gIHRoaXMub3B0aW9ucy5yZW5kZXJlciA9IHRoaXMub3B0aW9ucy5yZW5kZXJlciB8fCBuZXcgUmVuZGVyZXI7XG4gIHRoaXMucmVuZGVyZXIgPSB0aGlzLm9wdGlvbnMucmVuZGVyZXI7XG4gIHRoaXMucmVuZGVyZXIub3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbn1cblxuLyoqXG4gKiBTdGF0aWMgUGFyc2UgTWV0aG9kXG4gKi9cblxuUGFyc2VyLnBhcnNlID0gZnVuY3Rpb24oc3JjLCBvcHRpb25zLCByZW5kZXJlcikge1xuICB2YXIgcGFyc2VyID0gbmV3IFBhcnNlcihvcHRpb25zLCByZW5kZXJlcik7XG4gIHJldHVybiBwYXJzZXIucGFyc2Uoc3JjKTtcbn07XG5cbi8qKlxuICogUGFyc2UgTG9vcFxuICovXG5cblBhcnNlci5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbihzcmMpIHtcbiAgdGhpcy5pbmxpbmUgPSBuZXcgSW5saW5lTGV4ZXIoc3JjLmxpbmtzLCB0aGlzLm9wdGlvbnMsIHRoaXMucmVuZGVyZXIpO1xuICB0aGlzLnRva2VucyA9IHNyYy5yZXZlcnNlKCk7XG5cbiAgdmFyIG91dCA9ICcnO1xuICB3aGlsZSAodGhpcy5uZXh0KCkpIHtcbiAgICBvdXQgKz0gdGhpcy50b2soKTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIE5leHQgVG9rZW5cbiAqL1xuXG5QYXJzZXIucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMudG9rZW4gPSB0aGlzLnRva2Vucy5wb3AoKTtcbn07XG5cbi8qKlxuICogUHJldmlldyBOZXh0IFRva2VuXG4gKi9cblxuUGFyc2VyLnByb3RvdHlwZS5wZWVrID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnRva2Vuc1t0aGlzLnRva2Vucy5sZW5ndGggLSAxXSB8fCAwO1xufTtcblxuLyoqXG4gKiBQYXJzZSBUZXh0IFRva2Vuc1xuICovXG5cblBhcnNlci5wcm90b3R5cGUucGFyc2VUZXh0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBib2R5ID0gdGhpcy50b2tlbi50ZXh0O1xuXG4gIHdoaWxlICh0aGlzLnBlZWsoKS50eXBlID09PSAndGV4dCcpIHtcbiAgICBib2R5ICs9ICdcXG4nICsgdGhpcy5uZXh0KCkudGV4dDtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmlubGluZS5vdXRwdXQoYm9keSk7XG59O1xuXG4vKipcbiAqIFBhcnNlIEN1cnJlbnQgVG9rZW5cbiAqL1xuXG5QYXJzZXIucHJvdG90eXBlLnRvayA9IGZ1bmN0aW9uKCkge1xuICBzd2l0Y2ggKHRoaXMudG9rZW4udHlwZSkge1xuICAgIGNhc2UgJ3NwYWNlJzoge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBjYXNlICdocic6IHtcbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLmhyKCk7XG4gICAgfVxuICAgIGNhc2UgJ2hlYWRpbmcnOiB7XG4gICAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5oZWFkaW5nKFxuICAgICAgICB0aGlzLmlubGluZS5vdXRwdXQodGhpcy50b2tlbi50ZXh0KSxcbiAgICAgICAgdGhpcy50b2tlbi5kZXB0aCxcbiAgICAgICAgdGhpcy50b2tlbi50ZXh0KTtcbiAgICB9XG4gICAgY2FzZSAnY29kZSc6IHtcbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLmNvZGUodGhpcy50b2tlbi50ZXh0LFxuICAgICAgICB0aGlzLnRva2VuLmxhbmcsXG4gICAgICAgIHRoaXMudG9rZW4uZXNjYXBlZCk7XG4gICAgfVxuICAgIGNhc2UgJ3RhYmxlJzoge1xuICAgICAgdmFyIGhlYWRlciA9ICcnXG4gICAgICAgICwgYm9keSA9ICcnXG4gICAgICAgICwgaVxuICAgICAgICAsIHJvd1xuICAgICAgICAsIGNlbGxcbiAgICAgICAgLCBmbGFnc1xuICAgICAgICAsIGo7XG5cbiAgICAgIC8vIGhlYWRlclxuICAgICAgY2VsbCA9ICcnO1xuICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMudG9rZW4uaGVhZGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZsYWdzID0geyBoZWFkZXI6IHRydWUsIGFsaWduOiB0aGlzLnRva2VuLmFsaWduW2ldIH07XG4gICAgICAgIGNlbGwgKz0gdGhpcy5yZW5kZXJlci50YWJsZWNlbGwoXG4gICAgICAgICAgdGhpcy5pbmxpbmUub3V0cHV0KHRoaXMudG9rZW4uaGVhZGVyW2ldKSxcbiAgICAgICAgICB7IGhlYWRlcjogdHJ1ZSwgYWxpZ246IHRoaXMudG9rZW4uYWxpZ25baV0gfVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaGVhZGVyICs9IHRoaXMucmVuZGVyZXIudGFibGVyb3coY2VsbCk7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLnRva2VuLmNlbGxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJvdyA9IHRoaXMudG9rZW4uY2VsbHNbaV07XG5cbiAgICAgICAgY2VsbCA9ICcnO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgcm93Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY2VsbCArPSB0aGlzLnJlbmRlcmVyLnRhYmxlY2VsbChcbiAgICAgICAgICAgIHRoaXMuaW5saW5lLm91dHB1dChyb3dbal0pLFxuICAgICAgICAgICAgeyBoZWFkZXI6IGZhbHNlLCBhbGlnbjogdGhpcy50b2tlbi5hbGlnbltqXSB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJvZHkgKz0gdGhpcy5yZW5kZXJlci50YWJsZXJvdyhjZWxsKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLnRhYmxlKGhlYWRlciwgYm9keSk7XG4gICAgfVxuICAgIGNhc2UgJ2Jsb2NrcXVvdGVfc3RhcnQnOiB7XG4gICAgICB2YXIgYm9keSA9ICcnO1xuXG4gICAgICB3aGlsZSAodGhpcy5uZXh0KCkudHlwZSAhPT0gJ2Jsb2NrcXVvdGVfZW5kJykge1xuICAgICAgICBib2R5ICs9IHRoaXMudG9rKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLmJsb2NrcXVvdGUoYm9keSk7XG4gICAgfVxuICAgIGNhc2UgJ2xpc3Rfc3RhcnQnOiB7XG4gICAgICB2YXIgYm9keSA9ICcnXG4gICAgICAgICwgb3JkZXJlZCA9IHRoaXMudG9rZW4ub3JkZXJlZDtcblxuICAgICAgd2hpbGUgKHRoaXMubmV4dCgpLnR5cGUgIT09ICdsaXN0X2VuZCcpIHtcbiAgICAgICAgYm9keSArPSB0aGlzLnRvaygpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5yZW5kZXJlci5saXN0KGJvZHksIG9yZGVyZWQpO1xuICAgIH1cbiAgICBjYXNlICdsaXN0X2l0ZW1fc3RhcnQnOiB7XG4gICAgICB2YXIgYm9keSA9ICcnO1xuXG4gICAgICB3aGlsZSAodGhpcy5uZXh0KCkudHlwZSAhPT0gJ2xpc3RfaXRlbV9lbmQnKSB7XG4gICAgICAgIGJvZHkgKz0gdGhpcy50b2tlbi50eXBlID09PSAndGV4dCdcbiAgICAgICAgICA/IHRoaXMucGFyc2VUZXh0KClcbiAgICAgICAgICA6IHRoaXMudG9rKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLmxpc3RpdGVtKGJvZHkpO1xuICAgIH1cbiAgICBjYXNlICdsb29zZV9pdGVtX3N0YXJ0Jzoge1xuICAgICAgdmFyIGJvZHkgPSAnJztcblxuICAgICAgd2hpbGUgKHRoaXMubmV4dCgpLnR5cGUgIT09ICdsaXN0X2l0ZW1fZW5kJykge1xuICAgICAgICBib2R5ICs9IHRoaXMudG9rKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLmxpc3RpdGVtKGJvZHkpO1xuICAgIH1cbiAgICBjYXNlICdodG1sJzoge1xuICAgICAgdmFyIGh0bWwgPSAhdGhpcy50b2tlbi5wcmUgJiYgIXRoaXMub3B0aW9ucy5wZWRhbnRpY1xuICAgICAgICA/IHRoaXMuaW5saW5lLm91dHB1dCh0aGlzLnRva2VuLnRleHQpXG4gICAgICAgIDogdGhpcy50b2tlbi50ZXh0O1xuICAgICAgcmV0dXJuIHRoaXMucmVuZGVyZXIuaHRtbChodG1sKTtcbiAgICB9XG4gICAgY2FzZSAncGFyYWdyYXBoJzoge1xuICAgICAgcmV0dXJuIHRoaXMucmVuZGVyZXIucGFyYWdyYXBoKHRoaXMuaW5saW5lLm91dHB1dCh0aGlzLnRva2VuLnRleHQpKTtcbiAgICB9XG4gICAgY2FzZSAndGV4dCc6IHtcbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLnBhcmFncmFwaCh0aGlzLnBhcnNlVGV4dCgpKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogSGVscGVyc1xuICovXG5cbmZ1bmN0aW9uIGVzY2FwZShodG1sLCBlbmNvZGUpIHtcbiAgcmV0dXJuIGh0bWxcbiAgICAucmVwbGFjZSghZW5jb2RlID8gLyYoPyEjP1xcdys7KS9nIDogLyYvZywgJyZhbXA7JylcbiAgICAucmVwbGFjZSgvPC9nLCAnJmx0OycpXG4gICAgLnJlcGxhY2UoLz4vZywgJyZndDsnKVxuICAgIC5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7JylcbiAgICAucmVwbGFjZSgvJy9nLCAnJiMzOTsnKTtcbn1cblxuZnVuY3Rpb24gdW5lc2NhcGUoaHRtbCkge1xuXHQvLyBleHBsaWNpdGx5IG1hdGNoIGRlY2ltYWwsIGhleCwgYW5kIG5hbWVkIEhUTUwgZW50aXRpZXMgXG4gIHJldHVybiBodG1sLnJlcGxhY2UoLyYoIyg/OlxcZCspfCg/OiN4WzAtOUEtRmEtZl0rKXwoPzpcXHcrKSk7Py9nLCBmdW5jdGlvbihfLCBuKSB7XG4gICAgbiA9IG4udG9Mb3dlckNhc2UoKTtcbiAgICBpZiAobiA9PT0gJ2NvbG9uJykgcmV0dXJuICc6JztcbiAgICBpZiAobi5jaGFyQXQoMCkgPT09ICcjJykge1xuICAgICAgcmV0dXJuIG4uY2hhckF0KDEpID09PSAneCdcbiAgICAgICAgPyBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KG4uc3Vic3RyaW5nKDIpLCAxNikpXG4gICAgICAgIDogU3RyaW5nLmZyb21DaGFyQ29kZSgrbi5zdWJzdHJpbmcoMSkpO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlKHJlZ2V4LCBvcHQpIHtcbiAgcmVnZXggPSByZWdleC5zb3VyY2U7XG4gIG9wdCA9IG9wdCB8fCAnJztcbiAgcmV0dXJuIGZ1bmN0aW9uIHNlbGYobmFtZSwgdmFsKSB7XG4gICAgaWYgKCFuYW1lKSByZXR1cm4gbmV3IFJlZ0V4cChyZWdleCwgb3B0KTtcbiAgICB2YWwgPSB2YWwuc291cmNlIHx8IHZhbDtcbiAgICB2YWwgPSB2YWwucmVwbGFjZSgvKF58W15cXFtdKVxcXi9nLCAnJDEnKTtcbiAgICByZWdleCA9IHJlZ2V4LnJlcGxhY2UobmFtZSwgdmFsKTtcbiAgICByZXR1cm4gc2VsZjtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5ub29wLmV4ZWMgPSBub29wO1xuXG5mdW5jdGlvbiBtZXJnZShvYmopIHtcbiAgdmFyIGkgPSAxXG4gICAgLCB0YXJnZXRcbiAgICAsIGtleTtcblxuICBmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHRhcmdldCA9IGFyZ3VtZW50c1tpXTtcbiAgICBmb3IgKGtleSBpbiB0YXJnZXQpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGFyZ2V0LCBrZXkpKSB7XG4gICAgICAgIG9ialtrZXldID0gdGFyZ2V0W2tleV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuXG4vKipcbiAqIE1hcmtlZFxuICovXG5cbmZ1bmN0aW9uIG1hcmtlZChzcmMsIG9wdCwgY2FsbGJhY2spIHtcbiAgaWYgKGNhbGxiYWNrIHx8IHR5cGVvZiBvcHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgICBjYWxsYmFjayA9IG9wdDtcbiAgICAgIG9wdCA9IG51bGw7XG4gICAgfVxuXG4gICAgb3B0ID0gbWVyZ2Uoe30sIG1hcmtlZC5kZWZhdWx0cywgb3B0IHx8IHt9KTtcblxuICAgIHZhciBoaWdobGlnaHQgPSBvcHQuaGlnaGxpZ2h0XG4gICAgICAsIHRva2Vuc1xuICAgICAgLCBwZW5kaW5nXG4gICAgICAsIGkgPSAwO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRva2VucyA9IExleGVyLmxleChzcmMsIG9wdClcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZSk7XG4gICAgfVxuXG4gICAgcGVuZGluZyA9IHRva2Vucy5sZW5ndGg7XG5cbiAgICB2YXIgZG9uZSA9IGZ1bmN0aW9uKGVycikge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBvcHQuaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgIH1cblxuICAgICAgdmFyIG91dDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgb3V0ID0gUGFyc2VyLnBhcnNlKHRva2Vucywgb3B0KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZXJyID0gZTtcbiAgICAgIH1cblxuICAgICAgb3B0LmhpZ2hsaWdodCA9IGhpZ2hsaWdodDtcblxuICAgICAgcmV0dXJuIGVyclxuICAgICAgICA/IGNhbGxiYWNrKGVycilcbiAgICAgICAgOiBjYWxsYmFjayhudWxsLCBvdXQpO1xuICAgIH07XG5cbiAgICBpZiAoIWhpZ2hsaWdodCB8fCBoaWdobGlnaHQubGVuZ3RoIDwgMykge1xuICAgICAgcmV0dXJuIGRvbmUoKTtcbiAgICB9XG5cbiAgICBkZWxldGUgb3B0LmhpZ2hsaWdodDtcblxuICAgIGlmICghcGVuZGluZykgcmV0dXJuIGRvbmUoKTtcblxuICAgIGZvciAoOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAoZnVuY3Rpb24odG9rZW4pIHtcbiAgICAgICAgaWYgKHRva2VuLnR5cGUgIT09ICdjb2RlJykge1xuICAgICAgICAgIHJldHVybiAtLXBlbmRpbmcgfHwgZG9uZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoaWdobGlnaHQodG9rZW4udGV4dCwgdG9rZW4ubGFuZywgZnVuY3Rpb24oZXJyLCBjb2RlKSB7XG4gICAgICAgICAgaWYgKGVycikgcmV0dXJuIGRvbmUoZXJyKTtcbiAgICAgICAgICBpZiAoY29kZSA9PSBudWxsIHx8IGNvZGUgPT09IHRva2VuLnRleHQpIHtcbiAgICAgICAgICAgIHJldHVybiAtLXBlbmRpbmcgfHwgZG9uZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0b2tlbi50ZXh0ID0gY29kZTtcbiAgICAgICAgICB0b2tlbi5lc2NhcGVkID0gdHJ1ZTtcbiAgICAgICAgICAtLXBlbmRpbmcgfHwgZG9uZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pKHRva2Vuc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuO1xuICB9XG4gIHRyeSB7XG4gICAgaWYgKG9wdCkgb3B0ID0gbWVyZ2Uoe30sIG1hcmtlZC5kZWZhdWx0cywgb3B0KTtcbiAgICByZXR1cm4gUGFyc2VyLnBhcnNlKExleGVyLmxleChzcmMsIG9wdCksIG9wdCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlLm1lc3NhZ2UgKz0gJ1xcblBsZWFzZSByZXBvcnQgdGhpcyB0byBodHRwczovL2dpdGh1Yi5jb20vY2hqai9tYXJrZWQuJztcbiAgICBpZiAoKG9wdCB8fCBtYXJrZWQuZGVmYXVsdHMpLnNpbGVudCkge1xuICAgICAgcmV0dXJuICc8cD5BbiBlcnJvciBvY2N1cmVkOjwvcD48cHJlPidcbiAgICAgICAgKyBlc2NhcGUoZS5tZXNzYWdlICsgJycsIHRydWUpXG4gICAgICAgICsgJzwvcHJlPic7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cbn1cblxuLyoqXG4gKiBPcHRpb25zXG4gKi9cblxubWFya2VkLm9wdGlvbnMgPVxubWFya2VkLnNldE9wdGlvbnMgPSBmdW5jdGlvbihvcHQpIHtcbiAgbWVyZ2UobWFya2VkLmRlZmF1bHRzLCBvcHQpO1xuICByZXR1cm4gbWFya2VkO1xufTtcblxubWFya2VkLmRlZmF1bHRzID0ge1xuICBnZm06IHRydWUsXG4gIHRhYmxlczogdHJ1ZSxcbiAgYnJlYWtzOiBmYWxzZSxcbiAgcGVkYW50aWM6IGZhbHNlLFxuICBzYW5pdGl6ZTogZmFsc2UsXG4gIHNhbml0aXplcjogbnVsbCxcbiAgbWFuZ2xlOiB0cnVlLFxuICBzbWFydExpc3RzOiBmYWxzZSxcbiAgc2lsZW50OiBmYWxzZSxcbiAgaGlnaGxpZ2h0OiBudWxsLFxuICBsYW5nUHJlZml4OiAnbGFuZy0nLFxuICBzbWFydHlwYW50czogZmFsc2UsXG4gIGhlYWRlclByZWZpeDogJycsXG4gIHJlbmRlcmVyOiBuZXcgUmVuZGVyZXIsXG4gIHhodG1sOiBmYWxzZVxufTtcblxuLyoqXG4gKiBFeHBvc2VcbiAqL1xuXG5tYXJrZWQuUGFyc2VyID0gUGFyc2VyO1xubWFya2VkLnBhcnNlciA9IFBhcnNlci5wYXJzZTtcblxubWFya2VkLlJlbmRlcmVyID0gUmVuZGVyZXI7XG5cbm1hcmtlZC5MZXhlciA9IExleGVyO1xubWFya2VkLmxleGVyID0gTGV4ZXIubGV4O1xuXG5tYXJrZWQuSW5saW5lTGV4ZXIgPSBJbmxpbmVMZXhlcjtcbm1hcmtlZC5pbmxpbmVMZXhlciA9IElubGluZUxleGVyLm91dHB1dDtcblxubWFya2VkLnBhcnNlID0gbWFya2VkO1xuXG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gbWFya2VkO1xufSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgZGVmaW5lKGZ1bmN0aW9uKCkgeyByZXR1cm4gbWFya2VkOyB9KTtcbn0gZWxzZSB7XG4gIHRoaXMubWFya2VkID0gbWFya2VkO1xufVxuXG59KS5jYWxsKGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcyB8fCAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiBnbG9iYWwpO1xufSgpKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9tYXJrZWQvbGliL21hcmtlZC5qc1xuLy8gbW9kdWxlIGlkID0gOTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIilcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzXG4vLyBtb2R1bGUgaWQgPSA5M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGJ1ZmZlclNoaW0gPSByZXF1aXJlKCdidWZmZXItc2hpbXMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlckxpc3Q7XG5cbmZ1bmN0aW9uIEJ1ZmZlckxpc3QoKSB7XG4gIHRoaXMuaGVhZCA9IG51bGw7XG4gIHRoaXMudGFpbCA9IG51bGw7XG4gIHRoaXMubGVuZ3RoID0gMDtcbn1cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uICh2KSB7XG4gIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogbnVsbCB9O1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB0aGlzLnRhaWwubmV4dCA9IGVudHJ5O2Vsc2UgdGhpcy5oZWFkID0gZW50cnk7XG4gIHRoaXMudGFpbCA9IGVudHJ5O1xuICArK3RoaXMubGVuZ3RoO1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uICh2KSB7XG4gIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogdGhpcy5oZWFkIH07XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgdGhpcy50YWlsID0gZW50cnk7XG4gIHRoaXMuaGVhZCA9IGVudHJ5O1xuICArK3RoaXMubGVuZ3RoO1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuc2hpZnQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICB2YXIgcmV0ID0gdGhpcy5oZWFkLmRhdGE7XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMuaGVhZC5uZXh0O1xuICAtLXRoaXMubGVuZ3RoO1xuICByZXR1cm4gcmV0O1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gIHRoaXMubGVuZ3RoID0gMDtcbn07XG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAocykge1xuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gIHZhciByZXQgPSAnJyArIHAuZGF0YTtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICByZXQgKz0gcyArIHAuZGF0YTtcbiAgfXJldHVybiByZXQ7XG59O1xuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5jb25jYXQgPSBmdW5jdGlvbiAobikge1xuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiBidWZmZXJTaGltLmFsbG9jKDApO1xuICBpZiAodGhpcy5sZW5ndGggPT09IDEpIHJldHVybiB0aGlzLmhlYWQuZGF0YTtcbiAgdmFyIHJldCA9IGJ1ZmZlclNoaW0uYWxsb2NVbnNhZmUobiA+Pj4gMCk7XG4gIHZhciBwID0gdGhpcy5oZWFkO1xuICB2YXIgaSA9IDA7XG4gIHdoaWxlIChwKSB7XG4gICAgcC5kYXRhLmNvcHkocmV0LCBpKTtcbiAgICBpICs9IHAuZGF0YS5sZW5ndGg7XG4gICAgcCA9IHAubmV4dDtcbiAgfVxuICByZXR1cm4gcmV0O1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QuanNcbi8vIG1vZHVsZSBpZCA9IDk0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIilcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanNcbi8vIG1vZHVsZSBpZCA9IDk1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBTdHJlYW0gPSAoZnVuY3Rpb24gKCl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlcXVpcmUoJ3N0JyArICdyZWFtJyk7IC8vIGhhY2sgdG8gZml4IGEgY2lyY3VsYXIgZGVwZW5kZW5jeSBpc3N1ZSB3aGVuIHVzZWQgd2l0aCBicm93c2VyaWZ5XG4gIH0gY2F0Y2goXyl7fVxufSgpKTtcbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcmVhZGFibGUuanMnKTtcbmV4cG9ydHMuU3RyZWFtID0gU3RyZWFtIHx8IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG5leHBvcnRzLkR1cGxleCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fZHVwbGV4LmpzJyk7XG5leHBvcnRzLlRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzJyk7XG5leHBvcnRzLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcycpO1xuXG5pZiAoIXByb2Nlc3MuYnJvd3NlciAmJiBwcm9jZXNzLmVudi5SRUFEQUJMRV9TVFJFQU0gPT09ICdkaXNhYmxlJyAmJiBTdHJlYW0pIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzXG4vLyBtb2R1bGUgaWQgPSA5NlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanNcbi8vIG1vZHVsZSBpZCA9IDk3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIilcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcbi8vIG1vZHVsZSBpZCA9IDk4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHN0cmluZykge1xuICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoL1stXFxcXF4kKis/LigpfFtcXF17fV0vZywgXCJcXFxcJCZcIilcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yZWdleHAtcXVvdGUvcmVnZXhwLXF1b3RlLmpzXG4vLyBtb2R1bGUgaWQgPSA5OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgaHRtbHBhcnNlciA9IHJlcXVpcmUoJ2h0bWxwYXJzZXIyJyk7XG52YXIgZXh0ZW5kID0gcmVxdWlyZSgneHRlbmQnKTtcbnZhciBxdW90ZVJlZ2V4cCA9IHJlcXVpcmUoJ3JlZ2V4cC1xdW90ZScpO1xuXG5mdW5jdGlvbiBlYWNoKG9iaiwgY2IpIHtcbiAgaWYgKG9iaikgT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICBjYihvYmpba2V5XSwga2V5KTtcbiAgfSk7XG59XG5cbi8vIEF2b2lkIGZhbHNlIHBvc2l0aXZlcyB3aXRoIC5fX3Byb3RvX18sIC5oYXNPd25Qcm9wZXJ0eSwgZXRjLlxuZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gIHJldHVybiAoe30pLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNhbml0aXplSHRtbDtcblxuLy8gSWdub3JlIHRoZSBfcmVjdXJzaW5nIGZsYWc7IGl0J3MgdGhlcmUgZm9yIHJlY3Vyc2l2ZVxuLy8gaW52b2NhdGlvbiBhcyBhIGd1YXJkIGFnYWluc3QgdGhpcyBleHBsb2l0OlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZiNTUvaHRtbHBhcnNlcjIvaXNzdWVzLzEwNVxuXG5mdW5jdGlvbiBzYW5pdGl6ZUh0bWwoaHRtbCwgb3B0aW9ucywgX3JlY3Vyc2luZykge1xuICB2YXIgcmVzdWx0ID0gJyc7XG5cbiAgZnVuY3Rpb24gRnJhbWUodGFnLCBhdHRyaWJzKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHRoaXMudGFnID0gdGFnO1xuICAgIHRoaXMuYXR0cmlicyA9IGF0dHJpYnMgfHwge307XG4gICAgdGhpcy50YWdQb3NpdGlvbiA9IHJlc3VsdC5sZW5ndGg7XG4gICAgdGhpcy50ZXh0ID0gJyc7IC8vIE5vZGUgaW5uZXIgdGV4dFxuXG4gICAgdGhpcy51cGRhdGVQYXJlbnROb2RlVGV4dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHN0YWNrLmxlbmd0aCkge1xuICAgICAgICAgIHZhciBwYXJlbnRGcmFtZSA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuICAgICAgICAgIHBhcmVudEZyYW1lLnRleHQgKz0gdGhhdC50ZXh0O1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gc2FuaXRpemVIdG1sLmRlZmF1bHRzO1xuICAgIG9wdGlvbnMucGFyc2VyID0gaHRtbFBhcnNlckRlZmF1bHRzO1xuICB9IGVsc2Uge1xuICAgIG9wdGlvbnMgPSBleHRlbmQoc2FuaXRpemVIdG1sLmRlZmF1bHRzLCBvcHRpb25zKTtcbiAgICBpZiAob3B0aW9ucy5wYXJzZXIpIHtcbiAgICAgIG9wdGlvbnMucGFyc2VyID0gZXh0ZW5kKGh0bWxQYXJzZXJEZWZhdWx0cywgb3B0aW9ucy5wYXJzZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zLnBhcnNlciA9IGh0bWxQYXJzZXJEZWZhdWx0cztcbiAgICB9XG4gIH1cblxuICAvLyBUYWdzIHRoYXQgY29udGFpbiBzb21ldGhpbmcgb3RoZXIgdGhhbiBIVE1MLCBvciB3aGVyZSBkaXNjYXJkaW5nXG4gIC8vIHRoZSB0ZXh0IHdoZW4gdGhlIHRhZyBpcyBkaXNhbGxvd2VkIG1ha2VzIHNlbnNlIGZvciBvdGhlciByZWFzb25zLlxuICAvLyBJZiB3ZSBhcmUgbm90IGFsbG93aW5nIHRoZXNlIHRhZ3MsIHdlIHNob3VsZCBkcm9wIHRoZWlyIGNvbnRlbnQgdG9vLlxuICAvLyBGb3Igb3RoZXIgdGFncyB5b3Ugd291bGQgZHJvcCB0aGUgdGFnIGJ1dCBrZWVwIGl0cyBjb250ZW50LlxuICB2YXIgbm9uVGV4dFRhZ3NBcnJheSA9IG9wdGlvbnMubm9uVGV4dFRhZ3MgfHwgWyAnc2NyaXB0JywgJ3N0eWxlJywgJ3RleHRhcmVhJyBdO1xuICB2YXIgYWxsb3dlZEF0dHJpYnV0ZXNNYXA7XG4gIHZhciBhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXA7XG4gIGlmKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMpIHtcbiAgICBhbGxvd2VkQXR0cmlidXRlc01hcCA9IHt9O1xuICAgIGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcCA9IHt9O1xuICAgIGVhY2gob3B0aW9ucy5hbGxvd2VkQXR0cmlidXRlcywgZnVuY3Rpb24oYXR0cmlidXRlcywgdGFnKSB7XG4gICAgICBhbGxvd2VkQXR0cmlidXRlc01hcFt0YWddID0gW107XG4gICAgICB2YXIgZ2xvYlJlZ2V4ID0gW107XG4gICAgICBhdHRyaWJ1dGVzLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuICAgICAgICBpZihuYW1lLmluZGV4T2YoJyonKSA+PSAwKSB7XG4gICAgICAgICAgZ2xvYlJlZ2V4LnB1c2gocXVvdGVSZWdleHAobmFtZSkucmVwbGFjZSgvXFxcXFxcKi9nLCAnLionKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXS5wdXNoKG5hbWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFt0YWddID0gbmV3IFJlZ0V4cCgnXignICsgZ2xvYlJlZ2V4LmpvaW4oJ3wnKSArICcpJCcpO1xuICAgIH0pO1xuICB9XG4gIHZhciBhbGxvd2VkQ2xhc3Nlc01hcCA9IHt9O1xuICBlYWNoKG9wdGlvbnMuYWxsb3dlZENsYXNzZXMsIGZ1bmN0aW9uKGNsYXNzZXMsIHRhZykge1xuICAgIC8vIEltcGxpY2l0bHkgYWxsb3dzIHRoZSBjbGFzcyBhdHRyaWJ1dGVcbiAgICBpZihhbGxvd2VkQXR0cmlidXRlc01hcCkge1xuICAgICAgaWYgKCFoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsIHRhZykpIHtcbiAgICAgICAgYWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXSA9IFtdO1xuICAgICAgfVxuICAgICAgYWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXS5wdXNoKCdjbGFzcycpO1xuICAgIH1cblxuICAgIGFsbG93ZWRDbGFzc2VzTWFwW3RhZ10gPSBjbGFzc2VzO1xuICB9KTtcblxuICB2YXIgdHJhbnNmb3JtVGFnc01hcCA9IHt9O1xuICB2YXIgdHJhbnNmb3JtVGFnc0FsbDtcbiAgZWFjaChvcHRpb25zLnRyYW5zZm9ybVRhZ3MsIGZ1bmN0aW9uKHRyYW5zZm9ybSwgdGFnKSB7XG4gICAgdmFyIHRyYW5zRnVuO1xuICAgIGlmICh0eXBlb2YgdHJhbnNmb3JtID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0cmFuc0Z1biA9IHRyYW5zZm9ybTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0cmFuc2Zvcm0gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRyYW5zRnVuID0gc2FuaXRpemVIdG1sLnNpbXBsZVRyYW5zZm9ybSh0cmFuc2Zvcm0pO1xuICAgIH1cbiAgICBpZiAodGFnID09PSAnKicpIHtcbiAgICAgIHRyYW5zZm9ybVRhZ3NBbGwgPSB0cmFuc0Z1bjtcbiAgICB9IGVsc2Uge1xuICAgICAgdHJhbnNmb3JtVGFnc01hcFt0YWddID0gdHJhbnNGdW47XG4gICAgfVxuICB9KTtcblxuICB2YXIgZGVwdGggPSAwO1xuICB2YXIgc3RhY2sgPSBbXTtcbiAgdmFyIHNraXBNYXAgPSB7fTtcbiAgdmFyIHRyYW5zZm9ybU1hcCA9IHt9O1xuICB2YXIgc2tpcFRleHQgPSBmYWxzZTtcbiAgdmFyIHNraXBUZXh0RGVwdGggPSAwO1xuXG4gIHZhciBwYXJzZXIgPSBuZXcgaHRtbHBhcnNlci5QYXJzZXIoe1xuICAgIG9ub3BlbnRhZzogZnVuY3Rpb24obmFtZSwgYXR0cmlicykge1xuICAgICAgaWYgKHNraXBUZXh0KSB7XG4gICAgICAgIHNraXBUZXh0RGVwdGgrKztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdmFyIGZyYW1lID0gbmV3IEZyYW1lKG5hbWUsIGF0dHJpYnMpO1xuICAgICAgc3RhY2sucHVzaChmcmFtZSk7XG5cbiAgICAgIHZhciBza2lwID0gZmFsc2U7XG4gICAgICB2YXIgaGFzVGV4dCA9IGZyYW1lLnRleHQgPyB0cnVlIDogZmFsc2U7XG4gICAgICB2YXIgdHJhbnNmb3JtZWRUYWc7XG4gICAgICBpZiAoaGFzKHRyYW5zZm9ybVRhZ3NNYXAsIG5hbWUpKSB7XG4gICAgICAgIHRyYW5zZm9ybWVkVGFnID0gdHJhbnNmb3JtVGFnc01hcFtuYW1lXShuYW1lLCBhdHRyaWJzKTtcblxuICAgICAgICBmcmFtZS5hdHRyaWJzID0gYXR0cmlicyA9IHRyYW5zZm9ybWVkVGFnLmF0dHJpYnM7XG5cbiAgICAgICAgaWYgKHRyYW5zZm9ybWVkVGFnLnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZyYW1lLmlubmVyVGV4dCA9IHRyYW5zZm9ybWVkVGFnLnRleHQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmFtZSAhPT0gdHJhbnNmb3JtZWRUYWcudGFnTmFtZSkge1xuICAgICAgICAgIGZyYW1lLm5hbWUgPSBuYW1lID0gdHJhbnNmb3JtZWRUYWcudGFnTmFtZTtcbiAgICAgICAgICB0cmFuc2Zvcm1NYXBbZGVwdGhdID0gdHJhbnNmb3JtZWRUYWcudGFnTmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRyYW5zZm9ybVRhZ3NBbGwpIHtcbiAgICAgICAgdHJhbnNmb3JtZWRUYWcgPSB0cmFuc2Zvcm1UYWdzQWxsKG5hbWUsIGF0dHJpYnMpO1xuXG4gICAgICAgIGZyYW1lLmF0dHJpYnMgPSBhdHRyaWJzID0gdHJhbnNmb3JtZWRUYWcuYXR0cmlicztcbiAgICAgICAgaWYgKG5hbWUgIT09IHRyYW5zZm9ybWVkVGFnLnRhZ05hbWUpIHtcbiAgICAgICAgICBmcmFtZS5uYW1lID0gbmFtZSA9IHRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7XG4gICAgICAgICAgdHJhbnNmb3JtTWFwW2RlcHRoXSA9IHRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMuYWxsb3dlZFRhZ3MgJiYgb3B0aW9ucy5hbGxvd2VkVGFncy5pbmRleE9mKG5hbWUpID09PSAtMSkge1xuICAgICAgICBza2lwID0gdHJ1ZTtcbiAgICAgICAgaWYgKG5vblRleHRUYWdzQXJyYXkuaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgICBza2lwVGV4dCA9IHRydWU7XG4gICAgICAgICAgc2tpcFRleHREZXB0aCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcE1hcFtkZXB0aF0gPSB0cnVlO1xuICAgICAgfVxuICAgICAgZGVwdGgrKztcbiAgICAgIGlmIChza2lwKSB7XG4gICAgICAgIC8vIFdlIHdhbnQgdGhlIGNvbnRlbnRzIGJ1dCBub3QgdGhpcyB0YWdcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmVzdWx0ICs9ICc8JyArIG5hbWU7XG4gICAgICBpZiAoIWFsbG93ZWRBdHRyaWJ1dGVzTWFwIHx8IGhhcyhhbGxvd2VkQXR0cmlidXRlc01hcCwgbmFtZSkgfHwgYWxsb3dlZEF0dHJpYnV0ZXNNYXBbJyonXSkge1xuICAgICAgICBlYWNoKGF0dHJpYnMsIGZ1bmN0aW9uKHZhbHVlLCBhKSB7XG4gICAgICAgICAgaWYgKCFhbGxvd2VkQXR0cmlidXRlc01hcCB8fFxuICAgICAgICAgICAgICAoaGFzKGFsbG93ZWRBdHRyaWJ1dGVzTWFwLCBuYW1lKSAmJiBhbGxvd2VkQXR0cmlidXRlc01hcFtuYW1lXS5pbmRleE9mKGEpICE9PSAtMSApIHx8XG4gICAgICAgICAgICAgIChhbGxvd2VkQXR0cmlidXRlc01hcFsnKiddICYmIGFsbG93ZWRBdHRyaWJ1dGVzTWFwWycqJ10uaW5kZXhPZihhKSAhPT0gLTEgKSB8fFxuICAgICAgICAgICAgICAoaGFzKGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcCwgbmFtZSkgJiYgYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwW25hbWVdLnRlc3QoYSkpIHx8XG4gICAgICAgICAgICAgIChhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXBbJyonXSAmJiBhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXBbJyonXS50ZXN0KGEpKSkge1xuICAgICAgICAgICAgaWYgKChhID09PSAnaHJlZicpIHx8IChhID09PSAnc3JjJykpIHtcbiAgICAgICAgICAgICAgaWYgKG5hdWdodHlIcmVmKG5hbWUsIHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBmcmFtZS5hdHRyaWJzW2FdO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGEgPT09ICdjbGFzcycpIHtcbiAgICAgICAgICAgICAgdmFsdWUgPSBmaWx0ZXJDbGFzc2VzKHZhbHVlLCBhbGxvd2VkQ2xhc3Nlc01hcFtuYW1lXSk7XG4gICAgICAgICAgICAgIGlmICghdmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV07XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQgKz0gJyAnICsgYTtcbiAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9ICc9XCInICsgZXNjYXBlSHRtbCh2YWx1ZSkgKyAnXCInO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWxldGUgZnJhbWUuYXR0cmlic1thXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuc2VsZkNsb3NpbmcuaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgcmVzdWx0ICs9IFwiIC8+XCI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgKz0gXCI+XCI7XG4gICAgICAgIGlmIChmcmFtZS5pbm5lclRleHQgJiYgIWhhc1RleHQgJiYgIW9wdGlvbnMudGV4dEZpbHRlcikge1xuICAgICAgICAgIHJlc3VsdCArPSBmcmFtZS5pbm5lclRleHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIG9udGV4dDogZnVuY3Rpb24odGV4dCkge1xuICAgICAgaWYgKHNraXBUZXh0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBsYXN0RnJhbWUgPSBzdGFja1tzdGFjay5sZW5ndGgtMV07XG4gICAgICB2YXIgdGFnO1xuXG4gICAgICBpZiAobGFzdEZyYW1lKSB7XG4gICAgICAgIHRhZyA9IGxhc3RGcmFtZS50YWc7XG4gICAgICAgIC8vIElmIGlubmVyIHRleHQgd2FzIHNldCBieSB0cmFuc2Zvcm0gZnVuY3Rpb24gdGhlbiBsZXQncyB1c2UgaXRcbiAgICAgICAgdGV4dCA9IGxhc3RGcmFtZS5pbm5lclRleHQgIT09IHVuZGVmaW5lZCA/IGxhc3RGcmFtZS5pbm5lclRleHQgOiB0ZXh0O1xuICAgICAgfVxuXG4gICAgICBpZiAoKHRhZyA9PT0gJ3NjcmlwdCcpIHx8ICh0YWcgPT09ICdzdHlsZScpKSB7XG4gICAgICAgIC8vIGh0bWxwYXJzZXIyIGdpdmVzIHVzIHRoZXNlIGFzLWlzLiBFc2NhcGluZyB0aGVtIHJ1aW5zIHRoZSBjb250ZW50LiBBbGxvd2luZ1xuICAgICAgICAvLyBzY3JpcHQgdGFncyBpcywgYnkgZGVmaW5pdGlvbiwgZ2FtZSBvdmVyIGZvciBYU1MgcHJvdGVjdGlvbiwgc28gaWYgdGhhdCdzXG4gICAgICAgIC8vIHlvdXIgY29uY2VybiwgZG9uJ3QgYWxsb3cgdGhlbS4gVGhlIHNhbWUgaXMgZXNzZW50aWFsbHkgdHJ1ZSBmb3Igc3R5bGUgdGFnc1xuICAgICAgICAvLyB3aGljaCBoYXZlIHRoZWlyIG93biBjb2xsZWN0aW9uIG9mIFhTUyB2ZWN0b3JzLlxuICAgICAgICByZXN1bHQgKz0gdGV4dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBlc2NhcGVkID0gZXNjYXBlSHRtbCh0ZXh0KTtcbiAgICAgICAgaWYgKG9wdGlvbnMudGV4dEZpbHRlcikge1xuICAgICAgICAgIHJlc3VsdCArPSBvcHRpb25zLnRleHRGaWx0ZXIoZXNjYXBlZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0ICs9IGVzY2FwZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChzdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICAgdmFyIGZyYW1lID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07XG4gICAgICAgICAgIGZyYW1lLnRleHQgKz0gdGV4dDtcbiAgICAgIH1cbiAgICB9LFxuICAgIG9uY2xvc2V0YWc6IGZ1bmN0aW9uKG5hbWUpIHtcblxuICAgICAgaWYgKHNraXBUZXh0KSB7XG4gICAgICAgIHNraXBUZXh0RGVwdGgtLTtcbiAgICAgICAgaWYgKCFza2lwVGV4dERlcHRoKSB7XG4gICAgICAgICAgc2tpcFRleHQgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGZyYW1lID0gc3RhY2sucG9wKCk7XG4gICAgICBpZiAoIWZyYW1lKSB7XG4gICAgICAgIC8vIERvIG5vdCBjcmFzaCBvbiBiYWQgbWFya3VwXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHNraXBUZXh0ID0gZmFsc2U7XG4gICAgICBkZXB0aC0tO1xuICAgICAgaWYgKHNraXBNYXBbZGVwdGhdKSB7XG4gICAgICAgIGRlbGV0ZSBza2lwTWFwW2RlcHRoXTtcbiAgICAgICAgZnJhbWUudXBkYXRlUGFyZW50Tm9kZVRleHQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodHJhbnNmb3JtTWFwW2RlcHRoXSkge1xuICAgICAgICBuYW1lID0gdHJhbnNmb3JtTWFwW2RlcHRoXTtcbiAgICAgICAgZGVsZXRlIHRyYW5zZm9ybU1hcFtkZXB0aF07XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmV4Y2x1c2l2ZUZpbHRlciAmJiBvcHRpb25zLmV4Y2x1c2l2ZUZpbHRlcihmcmFtZSkpIHtcbiAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdWJzdHIoMCwgZnJhbWUudGFnUG9zaXRpb24pO1xuICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmcmFtZS51cGRhdGVQYXJlbnROb2RlVGV4dCgpO1xuXG4gICAgICBpZiAob3B0aW9ucy5zZWxmQ2xvc2luZy5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgICAgLy8gQWxyZWFkeSBvdXRwdXQgLz5cbiAgICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcmVzdWx0ICs9IFwiPC9cIiArIG5hbWUgKyBcIj5cIjtcbiAgICB9XG4gIH0sIG9wdGlvbnMucGFyc2VyKTtcbiAgcGFyc2VyLndyaXRlKGh0bWwpO1xuICBwYXJzZXIuZW5kKCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcblxuICBmdW5jdGlvbiBlc2NhcGVIdG1sKHMpIHtcbiAgICBpZiAodHlwZW9mKHMpICE9PSAnc3RyaW5nJykge1xuICAgICAgcyA9IHMgKyAnJztcbiAgICB9XG4gICAgcmV0dXJuIHMucmVwbGFjZSgvXFwmL2csICcmYW1wOycpLnJlcGxhY2UoLzwvZywgJyZsdDsnKS5yZXBsYWNlKC9cXD4vZywgJyZndDsnKS5yZXBsYWNlKC9cXFwiL2csICcmcXVvdDsnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5hdWdodHlIcmVmKG5hbWUsIGhyZWYpIHtcbiAgICAvLyBCcm93c2VycyBpZ25vcmUgY2hhcmFjdGVyIGNvZGVzIG9mIDMyIChzcGFjZSkgYW5kIGJlbG93IGluIGEgc3VycHJpc2luZ1xuICAgIC8vIG51bWJlciBvZiBzaXR1YXRpb25zLiBTdGFydCByZWFkaW5nIGhlcmU6XG4gICAgLy8gaHR0cHM6Ly93d3cub3dhc3Aub3JnL2luZGV4LnBocC9YU1NfRmlsdGVyX0V2YXNpb25fQ2hlYXRfU2hlZXQjRW1iZWRkZWRfdGFiXG4gICAgaHJlZiA9IGhyZWYucmVwbGFjZSgvW1xceDAwLVxceDIwXSsvZywgJycpO1xuICAgIC8vIENsb2JiZXIgYW55IGNvbW1lbnRzIGluIFVSTHMsIHdoaWNoIHRoZSBicm93c2VyIG1pZ2h0XG4gICAgLy8gaW50ZXJwcmV0IGluc2lkZSBhbiBYTUwgZGF0YSBpc2xhbmQsIGFsbG93aW5nXG4gICAgLy8gYSBqYXZhc2NyaXB0OiBVUkwgdG8gYmUgc251Y2sgdGhyb3VnaFxuICAgIGhyZWYgPSBocmVmLnJlcGxhY2UoLzxcXCFcXC1cXC0uKj9cXC1cXC1cXD4vZywgJycpO1xuICAgIC8vIENhc2UgaW5zZW5zaXRpdmUgc28gd2UgZG9uJ3QgZ2V0IGZha2VkIG91dCBieSBKQVZBU0NSSVBUICMxXG4gICAgdmFyIG1hdGNoZXMgPSBocmVmLm1hdGNoKC9eKFthLXpBLVpdKylcXDovKTtcbiAgICBpZiAoIW1hdGNoZXMpIHtcbiAgICAgIC8vIFByb3RvY29sLXJlbGF0aXZlIFVSTDogXCIvL3NvbWUuZXZpbC5jb20vbmFzdHlcIlxuICAgICAgaWYgKGhyZWYubWF0Y2goL15cXC9cXC8vKSkge1xuICAgICAgICByZXR1cm4gIW9wdGlvbnMuYWxsb3dQcm90b2NvbFJlbGF0aXZlO1xuICAgICAgfVxuXG4gICAgICAvLyBObyBzY2hlbWVcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIHNjaGVtZSA9IG1hdGNoZXNbMV0udG9Mb3dlckNhc2UoKTtcblxuICAgIGlmIChoYXMob3B0aW9ucy5hbGxvd2VkU2NoZW1lc0J5VGFnLCBuYW1lKSkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZ1tuYW1lXS5pbmRleE9mKHNjaGVtZSkgPT09IC0xO1xuICAgIH1cblxuICAgIHJldHVybiAhb3B0aW9ucy5hbGxvd2VkU2NoZW1lcyB8fCBvcHRpb25zLmFsbG93ZWRTY2hlbWVzLmluZGV4T2Yoc2NoZW1lKSA9PT0gLTE7XG4gIH1cblxuICBmdW5jdGlvbiBmaWx0ZXJDbGFzc2VzKGNsYXNzZXMsIGFsbG93ZWQpIHtcbiAgICBpZiAoIWFsbG93ZWQpIHtcbiAgICAgIC8vIFRoZSBjbGFzcyBhdHRyaWJ1dGUgaXMgYWxsb3dlZCB3aXRob3V0IGZpbHRlcmluZyBvbiB0aGlzIHRhZ1xuICAgICAgcmV0dXJuIGNsYXNzZXM7XG4gICAgfVxuICAgIGNsYXNzZXMgPSBjbGFzc2VzLnNwbGl0KC9cXHMrLyk7XG4gICAgcmV0dXJuIGNsYXNzZXMuZmlsdGVyKGZ1bmN0aW9uKGNsc3MpIHtcbiAgICAgIHJldHVybiBhbGxvd2VkLmluZGV4T2YoY2xzcykgIT09IC0xO1xuICAgIH0pLmpvaW4oJyAnKTtcbiAgfVxufVxuXG4vLyBEZWZhdWx0cyBhcmUgYWNjZXNzaWJsZSB0byB5b3Ugc28gdGhhdCB5b3UgY2FuIHVzZSB0aGVtIGFzIGEgc3RhcnRpbmcgcG9pbnRcbi8vIHByb2dyYW1tYXRpY2FsbHkgaWYgeW91IHdpc2hcblxudmFyIGh0bWxQYXJzZXJEZWZhdWx0cyA9IHtcbiAgZGVjb2RlRW50aXRpZXM6IHRydWVcbn07XG5zYW5pdGl6ZUh0bWwuZGVmYXVsdHMgPSB7XG4gIGFsbG93ZWRUYWdzOiBbICdoMycsICdoNCcsICdoNScsICdoNicsICdibG9ja3F1b3RlJywgJ3AnLCAnYScsICd1bCcsICdvbCcsXG4gICAgJ25sJywgJ2xpJywgJ2InLCAnaScsICdzdHJvbmcnLCAnZW0nLCAnc3RyaWtlJywgJ2NvZGUnLCAnaHInLCAnYnInLCAnZGl2JyxcbiAgICAndGFibGUnLCAndGhlYWQnLCAnY2FwdGlvbicsICd0Ym9keScsICd0cicsICd0aCcsICd0ZCcsICdwcmUnIF0sXG4gIGFsbG93ZWRBdHRyaWJ1dGVzOiB7XG4gICAgYTogWyAnaHJlZicsICduYW1lJywgJ3RhcmdldCcgXSxcbiAgICAvLyBXZSBkb24ndCBjdXJyZW50bHkgYWxsb3cgaW1nIGl0c2VsZiBieSBkZWZhdWx0LCBidXQgdGhpc1xuICAgIC8vIHdvdWxkIG1ha2Ugc2Vuc2UgaWYgd2UgZGlkXG4gICAgaW1nOiBbICdzcmMnIF1cbiAgfSxcbiAgLy8gTG90cyBvZiB0aGVzZSB3b24ndCBjb21lIHVwIGJ5IGRlZmF1bHQgYmVjYXVzZSB3ZSBkb24ndCBhbGxvdyB0aGVtXG4gIHNlbGZDbG9zaW5nOiBbICdpbWcnLCAnYnInLCAnaHInLCAnYXJlYScsICdiYXNlJywgJ2Jhc2Vmb250JywgJ2lucHV0JywgJ2xpbmsnLCAnbWV0YScgXSxcbiAgLy8gVVJMIHNjaGVtZXMgd2UgcGVybWl0XG4gIGFsbG93ZWRTY2hlbWVzOiBbICdodHRwJywgJ2h0dHBzJywgJ2Z0cCcsICdtYWlsdG8nIF0sXG4gIGFsbG93ZWRTY2hlbWVzQnlUYWc6IHt9LFxuICBhbGxvd1Byb3RvY29sUmVsYXRpdmU6IHRydWVcbn07XG5cbnNhbml0aXplSHRtbC5zaW1wbGVUcmFuc2Zvcm0gPSBmdW5jdGlvbihuZXdUYWdOYW1lLCBuZXdBdHRyaWJzLCBtZXJnZSkge1xuICBtZXJnZSA9IChtZXJnZSA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiBtZXJnZTtcbiAgbmV3QXR0cmlicyA9IG5ld0F0dHJpYnMgfHwge307XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHRhZ05hbWUsIGF0dHJpYnMpIHtcbiAgICB2YXIgYXR0cmliO1xuICAgIGlmIChtZXJnZSkge1xuICAgICAgZm9yIChhdHRyaWIgaW4gbmV3QXR0cmlicykge1xuICAgICAgICBhdHRyaWJzW2F0dHJpYl0gPSBuZXdBdHRyaWJzW2F0dHJpYl07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGF0dHJpYnMgPSBuZXdBdHRyaWJzO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0YWdOYW1lOiBuZXdUYWdOYW1lLFxuICAgICAgYXR0cmliczogYXR0cmlic1xuICAgIH07XG4gIH07XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Nhbml0aXplLWh0bWwvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDEwMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIoZnVuY3Rpb24gKGdsb2JhbCwgdW5kZWZpbmVkKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBpZiAoZ2xvYmFsLnNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5leHRIYW5kbGUgPSAxOyAvLyBTcGVjIHNheXMgZ3JlYXRlciB0aGFuIHplcm9cbiAgICB2YXIgdGFza3NCeUhhbmRsZSA9IHt9O1xuICAgIHZhciBjdXJyZW50bHlSdW5uaW5nQVRhc2sgPSBmYWxzZTtcbiAgICB2YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xuICAgIHZhciByZWdpc3RlckltbWVkaWF0ZTtcblxuICAgIGZ1bmN0aW9uIHNldEltbWVkaWF0ZShjYWxsYmFjaykge1xuICAgICAgLy8gQ2FsbGJhY2sgY2FuIGVpdGhlciBiZSBhIGZ1bmN0aW9uIG9yIGEgc3RyaW5nXG4gICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBuZXcgRnVuY3Rpb24oXCJcIiArIGNhbGxiYWNrKTtcbiAgICAgIH1cbiAgICAgIC8vIENvcHkgZnVuY3Rpb24gYXJndW1lbnRzXG4gICAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2kgKyAxXTtcbiAgICAgIH1cbiAgICAgIC8vIFN0b3JlIGFuZCByZWdpc3RlciB0aGUgdGFza1xuICAgICAgdmFyIHRhc2sgPSB7IGNhbGxiYWNrOiBjYWxsYmFjaywgYXJnczogYXJncyB9O1xuICAgICAgdGFza3NCeUhhbmRsZVtuZXh0SGFuZGxlXSA9IHRhc2s7XG4gICAgICByZWdpc3RlckltbWVkaWF0ZShuZXh0SGFuZGxlKTtcbiAgICAgIHJldHVybiBuZXh0SGFuZGxlKys7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2xlYXJJbW1lZGlhdGUoaGFuZGxlKSB7XG4gICAgICAgIGRlbGV0ZSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcnVuKHRhc2spIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gdGFzay5jYWxsYmFjaztcbiAgICAgICAgdmFyIGFyZ3MgPSB0YXNrLmFyZ3M7XG4gICAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcnVuSWZQcmVzZW50KGhhbmRsZSkge1xuICAgICAgICAvLyBGcm9tIHRoZSBzcGVjOiBcIldhaXQgdW50aWwgYW55IGludm9jYXRpb25zIG9mIHRoaXMgYWxnb3JpdGhtIHN0YXJ0ZWQgYmVmb3JlIHRoaXMgb25lIGhhdmUgY29tcGxldGVkLlwiXG4gICAgICAgIC8vIFNvIGlmIHdlJ3JlIGN1cnJlbnRseSBydW5uaW5nIGEgdGFzaywgd2UnbGwgbmVlZCB0byBkZWxheSB0aGlzIGludm9jYXRpb24uXG4gICAgICAgIGlmIChjdXJyZW50bHlSdW5uaW5nQVRhc2spIHtcbiAgICAgICAgICAgIC8vIERlbGF5IGJ5IGRvaW5nIGEgc2V0VGltZW91dC4gc2V0SW1tZWRpYXRlIHdhcyB0cmllZCBpbnN0ZWFkLCBidXQgaW4gRmlyZWZveCA3IGl0IGdlbmVyYXRlZCBhXG4gICAgICAgICAgICAvLyBcInRvbyBtdWNoIHJlY3Vyc2lvblwiIGVycm9yLlxuICAgICAgICAgICAgc2V0VGltZW91dChydW5JZlByZXNlbnQsIDAsIGhhbmRsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgdGFzayA9IHRhc2tzQnlIYW5kbGVbaGFuZGxlXTtcbiAgICAgICAgICAgIGlmICh0YXNrKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudGx5UnVubmluZ0FUYXNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBydW4odGFzayk7XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJJbW1lZGlhdGUoaGFuZGxlKTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudGx5UnVubmluZ0FUYXNrID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbE5leHRUaWNrSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uICgpIHsgcnVuSWZQcmVzZW50KGhhbmRsZSk7IH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhblVzZVBvc3RNZXNzYWdlKCkge1xuICAgICAgICAvLyBUaGUgdGVzdCBhZ2FpbnN0IGBpbXBvcnRTY3JpcHRzYCBwcmV2ZW50cyB0aGlzIGltcGxlbWVudGF0aW9uIGZyb20gYmVpbmcgaW5zdGFsbGVkIGluc2lkZSBhIHdlYiB3b3JrZXIsXG4gICAgICAgIC8vIHdoZXJlIGBnbG9iYWwucG9zdE1lc3NhZ2VgIG1lYW5zIHNvbWV0aGluZyBjb21wbGV0ZWx5IGRpZmZlcmVudCBhbmQgY2FuJ3QgYmUgdXNlZCBmb3IgdGhpcyBwdXJwb3NlLlxuICAgICAgICBpZiAoZ2xvYmFsLnBvc3RNZXNzYWdlICYmICFnbG9iYWwuaW1wb3J0U2NyaXB0cykge1xuICAgICAgICAgICAgdmFyIHBvc3RNZXNzYWdlSXNBc3luY2hyb25vdXMgPSB0cnVlO1xuICAgICAgICAgICAgdmFyIG9sZE9uTWVzc2FnZSA9IGdsb2JhbC5vbm1lc3NhZ2U7XG4gICAgICAgICAgICBnbG9iYWwub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyA9IGZhbHNlO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShcIlwiLCBcIipcIik7XG4gICAgICAgICAgICBnbG9iYWwub25tZXNzYWdlID0gb2xkT25NZXNzYWdlO1xuICAgICAgICAgICAgcmV0dXJuIHBvc3RNZXNzYWdlSXNBc3luY2hyb25vdXM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsUG9zdE1lc3NhZ2VJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgLy8gSW5zdGFsbHMgYW4gZXZlbnQgaGFuZGxlciBvbiBgZ2xvYmFsYCBmb3IgdGhlIGBtZXNzYWdlYCBldmVudDogc2VlXG4gICAgICAgIC8vICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vRE9NL3dpbmRvdy5wb3N0TWVzc2FnZVxuICAgICAgICAvLyAqIGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvbXVsdGlwYWdlL2NvbW1zLmh0bWwjY3Jvc3NEb2N1bWVudE1lc3NhZ2VzXG5cbiAgICAgICAgdmFyIG1lc3NhZ2VQcmVmaXggPSBcInNldEltbWVkaWF0ZSRcIiArIE1hdGgucmFuZG9tKCkgKyBcIiRcIjtcbiAgICAgICAgdmFyIG9uR2xvYmFsTWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc291cmNlID09PSBnbG9iYWwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgZXZlbnQuZGF0YSA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICAgICAgIGV2ZW50LmRhdGEuaW5kZXhPZihtZXNzYWdlUHJlZml4KSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudCgrZXZlbnQuZGF0YS5zbGljZShtZXNzYWdlUHJlZml4Lmxlbmd0aCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIG9uR2xvYmFsTWVzc2FnZSwgZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2xvYmFsLmF0dGFjaEV2ZW50KFwib25tZXNzYWdlXCIsIG9uR2xvYmFsTWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKG1lc3NhZ2VQcmVmaXggKyBoYW5kbGUsIFwiKlwiKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsTWVzc2FnZUNoYW5uZWxJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGV2ZW50LmRhdGE7XG4gICAgICAgICAgICBydW5JZlByZXNlbnQoaGFuZGxlKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZShoYW5kbGUpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxSZWFkeVN0YXRlQ2hhbmdlSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHZhciBodG1sID0gZG9jLmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBhIDxzY3JpcHQ+IGVsZW1lbnQ7IGl0cyByZWFkeXN0YXRlY2hhbmdlIGV2ZW50IHdpbGwgYmUgZmlyZWQgYXN5bmNocm9ub3VzbHkgb25jZSBpdCBpcyBpbnNlcnRlZFxuICAgICAgICAgICAgLy8gaW50byB0aGUgZG9jdW1lbnQuIERvIHNvLCB0aHVzIHF1ZXVpbmcgdXAgdGhlIHRhc2suIFJlbWVtYmVyIHRvIGNsZWFuIHVwIG9uY2UgaXQncyBiZWVuIGNhbGxlZC5cbiAgICAgICAgICAgIHZhciBzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKTtcbiAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcnVuSWZQcmVzZW50KGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgc2NyaXB0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgaHRtbC5yZW1vdmVDaGlsZChzY3JpcHQpO1xuICAgICAgICAgICAgICAgIHNjcmlwdCA9IG51bGw7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaHRtbC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KHJ1bklmUHJlc2VudCwgMCwgaGFuZGxlKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBJZiBzdXBwb3J0ZWQsIHdlIHNob3VsZCBhdHRhY2ggdG8gdGhlIHByb3RvdHlwZSBvZiBnbG9iYWwsIHNpbmNlIHRoYXQgaXMgd2hlcmUgc2V0VGltZW91dCBldCBhbC4gbGl2ZS5cbiAgICB2YXIgYXR0YWNoVG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGdsb2JhbCk7XG4gICAgYXR0YWNoVG8gPSBhdHRhY2hUbyAmJiBhdHRhY2hUby5zZXRUaW1lb3V0ID8gYXR0YWNoVG8gOiBnbG9iYWw7XG5cbiAgICAvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IGUuZy4gYnJvd3NlcmlmeSBlbnZpcm9ubWVudHMuXG4gICAgaWYgKHt9LnRvU3RyaW5nLmNhbGwoZ2xvYmFsLnByb2Nlc3MpID09PSBcIltvYmplY3QgcHJvY2Vzc11cIikge1xuICAgICAgICAvLyBGb3IgTm9kZS5qcyBiZWZvcmUgMC45XG4gICAgICAgIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGNhblVzZVBvc3RNZXNzYWdlKCkpIHtcbiAgICAgICAgLy8gRm9yIG5vbi1JRTEwIG1vZGVybiBicm93c2Vyc1xuICAgICAgICBpbnN0YWxsUG9zdE1lc3NhZ2VJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChnbG9iYWwuTWVzc2FnZUNoYW5uZWwpIHtcbiAgICAgICAgLy8gRm9yIHdlYiB3b3JrZXJzLCB3aGVyZSBzdXBwb3J0ZWRcbiAgICAgICAgaW5zdGFsbE1lc3NhZ2VDaGFubmVsSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoZG9jICYmIFwib25yZWFkeXN0YXRlY2hhbmdlXCIgaW4gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIikpIHtcbiAgICAgICAgLy8gRm9yIElFIDbigJM4XG4gICAgICAgIGluc3RhbGxSZWFkeVN0YXRlQ2hhbmdlSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZvciBvbGRlciBicm93c2Vyc1xuICAgICAgICBpbnN0YWxsU2V0VGltZW91dEltcGxlbWVudGF0aW9uKCk7XG4gICAgfVxuXG4gICAgYXR0YWNoVG8uc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlO1xuICAgIGF0dGFjaFRvLmNsZWFySW1tZWRpYXRlID0gY2xlYXJJbW1lZGlhdGU7XG59KHR5cGVvZiBzZWxmID09PSBcInVuZGVmaW5lZFwiID8gdHlwZW9mIGdsb2JhbCA9PT0gXCJ1bmRlZmluZWRcIiA/IHRoaXMgOiBnbG9iYWwgOiBzZWxmKSk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vc2V0aW1tZWRpYXRlL3NldEltbWVkaWF0ZS5qc1xuLy8gbW9kdWxlIGlkID0gMTAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcyEuL3N0eWxlLmNzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcyEuL3N0eWxlLmNzc1wiLCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBuZXdDb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanMhLi9zdHlsZS5jc3NcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nob2NvbGF0ZXktY2xpZW50L3N0eWxlcy9zdHlsZS5jc3Ncbi8vIG1vZHVsZSBpZCA9IDEwMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanMhLi9ib290c3RyYXAtdG91ci5jc3NcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4uLy4uLy4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanMhLi9ib290c3RyYXAtdG91ci5jc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzIS4vYm9vdHN0cmFwLXRvdXIuY3NzXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jbG91ZHNoYXJlLXRvdXIvYm9vdHN0cmFwLXRvdXIvYm9vdHN0cmFwLXRvdXIuY3NzXG4vLyBtb2R1bGUgaWQgPSAxMDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzIS4vRmxvd1RlbXBsYXRlLmNzc1wiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcyEuL0Zsb3dUZW1wbGF0ZS5jc3NcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzIS4vRmxvd1RlbXBsYXRlLmNzc1wiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9GbG93VGVtcGxhdGUuY3NzXG4vLyBtb2R1bGUgaWQgPSAxMDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzIS4vSW1hZ2VGbG93TW9kYWwuY3NzXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLi8uLi8uLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzIS4vSW1hZ2VGbG93TW9kYWwuY3NzXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcyEuL0ltYWdlRmxvd01vZGFsLmNzc1wiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2xvdWRzaGFyZS10b3VyL3RlbXBsYXRlcy9JbWFnZUZsb3dNb2RhbC5jc3Ncbi8vIG1vZHVsZSBpZCA9IDEwNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgYXBwbHkgPSBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHk7XG5cbi8vIERPTSBBUElzLCBmb3IgY29tcGxldGVuZXNzXG5cbmV4cG9ydHMuc2V0VGltZW91dCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRUaW1lb3V0LCB3aW5kb3csIGFyZ3VtZW50cyksIGNsZWFyVGltZW91dCk7XG59O1xuZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRJbnRlcnZhbCwgd2luZG93LCBhcmd1bWVudHMpLCBjbGVhckludGVydmFsKTtcbn07XG5leHBvcnRzLmNsZWFyVGltZW91dCA9XG5leHBvcnRzLmNsZWFySW50ZXJ2YWwgPSBmdW5jdGlvbih0aW1lb3V0KSB7XG4gIGlmICh0aW1lb3V0KSB7XG4gICAgdGltZW91dC5jbG9zZSgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBUaW1lb3V0KGlkLCBjbGVhckZuKSB7XG4gIHRoaXMuX2lkID0gaWQ7XG4gIHRoaXMuX2NsZWFyRm4gPSBjbGVhckZuO1xufVxuVGltZW91dC5wcm90b3R5cGUudW5yZWYgPSBUaW1lb3V0LnByb3RvdHlwZS5yZWYgPSBmdW5jdGlvbigpIHt9O1xuVGltZW91dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fY2xlYXJGbi5jYWxsKHdpbmRvdywgdGhpcy5faWQpO1xufTtcblxuLy8gRG9lcyBub3Qgc3RhcnQgdGhlIHRpbWUsIGp1c3Qgc2V0cyB1cCB0aGUgbWVtYmVycyBuZWVkZWQuXG5leHBvcnRzLmVucm9sbCA9IGZ1bmN0aW9uKGl0ZW0sIG1zZWNzKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSBtc2Vjcztcbn07XG5cbmV4cG9ydHMudW5lbnJvbGwgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSAtMTtcbn07XG5cbmV4cG9ydHMuX3VucmVmQWN0aXZlID0gZXhwb3J0cy5hY3RpdmUgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcblxuICB2YXIgbXNlY3MgPSBpdGVtLl9pZGxlVGltZW91dDtcbiAgaWYgKG1zZWNzID49IDApIHtcbiAgICBpdGVtLl9pZGxlVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiBvblRpbWVvdXQoKSB7XG4gICAgICBpZiAoaXRlbS5fb25UaW1lb3V0KVxuICAgICAgICBpdGVtLl9vblRpbWVvdXQoKTtcbiAgICB9LCBtc2Vjcyk7XG4gIH1cbn07XG5cbi8vIHNldGltbWVkaWF0ZSBhdHRhY2hlcyBpdHNlbGYgdG8gdGhlIGdsb2JhbCBvYmplY3RcbnJlcXVpcmUoXCJzZXRpbW1lZGlhdGVcIik7XG5leHBvcnRzLnNldEltbWVkaWF0ZSA9IHNldEltbWVkaWF0ZTtcbmV4cG9ydHMuY2xlYXJJbW1lZGlhdGUgPSBjbGVhckltbWVkaWF0ZTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi90aW1lcnMtYnJvd3NlcmlmeS9tYWluLmpzXG4vLyBtb2R1bGUgaWQgPSAxMDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVwcmVjYXRlO1xuXG4vKipcbiAqIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4gKiBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2Uubm9EZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudGhyb3dEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCB0aHJvdyBhbiBFcnJvciB3aGVuIGludm9rZWQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50cmFjZURlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIGludm9rZSBgY29uc29sZS50cmFjZSgpYCBpbnN0ZWFkIG9mIGBjb25zb2xlLmVycm9yKClgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGRlcHJlY2F0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyAtIHRoZSBzdHJpbmcgdG8gcHJpbnQgdG8gdGhlIGNvbnNvbGUgd2hlbiBgZm5gIGlzIGludm9rZWRcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYSBuZXcgXCJkZXByZWNhdGVkXCIgdmVyc2lvbiBvZiBgZm5gXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZSAoZm4sIG1zZykge1xuICBpZiAoY29uZmlnKCdub0RlcHJlY2F0aW9uJykpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChjb25maWcoJ3Rocm93RGVwcmVjYXRpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAoY29uZmlnKCd0cmFjZURlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBgbG9jYWxTdG9yYWdlYCBmb3IgYm9vbGVhbiB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBgbmFtZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY29uZmlnIChuYW1lKSB7XG4gIC8vIGFjY2Vzc2luZyBnbG9iYWwubG9jYWxTdG9yYWdlIGNhbiB0cmlnZ2VyIGEgRE9NRXhjZXB0aW9uIGluIHNhbmRib3hlZCBpZnJhbWVzXG4gIHRyeSB7XG4gICAgaWYgKCFnbG9iYWwubG9jYWxTdG9yYWdlKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2ggKF8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHZhbCA9IGdsb2JhbC5sb2NhbFN0b3JhZ2VbbmFtZV07XG4gIGlmIChudWxsID09IHZhbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gU3RyaW5nKHZhbCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3V0aWwtZGVwcmVjYXRlL2Jyb3dzZXIuanNcbi8vIG1vZHVsZSBpZCA9IDEwN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG1vZHVsZSkge1xyXG5cdGlmKCFtb2R1bGUud2VicGFja1BvbHlmaWxsKSB7XHJcblx0XHRtb2R1bGUuZGVwcmVjYXRlID0gZnVuY3Rpb24oKSB7fTtcclxuXHRcdG1vZHVsZS5wYXRocyA9IFtdO1xyXG5cdFx0Ly8gbW9kdWxlLnBhcmVudCA9IHVuZGVmaW5lZCBieSBkZWZhdWx0XHJcblx0XHRpZighbW9kdWxlLmNoaWxkcmVuKSBtb2R1bGUuY2hpbGRyZW4gPSBbXTtcclxuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2R1bGUsIFwibG9hZGVkXCIsIHtcclxuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcclxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRyZXR1cm4gbW9kdWxlLmw7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZSwgXCJpZFwiLCB7XHJcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXHJcblx0XHRcdGdldDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0cmV0dXJuIG1vZHVsZS5pO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHRcdG1vZHVsZS53ZWJwYWNrUG9seWZpbGwgPSAxO1xyXG5cdH1cclxuXHRyZXR1cm4gbW9kdWxlO1xyXG59O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAod2VicGFjaykvYnVpbGRpbi9tb2R1bGUuanNcbi8vIG1vZHVsZSBpZCA9IDEwOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IGV4dGVuZFxuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5mdW5jdGlvbiBleHRlbmQoKSB7XG4gICAgdmFyIHRhcmdldCA9IHt9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldXG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldFxufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3h0ZW5kL2ltbXV0YWJsZS5qc1xuLy8gbW9kdWxlIGlkID0gMTA5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImZ1bmN0aW9uIENob2NvbGF0ZXlQYWNrYWdlcyhjc3NkaywgY29uZmlnKSB7XHJcblx0dGhpcy5jc3NkayA9IGNzc2RrO1xyXG5cdHRoaXMuY29uZmlnID0gY29uZmlnO1xyXG59XHJcblxyXG5DaG9jb2xhdGV5UGFja2FnZXMucHJvdG90eXBlLnNlYXJjaCA9IGZ1bmN0aW9uKHF1ZXJ5LCBza2lwLCB0YWtlKSB7XHJcblx0cmV0dXJuIHBvc3QodGhpcywgXCJjaG9jb2xhdGV5U2VhcmNoXCIsIHtcclxuXHRcdHF1ZXJ5OiBxdWVyeSxcclxuXHRcdG9yZGVyQnk6IFwicmVsZXZhbmNlXCIsXHJcblx0XHRza2lwOiBza2lwLFxyXG5cdFx0dGFrZTogdGFrZVxyXG5cdH0pO1xyXG59XHJcblxyXG5DaG9jb2xhdGV5UGFja2FnZXMucHJvdG90eXBlLmdldE1vc3RQb3B1bGFyID0gZnVuY3Rpb24oc2tpcCwgdGFrZSkge1xyXG5cdHJldHVybiBnZXQodGhpcywgXCJjaG9jb2xhdGV5U2VhcmNoL2FjdGlvbnMvZ2V0TW9zdFBvcHVsYXJcIiwge1xyXG5cdFx0c2tpcDogc2tpcCxcclxuXHRcdHRha2U6IHRha2VcclxuXHR9KTtcclxufVxyXG5cclxuQ2hvY29sYXRleVBhY2thZ2VzLnByb3RvdHlwZS5nZXRBbGxWZXJzaW9ucyA9IGZ1bmN0aW9uKGlkTmFtZSwgc2tpcCwgdGFrZSkge1xyXG5cdHJldHVybiBnZXQodGhpcywgXCJjaG9jb2xhdGV5U2VhcmNoL2FjdGlvbnMvZ2V0QWxsVmVyc2lvbnNcIiwge1xyXG5cdFx0aWROYW1lOiBpZE5hbWUsXHJcblx0XHRza2lwOiBza2lwLFxyXG5cdFx0dGFrZTogdGFrZVxyXG5cdH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXQoc2VsZiwgcGF0aCwgcXVlcnlQYXJhbXMpIHtcclxuXHRyZXR1cm4gcmVxKHNlbGYsICdHRVQnLCBwYXRoLCBxdWVyeVBhcmFtcyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHBvc3Qoc2VsZiwgcGF0aCwgY29udGVudCkge1xyXG5cdHJldHVybiByZXEoc2VsZiwgJ1BPU1QnLCBwYXRoLCBudWxsLCBjb250ZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVxKHNlbGYsIG1ldGhvZCwgcGF0aCwgcXVlcnlQYXJhbXMsIGNvbnRlbnQpIHtcclxuXHRyZXR1cm4gc2VsZi5jc3Nkay5yZXEoe1xyXG5cdFx0aG9zdG5hbWU6IHNlbGYuY29uZmlnLmNsb3VkU2hhcmVIb3N0bmFtZSxcclxuXHRcdG1ldGhvZDogbWV0aG9kLFxyXG5cdFx0YXBpSWQ6IHNlbGYuY29uZmlnLmFwaUlkLFxyXG5cdFx0YXBpS2V5OiBzZWxmLmNvbmZpZy5hcGlLZXksXHJcblx0XHRwYXRoOiBwYXRoLFxyXG5cdFx0cXVlcnlQYXJhbXM6IHF1ZXJ5UGFyYW1zLFxyXG5cdFx0Y29udGVudDogY29udGVudFxyXG5cdH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IENob2NvbGF0ZXlQYWNrYWdlcztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9jaG9jb2xhdGV5LXBhY2thZ2VzLmpzXG4vLyBtb2R1bGUgaWQgPSAxMTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIG5nTW9kdWxlID0gcmVxdWlyZSgnLi4vbmctbW9kdWxlJyk7XHJcblxyXG5uZ01vZHVsZVxyXG4uZGlyZWN0aXZlKFwiY2hvY29sYXRleUJ1dHRvblwiLCBbXCJjaG9jb2xhdGV5Q2xpZW50Q29uZmlnXCIsIGZ1bmN0aW9uKGNob2NvbGF0ZXlDbGllbnRDb25maWcpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0c2NvcGU6IHtcclxuXHRcdFx0bmdDbGljazogXCImXCJcclxuXHRcdH0sXHJcblx0XHRyZXN0cmljdDogJ0UnLFxyXG5cdFx0dGVtcGxhdGU6IHJlcXVpcmUoJy4vY2hvY29sYXRleS1idXR0b24uaHRtbCcpLFxyXG5cdFx0bGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQpIHtcclxuXHRcdFx0ZWxlbWVudC5maW5kKCdidXR0b24nKVxyXG5cdFx0XHQuY3NzKCdiYWNrZ3JvdW5kLWltYWdlJywgJ3VybCgnICsgY2hvY29sYXRleUNsaWVudENvbmZpZy5jaG9jb2xhdGV5SWNvblNtYWxsSW1hZ2VQYXRoICsgJyknKTtcclxuXHRcdH1cclxuXHR9O1xyXG59XSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9jaG9jb2xhdGV5LWJ1dHRvbi5qc1xuLy8gbW9kdWxlIGlkID0gMTExXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBuZ01vZHVsZSA9IHJlcXVpcmUoJy4uL25nLW1vZHVsZScpO1xyXG5cclxubmdNb2R1bGVcclxuLmRpcmVjdGl2ZShcImNob2NvbGF0ZXlDbGllbnRcIiwgZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHtcclxuXHRcdHNjb3BlOiB7XHJcblx0XHRcdHNlbGVjdGVkUGFja2FnZXM6IFwiPW5nTW9kZWxcIlxyXG5cdFx0fSxcclxuXHRcdHJlc3RyaWN0OiAnRScsXHJcblx0XHR0ZW1wbGF0ZTogcmVxdWlyZSgnLi9jaG9jb2xhdGV5LWNsaWVudC5odG1sJyksXHJcblx0XHRjb250cm9sbGVyOiAnY2hvY29sYXRleUNsaWVudENvbnRyb2xsZXInXHJcblx0fTtcclxufSlcclxuLmNvbnRyb2xsZXIoJ2Nob2NvbGF0ZXlDbGllbnRDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHtcclxuXHQkc2NvcGUuc2VsZWN0UGFja2FnZSA9IGZ1bmN0aW9uKHBhY2thZ2UpIHtcclxuXHRcdGlmICghdHJ5VG9SZXBsYWNlRXhpc3RpbmdQYWNrYWdlKHBhY2thZ2UpKSBcclxuXHRcdFx0JHNjb3BlLnNlbGVjdGVkUGFja2FnZXMucHVzaChwYWNrYWdlKTtcclxuXHR9O1xyXG5cclxuXHQkc2NvcGUudW5zZWxlY3RQYWNrYWdlID0gZnVuY3Rpb24ocGFja2FnZSkge1xyXG5cdFx0JHNjb3BlLnNlbGVjdGVkUGFja2FnZXMgPSAkc2NvcGUuc2VsZWN0ZWRQYWNrYWdlcy5maWx0ZXIoZnVuY3Rpb24ocGtnKSB7XHJcblx0XHRcdHJldHVybiBwa2cuaWROYW1lICE9PSBwYWNrYWdlLmlkTmFtZSB8fFxyXG5cdFx0XHRcdCAgIHBrZy52ZXJzaW9uICE9PSBwYWNrYWdlLnZlcnNpb247XHJcblx0XHR9KTtcclxuXHR9O1xyXG5cclxuXHRmdW5jdGlvbiB0cnlUb1JlcGxhY2VFeGlzdGluZ1BhY2thZ2UocGFja2FnZSkge1xyXG5cdFx0dmFyIHJlcGxhY2VkID0gZmFsc2U7XHJcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8ICRzY29wZS5zZWxlY3RlZFBhY2thZ2VzLmxlbmd0aDsgKytpKSB7XHJcblx0XHRcdHZhciBwID0gJHNjb3BlLnNlbGVjdGVkUGFja2FnZXNbaV07XHJcblx0XHRcdGlmIChwLmlkTmFtZSA9PSBwYWNrYWdlLmlkTmFtZSkge1xyXG5cdFx0XHRcdCRzY29wZS5zZWxlY3RlZFBhY2thZ2VzW2ldID0gcGFja2FnZTtcclxuXHRcdFx0XHRyZXBsYWNlZCA9IHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiByZXBsYWNlZDtcclxuXHR9XHJcbn1dKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL2Nob2NvbGF0ZXktY2xpZW50LmpzXG4vLyBtb2R1bGUgaWQgPSAxMTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIG5nTW9kdWxlID0gcmVxdWlyZSgnLi4vbmctbW9kdWxlJyk7XHJcblxyXG5uZ01vZHVsZVxyXG4uZGlyZWN0aXZlKFwiZGV0YWlsc1BhbmVcIiwgZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHtcclxuXHRcdHNjb3BlOiB7XHJcblx0XHRcdGJhY2s6IFwiPVwiLFxyXG5cdFx0XHRwYWNrYWdlOiBcIj1cIixcclxuXHRcdFx0b25TZWxlY3RQYWNrYWdlOiBcIj1cIixcclxuXHRcdFx0b25VbnNlbGVjdFBhY2thZ2U6IFwiPVwiLFxyXG5cdFx0XHRzZWxlY3RlZFBhY2thZ2VzOiBcIj1cIlxyXG5cdFx0fSxcclxuXHRcdHJlc3RyaWN0OiAnRScsXHJcblx0XHR0ZW1wbGF0ZTogcmVxdWlyZSgnLi9kZXRhaWxzLXBhbmUuaHRtbCcpLFxyXG5cdFx0Y29udHJvbGxlcjogJ2RldGFpbHNQYW5lQ29udHJvbGxlcidcclxuXHR9O1xyXG59KVxyXG4uY29udHJvbGxlcignZGV0YWlsc1BhbmVDb250cm9sbGVyJywgWyckc2NvcGUnLCBmdW5jdGlvbigkc2NvcGUpIHtcclxuXHRcclxuXHQkc2NvcGUudW5zZWxlY3RBbmRHb0JhY2sgPSBmdW5jdGlvbigpIHtcclxuXHRcdCRzY29wZS5vblVuc2VsZWN0UGFja2FnZSgkc2NvcGUucGFja2FnZSk7XHJcblx0XHQkc2NvcGUuYmFjaygpO1xyXG5cdH07XHJcblxyXG5cdCRzY29wZS5pc1NlbGVjdGVkID0gZnVuY3Rpb24odmVyc2lvbikge1xyXG5cdFx0aWYgKCEkc2NvcGUuc2VsZWN0ZWRQYWNrYWdlcyB8fCAhJHNjb3BlLnBhY2thZ2UpXHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdGlmICghdmVyc2lvbilcclxuXHRcdFx0dmVyc2lvbiA9ICRzY29wZS5wYWNrYWdlLnZlcnNpb247XHJcblx0XHRyZXR1cm4gISRzY29wZS5zZWxlY3RlZFBhY2thZ2VzLmV2ZXJ5KGZ1bmN0aW9uKHApIHtcclxuXHRcdFx0cmV0dXJuIHAuaWROYW1lICE9PSAkc2NvcGUucGFja2FnZS5pZE5hbWUgfHxcclxuXHRcdFx0XHQgICBwLnZlcnNpb24gIT09IHZlcnNpb247XHJcblx0XHR9KTtcclxuXHR9O1xyXG59XSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9kZXRhaWxzLXBhbmUuanNcbi8vIG1vZHVsZSBpZCA9IDExM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgbmdNb2R1bGUgPSByZXF1aXJlKCcuLi9uZy1tb2R1bGUnKTtcclxudmFyIG1hcmtlZCA9IHJlcXVpcmUoJ21hcmtlZCcpO1xyXG5cclxubmdNb2R1bGVcclxuLmRpcmVjdGl2ZSgnbWFya2Rvd24nLCBmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0c2NvcGU6IHtcclxuXHRcdFx0Y29udGVudDogXCI9XCJcclxuXHRcdH0sXHJcblx0XHRyZXN0cmljdDogJ0UnLFxyXG5cdFx0bGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQpIHtcclxuXHRcdFx0c2NvcGUuJHdhdGNoKCdjb250ZW50JywgZnVuY3Rpb24obmV3VmFsdWUpIHtcclxuXHRcdFx0XHRpZiAobmV3VmFsdWUpXHJcblx0XHRcdFx0XHRzY29wZS5wYXJzZWRDb250ZW50ID0gbWFya2VkKG5ld1ZhbHVlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9LFxyXG5cdFx0dGVtcGxhdGU6IHJlcXVpcmUoJy4vbWFya2Rvd24uaHRtbCcpXHJcblx0fTtcclxufSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9tYXJrZG93bi5qc1xuLy8gbW9kdWxlIGlkID0gMTE0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBuZ01vZHVsZSA9IHJlcXVpcmUoJy4uL25nLW1vZHVsZScpO1xyXG5cclxubmdNb2R1bGVcclxuLmRpcmVjdGl2ZShcInBhY2thZ2VEZXRhaWxlZEl0ZW1cIiwgW1wiJHRpbWVvdXRcIiwgZnVuY3Rpb24oJHRpbWVvdXQpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0c2NvcGU6IHtcclxuXHRcdFx0cGFja2FnZTogXCI9XCIsXHJcblx0XHRcdG9uU2VsZWN0UGFja2FnZTogXCI9XCIsXHJcblx0XHRcdG9uVW5zZWxlY3RQYWNrYWdlOiBcIj1cIixcclxuXHRcdFx0c2VsZWN0ZWRQYWNrYWdlczogXCI9XCJcclxuXHRcdH0sXHJcblx0XHRyZXN0cmljdDogJ0UnLFxyXG5cdFx0bGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQpIHtcclxuXHRcdFx0dmFyIGVsID0gJChlbGVtZW50LmZpbmQoJy5wYWNrYWdlLWRldGFpbGVkLWl0ZW0nKSk7XHJcblx0XHRcdGVsLnNsaW1TY3JvbGwoe1xyXG5cdFx0XHRcdGhlaWdodDogJzQ3MHB4JyxcclxuXHRcdFx0XHRyYWlsRHJhZ2dhYmxlIDogdHJ1ZVxyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGVsLnNjcm9sbChmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRpZiAodGhpcy5zY3JvbGxUb3AgKyB0aGlzLm9mZnNldEhlaWdodCA9PSB0aGlzLnNjcm9sbEhlaWdodClcclxuXHRcdFx0XHRcdCR0aW1lb3V0KHNjb3BlLmZldGNoVmVyc2lvbnMsIDAsIHRydWUpO1xyXG5cdFx0XHRcdHZhciBzY3JvbGxUb3AgPSB0aGlzLnNjcm9sbFRvcDtcclxuXHRcdFx0XHQkdGltZW91dChmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRcdHNjb3BlLnNjcm9sbGVkID0gc2Nyb2xsVG9wID4gMDtcclxuXHRcdFx0XHR9LCAwLCB0cnVlKTtcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRzY29wZS4kd2F0Y2goJ3ZlcnNpb25zJywgZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0aWYgKGVsWzBdLnNjcm9sbFRvcCA9PSAwICYmIGVsWzBdLm9mZnNldEhlaWdodCA9PT0gZWxbMF0uc2Nyb2xsSGVpZ2h0KVxyXG5cdFx0XHRcdFx0JHRpbWVvdXQoc2NvcGUuZmV0Y2hWZXJzaW9ucywgMCwgdHJ1ZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSxcclxuXHRcdHRlbXBsYXRlOiByZXF1aXJlKCcuL3BhY2thZ2UtZGV0YWlsZWQtaXRlbS5odG1sJyksXHJcblx0XHRjb250cm9sbGVyOiBcInBhY2thZ2VEZXRhaWxlZEl0ZW1Db250cm9sbGVyXCJcclxuXHR9O1x0XHJcbn1dKVxyXG4uY29udHJvbGxlcihcInBhY2thZ2VEZXRhaWxlZEl0ZW1Db250cm9sbGVyXCIsIFtcIiRzY29wZVwiLCBcIiR0aW1lb3V0XCIsIFwiY2hvY29sYXRleVBhY2thZ2VzXCIsIGZ1bmN0aW9uKCRzY29wZSwgJHRpbWVvdXQsIGNob2NvbGF0ZXlQYWNrYWdlcykge1xyXG5cdCRzY29wZS5mZXRjaFZlcnNpb25zID0gZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoISRzY29wZS5wYWNrYWdlIHx8ICRzY29wZS5ub01vcmUgfHwgJHNjb3BlLnRpZClcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0JHNjb3BlLnNob3dWZXJzaW9uU3Bpbm5lciA9IHRydWU7XHJcblx0XHQkc2NvcGUudGlkID0gJHRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcblx0XHRcdGNob2NvbGF0ZXlQYWNrYWdlcy5nZXRBbGxWZXJzaW9ucygkc2NvcGUucGFja2FnZS5pZE5hbWUsICRzY29wZS5za2lwLCAkc2NvcGUudGFrZSlcclxuXHRcdFx0LnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuXHRcdFx0XHRpZiAocmVzcG9uc2UuY29udGVudC5sZW5ndGggPT09IDAgfHwgcmVzcG9uc2UuY29udGVudC5sZW5ndGggPCAkc2NvcGUudGFrZSlcclxuXHRcdFx0XHRcdCRzY29wZS5ub01vcmUgPSB0cnVlO1xyXG5cdFx0XHRcdCRzY29wZS52ZXJzaW9ucyA9ICRzY29wZS52ZXJzaW9ucy5jb25jYXQocmVzcG9uc2UuY29udGVudC5tYXAoZnVuY3Rpb24ocCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHAudmVyc2lvbjtcclxuXHRcdFx0XHR9KSk7XHJcblx0XHRcdFx0JHNjb3BlLnNob3dWZXJzaW9uU3Bpbm5lciA9IGZhbHNlO1xyXG5cdFx0XHRcdCRzY29wZS50aWQgPSBudWxsO1xyXG5cdFx0XHRcdCRzY29wZS5za2lwICs9ICRzY29wZS50YWtlO1xyXG5cdFx0XHRcdCRzY29wZS4kYXBwbHkoKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9LCAxMDAwKTtcclxuXHR9O1xyXG5cclxuXHQkc2NvcGUuc2VsZWN0VmVyc2lvbiA9IGZ1bmN0aW9uKHZlcnNpb24pIHtcclxuXHRcdGlmICghJHNjb3BlLm9uU2VsZWN0UGFja2FnZSB8fCAhJHNjb3BlLnBhY2thZ2UpXHJcblx0XHRcdHJldHVybjtcclxuXHRcdHZhciBuZXdQYWNrYWdlID0gY29weU9iamVjdCgkc2NvcGUucGFja2FnZSk7XHJcblx0XHRuZXdQYWNrYWdlLnZlcnNpb24gPSB2ZXJzaW9uO1xyXG5cdFx0JHNjb3BlLm9uU2VsZWN0UGFja2FnZShuZXdQYWNrYWdlKTtcclxuXHR9O1xyXG5cclxuXHQkc2NvcGUuaXNTZWxlY3RlZCA9IGZ1bmN0aW9uKHZlcnNpb24pIHtcclxuXHRcdGlmICghJHNjb3BlLnNlbGVjdGVkUGFja2FnZXMgfHwgISRzY29wZS5wYWNrYWdlKVxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRpZiAoIXZlcnNpb24pXHJcblx0XHRcdHZlcnNpb24gPSAkc2NvcGUucGFja2FnZS52ZXJzaW9uO1xyXG5cdFx0cmV0dXJuICEkc2NvcGUuc2VsZWN0ZWRQYWNrYWdlcy5ldmVyeShmdW5jdGlvbihwKSB7XHJcblx0XHRcdHJldHVybiBwLmlkTmFtZSAhPT0gJHNjb3BlLnBhY2thZ2UuaWROYW1lIHx8XHJcblx0XHRcdFx0ICAgcC52ZXJzaW9uICE9PSB2ZXJzaW9uO1xyXG5cdFx0fSk7XHJcblx0fTtcclxuXHJcblx0JHNjb3BlLiR3YXRjaCgncGFja2FnZScsIHJlc2V0KTtcclxuXHRyZXNldCgpO1xyXG5cclxuXHRmdW5jdGlvbiByZXNldCgpIHtcclxuXHRcdCRzY29wZS50YWtlID0gNTtcclxuXHRcdCRzY29wZS5za2lwID0gMDtcclxuXHRcdCRzY29wZS52ZXJzaW9ucyA9IFtdO1xyXG5cdFx0JHNjb3BlLm5vTW9yZSA9IGZhbHNlO1xyXG5cdFx0JHNjb3BlLnNob3dWZXJzaW9uU3Bpbm5lciA9IGZhbHNlO1xyXG5cdFx0JHNjb3BlLnRpZCA9IG51bGw7XHJcblx0XHQkc2NvcGUuZmV0Y2hWZXJzaW9ucygpO1xyXG5cdH1cclxuXHJcblx0ZnVuY3Rpb24gY29weU9iamVjdChvYmplY3QpIHtcclxuXHRcdHZhciByZXN1bHQgPSB7fTtcclxuXHRcdGZvciAodmFyIGsgaW4gb2JqZWN0KSB7XHJcblx0XHRcdGlmIChvYmplY3QuaGFzT3duUHJvcGVydHkoaykpXHJcblx0XHRcdFx0cmVzdWx0W2tdID0gb2JqZWN0W2tdO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcbn1dKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jaG9jb2xhdGV5LWNsaWVudC9kaXJlY3RpdmVzL3BhY2thZ2UtZGV0YWlsZWQtaXRlbS5qc1xuLy8gbW9kdWxlIGlkID0gMTE1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBuZ01vZHVsZSA9IHJlcXVpcmUoJy4uL25nLW1vZHVsZScpO1xyXG5cclxubmdNb2R1bGVcclxuLmRpcmVjdGl2ZShcInBhY2thZ2VJdGVtXCIsIGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiB7XHJcblx0XHRzY29wZToge1xyXG5cdFx0XHRwYWNrYWdlOiBcIj1cIixcclxuXHRcdFx0b25WaWV3RGV0YWlsczogXCI9XCIsXHJcblx0XHRcdG9uVmlld1ZlcnNpb25zOiBcIj1cIixcclxuXHRcdFx0b25TZWxlY3RQYWNrYWdlOiBcIj1cIixcclxuXHRcdFx0b25VbnNlbGVjdFBhY2thZ2U6IFwiPVwiLFxyXG5cdFx0XHRzZWxlY3RlZFBhY2thZ2VzOiBcIj1cIlxyXG5cdFx0fSxcclxuXHRcdHJlc3RyaWN0OiAnRScsXHJcblx0XHRsaW5rOiBmdW5jdGlvbihzY29wZSkge1xyXG5cdFx0XHR2YXIgZGVzY3JpcHRpb24gPSBzY29wZS5wYWNrYWdlLmRlc2NyaXB0aW9uO1xyXG5cdFx0XHRpZiAoZGVzY3JpcHRpb24gJiYgZGVzY3JpcHRpb24ubGVuZ3RoID4gMjUwKSB7XHJcblx0XHRcdFx0c2NvcGUuc2hvcnREZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLnN1YnN0cigwLCAyNTApICsgXCIuLi5cIjtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRzY29wZS5zaG9ydERlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblx0XHR0ZW1wbGF0ZTogcmVxdWlyZSgnLi9wYWNrYWdlLWl0ZW0uaHRtbCcpLFxyXG5cdFx0Y29udHJvbGxlcjogXCJwYWNrYWdlSXRlbUNvbnRyb2xsZXJcIlxyXG5cdH07XHRcclxufSlcclxuLmNvbnRyb2xsZXIoXCJwYWNrYWdlSXRlbUNvbnRyb2xsZXJcIiwgW1wiJHNjb3BlXCIsIGZ1bmN0aW9uKCRzY29wZSkge1xyXG5cdCRzY29wZS5pc1NlbGVjdGVkID0gZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoISRzY29wZS5zZWxlY3RlZFBhY2thZ2VzKVxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRyZXR1cm4gISRzY29wZS5zZWxlY3RlZFBhY2thZ2VzLmV2ZXJ5KGZ1bmN0aW9uKHApIHtcclxuXHRcdFx0cmV0dXJuIHAuaWROYW1lICE9PSAkc2NvcGUucGFja2FnZS5pZE5hbWUgfHxcclxuXHRcdFx0XHQgICBwLnZlcnNpb24gIT09ICRzY29wZS5wYWNrYWdlLnZlcnNpb247XHJcblx0XHR9KTtcclxuXHR9O1xyXG59XSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9wYWNrYWdlLWl0ZW0uanNcbi8vIG1vZHVsZSBpZCA9IDExNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgbmdNb2R1bGUgPSByZXF1aXJlKCcuLi9uZy1tb2R1bGUnKTtcclxuXHJcbm5nTW9kdWxlXHJcbi5kaXJlY3RpdmUoXCJwYWNrYWdlTGlzdFwiLCBbJyR0aW1lb3V0JywgZnVuY3Rpb24oJHRpbWVvdXQpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0c2NvcGU6IHtcclxuXHRcdFx0cGFja2FnZXM6IFwiPVwiLFxyXG5cdFx0XHRzaG93U3Bpbm5lcjogXCI9XCIsXHJcblx0XHRcdGVtcHR5UGhyYXNlOiBcIkBcIixcclxuXHRcdFx0b25WaWV3RGV0YWlsczogXCI9XCIsXHJcblx0XHRcdG9uVmlld1ZlcnNpb25zOiBcIj1cIixcclxuXHRcdFx0b25TZWxlY3RQYWNrYWdlOiBcIj1cIixcclxuXHRcdFx0b25VbnNlbGVjdFBhY2thZ2U6IFwiPVwiLFxyXG5cdFx0XHRvbk5lZWRNb3JlOiBcIj1cIixcclxuXHRcdFx0c2VsZWN0ZWRQYWNrYWdlczogXCI9XCJcclxuXHRcdH0sXHJcblx0XHRyZXN0cmljdDogJ0UnLFxyXG5cdFx0bGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQpIHtcclxuXHRcdFx0dmFyIGxpc3RFbGVtZW50ID0gJChlbGVtZW50KS5maW5kKCcucGFja2FnZS1saXN0Jyk7XHJcblx0XHRcdGxpc3RFbGVtZW50LmZpcnN0KCkuc2xpbVNjcm9sbCh7XHJcblx0XHRcdFx0aGVpZ2h0OiAnNTAwcHgnLFxyXG5cdFx0XHRcdHJhaWxEcmFnZ2FibGUgOiB0cnVlLFxyXG5cdFx0XHRcdGFsd2F5c1Zpc2libGU6IHRydWVcclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRsaXN0RWxlbWVudC5zY3JvbGwoZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0aWYgKHRoaXMuc2Nyb2xsVG9wICsgdGhpcy5vZmZzZXRIZWlnaHQgPT0gdGhpcy5zY3JvbGxIZWlnaHQgJiYgc2NvcGUub25OZWVkTW9yZSlcclxuXHRcdFx0XHRcdCR0aW1lb3V0KHNjb3BlLm9uTmVlZE1vcmUsIDAsIHRydWUpO1xyXG5cdFx0XHRcdHZhciBzY3JvbGxUb3AgPSB0aGlzLnNjcm9sbFRvcDtcclxuXHRcdFx0XHQkdGltZW91dChmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRcdHNjb3BlLnNjcm9sbGVkID0gc2Nyb2xsVG9wID4gMDtcclxuXHRcdFx0XHR9LCAwLCB0cnVlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9LFxyXG5cdFx0dGVtcGxhdGU6IHJlcXVpcmUoJy4vcGFja2FnZS1saXN0Lmh0bWwnKVxyXG5cdH07XHRcclxufV0pXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9wYWNrYWdlLWxpc3QuanNcbi8vIG1vZHVsZSBpZCA9IDExN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgbmdNb2R1bGUgPSByZXF1aXJlKCcuLi9uZy1tb2R1bGUnKTtcclxuXHJcbm5nTW9kdWxlXHJcbi5kaXJlY3RpdmUoXCJwYWNrYWdlc1BhbmVcIiwgZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHtcclxuXHRcdHNjb3BlOiB7XHJcblx0XHRcdHNob3dTZWFyY2g6IFwiPVwiLFxyXG5cdFx0XHRmaXJzdFZpZXc6IFwiQFwiLFxyXG5cdFx0XHR0aXRsZTogXCJAXCIsXHJcblx0XHRcdHNlbGVjdGVkUGFja2FnZXM6IFwiPVwiLFxyXG5cdFx0XHRvblNlbGVjdFBhY2thZ2U6IFwiPVwiLFxyXG5cdFx0XHRvblVuc2VsZWN0UGFja2FnZTogXCI9XCJcclxuXHRcdH0sXHJcblx0XHRyZXN0cmljdDogJ0UnLFxyXG5cdFx0dGVtcGxhdGU6IHJlcXVpcmUoXCIuL3BhY2thZ2VzLXBhbmUuaHRtbFwiKSxcclxuXHRcdGNvbnRyb2xsZXI6ICdwYWNrYWdlc1BhbmVDb250cm9sbGVyJ1xyXG5cdH07XHJcbn0pXHJcbi5jb250cm9sbGVyKFwicGFja2FnZXNQYW5lQ29udHJvbGxlclwiLCBbXCIkc2NvcGVcIiwgXCIkdGltZW91dFwiLCBcImNob2NvbGF0ZXlQYWNrYWdlc1wiLCBmdW5jdGlvbigkc2NvcGUsICR0aW1lb3V0LCBjaG9jb2xhdGV5UGFja2FnZXMpIHtcclxuXHQkc2NvcGUuYmFjayA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0aWYgKCRzY29wZS52aWV3QnJlYWRjcnVtYnMubGVuZ3RoID4gMSlcclxuXHRcdFx0JHNjb3BlLnZpZXdCcmVhZGNydW1icy5wb3AoKTtcclxuXHRcdCRzY29wZS5zZWxlY3RlZFZpZXcgPSAkc2NvcGUudmlld0JyZWFkY3J1bWJzWyRzY29wZS52aWV3QnJlYWRjcnVtYnMubGVuZ3RoIC0gMV07XHJcblx0fTtcclxuXHJcblx0JHNjb3BlLnZpZXdEZXRhaWxzID0gZnVuY3Rpb24ocGFja2FnZSkge1xyXG5cdFx0JHNjb3BlLnZpZXdQYWNrYWdlID0gcGFja2FnZTtcclxuXHRcdCRzY29wZS52aWV3QnJlYWRjcnVtYnMucHVzaCgnZGV0YWlscycpO1xyXG5cdFx0JHNjb3BlLnNlbGVjdGVkVmlldyA9ICdkZXRhaWxzJztcclxuXHR9O1xyXG5cclxuXHQkc2NvcGUuc2VhcmNoUGFja2FnZXMgPSBmdW5jdGlvbihxdWVyeSkge1xyXG5cdFx0aWYgKHF1ZXJ5KSB7XHJcblx0XHRcdCRzY29wZS5zZWxlY3RlZFZpZXcgPSAnc2VhcmNoJztcclxuXHRcdFx0JHNjb3BlLnZpZXdCcmVhZGNydW1icyA9IFsnc2VhcmNoJ107XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQkc2NvcGUuc2VsZWN0ZWRWaWV3ID0gJ3BvcHVsYXInO1xyXG5cdFx0XHQkc2NvcGUudmlld0JyZWFkY3J1bWJzID0gWydwb3B1bGFyJ107XHJcblx0XHRcdCRzY29wZS5nZXRNb3N0UG9wdWxhcigpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHQkc2NvcGUuc2tpcCA9IDA7XHJcblx0XHQkc2NvcGUudGFrZSA9IDU7XHJcblx0XHQkc2NvcGUucXVlcnkgPSBxdWVyeTtcclxuXHRcdCRzY29wZS5zaG93U3Bpbm5lciA9IHRydWU7XHJcblx0XHRjaG9jb2xhdGV5UGFja2FnZXMuc2VhcmNoKHF1ZXJ5LCAkc2NvcGUuc2tpcCwgJHNjb3BlLnRha2UpXHJcblx0XHQudGhlbihmdW5jdGlvbihyZXNwb25zZSkge1xyXG5cdFx0XHQkc2NvcGUuc2hvd1NwaW5uZXIgPSBmYWxzZTtcclxuXHRcdFx0JHNjb3BlLnBhY2thZ2VzID0gcmVzcG9uc2UuY29udGVudDtcclxuXHRcdFx0JHNjb3BlLiRhcHBseSgpO1xyXG5cdFx0fSk7XHJcblx0fTtcclxuXHJcblx0JHNjb3BlLmdldE1vc3RQb3B1bGFyID0gZnVuY3Rpb24oKSB7XHJcblx0XHQkc2NvcGUuc2tpcCA9IDA7XHJcblx0XHQkc2NvcGUudGFrZSA9IDU7XHJcblx0XHQkc2NvcGUucGFja2FnZXMgPSBudWxsO1xyXG5cdFx0JHNjb3BlLm5vTW9yZSA9IGZhbHNlO1xyXG5cdFx0JHNjb3BlLnNob3dTcGlubmVyID0gdHJ1ZTtcclxuXHRcdGNob2NvbGF0ZXlQYWNrYWdlcy5nZXRNb3N0UG9wdWxhcigkc2NvcGUuc2tpcCwgJHNjb3BlLnRha2UpXHJcblx0XHQudGhlbihmdW5jdGlvbihyZXNwb25zZSkge1xyXG5cdFx0XHQkc2NvcGUuc2hvd1NwaW5uZXIgPSBmYWxzZTtcclxuXHRcdFx0JHNjb3BlLnBhY2thZ2VzID0gcmVzcG9uc2UuY29udGVudDtcclxuXHRcdFx0JHNjb3BlLiRhcHBseSgpO1xyXG5cdFx0fSk7XHJcblx0fTtcclxuXHJcblx0JHNjb3BlLmZldGNoTW9yZVNlYXJjaCA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0aWYgKCRzY29wZS5xdWVyeSA9PSBudWxsIHx8ICRzY29wZS5ub01vcmUgfHwgJHNjb3BlLnRpZClcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0JHNjb3BlLnNraXAgKz0gJHNjb3BlLnRha2U7XHJcblx0XHQkc2NvcGUuc2hvd1NwaW5uZXIgPSB0cnVlO1xyXG5cdFx0JHNjb3BlLnRpZCA9ICR0aW1lb3V0KGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRjaG9jb2xhdGV5UGFja2FnZXMuc2VhcmNoKCRzY29wZS5xdWVyeSwgJHNjb3BlLnNraXAsICRzY29wZS50YWtlKVxyXG5cdFx0XHQudGhlbihmdW5jdGlvbihyZXNwb25zZSkge1xyXG5cdFx0XHRcdGlmIChyZXNwb25zZS5jb250ZW50Lmxlbmd0aCA9PSAwKVxyXG5cdFx0XHRcdFx0JHNjb3BlLm5vTW9yZSA9IHRydWU7XHJcblx0XHRcdFx0JHNjb3BlLnNob3dTcGlubmVyID0gZmFsc2U7XHJcblx0XHRcdFx0JHNjb3BlLnBhY2thZ2VzID0gJHNjb3BlLnBhY2thZ2VzLmNvbmNhdChyZXNwb25zZS5jb250ZW50KTtcclxuXHRcdFx0XHQkc2NvcGUudGlkID0gbnVsbDtcclxuXHRcdFx0XHQkc2NvcGUuJGFwcGx5KCk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSwgMTAwMCk7XHJcblx0fTtcclxuXHJcblx0JHNjb3BlLmZldGNoTW9yZVBvcHVsYXIgPSBmdW5jdGlvbigpIHtcclxuXHRcdGlmICgkc2NvcGUubm9Nb3JlIHx8ICRzY29wZS50aWQpXHJcblx0XHRcdHJldHVybjtcclxuXHRcdCRzY29wZS5za2lwICs9ICRzY29wZS50YWtlO1xyXG5cdFx0JHNjb3BlLnNob3dTcGlubmVyID0gdHJ1ZTtcclxuXHRcdCRzY29wZS50aWQgPSAkdGltZW91dChmdW5jdGlvbigpIHtcclxuXHRcdFx0Y2hvY29sYXRleVBhY2thZ2VzLmdldE1vc3RQb3B1bGFyKCRzY29wZS5za2lwLCAkc2NvcGUudGFrZSlcclxuXHRcdFx0LnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuXHRcdFx0XHQkc2NvcGUuc2hvd1NwaW5uZXIgPSBmYWxzZTtcclxuXHRcdFx0XHQkc2NvcGUucGFja2FnZXMgPSAkc2NvcGUucGFja2FnZXMuY29uY2F0KHJlc3BvbnNlLmNvbnRlbnQpO1xyXG5cdFx0XHRcdCRzY29wZS50aWQgPSBudWxsO1xyXG5cdFx0XHRcdCRzY29wZS4kYXBwbHkoKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9LCAxMDAwKTtcclxuXHR9O1xyXG5cdFxyXG5cdCRzY29wZS5za2lwID0gMDtcclxuXHQkc2NvcGUudGFrZSA9IDU7XHJcblx0JHNjb3BlLnBhY2thZ2VzID0gbnVsbDtcclxuXHQkc2NvcGUucXVlcnkgPSBudWxsO1xyXG5cdCRzY29wZS5zaG93U3Bpbm5lciA9IGZhbHNlO1xyXG5cdCRzY29wZS5ub01vcmUgPSBmYWxzZTtcclxuXHQkc2NvcGUudGlkID0gbnVsbDtcclxuXHRpZiAoISRzY29wZS5zZWxlY3RlZFBhY2thZ2VzKVxyXG5cdFx0JHNjb3BlLnNlbGVjdGVkUGFja2FnZXMgPSBbXTtcclxuXHQkc2NvcGUuc2VsZWN0ZWRWaWV3ID0gJHNjb3BlLmZpcnN0VmlldyB8fCAncG9wdWxhcic7XHJcblx0JHNjb3BlLnZpZXdCcmVhZGNydW1icyA9IFskc2NvcGUuc2VsZWN0ZWRWaWV3XTtcclxuXHQkc2NvcGUudmlld1BhY2thZ2UgPSBudWxsO1xyXG5cdCRzY29wZS5nZXRNb3N0UG9wdWxhcigpO1xyXG59XSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9wYWNrYWdlcy1wYW5lLmpzXG4vLyBtb2R1bGUgaWQgPSAxMThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIG5nTW9kdWxlID0gcmVxdWlyZSgnLi4vbmctbW9kdWxlJyk7XHJcblxyXG5uZ01vZHVsZVxyXG4uZGlyZWN0aXZlKFwic2VhcmNoSW5wdXRcIiwgWyckdGltZW91dCcsIGZ1bmN0aW9uKCR0aW1lb3V0KSB7XHJcblx0cmV0dXJuIHtcclxuXHRcdHNjb3BlOiB7XHJcblx0XHRcdG9uU2VhcmNoOiAnPSdcclxuXHRcdH0sXHJcblx0XHRyZXN0cmljdDogJ0UnLFxyXG5cdFx0bGluazogZnVuY3Rpb24oc2NvcGUsIGVsZW1lbnQpIHtcclxuXHRcdFx0dmFyIHRpZCA9IG51bGw7XHJcblx0XHRcdGVsZW1lbnQuZmluZChcImlucHV0W3R5cGU9dGV4dF1cIikub24oJ2tleXVwJywgZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0dmFyIGlucHV0RWxlbWVudCA9IHRoaXM7XHJcblx0XHRcdFx0aWYgKHRpZCAhPSBudWxsKSB7XHJcblx0XHRcdFx0XHQkdGltZW91dC5jYW5jZWwodGlkKTtcclxuXHRcdFx0XHRcdHRpZCA9IG51bGw7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHRpZCA9ICR0aW1lb3V0KGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0c2NvcGUub25TZWFyY2goaW5wdXRFbGVtZW50LnZhbHVlKTtcclxuXHRcdFx0XHR9LCA1MDApO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0sXHJcblx0XHR0ZW1wbGF0ZTogcmVxdWlyZSgnLi9zZWFyY2gtaW5wdXQuaHRtbCcpXHJcblx0fTtcdFxyXG59XSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9zZWFyY2gtaW5wdXQuanNcbi8vIG1vZHVsZSBpZCA9IDExOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgbmdNb2R1bGUgPSByZXF1aXJlKCcuLi9uZy1tb2R1bGUnKTtcclxudmFyICQgPSByZXF1aXJlKCdqUXVlcnknKTtcclxuXHJcbm5nTW9kdWxlXHJcbi5kaXJlY3RpdmUoXCJzcGlubmVyXCIsIFsnY2hvY29sYXRleUNsaWVudENvbmZpZycsIGZ1bmN0aW9uKGNob2NvbGF0ZXlDbGllbnRDb25maWcpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0c2NvcGU6IHt9LFxyXG5cdFx0cmVzdHJpY3Q6ICdFJyxcclxuXHRcdGxpbms6IGZ1bmN0aW9uKHNjb3BlLCBlbGVtZW50KSB7XHJcblx0XHRcdGVsZW1lbnQuZmluZCgnaW1nJykuYXR0cignc3JjJywgY2hvY29sYXRleUNsaWVudENvbmZpZy5wcmVsb2FkZXJJbWFnZVBhdGgpO1xyXG5cdFx0fSxcclxuXHRcdHRlbXBsYXRlOiByZXF1aXJlKCcuL3NwaW5uZXIuaHRtbCcpXHJcblx0fTtcdFxyXG59XSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2hvY29sYXRleS1jbGllbnQvZGlyZWN0aXZlcy9zcGlubmVyLmpzXG4vLyBtb2R1bGUgaWQgPSAxMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwicmVxdWlyZShcIi4vYm9vdHN0cmFwLXRvdXIuY3NzXCIpO1xyXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2Jvb3RzdHJhcC10b3VyXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nsb3Vkc2hhcmUtdG91ci9ib290c3RyYXAtdG91ci9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMTIxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBCb3R0bGUgPSByZXF1aXJlKCdib3R0bGVqcycpO1xyXG52YXIgYm90dGxlID0gbmV3IEJvdHRsZSgpO1xyXG5cclxuYm90dGxlLnZhbHVlKFwiWE1MSHR0cFJlcXVlc3RcIiwgWE1MSHR0cFJlcXVlc3QpO1xyXG5ib3R0bGUudmFsdWUoXCJUb3VyXCIsIHJlcXVpcmUoXCIuL2Jvb3RzdHJhcC10b3VyXCIpKTtcclxuYm90dGxlLnNlcnZpY2UoXCJUb3VyU2VydmljZVwiLCByZXF1aXJlKFwiLi9jcy10b3VyLXNlcnZpY2VcIiksIFwiWE1MSHR0cFJlcXVlc3RcIiwgXCJUb3VyXCIpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBib3R0bGU7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Nsb3Vkc2hhcmUtdG91ci9ib3R0bGUtbWFwcGluZy5qc1xuLy8gbW9kdWxlIGlkID0gMTIyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciAkID0gcmVxdWlyZShcImpRdWVyeVwiKTtcclxudmFyIFByb21pc2UgPSByZXF1aXJlKCdlczYtcHJvbWlzZScpLlByb21pc2U7XHJcbnZhciBUT1VSX0RFQlVHID0gZmFsc2U7XHJcbnJlcXVpcmUoXCIuL3RlbXBsYXRlcy9JbWFnZUZsb3dNb2RhbC5jc3NcIik7XHJcbnJlcXVpcmUoXCIuL3RlbXBsYXRlcy9GbG93VGVtcGxhdGUuY3NzXCIpO1xyXG5cclxuZnVuY3Rpb24gVG91clNlcnZpY2UoWE1MSHR0cFJlcXVlc3QsIFRvdXIpIHtcclxuICAgIHRoaXMuX1hNTEh0dHBSZXF1ZXN0ID0gWE1MSHR0cFJlcXVlc3Q7XHJcbiAgICB0aGlzLl9Ub3VyID0gVG91cjtcclxuXHJcbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5faW5pdFByb21pc2UgPSBudWxsO1xyXG4gICAgdGhpcy5fb25jZXMgPSB7fTtcclxuICAgIHRoaXMuX2Zsb3dzID0ge307XHJcbiAgICB0aGlzLl9pbWFnZUZsb3dzID0ge307XHJcblxyXG4gICAgdGhpcy5fZmxvd1RvdXJzID0ge307XHJcbiAgICB0aGlzLl9pbWFnZUZsb3dUb3VycyA9IHt9O1xyXG4gICAgdGhpcy5fb25jZVRvdXJzID0ge307XHJcblxyXG4gICAgdGhpcy5faW1hZ2VGbG93TW9kYWxFbGVtZW50cyA9IHt9O1xyXG5cclxuICAgIHRoaXMuX2V2ZW50TGlzdGVuZXJzID0ge1xyXG4gICAgICAgIHNob3c6IHt9LFxyXG4gICAgICAgIGhpZGU6IHt9LFxyXG4gICAgICAgIG5leHQ6IHt9LFxyXG4gICAgICAgIGVuZDogW11cclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5fY3VycmVudGx5U3RhcnRlZEZsb3dOYW1lcyA9IHt9O1xyXG4gICAgdGhpcy5fY3VycmVudGx5U3RhcnRlZE9uY2VOYW1lcyA9IHt9O1xyXG4gICAgdGhpcy5fZGljdGlvbmFyeSA9IHt9O1xyXG5cclxuICAgIHRoaXMuX2hpZGVBbGxGbG93c09uSGFzaENoYW5nZSgpO1xyXG4gICAgdGhpcy5fb3BlbkltYWdlRmxvd0FuY2hvckNsaWNrcygpO1xyXG59XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcclxuICAgICAgICAgICAgcmVzb2x2ZSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9pbml0UHJvbWlzZSlcclxuICAgICAgICByZXR1cm4gdGhpcy5faW5pdFByb21pc2U7XHJcblxyXG4gICAgdGhpcy5faW5pdFByb21pc2UgPSB0aGlzLl9nZXRUb3VyRGIoKVxyXG4gICAgICAgIC50aGVuKChmdW5jdGlvbih0b3VyRGIpIHtcclxuICAgICAgICAgICAgdGhpcy5fb25jZXMgPSB0aGlzLl9nZXRPbmNlc0Zyb21Ub3VyRGIodG91ckRiKTtcclxuICAgICAgICAgICAgdGhpcy5fZmxvd3MgPSB0aGlzLl9nZXRGbG93c0Zyb21Ub3VyRGIodG91ckRiKTtcclxuICAgICAgICAgICAgdGhpcy5faW1hZ2VGbG93cyA9IHRvdXJEYi5pbWFnZUZsb3dzO1xyXG4gICAgICAgICAgICB0aGlzLl9mbG93VG91cnMgPSB0aGlzLl9jcmVhdGVGbG93VG91cnModGhpcy5fZmxvd3MpO1xyXG4gICAgICAgICAgICB0aGlzLl9pbWFnZUZsb3dUb3VycyA9IHRoaXMuX2NyZWF0ZUltYWdlRmxvd1RvdXJzKHRoaXMuX2ltYWdlRmxvd3MpO1xyXG4gICAgICAgICAgICB0aGlzLl9vbmNlVG91cnMgPSB0aGlzLl9jcmVhdGVPbmNlVG91cnModGhpcy5fb25jZXMpO1xyXG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuX2luaXRQcm9taXNlID0gbnVsbDtcclxuICAgICAgICB9KS5iaW5kKHRoaXMpKVxyXG4gICAgICAgIFtcImNhdGNoXCJdKGZ1bmN0aW9uKGVycm9yKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5faW5pdFByb21pc2U7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUucmVwb3J0UHJvY2VlZEV2ZW50ID0gZnVuY3Rpb24obmFtZSkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHRoaXMuaW5pdCgpXHJcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKF90aGlzLl9mbG93cykuZm9yRWFjaChmdW5jdGlvbihmbG93TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGZsb3cgPSBfdGhpcy5fZmxvd3NbZmxvd05hbWVdO1xyXG4gICAgICAgICAgICAgICAgZmxvdy5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dTdGVwLCBzdGVwSW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmxvd1N0ZXAucHJvY2VlZE9uID09PSBuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmbG93VG91ciA9IF90aGlzLl9mbG93VG91cnNbZmxvd05hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZsb3dUb3VyLmlzSW5pdGlhbGl6ZWQoKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb3dUb3VyLmluaXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZsb3dUb3VyLmdldEN1cnJlbnRTdGVwKCkgPT09IHN0ZXBJbmRleClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb3dUb3VyLm5leHQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuc3RhcnRGbG93ID0gZnVuY3Rpb24oZmxvd05hbWUpIHtcclxuICAgIHJldHVybiB0aGlzLl9nZXRUb3VyRmxvdyhmbG93TmFtZSlcclxuICAgICAgICAudGhlbigoZnVuY3Rpb24odG91cikge1xyXG4gICAgICAgICAgICBpZiAoIXRvdXIgfHwgdGhpcy5faGFzU3RhcnRlZEZsb3dzKGZsb3dOYW1lKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIHRvdXIuaW5pdCgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRvdXIuZW5kZWQoKSlcclxuICAgICAgICAgICAgICAgIHRvdXIucmVzdGFydCgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fY3VycmVudGx5U3RhcnRlZEZsb3dOYW1lc1tmbG93TmFtZV0gPSB0cnVlO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5yZXN0YXJ0RmxvdyA9IGZ1bmN0aW9uKGZsb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fZ2V0VG91ckZsb3coZmxvd05hbWUpXHJcbiAgICAgICAgLnRoZW4oKGZ1bmN0aW9uKHRvdXIpIHtcclxuICAgICAgICAgICAgaWYgKCF0b3VyIHx8IHRoaXMuX2hhc1N0YXJ0ZWRGbG93cyhmbG93TmFtZSkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICB0b3VyLnJlc3RhcnQoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRseVN0YXJ0ZWRGbG93TmFtZXNbZmxvd05hbWVdID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuZ2V0Q3VycmVudFN0ZXAgPSBmdW5jdGlvbihmbG93TmFtZSkge1xyXG4gICAgdmFyIHRvdXIgPSB0aGlzLl9mbG93VG91cnNbZmxvd05hbWVdO1xyXG4gICAgaWYgKCF0b3VyKSB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkNvdWxkbid0IGZpbmQgZmxvdyBcIiArIGZsb3dOYW1lKTtcclxuICAgICAgICByZXR1cm4gLTE7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG91ci5nZXRDdXJyZW50U3RlcCgpIHx8IDA7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuc2hvd09uY2UgPSBmdW5jdGlvbih0YWdOYW1lKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG5cclxuICAgIHJldHVybiB0aGlzLmluaXQoKVxyXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuX2hhc1N0YXJ0ZWRGbG93cygpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgdmFyIG9uY2UgPSBfdGhpcy5fb25jZVRvdXJzW3RhZ05hbWVdO1xyXG4gICAgICAgICAgICBpZiAoIW9uY2UpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJDb3VsZG4ndCBmaW5kIG9uY2UgZm9yIHRhZyBuYW1lIFwiICsgdGFnTmFtZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFvbmNlLmlzSW5pdGlhbGl6ZWQoKSlcclxuICAgICAgICAgICAgICAgIG9uY2UuaW5pdCgpO1xyXG4gICAgICAgICAgICBvbmNlLnN0YXJ0KCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9KTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTdGFydHMgYWxsIGZsb3dzIHRoYXQgYXJlIHRyaWdnZXJlZCB3aXRoIHRhZ05hbWUuXHJcbiAqXHJcbiAqIFRoaXMgYWxsb3dzIHRvICd3YWtlJyB0aGUgdG91ciB1cCB1cG9uIHJlZnJlc2ggd2hlbiB0aGUgdGFnJ3NcclxuICogZWxlbWVudCBpcyByZWFkeS5cclxuICpcclxuICogSWYgdGhlIGZsb3cgaXMgc3RvcHBlZCBvbiBhbm90aGVyIHRhZyBhbmQgc3RlcCB0aGUgdG91ciBpc24ndCBzdGFydGVkXHJcbiAqXHJcbiAqIEBwYXJhbSB0YWdOYW1lXHJcbiAqL1xyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuc3RhcnRGbG93c09uVGFnTmFtZSA9IGZ1bmN0aW9uKHRhZ05hbWUpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaW5pdCgpXHJcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5faGFzU3RhcnRlZEZsb3dzKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKF90aGlzLl9mbG93cykuZm9yRWFjaChmdW5jdGlvbihmbG93TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGZsb3cgPSBfdGhpcy5fZmxvd3NbZmxvd05hbWVdO1xyXG4gICAgICAgICAgICAgICAgZmxvdy5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dTdGVwLCBzdGVwSW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmxvd1N0ZXAudGFnTmFtZSA9PT0gdGFnTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmxvd1RvdXIgPSBfdGhpcy5fZmxvd1RvdXJzW2Zsb3dOYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCghZmxvd1N0ZXAuZGlzYWJsZUF1dG9Db250aW51ZSAmJiAhZmxvd1RvdXIuZW5kZWQoKSAmJiBzdGVwSW5kZXggPT09IGZsb3dUb3VyLmdldEN1cnJlbnRTdGVwKCkpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZmxvd1N0ZXAuYXV0b1N0YXJ0ICYmIGZsb3dUb3VyLmdldEN1cnJlbnRTdGVwKCkgPT09IG51bGwpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZsb3dUb3VyLmlzSW5pdGlhbGl6ZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb3dUb3VyLmluaXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmxvd1RvdXIuZ2V0Q3VycmVudFN0ZXAoKSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb3dUb3VyLnN0YXJ0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG93VG91ci5zaG93U3RlcChmbG93VG91ci5nZXRDdXJyZW50U3RlcCgpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLl9jdXJyZW50bHlTdGFydGVkRmxvd05hbWVzW2Zsb3dOYW1lXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH0pO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFNob3dzIGFsbCBvbmNlcyB0aGF0IGFyZSB0cmlnZ2VyZWQgd2l0aCB0YWdOYW1lLlxyXG4gKlxyXG4gKiBUaGlzIGFsbG93cyB0byAnd2FrZScgdGhlIHRvdXIgdXAgdXBvbiByZWZyZXNoIHdoZW4gdGhlIHRhZydzXHJcbiAqIGVsZW1lbnQgaXMgcmVhZHkuXHJcbiAqXHJcbiAqIEBwYXJhbSB0YWdOYW1lXHJcbiAqL1xyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuc2hvd09uY2VzT25UYWdOYW1lID0gZnVuY3Rpb24odGFnTmFtZSkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICByZXR1cm4gdGhpcy5pbml0KClcclxuICAgICAgICAudGhlbihmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgaWYgKF90aGlzLl9oYXNTdGFydGVkRmxvd3MoKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKF90aGlzLl9vbmNlcykuZm9yRWFjaChmdW5jdGlvbihvbmNlVGFnTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRhZ05hbWUgPT09IG9uY2VUYWdOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9uY2VUb3VyID0gX3RoaXMuX29uY2VUb3Vyc1tvbmNlVGFnTmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvbmNlVG91ci5pc0luaXRpYWxpemVkKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uY2VUb3VyLmluaXQoKTtcclxuICAgICAgICAgICAgICAgICAgICBvbmNlVG91ci5zaG93U3RlcCgwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9KTtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnROYW1lLCBmbG93TmFtZSwgc3RlcEluZGV4LCBjYWxsYmFjaykge1xyXG4gICAgaWYgKGV2ZW50TmFtZSA9PT0gXCJlbmRcIikge1xyXG4gICAgICAgIHRoaXMuX2V2ZW50TGlzdGVuZXJzLmVuZC5wdXNoKGFyZ3VtZW50c1sxXSB8fCBmdW5jdGlvbigpe30pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgZmxvd0xpc3RlbmVycyA9IHRoaXMuX2V2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gPSB0aGlzLl9ldmVudExpc3RlbmVyc1tldmVudE5hbWVdIHx8IHt9O1xyXG4gICAgICAgIHZhciBzdGVwTGlzdGVuZXJzID0gZmxvd0xpc3RlbmVyc1tmbG93TmFtZV0gPSBmbG93TGlzdGVuZXJzW2Zsb3dOYW1lXSB8fCB7fTtcclxuICAgICAgICBzdGVwTGlzdGVuZXJzW3N0ZXBJbmRleF0gPSBjYWxsYmFjaztcclxuICAgIH1cclxuXHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuYWRkVG9EaWN0aW9uYXJ5ID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIGlmICh0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgdGhpcy5fZGljdGlvbmFyeVtrZXldID0gdmFsdWU7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBrZXkgPT09IFwib2JqZWN0XCIpIHtcclxuICAgICAgICB2YXIgZGljdGlvbmFyeSA9IGtleTtcclxuICAgICAgICBPYmplY3Qua2V5cyhkaWN0aW9uYXJ5KS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xyXG4gICAgICAgICAgICBfdGhpcy5fZGljdGlvbmFyeVtrZXldID0gZGljdGlvbmFyeVtrZXldO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLmVuZEZsb3cgPSBmdW5jdGlvbihmbG93TmFtZSkge1xyXG4gICAgdmFyIHRvdXIgPSB0aGlzLl9mbG93VG91cnNbZmxvd05hbWVdO1xyXG4gICAgaWYgKHRvdXIpXHJcbiAgICAgICAgdG91ci5lbmQoKTtcclxuICAgIHRoaXMuX2N1cnJlbnRseVN0YXJ0ZWRGbG93TmFtZXNbZmxvd05hbWVdID0gZmFsc2U7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuaGlkZUFsbEZsb3dzID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgdGhpc18gPSB0aGlzO1xyXG5cclxuICAgIE9iamVjdC5rZXlzKHRoaXNfLl9jdXJyZW50bHlTdGFydGVkRmxvd05hbWVzKS5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dOYW1lKSB7XHJcbiAgICAgICAgdmFyIHRvdXIgPSB0aGlzXy5fZmxvd1RvdXJzW2Zsb3dOYW1lXTtcclxuICAgICAgICB0b3VyLmhpZGVTdGVwKHRvdXIuZ2V0Q3VycmVudFN0ZXAoKSk7XHJcbiAgICAgICAgdGhpc18uX2N1cnJlbnRseVN0YXJ0ZWRGbG93TmFtZXNbZmxvd05hbWVdID0gZmFsc2U7XHJcbiAgICB9KTtcclxuXHJcbiAgICBPYmplY3Qua2V5cyh0aGlzXy5fb25jZVRvdXJzKS5mb3JFYWNoKGZ1bmN0aW9uKG9uY2VOYW1lKSB7XHJcbiAgICAgICAgdmFyIHRvdXIgPSB0aGlzXy5fb25jZVRvdXJzW29uY2VOYW1lXTtcclxuICAgICAgICB0b3VyLmhpZGVTdGVwKHRvdXIuZ2V0Q3VycmVudFN0ZXAoKSk7XHJcbiAgICB9KTtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5faGlkZUFsbE9uY2VzID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgT2JqZWN0LmtleXModGhpcy5fY3VycmVudGx5U3RhcnRlZE9uY2VOYW1lcykuZm9yRWFjaChmdW5jdGlvbihvbmNlVGFnTmFtZSkge1xyXG4gICAgICAgIGlmICghX3RoaXMuX2N1cnJlbnRseVN0YXJ0ZWRPbmNlTmFtZXNbb25jZVRhZ05hbWVdKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdmFyIHRvdXIgPSBfdGhpcy5fb25jZVRvdXJzW29uY2VUYWdOYW1lXTtcclxuICAgICAgICBpZiAoIXRvdXIpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB0b3VyLmhpZGVTdGVwKDApO1xyXG4gICAgfSk7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuc3RhcnRJbWFnZUZsb3cgPSBmdW5jdGlvbihmbG93TmFtZSkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICByZXR1cm4gdGhpcy5pbml0KClcclxuICAgICAgICAudGhlbihmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgX3RoaXMuX2FkZEltYWdlRmxvd01vZGFsKGZsb3dOYW1lKTtcclxuICAgICAgICB9KVxyXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICB2YXIgdG91ciA9IF90aGlzLl9pbWFnZUZsb3dUb3Vyc1tmbG93TmFtZV07XHJcbiAgICAgICAgICAgIGlmICghdG91cilcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGlmICghdG91ci5pc0luaXRpYWxpemVkKCkpXHJcbiAgICAgICAgICAgICAgICB0b3VyLmluaXQoKTtcclxuICAgICAgICAgICAgaWYgKHRvdXIuZ2V0Q3VycmVudFN0ZXAoKSA9PT0gbnVsbClcclxuICAgICAgICAgICAgICAgIHRvdXIuc3RhcnQoKTtcclxuICAgICAgICAgICAgaWYgKHRvdXIuZW5kZWQoKSlcclxuICAgICAgICAgICAgICAgIHRvdXIucmVzdGFydCgpO1xyXG5cclxuICAgICAgICAgICAgX3RoaXMuX2N1cnJlbnRseVN0YXJ0ZWRGbG93TmFtZXNbZmxvd05hbWVdID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSk7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX2NyZWF0ZUltYWdlRmxvd01vZGFsRWxlbWVudCA9IGZ1bmN0aW9uKGZsb3dOYW1lKSB7XHJcbiAgICB2YXIgaW1hZ2VGbG93ID0gdGhpcy5faW1hZ2VGbG93c1tmbG93TmFtZV07XHJcbiAgICB2YXIgbW9kYWwgPSAkKHJlcXVpcmUoXCIuL3RlbXBsYXRlcy9JbWFnZUZsb3dNb2RhbC5odG1sXCIpKTtcclxuXHJcbiAgICBtb2RhbC5maW5kKFwiLmZsb3ctbW9kYWwtaGVhZGVyXCIpLnRleHQoaW1hZ2VGbG93LnRpdGxlKTtcclxuICAgIHZhciBpbWFnZSA9IG5ldyBJbWFnZSgpO1xyXG4gICAgaW1hZ2Uuc3JjID0gaW1hZ2VGbG93LmltYWdlVXJsO1xyXG4gICAgdmFyIGltYWdlQ29udGFpbmVyRWxlbWVudCA9IG1vZGFsLmZpbmQoXCIuZmxvdy1tb2RhbC1pbWFnZS1jb250YWluZXJcIik7XHJcbiAgICBpbWFnZUNvbnRhaW5lckVsZW1lbnQuYXBwZW5kKGltYWdlKTtcclxuXHJcbiAgICBpbWFnZUZsb3cuc3RlcHMuZm9yRWFjaChmdW5jdGlvbihzdGVwKSB7XHJcbiAgICAgICAgaWYgKCFzdGVwLnBvc2l0aW9uKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdmFyIHNwb3RFbGVtZW50ID0gJCgnPGRpdiBpbWFnZS1mbG93LXNwb3Q9XCInK3N0ZXAucG9zaXRpb25bMF0rJy0nK3N0ZXAucG9zaXRpb25bMV0rJ1wiLz4nKTtcclxuICAgICAgICBzcG90RWxlbWVudC5jc3MoXCJsZWZ0XCIsIChzdGVwLnBvc2l0aW9uWzBdICogMTAwKSArIFwiJVwiKTtcclxuICAgICAgICBzcG90RWxlbWVudC5jc3MoXCJ0b3BcIiwgKHN0ZXAucG9zaXRpb25bMV0gKiAxMDApICsgXCIlXCIpO1xyXG4gICAgICAgIGltYWdlQ29udGFpbmVyRWxlbWVudC5hcHBlbmQoc3BvdEVsZW1lbnQpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gbW9kYWw7XHJcbn07XHJcblxyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50TmFtZSwgZmxvd05hbWUsIHN0ZXBJbmRleCkge1xyXG4gICAgaWYgKGV2ZW50TmFtZSA9PT0gXCJlbmRcIikge1xyXG4gICAgICAgIHZhciBsYXN0U3RlcCA9IHRoaXMuX2Zsb3dzW2Zsb3dOYW1lXS5sZW5ndGggLSAxID09PSBzdGVwSW5kZXg7XHJcbiAgICAgICAgdGhpcy5fZXZlbnRMaXN0ZW5lcnMuZW5kLmZvckVhY2goZnVuY3Rpb24oZil7ZihmbG93TmFtZSwgbGFzdFN0ZXApO30pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2V2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gfHxcclxuICAgICAgICAgICAgIXRoaXMuX2V2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV1bZmxvd05hbWVdIHx8XHJcbiAgICAgICAgICAgICF0aGlzLl9ldmVudExpc3RlbmVyc1tldmVudE5hbWVdW2Zsb3dOYW1lXVtzdGVwSW5kZXhdKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXVtmbG93TmFtZV1bc3RlcEluZGV4XSgpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9oYXNTdGFydGVkRmxvd3MgPSBmdW5jdGlvbihleGNlcHRGbG93TmFtZSkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9jdXJyZW50bHlTdGFydGVkRmxvd05hbWVzKS5maWx0ZXIoZnVuY3Rpb24oZmxvd05hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZsb3dOYW1lICE9PSBleGNlcHRGbG93TmFtZSAmJiBfdGhpcy5fY3VycmVudGx5U3RhcnRlZEZsb3dOYW1lc1tmbG93TmFtZV07XHJcbiAgICAgICAgfSkubGVuZ3RoID4gMDtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5faGlkZUFsbEZsb3dzT25IYXNoQ2hhbmdlID0gZnVuY3Rpb24oKSB7XHJcbiAgICB2YXIgdGhpc18gPSB0aGlzO1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJoYXNoY2hhbmdlXCIsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHRoaXNfLmhpZGVBbGxGbG93cygpO1xyXG4gICAgfSk7XHJcbn07XHJcblxyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9nZXRUb3VyRmxvdyA9IGZ1bmN0aW9uKGZsb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gdGhpcy5pbml0KClcclxuICAgICAgICAudGhlbigoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciB0b3VyID0gdGhpcy5fZmxvd1RvdXJzW2Zsb3dOYW1lXTtcclxuICAgICAgICAgICAgaWYgKCF0b3VyKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiQ291bGRuJ3QgZmluZCBmbG93IFwiICsgZmxvd05hbWUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRvdXI7XHJcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX2dldEZsb3dzRnJvbVRvdXJEYiA9IGZ1bmN0aW9uKHRvdXJEYikge1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG5cclxuICAgIE9iamVjdC5rZXlzKHRvdXJEYi5mbG93cykuZm9yRWFjaChmdW5jdGlvbihmbG93TmFtZSkge1xyXG4gICAgICAgIHZhciBmbG93ID0gdG91ckRiLmZsb3dzW2Zsb3dOYW1lXTtcclxuICAgICAgICBpZiAoIWZsb3cuZW5hYmxlZClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIGZsb3cuc3RlcHMuZm9yRWFjaChmdW5jdGlvbihmbG93U3RlcCkge1xyXG4gICAgICAgICAgICBpZiAoIXJlc3VsdFtmbG93TmFtZV0pXHJcbiAgICAgICAgICAgICAgICByZXN1bHRbZmxvd05hbWVdID0gW107XHJcbiAgICAgICAgICAgIGZsb3dTdGVwLmRpc2FibGVBdXRvQ29udGludWUgPSBmbG93LmRpc2FibGVBdXRvQ29udGludWU7XHJcbiAgICAgICAgICAgIHJlc3VsdFtmbG93TmFtZV0ucHVzaChmbG93U3RlcCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9nZXRPbmNlc0Zyb21Ub3VyRGIgPSBmdW5jdGlvbih0b3VyRGIpIHtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuXHJcbiAgICBPYmplY3Qua2V5cyh0b3VyRGIub25jZXMpLmZvckVhY2goZnVuY3Rpb24ob25jZVRhZykge1xyXG4gICAgICAgIHZhciBvbmNlID0gdG91ckRiLm9uY2VzW29uY2VUYWddO1xyXG4gICAgICAgIGlmICghb25jZS5lbmFibGVkKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgb25jZS50YWdOYW1lID0gb25jZVRhZztcclxuICAgICAgICByZXN1bHRbb25jZVRhZ10gPSBvbmNlO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fcmVwbGFjZURpY3Rpb25hcnlLZXlzSW5TdGVwID0gZnVuY3Rpb24oZmxvd05hbWUsIHN0ZXBJbmRleCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHZhciB0b3VyRWxlbWVudCA9ICQoXCIudG91ci1jcy10b3VyLWZsb3ctXCIgKyBmbG93TmFtZSArIFwiLVwiICsgc3RlcEluZGV4KTtcclxuICAgIHZhciB0b3VyVGl0bGVFbGVtZW50ID0gdG91ckVsZW1lbnQuZmluZChcIi5wb3BvdmVyLXRpdGxlXCIpO1xyXG4gICAgdmFyIHRvdXJDb250ZW50RWxlbWVudCA9IHRvdXJFbGVtZW50LmZpbmQoXCIucG9wb3Zlci1jb250ZW50XCIpO1xyXG5cclxuICAgIHJlcGxhY2VUb2tlbnModG91clRpdGxlRWxlbWVudCk7XHJcbiAgICByZXBsYWNlVG9rZW5zKHRvdXJDb250ZW50RWxlbWVudCk7XHJcblxyXG4gICAgZnVuY3Rpb24gcmVwbGFjZVRva2VucyhlbGVtZW50KSB7XHJcbiAgICAgICAgdmFyIGh0bWwgPSBlbGVtZW50Lmh0bWwoKSB8fCBcIlwiO1xyXG4gICAgICAgIGVsZW1lbnQuaHRtbChfdGhpcy5fcmVwbGFjZURpY3Rpb25hcnlLZXlzKGh0bWwpKTtcclxuICAgIH1cclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fcmVwbGFjZURpY3Rpb25hcnlLZXlzID0gZnVuY3Rpb24odGV4dCwgZXNjYXBlKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG5cclxuICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL1xcJFxceygoXFxzfC4pKyl9L2dpLCBmdW5jdGlvbihtYXRjaCwga2V5KSB7XHJcbiAgICAgICAgdmFyIHZhbHVlID0gX3RoaXMuX2RpY3Rpb25hcnlba2V5XTtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKVxyXG4gICAgICAgICAgICByZXR1cm4gZXNjYXBlID09PSBmYWxzZSA/IHZhbHVlIDogZXNjYXBlSFRNTCh2YWx1ZSk7XHJcbiAgICAgICAgcmV0dXJuIG1hdGNoO1xyXG4gICAgfSk7XHJcblxyXG4gICAgZnVuY3Rpb24gZXNjYXBlSFRNTChodG1sKSB7XHJcbiAgICAgICAgcmV0dXJuICQoXCI8ZGl2PlwiKS50ZXh0KGh0bWwpLmh0bWwoKTtcclxuICAgIH1cclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fY3JlYXRlRmxvd1RvdXJzID0gZnVuY3Rpb24oZmxvd3MpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcblxyXG4gICAgT2JqZWN0LmtleXMoZmxvd3MpLmZvckVhY2goZnVuY3Rpb24oZmxvd05hbWUpIHtcclxuICAgICAgICB2YXIgZmxvdyA9IGZsb3dzW2Zsb3dOYW1lXTtcclxuXHJcbiAgICAgICAgcmVzdWx0W2Zsb3dOYW1lXSA9IG5ldyBfdGhpcy5fVG91cih7XHJcbiAgICAgICAgICAgIG5hbWU6IF90aGlzLl9nZXRGbG93U3RvcmFnZUtleShmbG93TmFtZSksXHJcbiAgICAgICAgICAgIGRlYnVnOiBUT1VSX0RFQlVHLFxyXG4gICAgICAgICAgICBrZXlib2FyZDogZmFsc2UsXHJcbiAgICAgICAgICAgIHN0ZXBzOiBfdGhpcy5fZmxvd1N0ZXBzVG9Ub3VyU3RlcHMoZmxvdyksXHJcbiAgICAgICAgICAgIG9uU2hvdzogZnVuY3Rpb24odG91cikge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKFwic2hvd1wiLCBmbG93TmFtZSwgdG91ci5nZXRDdXJyZW50U3RlcCgpKTtcclxuXHJcbiAgICAgICAgICAgICAgICBfdGhpcy5fb3BlblN0ZXBTaWRlQmFyTWVudShmbG93LCB0b3VyLmdldEN1cnJlbnRTdGVwKCkpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2hpZGVBbGxPbmNlcygpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBvblNob3duOiBmdW5jdGlvbih0b3VyKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZmxvd1N0ZXAgPSBmbG93W3RvdXIuZ2V0Q3VycmVudFN0ZXAoKV07XHJcbiAgICAgICAgICAgICAgICBpZiAoZmxvd1N0ZXAucHJvY2VlZE9uVGV4dElucHV0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSAkKF90aGlzLl9nZXRUb3VyVGFnTmFtZVNlbGVjdG9yKGZsb3dTdGVwLnRhZ05hbWUpKTtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50Lm9uKFwiaW5wdXQudG91ckRlYm91bmNlXCIsIGNyZWF0ZURlYm91bmNlKHRvdXIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIF90aGlzLl9yZXBsYWNlRGljdGlvbmFyeUtleXNJblN0ZXAoZmxvd05hbWUsIHRvdXIuZ2V0Q3VycmVudFN0ZXAoKSk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoXCJzaG93blwiLCBmbG93TmFtZSwgdG91ci5nZXRDdXJyZW50U3RlcCgpKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb25IaWRlOiBmdW5jdGlvbih0b3VyKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoXCJoaWRlXCIsIGZsb3dOYW1lLCB0b3VyLmdldEN1cnJlbnRTdGVwKCkpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBvbkVuZDogZnVuY3Rpb24gKHRvdXIpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLl9jYWxsRXZlbnRMaXN0ZW5lcihcImVuZFwiLCBmbG93TmFtZSwgdG91ci5nZXRDdXJyZW50U3RlcCgpKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLl9wb3N0RW5kVG91ckV2ZW50KGZsb3dOYW1lLCB0b3VyLmdldEN1cnJlbnRTdGVwKCkpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2N1cnJlbnRseVN0YXJ0ZWRGbG93TmFtZXNbZmxvd05hbWVdID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG9uTmV4dDogZnVuY3Rpb24gKHRvdXIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBmbG93U3RlcCA9IGZsb3dbdG91ci5nZXRDdXJyZW50U3RlcCgpXTtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gJChfdGhpcy5fZ2V0VG91clRhZ05hbWVTZWxlY3RvcihmbG93U3RlcC50YWdOYW1lKSk7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50Lm9mZihcImlucHV0LnRvdXJEZWJvdW5jZVwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodG91ci5nZXRDdXJyZW50U3RlcCgpID09PSBmbG93Lmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICB0b3VyLmVuZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9jdXJyZW50bHlTdGFydGVkRmxvd05hbWVzW2Zsb3dOYW1lXSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgcmVkaXJlY3RWYWx1ZSA9IGZsb3dTdGVwLnJlZGlyZWN0ID8gX3RoaXMuX3JlcGxhY2VEaWN0aW9uYXJ5S2V5cyhcIlwiICsgZmxvd1N0ZXAucmVkaXJlY3QsIGZhbHNlKSA6IFwiXCI7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVkaXJlY3RWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRvdXIuc2V0Q3VycmVudFN0ZXAodG91ci5nZXRDdXJyZW50U3RlcCgpICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZsb3dTdGVwLm5leHRSZWRpcmVjdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gX3RoaXMuX2VzY2FwZVVSTChfdGhpcy5fcmVwbGFjZURpY3Rpb25hcnlLZXlzKGZsb3dTdGVwLm5leHRSZWRpcmVjdCwgZmFsc2UpKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWRpcmVjdFZhbHVlID09PSBcImhhc2hcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJoYXNoY2hhbmdlXCIsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKFwibmV4dFwiLCBmbG93TmFtZSwgdG91ci5nZXRDdXJyZW50U3RlcCgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBjcmVhdGVEZWJvdW5jZSh0b3VyKSB7XHJcbiAgICAgICAgICAgIHZhciB4ID0gbnVsbDtcclxuICAgICAgICAgICAgcmV0dXJuIGRlYm91bmNlO1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gZGVib3VuY2UoZSkge1xyXG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHgpO1xyXG4gICAgICAgICAgICAgICAgeCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdG91ci5uZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9LCAzNTApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX2NyZWF0ZUltYWdlRmxvd1RvdXJzID0gZnVuY3Rpb24oaW1hZ2VGbG93cykge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuXHJcbiAgICBPYmplY3Qua2V5cyhpbWFnZUZsb3dzKS5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dOYW1lKSB7XHJcbiAgICAgICAgdmFyIGltYWdlRmxvdyA9IGltYWdlRmxvd3NbZmxvd05hbWVdO1xyXG5cclxuICAgICAgICByZXN1bHRbZmxvd05hbWVdID0gbmV3IF90aGlzLl9Ub3VyKHtcclxuICAgICAgICAgICAgbmFtZTogX3RoaXMuX2dldEltYWdlRmxvd1N0b3JhZ2VLZXkoZmxvd05hbWUpLFxyXG4gICAgICAgICAgICBkZWJ1ZzogVE9VUl9ERUJVRyxcclxuICAgICAgICAgICAgc3RlcHM6IF90aGlzLl9pbWFnZUZsb3dTdGVwc1RvVG91clN0ZXBzKGltYWdlRmxvdy5zdGVwcyksXHJcbiAgICAgICAgICAgIG9uRW5kOiBmdW5jdGlvbiAodG91cikge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuX3JlbW92ZUltYWdlRmxvd01vZGFsKGZsb3dOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX2VzY2FwZVVSTCA9IGZ1bmN0aW9uKHVybCkge1xyXG4gICAgaWYgKHVybClcclxuICAgICAgICByZXR1cm4gdXJsLnJlcGxhY2UoL15qYXZhc2NyaXB0Oi8sIFwiXCIpO1xyXG4gICAgcmV0dXJuIHVybDtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fb3BlblN0ZXBTaWRlQmFyTWVudSA9IGZ1bmN0aW9uKGZsb3dTdGVwcywgY3VycmVudFN0ZXBJbmRleCkge1xyXG4gICAgdmFyIGN1cnJlbnRTdGVwO1xyXG4gICAgdmFyIG5leHRTdGVwO1xyXG4gICAgdmFyIGRlbGF5O1xyXG5cclxuICAgIGlmIChjdXJyZW50U3RlcEluZGV4ICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3VycmVudFN0ZXAgPSBmbG93U3RlcHNbY3VycmVudFN0ZXBJbmRleF07XHJcbiAgICAgICAgbmV4dFN0ZXAgPSBmbG93U3RlcHNbY3VycmVudFN0ZXBJbmRleCArIDFdO1xyXG4gICAgICAgIGRlbGF5ID0gY3VycmVudFN0ZXAuZGVsYXk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGN1cnJlbnRTdGVwID0gbnVsbDtcclxuICAgICAgICBuZXh0U3RlcCA9IGZsb3dTdGVwc1swXTtcclxuICAgICAgICBkZWxheSA9IG5leHRTdGVwLmRlbGF5O1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChuZXh0U3RlcCAmJiBuZXh0U3RlcC5vcGVuU2lkZUJhck1lbnUgJiYgd2luZG93LmNzICYmIHdpbmRvdy5jcy5zaWRlQmFyU2VydmljZSkge1xyXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5jcy5zaWRlQmFyU2VydmljZS5vcGVuU3ViTWVudShuZXh0U3RlcC5vcGVuU2lkZUJhck1lbnUpO1xyXG4gICAgICAgIH0sIGRlbGF5KTtcclxuICAgIH1cclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fY3JlYXRlT25jZVRvdXJzID0gZnVuY3Rpb24ob25jZXMpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcblxyXG4gICAgT2JqZWN0LmtleXMob25jZXMpLmZvckVhY2goKGZ1bmN0aW9uKG9uY2VUYWdOYW1lKSB7XHJcbiAgICAgICAgdmFyIG9uY2UgPSBvbmNlc1tvbmNlVGFnTmFtZV07XHJcblxyXG4gICAgICAgIHJlc3VsdFtvbmNlVGFnTmFtZV0gPSBuZXcgVG91cih7XHJcbiAgICAgICAgICAgIG5hbWU6IHRoaXMuX2dldE9uY2VTdG9yYWdlS2V5KG9uY2VUYWdOYW1lKSxcclxuICAgICAgICAgICAgZGVidWc6IFRPVVJfREVCVUcsXHJcbiAgICAgICAgICAgIHN0ZXBzOiBbdGhpcy5fb25jZU9yRmxvd1N0ZXBUb1RvdXJTdGVwKG9uY2UsIG9uY2VUYWdOYW1lKV0sXHJcbiAgICAgICAgICAgIG9uU2hvdzogZnVuY3Rpb24gKHRvdXIpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLl9jdXJyZW50bHlTdGFydGVkT25jZU5hbWVzW29uY2VUYWdOYW1lXSA9IHRydWU7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG9uSGlkZTogZnVuY3Rpb24odG91cikge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuX2N1cnJlbnRseVN0YXJ0ZWRPbmNlTmFtZXNbb25jZVRhZ05hbWVdID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH0pLmJpbmQodGhpcykpO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX2Zsb3dTdGVwc1RvVG91clN0ZXBzID0gZnVuY3Rpb24oZmxvd1N0ZXBzKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgcmV0dXJuIGZsb3dTdGVwcy5tYXAoZnVuY3Rpb24oc3RlcCkge1xyXG4gICAgICAgIHJldHVybiBfdGhpcy5fb25jZU9yRmxvd1N0ZXBUb1RvdXJTdGVwKHN0ZXApO1xyXG4gICAgfSk7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX29uY2VPckZsb3dTdGVwVG9Ub3VyU3RlcCA9IGZ1bmN0aW9uKHN0ZXAsIHRhZ05hbWUpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB0YWdOYW1lID0gdGFnTmFtZSB8fCBzdGVwLnRhZ05hbWU7XHJcbiAgICByZXR1cm4gIHtcclxuICAgICAgICBlbGVtZW50OiB0aGlzLl9nZXRUb3VyVGFnTmFtZVNlbGVjdG9yKHRhZ05hbWUpLFxyXG4gICAgICAgIGNvbnRhaW5lcjogc3RlcC5jb250YWluZXIgfHwgXCJib2R5XCIsXHJcbiAgICAgICAgYXV0b3Njcm9sbEVsZW1lbnQ6IHN0ZXAuYXV0b3Njcm9sbEVsZW1lbnQsXHJcbiAgICAgICAgb3JwaGFuOiBzdGVwLm9ycGhhbixcclxuICAgICAgICBhbmltYXRpb246IGZhbHNlLFxyXG4gICAgICAgIG9wdGlvbmFsOiBzdGVwLm9wdGlvbmFsLFxyXG4gICAgICAgIHRpdGxlOiBzdGVwLnRpdGxlLFxyXG4gICAgICAgIGNvbnRlbnQ6IHN0ZXAuZGVzY3JpcHRpb24sXHJcbiAgICAgICAgYmFja2Ryb3A6IHN0ZXAuZGFya0JhY2tncm91bmQsXHJcbiAgICAgICAgYmFja2Ryb3BCYWNrZ3JvdW5kQ3NzQ2xhc3M6IHN0ZXAuYmFja2Ryb3BCYWNrZ3JvdW5kQ3NzQ2xhc3MsXHJcbiAgICAgICAgYmFja2Ryb3BFbGVtZW50Q3NzQ2xhc3M6IHN0ZXAuYmFja2Ryb3BFbGVtZW50Q3NzQ2xhc3MsXHJcbiAgICAgICAgcGxhY2VtZW50OiBzdGVwLnBsYWNlbWVudCxcclxuICAgICAgICBvZmZzZXRYOiBzdGVwLm9mZnNldFgsXHJcbiAgICAgICAgb2Zmc2V0WTogc3RlcC5vZmZzZXRZLFxyXG4gICAgICAgIHdpZHRoOiBzdGVwLndpZHRoLFxyXG4gICAgICAgIGRlbGF5OiBzdGVwLmRlbGF5LFxyXG4gICAgICAgIHRlbXBsYXRlOiB0aGlzLl9nZXRUZW1wbGF0ZShzdGVwKSxcclxuICAgICAgICBkaXNhYmxlQ2xpY2s6IHN0ZXAuZGlzYWJsZUNsaWNrXHJcbiAgICB9O1xyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9nZXRUb3VyVGFnTmFtZVNlbGVjdG9yID0gZnVuY3Rpb24odGFnTmFtZSkge1xyXG4gICAgcmV0dXJuICB0YWdOYW1lID8gXCJbdG91ci10YWctbmFtZT0nXCIgKyB0YWdOYW1lICsgXCInXTpmaXJzdFwiIDogbnVsbDtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5faW1hZ2VGbG93U3RlcHNUb1RvdXJTdGVwcyA9IGZ1bmN0aW9uKGZsb3dTdGVwcykge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHJldHVybiBmbG93U3RlcHMubWFwKGZ1bmN0aW9uKHN0ZXApIHtcclxuICAgICAgICB2YXIgc2VsZWN0b3IgPSBcIi5mbG93LW1vZGFsLWltYWdlLWNvbnRhaW5lclwiO1xyXG4gICAgICAgIGlmIChzdGVwLnBvc2l0aW9uKVxyXG4gICAgICAgICAgICBzZWxlY3RvciA9IFwiW2ltYWdlLWZsb3ctc3BvdD1cXFwiXCIgKyBzdGVwLnBvc2l0aW9uWzBdICsgXCItXCIgKyBzdGVwLnBvc2l0aW9uWzFdICsgXCJcXFwiXVwiO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBlbGVtZW50OiBzZWxlY3RvcixcclxuICAgICAgICAgICAgY29udGFpbmVyOiBcImJvZHlcIixcclxuICAgICAgICAgICAgb3JwaGFuOiAhc3RlcC5wb3NpdGlvbiB8fCBzdGVwLm9ycGhhbixcclxuICAgICAgICAgICAgdGl0bGU6IHN0ZXAudGl0bGUsXHJcbiAgICAgICAgICAgIGNvbnRlbnQ6IHN0ZXAuZGVzY3JpcHRpb24sXHJcbiAgICAgICAgICAgIHBsYWNlbWVudDogc3RlcC5wbGFjZW1lbnQsXHJcbiAgICAgICAgICAgIGRlbGF5OiBzdGVwLmRlbGF5LFxyXG4gICAgICAgICAgICB0ZW1wbGF0ZTogX3RoaXMuX2dldFRlbXBsYXRlKHN0ZXApXHJcbiAgICAgICAgfTtcclxuICAgIH0pO1xyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9nZXRUb3VyRGIgPSBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLl94aHJHZXQoXCIvYXBpL3YzL3VuYXV0aGVudGljYXRlZC90b3VyZGJcIilcclxuICAgICAgICAudGhlbigoZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UocmVzcG9uc2UuY29udGVudCk7XHJcbiAgICAgICAgfSkuYmluZCh0aGlzKSwgZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkZhaWxlZCB0byBnZXQgdG91ckRiIGpzb25cIiwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgW1wiY2F0Y2hcIl0oZnVuY3Rpb24oZXJyb3IpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIHRvdXJEYiBqc29uXCIsIGVycm9yKTtcclxuICAgIH0pO1xyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9wb3N0RW5kVG91ckV2ZW50ID0gZnVuY3Rpb24oZmxvd05hbWUsIHN0ZXBJbmRleCkge1xyXG4gICAgdGhpcy5feGhyUG9zdChcIi9hcGkvdjMvdWkvYWRkdWlldmVudFwiLCB7XHJcbiAgICAgICAgZXZlbnROYW1lOiBcIkVuZFRvdXJcIixcclxuICAgICAgICBwYXJhbWV0ZXJzOiBbXHJcbiAgICAgICAgICAgIFwiZmxvd05hbWVcIiwgZmxvd05hbWUsXHJcbiAgICAgICAgICAgIFwic3RlcEluZGV4XCIsIHN0ZXBJbmRleFxyXG4gICAgICAgIF1cclxuICAgIH0pO1xyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl94aHJHZXQgPSBmdW5jdGlvbihwYXRoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fZG9YaHIoXCJHRVRcIiwgcGF0aCk7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX3hoclBvc3QgPSBmdW5jdGlvbihwYXRoLCBwYXlsb2FkKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fZG9YaHIoXCJQT1NUXCIsIHBhdGgsIHBheWxvYWQpO1xyXG59O1xyXG5cclxuVG91clNlcnZpY2UucHJvdG90eXBlLl9kb1hociA9IGZ1bmN0aW9uKG1ldGhvZCwgcGF0aCwgcGF5bG9hZCkge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICB2YXIgeGhyID0gbmV3IHRoaXMuX1hNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgeGhyLm9wZW4obWV0aG9kLCBwYXRoKTtcclxuICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gWE1MSHR0cFJlcXVlc3QuRE9ORSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlSW50KHhoci5zdGF0dXMgLyAxMDApID09PSAyKVxyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoe3N0YXR1czogeGhyLnN0YXR1cywgY29udGVudDogeGhyLnJlc3BvbnNlVGV4dH0pO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCh7c3RhdHVzOiB4aHIuc3RhdHVzLCBjb250ZW50OiB4aHIucmVzcG9uc2VUZXh0fSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmIChwYXlsb2FkKSB7XHJcbiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsIFwiYXBwbGljYXRpb24vanNvblwiKTtcclxuICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJBY2NlcHRcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xyXG4gICAgICAgICAgICB4aHIuc2VuZChKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgeGhyLnNlbmQoKTtcclxuICAgICAgICB9XHJcbiAgICB9KS5iaW5kKHRoaXMpKTtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fZ2V0SW1hZ2VGbG93U3RvcmFnZUtleSA9IGZ1bmN0aW9uKG5hbWUpIHtcclxuICAgIHJldHVybiBcImNzLWltYWdlLXRvdXItZmxvdy1cIiArIG5hbWU7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX2dldEZsb3dTdG9yYWdlS2V5ID0gZnVuY3Rpb24obmFtZSkge1xyXG4gICAgcmV0dXJuIFwiY3MtdG91ci1mbG93LVwiICsgbmFtZTtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fZ2V0T25jZVN0b3JhZ2VLZXkgPSBmdW5jdGlvbihuYW1lKSB7XHJcbiAgICByZXR1cm4gXCJjcy10b3VyLVwiICsgbmFtZTtcclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fZ2V0VGVtcGxhdGUgPSBmdW5jdGlvbihzdGVwKSB7XHJcbiAgICBzd2l0Y2ggKHN0ZXAudGVtcGxhdGUpIHtcclxuICAgICAgICBjYXNlIFwiZmxvd1wiOlxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY3VzdG9taXplVGVtcGxhdGUoc3RlcCwgcmVxdWlyZShcIi4vdGVtcGxhdGVzL0Zsb3dUZW1wbGF0ZS5odG1sXCIpKTtcclxuICAgICAgICBjYXNlIFwiZmxvdy13aXRob3V0LWV4aXRcIjpcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2N1c3RvbWl6ZVRlbXBsYXRlKHN0ZXAsIHJlcXVpcmUoXCIuL3RlbXBsYXRlcy9GbG93V2l0aG91dEV4aXRUZW1wbGF0ZS5odG1sXCIpKTtcclxuICAgICAgICBjYXNlIFwiZmxvdy13aXRoLW5leHRcIjpcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2N1c3RvbWl6ZVRlbXBsYXRlKHN0ZXAsIHJlcXVpcmUoXCIuL3RlbXBsYXRlcy9GbG93VGVtcGxhdGVXaXRoTmV4dC5odG1sXCIpKTtcclxuICAgICAgICBjYXNlIFwiZmxvdy13aXRoLWVuZFwiOlxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY3VzdG9taXplVGVtcGxhdGUoc3RlcCwgcmVxdWlyZShcIi4vdGVtcGxhdGVzL0Zsb3dUZW1wbGF0ZVdpdGhFbmQuaHRtbFwiKSk7XHJcbiAgICAgICAgY2FzZSBcImZsb3ctd2l0aC1uZXh0LWFuZC1lbmRcIjpcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2N1c3RvbWl6ZVRlbXBsYXRlKHN0ZXAsIHJlcXVpcmUoXCIuL3RlbXBsYXRlcy9GbG93VGVtcGxhdGVXaXRoTmV4dEFuZEVuZC5odG1sXCIpKTtcclxuICAgICAgICBjYXNlIFwic2hvdy1vbmNlLWZsb3dcIjpcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2N1c3RvbWl6ZVRlbXBsYXRlKHN0ZXAsIHJlcXVpcmUoXCIuL3RlbXBsYXRlcy9TaG93T25jZUZsb3dUZW1wbGF0ZS5odG1sXCIpKTtcclxuICAgICAgICBjYXNlIFwic2hvdy1vbmNlLWZsb3ctd2l0aC1uZXh0XCI6XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jdXN0b21pemVUZW1wbGF0ZShzdGVwLCByZXF1aXJlKFwiLi90ZW1wbGF0ZXMvU2hvd09uY2VGbG93VGVtcGxhdGVXaXRoTmV4dC5odG1sXCIpKTtcclxuICAgIH1cclxufTtcclxuXHJcblRvdXJTZXJ2aWNlLnByb3RvdHlwZS5fY3VzdG9taXplVGVtcGxhdGUgPSBmdW5jdGlvbihzdGVwLCB0ZW1wbGF0ZSkge1xyXG4gICAgaWYgKCFzdGVwLm5leHRMYWJlbClcclxuICAgICAgICByZXR1cm4gdGVtcGxhdGU7XHJcbiAgICB2YXIgZG9tID0gJCh0ZW1wbGF0ZSk7XHJcbiAgICBkb20uZmluZChcIltkYXRhLXJvbGU9bmV4dF06bnRoLWNoaWxkKDEpXCIpLnRleHQoc3RlcC5uZXh0TGFiZWwpO1xyXG4gICAgcmV0dXJuIGRvbVswXS5vdXRlckhUTUw7XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX2FkZEltYWdlRmxvd01vZGFsID0gZnVuY3Rpb24oZmxvd05hbWUpIHtcclxuICAgIGlmICghdGhpcy5faW1hZ2VGbG93TW9kYWxFbGVtZW50c1tmbG93TmFtZV0pXHJcbiAgICAgICAgdGhpcy5faW1hZ2VGbG93TW9kYWxFbGVtZW50c1tmbG93TmFtZV0gPSB0aGlzLl9jcmVhdGVJbWFnZUZsb3dNb2RhbEVsZW1lbnQoZmxvd05hbWUpO1xyXG4gICAgdmFyIG1vZGFsID0gdGhpcy5faW1hZ2VGbG93TW9kYWxFbGVtZW50c1tmbG93TmFtZV07XHJcbiAgICBpZiAobW9kYWwucGFyZW50KCkubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgJChkb2N1bWVudC5ib2R5KS5hcHBlbmQobW9kYWwpO1xyXG4gICAgICAgIG1vZGFsLmZhZGVPdXQoMCk7XHJcbiAgICAgICAgbW9kYWwuZmFkZUluKDIwMCk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX3JlbW92ZUltYWdlRmxvd01vZGFsID0gZnVuY3Rpb24oZmxvd05hbWUpIHtcclxuICAgIHZhciBtb2RhbEVsZW1lbnQgPSB0aGlzLl9pbWFnZUZsb3dNb2RhbEVsZW1lbnRzW2Zsb3dOYW1lXTtcclxuICAgIGlmIChtb2RhbEVsZW1lbnQpIHtcclxuICAgICAgICBtb2RhbEVsZW1lbnQuZmFkZU91dCgyMDAsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBtb2RhbEVsZW1lbnQucmVtb3ZlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5Ub3VyU2VydmljZS5wcm90b3R5cGUuX29wZW5JbWFnZUZsb3dBbmNob3JDbGlja3MgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICBpZiAoZS50YXJnZXQgJiYgZS50YXJnZXQubm9kZU5hbWUgPT09IFwiQVwiICYmIGUudGFyZ2V0LmF0dHJpYnV0ZXNbXCJpbWFnZS1mbG93XCJdKSB7XHJcbiAgICAgICAgICAgIHZhciBpbWFnZUZsb3dOYW1lID0gZS50YXJnZXQuYXR0cmlidXRlc1tcImltYWdlLWZsb3dcIl0udmFsdWU7XHJcbiAgICAgICAgICAgIF90aGlzLnN0YXJ0SW1hZ2VGbG93KGltYWdlRmxvd05hbWUpO1xyXG4gICAgICAgIH1cclxuICAgIH0sIHRydWUpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBUb3VyU2VydmljZTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jbG91ZHNoYXJlLXRvdXIvY3MtdG91ci1zZXJ2aWNlLmpzXG4vLyBtb2R1bGUgaWQgPSAxMjNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGJvdHRsZSA9IHJlcXVpcmUoJy4vYm90dGxlLW1hcHBpbmcnKTtcclxuXHJcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCBmdW5jdGlvbigpIHtcclxuXHRib3R0bGUuY29udGFpbmVyLlRvdXJTZXJ2aWNlLmluaXQoKTtcclxufSwgdHJ1ZSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGJvdHRsZS5jb250YWluZXIuVG91clNlcnZpY2U7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY2xvdWRzaGFyZS10b3VyL21haW4uanNcbi8vIG1vZHVsZSBpZCA9IDEyNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcclxuZnVuY3Rpb24gQXV0aGVudGljYXRpb25QYXJhbWV0ZXJQcm92aWRlcihobWFjU2VydmljZSkge1xyXG5cdHRoaXMuaG1hY1NlcnZpY2UgPSBobWFjU2VydmljZTtcclxufVxyXG5cclxuLypcclxuXHRvcHRpb25zID0ge1xyXG5cdFx0dXJsOiBlbnRpcmUgcmVxdWVzdCB1cmwgKGh0dHBzOi8vLi4uKSxcclxuXHRcdGFwaUlkXHJcblx0XHRhcGlLZXlcclxuXHR9XHJcbiovXHJcbkF1dGhlbnRpY2F0aW9uUGFyYW1ldGVyUHJvdmlkZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuXHR2YXIgcGFyYW1zID0gZ2V0UGFyYW1ldGVycyhvcHRpb25zKTtcclxuXHR2YXIgaG1hYyA9IGdldEhtYWModGhpcywgcGFyYW1zKTtcclxuXHRyZXR1cm4gZ2V0QXV0aFN0cmluZyhwYXJhbXMsIGhtYWMpO1xyXG59O1xyXG5cclxuZnVuY3Rpb24gZ2V0QXV0aFN0cmluZyhwYXJhbXMsIGhtYWMpIHtcclxuXHRyZXR1cm4gXCJ1c2VyYXBpaWQ6XCIgKyBwYXJhbXMuYXBpSWQgKyBcIjt0aW1lc3RhbXA6XCIgKyBwYXJhbXMudGltZXN0YW1wICsgXCI7dG9rZW46XCIgKyBwYXJhbXMudG9rZW4gKyBcIjtobWFjOlwiICsgaG1hYztcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0UGFyYW1ldGVycyhvcHRpb25zKSB7XHJcblx0cmV0dXJuIHtcclxuXHRcdGFwaUlkOiBvcHRpb25zLmFwaUlkLFxyXG5cdFx0YXBpS2V5OiBvcHRpb25zLmFwaUtleSxcclxuXHRcdHRpbWVzdGFtcDogZ2V0VGltZXN0YW1wKCksXHJcblx0XHR0b2tlbjogZ2V0UmVlbnRlcmFuY3lUb2tlbigpLFxyXG5cdFx0dXJsOiBvcHRpb25zLnVybFxyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFJlZW50ZXJhbmN5VG9rZW4oKSB7XHJcblx0cmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoKS5zdWJzdHJpbmcoMiwgMTIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRUaW1lc3RhbXAoKSB7XHJcblx0cmV0dXJuIE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRIbWFjKHNlbGYsIHBhcmFtcykge1xyXG5cdHJldHVybiBzZWxmLmhtYWNTZXJ2aWNlLmhhc2goe1xyXG5cdFx0YXBpS2V5OiBwYXJhbXMuYXBpS2V5LFxyXG5cdFx0dXJsOiBwYXJhbXMudXJsLFxyXG5cdFx0dGltZXN0YW1wOiBwYXJhbXMudGltZXN0YW1wLFxyXG5cdFx0dG9rZW46IHBhcmFtcy50b2tlblxyXG5cdH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEF1dGhlbnRpY2F0aW9uUGFyYW1ldGVyUHJvdmlkZXI7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NzLXNkay9hdXRoZW50aWNhdGlvbi1wYXJhbWV0ZXItcHJvdmlkZXIuanNcbi8vIG1vZHVsZSBpZCA9IDEyNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgQm90dGxlID0gcmVxdWlyZSgnYm90dGxlanMnKTtcclxudmFyIGJvdHRsZSA9IG5ldyBCb3R0bGUoKTtcclxuXHJcbmJvdHRsZS5zZXJ2aWNlKCdITUFDU2VydmljZScsIHJlcXVpcmUoJy4vaG1hYy1zZXJ2aWNlJykpO1xyXG5ib3R0bGUuc2VydmljZSgnSHR0cCcsIHJlcXVpcmUoJy4vaHR0cCcpKTtcclxuYm90dGxlLnNlcnZpY2UoJ0F1dGhlbnRpY2F0aW9uUGFyYW1ldGVyUHJvdmlkZXInLCByZXF1aXJlKCcuL2F1dGhlbnRpY2F0aW9uLXBhcmFtZXRlci1wcm92aWRlcicpLCAnSE1BQ1NlcnZpY2UnKTtcclxuYm90dGxlLnNlcnZpY2UoJ0Nsb3VkU2hhcmVDbGllbnQnLCByZXF1aXJlKCcuL2Nsb3Vkc2hhcmUtY2xpZW50JyksICdIdHRwJywgJ0F1dGhlbnRpY2F0aW9uUGFyYW1ldGVyUHJvdmlkZXInKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYm90dGxlO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NzLXNkay9ib3R0bGUuanNcbi8vIG1vZHVsZSBpZCA9IDEyNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgUHJvbWlzZSA9IHJlcXVpcmUoJ2VzNi1wcm9taXNlJykuUHJvbWlzZTtcclxuXHJcbmZ1bmN0aW9uIENsb3VkU2hhcmVDbGllbnQoaHR0cCwgYXV0aGVudGljYXRpb25QYXJhbWV0ZXJQcm92aWRlcikge1xyXG5cdHRoaXMuaHR0cCA9IGh0dHA7XHJcblx0dGhpcy5hdXRoUGFyYW1Qcm92aWRlciA9IGF1dGhlbnRpY2F0aW9uUGFyYW1ldGVyUHJvdmlkZXI7XHJcbn1cclxuXHJcbi8qXHJcblx0b3B0aW9ucyA9IHtcclxuXHRcdFtob3N0bmFtZV0sXHJcblx0XHRtZXRob2QsXHJcblx0XHRwYXRoLFxyXG5cdFx0W3F1ZXJ5UGFyYW1zXSxcclxuXHRcdFtjb250ZW50XSxcclxuXHRcdFthcGlJZF0sXHJcblx0XHRbYXBpS2V5XVxyXG5cdH1cclxuKi9cclxuQ2xvdWRTaGFyZUNsaWVudC5wcm90b3R5cGUucmVxID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG5cdHZhciBzZWxmID0gdGhpcztcclxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XHJcblx0XHRvcHRpb25zID0gdmFsaWRhdGVBbmRNYXNzYWdlT3B0aW9ucyhvcHRpb25zLCByZWplY3QpO1xyXG5cdFx0cmVzb2x2ZShyZXF1ZXN0KHNlbGYsIG9wdGlvbnMpKTtcclxuXHR9KTtcclxufTtcclxuXHJcbmZ1bmN0aW9uIHJlcXVlc3Qoc2VsZiwgb3B0aW9ucykge1xyXG5cdHJldHVybiBzZWxmLmh0dHAucmVxKHtcclxuXHRcdG1ldGhvZDogb3B0aW9ucy5tZXRob2QsXHJcblx0XHR1cmw6IGdlbmVyYXRlVXJsV2l0aG91dFF1ZXJ5U3RyaW5nKG9wdGlvbnMpLFxyXG5cdFx0aGVhZGVyczogZ2V0SGVhZGVycyhzZWxmLCBvcHRpb25zKSxcclxuXHRcdHF1ZXJ5UGFyYW1zOiBvcHRpb25zLnF1ZXJ5UGFyYW1zLFxyXG5cdFx0Y29udGVudDogb3B0aW9ucy5jb250ZW50XHJcblx0fSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEhlYWRlcnMoc2VsZiwgb3B0aW9ucykge1xyXG5cdHZhciBoZWFkZXJzID0ge1xyXG5cdFx0J0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcclxuXHRcdCdBY2NlcHQnOiAnYXBwbGljYXRpb24vanNvbidcclxuXHR9O1xyXG5cdGlmIChvcHRpb25zLmFwaUlkICYmIG9wdGlvbnMuYXBpS2V5KVxyXG5cdFx0aGVhZGVyc1snQXV0aG9yaXphdGlvbiddID0gJ2NzX3NoYTEgJyArIGdldEF1dGhQYXJhbShzZWxmLCBvcHRpb25zKTtcclxuXHRyZXR1cm4gaGVhZGVycztcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0QXV0aFBhcmFtKHNlbGYsIG9wdGlvbnMpIHtcclxuXHRyZXR1cm4gc2VsZi5hdXRoUGFyYW1Qcm92aWRlci5nZXQoe1xyXG5cdFx0dXJsOiBnZW5lcmF0ZVVybFdpdGhRdWVyeVN0cmluZyhvcHRpb25zKSxcclxuXHRcdGFwaUlkOiBvcHRpb25zLmFwaUlkLFxyXG5cdFx0YXBpS2V5OiBvcHRpb25zLmFwaUtleVxyXG5cdH0pO1x0XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHZhbGlkYXRlQW5kTWFzc2FnZU9wdGlvbnMob3B0aW9ucywgcmVqZWN0KSB7XHJcblx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblx0dmFsaWRhdGVPcHRpb25zKG9wdGlvbnMsIHJlamVjdCk7XHJcblx0cHJlZml4UGF0aFdpdGhTbGFzaChvcHRpb25zKTtcclxuXHRyZXR1cm4gb3B0aW9ucztcclxufVxyXG5cclxuZnVuY3Rpb24gcHJlZml4UGF0aFdpdGhTbGFzaChvcHRpb25zKSB7XHJcblx0aWYgKG9wdGlvbnMucGF0aC5pbmRleE9mKCcvJykgIT09IDApXHJcblx0XHRvcHRpb25zLnBhdGggPSAnLycgKyBvcHRpb25zLnBhdGg7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHZhbGlkYXRlT3B0aW9ucyhvcHRpb25zLCByZWplY3QpIHtcclxuXHRpZiAoIW9wdGlvbnMuaG9zdG5hbWUpXHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGhvc3RuYW1lXCIpO1xyXG5cdGVsc2UgaWYgKCFvcHRpb25zLm1ldGhvZClcclxuXHRcdHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgSFRUUCBtZXRob2RcIik7XHJcblx0ZWxzZSBpZiAoIW9wdGlvbnMucGF0aClcclxuXHRcdHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgcGF0aFwiKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVVcmxXaXRoUXVlcnlTdHJpbmcob3B0aW9ucykge1xyXG5cdHJldHVybiBnZW5lcmF0ZVVybFdpdGhvdXRRdWVyeVN0cmluZyhvcHRpb25zKSArIGNyZWF0ZVF1ZXJ5UGFyYW1zKG9wdGlvbnMucXVlcnlQYXJhbXMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZW5lcmF0ZVVybFdpdGhvdXRRdWVyeVN0cmluZyhvcHRpb25zKSB7XHJcblx0cmV0dXJuICdodHRwczovLycgKyBvcHRpb25zLmhvc3RuYW1lICsgJy9hcGkvdjMnICsgb3B0aW9ucy5wYXRoO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVRdWVyeVBhcmFtcyhvYmopIHtcclxuXHRpZiAoIW9iailcclxuXHRcdHJldHVybiBcIlwiO1xyXG5cdHZhciBzdHIgPSBbXTtcclxuXHRmb3IgKHZhciBwIGluIG9iaikge1xyXG5cdCAgIGlmIChvYmouaGFzT3duUHJvcGVydHkocCkpXHJcblx0ICAgICAgIHN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwKSArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KG9ialtwXSkpO1xyXG5cdH1cclxuXHRyZXR1cm4gc3RyLmxlbmd0aCA+IDAgPyBcIj9cIiArIHN0ci5qb2luKFwiJlwiKSA6IFwiXCI7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRyeUpTT05QYXJzZSh0ZXh0KSB7XHJcblx0dHJ5IHtcclxuXHRcdHJldHVybiBKU09OLnBhcnNlKHRleHQpO1xyXG5cdH0gY2F0Y2ggKGUpIHtcclxuXHRcdHJldHVybiB0ZXh0O1xyXG5cdH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBDbG91ZFNoYXJlQ2xpZW50O1xyXG5cclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY3Mtc2RrL2Nsb3Vkc2hhcmUtY2xpZW50LmpzXG4vLyBtb2R1bGUgaWQgPSAxMjdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGpzc2hhID0gcmVxdWlyZSgnanNzaGEnKTtcclxuXHJcbmZ1bmN0aW9uIEhNQUNTZXJ2aWNlKCkge1xyXG5cdHRoaXMuanNzaGEgPSBqc3NoYTtcclxufVxyXG5cclxuSE1BQ1NlcnZpY2UucHJvdG90eXBlLmhhc2ggPSBmdW5jdGlvbihwYXJhbXMpIHtcclxuXHR2YXIgdGV4dCA9IHBhcmFtcy5hcGlLZXkgKyBwYXJhbXMudXJsICsgcGFyYW1zLnRpbWVzdGFtcCArIHBhcmFtcy50b2tlbjtcclxuXHRyZXR1cm4gbmV3IHRoaXMuanNzaGEodGV4dCwgJ1RFWFQnKS5nZXRIYXNoKCdTSEEtMScsICdIRVgnKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBITUFDU2VydmljZTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jcy1zZGsvaG1hYy1zZXJ2aWNlLmpzXG4vLyBtb2R1bGUgaWQgPSAxMjhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIFByb21pc2UgPSByZXF1aXJlKCdlczYtcHJvbWlzZScpLlByb21pc2U7XHJcblxyXG5mdW5jdGlvbiBIdHRwKCkge1xyXG5cclxufVxyXG5cclxuLypcclxuXHRvcHRpb25zID0ge1xyXG5cdFx0bWV0aG9kXHJcblx0XHR1cmxcclxuXHRcdGhlYWRlcnMgW29iamVjdF1cclxuXHRcdHF1ZXJ5UGFyYW1zIFtvYmplY3RdXHJcblx0XHRjb250ZW50IFtvYmplY3R8c3RyaW5nXVxyXG5cdH1cclxuKi9cclxuSHR0cC5wcm90b3R5cGUucmVxID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcclxuXHRcdGlmICghb3B0aW9ucy5tZXRob2QpXHJcblx0XHRcdHRocm93IG5ldyBFcnJvcignSFRUUCBtZXRob2QgbWlzc2luZycpO1xyXG5cdFx0ZWxzZSBpZiAoIW9wdGlvbnMudXJsKVxyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1VSTCBpcyBtaXNzaW5nJyk7XHRcdFxyXG5cdFx0dmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG5cdFx0eGhyLm9wZW4ob3B0aW9ucy5tZXRob2QsIGNyZWF0ZVVybChvcHRpb25zLnVybCwgb3B0aW9ucy5xdWVyeVBhcmFtcykpO1xyXG5cdFx0c2V0SGVhZGVycyh4aHIsIG9wdGlvbnMuaGVhZGVycyk7XHJcblx0XHR4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XHJcblx0XHRcdG9uUmVhZHlTdGF0ZUNoYW5nZSh4aHIsIHJlc29sdmUsIHJlamVjdCk7XHJcblx0XHR9O1xyXG5cdFx0c2VuZCh4aHIsIG9wdGlvbnMuY29udGVudCk7XHJcblx0fSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVVybCh1cmwsIHF1ZXJ5UGFyYW1zKSB7XHJcblx0aWYgKHR5cGVvZiBxdWVyeVBhcmFtcyA9PT0gJ29iamVjdCcpXHJcblx0XHRyZXR1cm4gdXJsICsgJz8nICsgY3JlYXRlUXVlcnlQYXJhbXMocXVlcnlQYXJhbXMpO1xyXG5cdGVsc2VcclxuXHRcdHJldHVybiB1cmw7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNlbmQoeGhyLCBjb250ZW50KSB7XHJcblx0aWYgKHR5cGVvZiBjb250ZW50ID09PSAnb2JqZWN0JylcclxuXHRcdHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KGNvbnRlbnQpKTtcclxuXHRlbHNlIGlmICh0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpXHJcblx0XHR4aHIuc2VuZChjb250ZW50KTtcclxuXHRlbHNlXHJcblx0XHR4aHIuc2VuZCgpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBvblJlYWR5U3RhdGVDaGFuZ2UoeGhyLCByZXNvbHZlLCByZWplY3QpIHtcclxuXHRpZiAoeGhyLnJlYWR5U3RhdGUgIT09IDQpXHJcblx0XHRyZXR1cm47XHJcblx0dmFyIGNvbnRlbnQgPSBwYXJzZVJlc3BvbnNlVGV4dCh4aHIpO1xyXG5cdGlmICh4aHIuc3RhdHVzID49IDIwMCAmJiB4aHIuc3RhdHVzIDwgMzAwKSBcclxuXHRcdHJlc29sdmUoe2NvbnRlbnQ6IGNvbnRlbnQsIHN0YXR1czogeGhyLnN0YXR1c30pO1xyXG5cdGVsc2VcclxuXHRcdHJlamVjdCh7Y29udGVudDogY29udGVudCwgc3RhdHVzOiB4aHIuc3RhdHVzfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHBhcnNlUmVzcG9uc2VUZXh0KHhocikge1xyXG5cdGlmIChpc1Jlc3BvbnNlSnNvbih4aHIpKVxyXG5cdFx0cmV0dXJuIEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCk7XHJcblx0ZWxzZVxyXG5cdFx0cmV0dXJuIHhoci5yZXNwb25zZVRleHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzUmVzcG9uc2VKc29uKHhocikge1xyXG5cdHZhciBjb250ZW50VHlwZSA9IHhoci5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJyk7XHJcblx0cmV0dXJuIGNvbnRlbnRUeXBlICYmIFxyXG5cdFx0ICAgKGNvbnRlbnRUeXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA9PT0gMCB8fCBjb250ZW50VHlwZS5pbmRleE9mKCd0ZXh0L2pzb24nKSA9PT0gMCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldEhlYWRlcnMoeGhyLCBoZWFkZXJzKSB7XHJcblx0aWYgKCFoZWFkZXJzKVxyXG5cdFx0cmV0dXJuO1xyXG5cdHZhciBoZWFkZXJOYW1lcyA9IE9iamVjdC5rZXlzKGhlYWRlcnMpO1xyXG5cdGZvciAodmFyIGkgPSAwOyBpIDwgaGVhZGVyTmFtZXMubGVuZ3RoOyArK2kpIHtcclxuXHRcdHZhciBoZWFkZXJOYW1lID0gaGVhZGVyTmFtZXNbaV07XHJcblx0XHR4aHIuc2V0UmVxdWVzdEhlYWRlcihoZWFkZXJOYW1lLCBoZWFkZXJzW2hlYWRlck5hbWVdKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVF1ZXJ5UGFyYW1zKG9iaikge1xyXG5cdHZhciBzdHIgPSBbXTtcclxuXHRmb3IodmFyIHAgaW4gb2JqKXtcclxuXHQgICBpZiAob2JqLmhhc093blByb3BlcnR5KHApKSB7XHJcblx0ICAgICAgIHN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwKSArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KG9ialtwXSkpO1xyXG5cdCAgIH1cclxuXHR9XHJcblx0cmV0dXJuIHN0ci5qb2luKFwiJlwiKTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlRGVmZXJyZWQoKSB7XHJcblx0dmFyIHJlc29sdmUsIHJlamVjdDtcclxuXHR2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKF9yZXNvbHZlLCBfcmVqZWN0KSB7XHJcblx0XHRyZXNvbHZlID0gX3Jlc29sdmU7XHJcblx0XHRyZWplY3QgPSBfcmVqZWN0O1xyXG5cdH0pO1xyXG5cdHJldHVybiB7XHJcblx0XHRwcm9taXNlOiBwcm9taXNlLFxyXG5cdFx0cmVqZWN0OiByZWplY3QsXHJcblx0XHRyZXNvbHZlOiByZXNvbHZlXHJcblx0fTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBIdHRwO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NzLXNkay9odHRwLmpzXG4vLyBtb2R1bGUgaWQgPSAxMjlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIEJvdHRsZSA9IHJlcXVpcmUoJ2JvdHRsZWpzJyk7XHJcbnZhciBib3R0bGUgPSBuZXcgQm90dGxlKCk7XHJcblxyXG5ib3R0bGUuZmFjdG9yeSgnQ2xvdWRTaGFyZUNsaWVudCcsIGZ1bmN0aW9uKCkgeyByZXR1cm4gcmVxdWlyZSgnLi4vY3Mtc2RrJyk7IH0pO1xyXG5ib3R0bGUuc2VydmljZSgnU3lta2V5U2VydmljZScsIHJlcXVpcmUoJy4vc3lta2V5LXNlcnZpY2UnKSk7XHJcbmJvdHRsZS5zZXJ2aWNlKCdLZXlTdHJva2VzU2VydmljZScsIHJlcXVpcmUoJy4va2V5LXN0cm9rZXMtc2VydmljZScpLCAnU3lta2V5U2VydmljZScpO1xyXG5ib3R0bGUuc2VydmljZSgnR3VhY2Ftb2xlQ2xpZW50RmFjdG9yeScsIHJlcXVpcmUoJy4vZ3VhY2Ftb2xlLWNsaWVudC1mYWN0b3J5JykpO1xyXG5ib3R0bGUuc2VydmljZSgnQ2xvdWRTaGFyZUd1YWNhbW9sZScsIHJlcXVpcmUoJy4vY2xvdWRzaGFyZS1ndWFjYW1vbGUnKSwgJ0d1YWNhbW9sZUNsaWVudEZhY3RvcnknLCAnQ2xvdWRTaGFyZUNsaWVudCcsICdLZXlTdHJva2VzU2VydmljZScpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBib3R0bGU7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9ib3R0bGUuanNcbi8vIG1vZHVsZSBpZCA9IDEzMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgUHJvbWlzZSA9IHJlcXVpcmUoJ2VzNi1wcm9taXNlJykuUHJvbWlzZTtcclxudmFyIEd1YWNhbW9sZVN0YXRlcyA9IHJlcXVpcmUoJy4vZ3VhY2Ftb2xlLXN0YXRlcycpO1xyXG52YXIgQ29udHJvbFN5bWtleXMgPSByZXF1aXJlKCcuL2NvbnRyb2wtc3lta2V5cycpO1xyXG5cclxuZnVuY3Rpb24gQ2xvdWRTaGFyZUd1YWNhbW9sZShndWFjYW1vbGVDbGllbnRGYWN0b3J5LCBjc2NsaWVudCwga2V5U3Ryb2tlc1NlcnZpY2UpIHtcclxuXHR0aGlzLmd1YWNhbW9sZUNsaWVudEZhY3RvcnkgPSBndWFjYW1vbGVDbGllbnRGYWN0b3J5O1xyXG5cdHRoaXMuY3NjbGllbnQgPSBjc2NsaWVudDtcclxuXHR0aGlzLmtleVN0cm9rZXNTZXJ2aWNlID0ga2V5U3Ryb2tlc1NlcnZpY2U7XHJcblx0dGhpcy5ndWFjYW1vbGVDbGllbnRzID0ge307XHJcblx0dGhpcy5TVEFURVMgPSBHdWFjYW1vbGVTdGF0ZXM7XHJcbn1cclxuXHJcbi8qXHJcblx0b3B0aW9ucyA9IHtcclxuXHRcdGlkLFxyXG5cdFx0dXJsLFxyXG5cdFx0Y29udGFpbmVyRWxlbWVudCxcclxuXHRcdGNvbm5lY3Rpb25Db25maWd1cmF0aW9uLFxyXG5cdFx0Y2xvdWRTaGFyZUhvc3RuYW1lLFxyXG5cdFx0W2FwaUlkXSxcclxuXHRcdFthcGlLZXldLFxyXG5cdFx0W29uc3RhdGVjaGFuZ2VdLFxyXG5cdFx0W29uZXJyb3JdLFxyXG5cdFx0W29uY2xpcGJvYXJkXSxcclxuXHRcdFtvbnJlc2l6ZV0sXHJcblx0XHRbb25zeW5jXVxyXG5cdH1cclxuKi9cclxuQ2xvdWRTaGFyZUd1YWNhbW9sZS5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblx0cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcclxuXHRcdGNoZWNrT3B0aW9ucyhvcHRpb25zKTtcclxuXHRcdGlmICghaXNDbGllbnRDb25uZWN0ZWQoc2VsZiwgb3B0aW9ucy5pZCkpXHJcblx0XHRcdHJlc29sdmUocmVxdWVzdFBhc3N3b3JkQW5kQ29ubmVjdChzZWxmLCBvcHRpb25zKSk7XHJcblx0XHRlbHNlXHJcblx0XHRcdHJlc29sdmUoKTtcclxuXHR9KTtcclxufTtcclxuXHJcbkNsb3VkU2hhcmVHdWFjYW1vbGUucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbihpZCkge1xyXG5cdHZhciBzZWxmID0gdGhpcztcclxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xyXG5cdFx0dmFyIGNsaWVudCA9IHNlbGYuZ3VhY2Ftb2xlQ2xpZW50c1tpZF07XHJcblx0XHRpZiAoY2xpZW50KVxyXG5cdFx0XHRyZXNvbHZlKGNsaWVudC5kaXNjb25uZWN0KCkpO1xyXG5cdFx0ZWxzZVxyXG5cdFx0XHRyZXNvbHZlKCk7XHJcblx0fSk7XHJcbn07XHJcblxyXG5DbG91ZFNoYXJlR3VhY2Ftb2xlLnByb3RvdHlwZS5zZXRDbGlwYm9hcmQgPSBmdW5jdGlvbihpZCwgdGV4dCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdO1xyXG5cdGlmIChjbGllbnQpXHJcblx0XHRjbGllbnQuc2V0Q2xpcGJvYXJkKHRleHQpO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZUd1YWNhbW9sZS5wcm90b3R5cGUuc2VuZFRleHQgPSBmdW5jdGlvbihpZCwgdGV4dCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdO1xyXG5cdGlmICghY2xpZW50KVxyXG5cdFx0cmV0dXJuO1xyXG5cdHZhciBrcyA9IHRoaXMua2V5U3Ryb2tlc1NlcnZpY2UudG9LZXlTdHJva2VzKHRleHQpO1xyXG5cdHNlbmRLZXlTdHJva2VzKGNsaWVudCwga3MpO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZUd1YWNhbW9sZS5wcm90b3R5cGUuc2VuZEN0cmxBbHREZWxldGUgPSBmdW5jdGlvbihpZCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdO1xyXG5cdGlmICghY2xpZW50KVxyXG5cdFx0cmV0dXJuO1xyXG5cdHNlbmRLZXlTdHJva2VzKGNsaWVudCwgW1xyXG5cdFx0e2lzRG93bjogdHJ1ZSwgc3lta2V5OiBDb250cm9sU3lta2V5cy5DVFJMIH0sXHJcblx0XHR7aXNEb3duOiB0cnVlLCBzeW1rZXk6IENvbnRyb2xTeW1rZXlzLkFMVCB9LFxyXG5cdFx0e2lzRG93bjogdHJ1ZSwgc3lta2V5OiBDb250cm9sU3lta2V5cy5ERUxFVEUgfSxcclxuXHRcdHtpc0Rvd246IGZhbHNlLCBzeW1rZXk6IENvbnRyb2xTeW1rZXlzLkNUUkwgfSxcclxuXHRcdHtpc0Rvd246IGZhbHNlLCBzeW1rZXk6IENvbnRyb2xTeW1rZXlzLkFMVCB9LFxyXG5cdFx0e2lzRG93bjogZmFsc2UsIHN5bWtleTogQ29udHJvbFN5bWtleXMuREVMRVRFIH1cclxuXHRdKTtcclxufVxyXG5cclxuQ2xvdWRTaGFyZUd1YWNhbW9sZS5wcm90b3R5cGUuc2VuZFdpbmRvd3NLZXkgPSBmdW5jdGlvbihpZCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdO1xyXG5cdGlmICghY2xpZW50KVxyXG5cdFx0cmV0dXJuO1xyXG5cdHNlbmRLZXlTdHJva2VzKGNsaWVudCwgW1xyXG5cdFx0e2lzRG93bjogdHJ1ZSwgc3lta2V5OiBDb250cm9sU3lta2V5cy5XSU4gfSxcclxuXHRcdHtpc0Rvd246IGZhbHNlLCBzeW1rZXk6IENvbnRyb2xTeW1rZXlzLldJTiB9XHJcblx0XSk7XHJcbn1cclxuXHJcbkNsb3VkU2hhcmVHdWFjYW1vbGUucHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uKGlkLCB3aWR0aCwgaGVpZ2h0KSB7XHJcblx0dmFyIGNsaWVudCA9IHRoaXMuZ3VhY2Ftb2xlQ2xpZW50c1tpZF07XHJcblx0aWYgKGNsaWVudClcclxuXHRcdGNsaWVudC5yZXNpemUod2lkdGgsIGhlaWdodCk7XHJcbn07XHJcblxyXG5DbG91ZFNoYXJlR3VhY2Ftb2xlLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uKGlkLCBzY2FsZSkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdO1xyXG5cdGlmIChjbGllbnQpXHJcblx0XHRjbGllbnQuc2NhbGUoc2NhbGUpO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZUd1YWNhbW9sZS5wcm90b3R5cGUuZ2V0U2NhbGUgPSBmdW5jdGlvbihpZCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdO1xyXG5cdGlmIChjbGllbnQpXHJcblx0XHRyZXR1cm4gY2xpZW50LmdldFNjYWxlKCk7XHJcblx0ZWxzZVxyXG5cdFx0cmV0dXJuIDE7XHJcbn07XHJcblxyXG5DbG91ZFNoYXJlR3VhY2Ftb2xlLnByb3RvdHlwZS5nZXRTaGFyZVByb3RvY29sID0gZnVuY3Rpb24oaWQpIHtcclxuICAgIHZhciBjbGllbnQgPSB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdO1xyXG4gICAgaWYgKGNsaWVudClcclxuICAgICAgICByZXR1cm4gY2xpZW50LmdldFNoYXJlUHJvdG9jb2woKTtcclxuICAgIGVsc2VcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbkNsb3VkU2hhcmVHdWFjYW1vbGUucHJvdG90eXBlLmdldEZsYXR0ZW5lZENhbnZhcyA9IGZ1bmN0aW9uKGlkKSB7XHJcblx0dmFyIGNsaWVudCA9IHRoaXMuZ3VhY2Ftb2xlQ2xpZW50c1tpZF07XHJcblx0aWYgKGNsaWVudClcclxuXHRcdHJldHVybiBjbGllbnQuZ2V0RmxhdHRlbmVkQ2FudmFzKCk7XHJcbn07XHJcblxyXG5DbG91ZFNoYXJlR3VhY2Ftb2xlLnByb3RvdHlwZS5kaXNhYmxlSW5wdXRzID0gZnVuY3Rpb24oaWQpIHtcclxuXHR2YXIgY2xpZW50ID0gdGhpcy5ndWFjYW1vbGVDbGllbnRzW2lkXTtcclxuXHRpZiAoY2xpZW50KVxyXG5cdFx0cmV0dXJuIGNsaWVudC5kaXNhYmxlSW5wdXRzKCk7XHRcclxufTtcclxuXHJcbkNsb3VkU2hhcmVHdWFjYW1vbGUucHJvdG90eXBlLmVuYWJsZUlucHV0cyA9IGZ1bmN0aW9uKGlkKSB7XHJcblx0dmFyIGNsaWVudCA9IHRoaXMuZ3VhY2Ftb2xlQ2xpZW50c1tpZF07XHJcblx0aWYgKGNsaWVudClcclxuXHRcdHJldHVybiBjbGllbnQuZW5hYmxlSW5wdXRzKCk7XHRcclxufTtcclxuXHJcbkNsb3VkU2hhcmVHdWFjYW1vbGUucHJvdG90eXBlLmdldENvbm5lY3Rpb25UeXBlID0gZnVuY3Rpb24oaWQpIHtcclxuXHJcbiAgICBpZiAoaWQgPT09IG51bGwgfHwgaWQgPT09IHVuZGVmaW5lZCB8fCAhKHRoaXMuZ3VhY2Ftb2xlQ2xpZW50c1tpZF0pKVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG5cclxuICAgIHJldHVybiB0aGlzLmd1YWNhbW9sZUNsaWVudHNbaWRdLmdldENvbm5lY3Rpb25UeXBlKCk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiByZXF1ZXN0UGFzc3dvcmRBbmRDb25uZWN0KHNlbGYsIG9wdGlvbnMpIHtcclxuXHRyZXR1cm4gcmVxdWVzdFBhc3N3b3JkKHNlbGYsIG9wdGlvbnMpXHJcblx0LnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuXHRcdHZhciBjbGllbnQgPSBnZXRPckNyZWF0ZUd1YWNhbW9sZUNsaWVudChzZWxmLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5jb250ZW50Lmhvc3QsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmNvbnRlbnQuaHR0cEZhbGxCYWNrSG9zdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuY29udGVudC5wcm90b2NvbCk7XHJcblx0XHRyZXR1cm4gY2xpZW50LmNvbm5lY3QocmVzcG9uc2UuY29udGVudC5rZXksIHJlc3BvbnNlLmNvbnRlbnQubm9kZSk7XHJcblx0fSlbJ2NhdGNoJ10oZnVuY3Rpb24ocmVzcG9uc2UpIHtcclxuXHRcdGlmIChvcHRpb25zLm9uZXJyb3IpXHJcblx0XHRcdG9wdGlvbnMub25lcnJvcihuZXcgRXJyb3IoXCJGYWlsZWQgdG8gYXV0aGVudGljYXRlXCIpKTtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNDbGllbnRDb25uZWN0ZWQoc2VsZiwgaWQpIHtcclxuXHR2YXIgY2xpZW50ID0gc2VsZi5ndWFjYW1vbGVDbGllbnRzW2lkXTtcclxuXHRpZiAoIWNsaWVudClcclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHRyZXR1cm4gY2xpZW50LmN1cnJlbnRTdGF0ZSA9PT0gR3VhY2Ftb2xlU3RhdGVzLkNPTk5FQ1RJTkcgfHxcclxuXHRcdFx0Y2xpZW50LmN1cnJlbnRTdGF0ZSA9PT0gR3VhY2Ftb2xlU3RhdGVzLldBSVRJTkcgfHxcclxuXHRcdFx0Y2xpZW50LmN1cnJlbnRTdGF0ZSA9PT0gR3VhY2Ftb2xlU3RhdGVzLkNPTk5FQ1RFRDtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0T3JDcmVhdGVHdWFjYW1vbGVDbGllbnQoc2VsZiwgb3B0aW9ucywgb3ZlcnJpZGVIb3N0bmFtZSwgb3ZlcnJpZGVIdHRwSG9zdG5hbWUsIHNoYXJlUHJvdG9jb2wpIHtcclxuXHRpZiAoIXNlbGYuZ3VhY2Ftb2xlQ2xpZW50c1tvcHRpb25zLmlkXSkge1xyXG5cdFx0dmFyIGNsaWVudCA9IHNlbGYuZ3VhY2Ftb2xlQ2xpZW50c1tvcHRpb25zLmlkXSA9IGNyZWF0ZUd1YWNhbW9sZUNsaWVudChzZWxmLCBvcHRpb25zLCBvdmVycmlkZUhvc3RuYW1lLCBvdmVycmlkZUh0dHBIb3N0bmFtZSwgc2hhcmVQcm90b2NvbCk7XHJcblx0XHRzZWxmLmxhc3RVc2VkSG9zdE5hbWUgID0gY2xpZW50Lmhvc3RuYW1lO1xyXG5cdFx0b3B0aW9ucy5jb250YWluZXJFbGVtZW50LmFwcGVuZENoaWxkKGNsaWVudC5nZXRFbGVtZW50KCkpO1xyXG5cdH1cclxuXHRyZXR1cm4gc2VsZi5ndWFjYW1vbGVDbGllbnRzW29wdGlvbnMuaWRdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVHdWFjYW1vbGVDbGllbnQoc2VsZiwgb3B0aW9ucywgb3ZlcnJpZGVIb3N0bmFtZSwgb3ZlcnJpZGVIdHRwSG9zdG5hbWUsIHNoYXJlUHJvdG9jb2wpIHtcclxuXHRyZXR1cm4gc2VsZi5ndWFjYW1vbGVDbGllbnRGYWN0b3J5LmdldENsaWVudCh7XHJcblx0XHRob3N0bmFtZTogb3ZlcnJpZGVIb3N0bmFtZSB8fCBvcHRpb25zLmhvc3RuYW1lLFxyXG5cdFx0aG9zdG5hbWVGb3JIdHRwZmFpbG92ZXI6IG92ZXJyaWRlSHR0cEhvc3RuYW1lIHx8IG9wdGlvbnMuaG9zdG5hbWVGb3JIdHRwZmFpbG92ZXIsXHJcbiAgICAgICAgc2hhcmVQcm90b2NvbDogc2hhcmVQcm90b2NvbCxcclxuXHRcdG5vdFNlY3VyZTogISFvcHRpb25zLm5vdFNlY3VyZSxcclxuXHRcdG9uc3RhdGVjaGFuZ2U6IG9wdGlvbnMub25zdGF0ZWNoYW5nZSB8fCBmdW5jdGlvbigpIHt9LFxyXG5cdFx0b25lcnJvcjogb3B0aW9ucy5vbmVycm9yIHx8IGZ1bmN0aW9uKCkge30sXHJcblx0XHRvbmNsaXBib2FyZDogb3B0aW9ucy5vbmNsaXBib2FyZCB8fCBmdW5jdGlvbigpIHt9LFxyXG5cdFx0b25yZXNpemU6IG9wdGlvbnMub25yZXNpemUgfHwgZnVuY3Rpb24oKSB7fSxcclxuICAgICAgICBlbmFibGVodHRwZmFpbG92ZXI6IG9wdGlvbnMuZW5hYmxlaHR0cGZhaWxvdmVyICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmVuYWJsZWh0dHBmYWlsb3ZlciA6IGZhbHNlLFxyXG5cdFx0b25zeW5jOiBvcHRpb25zLm9uc3luYyB8fCBmdW5jdGlvbigpIHt9LFxyXG5cdFx0b25sb2dzeW5jOiBvcHRpb25zLm9ubG9nc3luYyB8fCBmdW5jdGlvbigpIHt9LFxyXG5cdFx0b25odHRwZmFsbGJhY2s6IG9wdGlvbnMub25odHRwZmFsbGJhY2sgfHwgZnVuY3Rpb24oKSB7fSxcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVxdWVzdFBhc3N3b3JkKHNlbGYsIG9wdGlvbnMpIHtcclxuXHRyZXR1cm4gc2VsZi5jc2NsaWVudC5yZXEoe1xyXG5cdFx0aG9zdG5hbWU6IG9wdGlvbnMuY2xvdWRTaGFyZUhvc3RuYW1lLFxyXG5cdFx0bWV0aG9kOiAnUE9TVCcsXHJcblx0XHRwYXRoOiAnR3VhY2Ftb2xlQ29ubmVjdGlvbicsXHJcblx0XHRhcGlJZDogb3B0aW9ucy5hcGlJZCxcclxuXHRcdGFwaUtleTogb3B0aW9ucy5hcGlLZXksXHJcblx0XHRjb250ZW50OiBvcHRpb25zLmNvbm5lY3Rpb25Db25maWd1cmF0aW9uXHJcblx0fSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNoZWNrT3B0aW9ucyhvcHRpb25zKSB7XHJcblx0aWYgKCFvcHRpb25zKVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIG9wdGlvbnMnKTtcclxuXHRlbHNlIGlmIChvcHRpb25zLmlkICE9PSAwICYmICFvcHRpb25zLmlkKVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIElEIHBhcmFtZXRlcicpO1xyXG5cdGVsc2UgaWYgKCFvcHRpb25zLmhvc3RuYW1lKVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGhvc3RuYW1lIHBhcmFtZXRlcicpO1xyXG5cdGVsc2UgaWYgKCFvcHRpb25zLmNvbnRhaW5lckVsZW1lbnQpXHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgY29udGFpbmVyRWxlbWVudCBwYXJhbWV0ZXInKTtcclxuXHRlbHNlIGlmICghb3B0aW9ucy5jb25uZWN0aW9uQ29uZmlndXJhdGlvbilcclxuXHRcdHRocm93IG5ldyBFcnJvcignTWlzc2luZyBjb25uZWN0aW9uQ29uZmlndXJhdGlvbiBwYXJhbWV0ZXInKTtcclxuXHRlbHNlIGlmICghb3B0aW9ucy5jbG91ZFNoYXJlSG9zdG5hbWUpXHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgY2xvdWRTaGFyZUhvc3RuYW1lIHBhcmFtZXRlcicpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZW5kS2V5U3Ryb2tlcyhjbGllbnQsIGtleVN0cm9rZXMpIHtcclxuXHRmb3IgKHZhciBpID0gMDsgaSA8IGtleVN0cm9rZXMubGVuZ3RoOyArK2kpIHtcclxuXHRcdHZhciBrID0ga2V5U3Ryb2tlc1tpXTtcclxuXHRcdGlmIChrLmlzRG93bilcclxuXHRcdFx0Y2xpZW50LnNlbmRTeW1rZXlEb3duKGsuc3lta2V5KTtcclxuXHRcdGVsc2VcclxuXHRcdFx0Y2xpZW50LnNlbmRTeW1rZXlVcChrLnN5bWtleSk7XHJcblx0fVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IENsb3VkU2hhcmVHdWFjYW1vbGU7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9jbG91ZHNoYXJlLWd1YWNhbW9sZS5qc1xuLy8gbW9kdWxlIGlkID0gMTMxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBHdWFjYW1vbGVDbGllbnQgPSByZXF1aXJlKCcuL2d1YWNhbW9sZS1jbGllbnQnKTtcclxuXHJcbmZ1bmN0aW9uIEd1YWNhbW9sZUNsaWVudEZhY3RvcnkoKSB7XHJcblxyXG59XHJcblxyXG4vKlxyXG5cdG9wdGlvbnMgPSB7XHJcblx0XHR1cmwsXHJcblx0XHRbb25zdGF0ZWNoYW5nZSxdXHJcblx0XHRbb25jbGlwYm9hcmQsXVxyXG5cdFx0W29uZXJyb3JdXHJcblx0fVxyXG4qL1xyXG5HdWFjYW1vbGVDbGllbnRGYWN0b3J5LnByb3RvdHlwZS5nZXRDbGllbnQgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcblx0dmFyIGNsaWVudCA9IG5ldyBHdWFjYW1vbGVDbGllbnQob3B0aW9ucyk7XHJcblx0Y2xpZW50LnNldHVwKCk7XHJcblx0cmV0dXJuIGNsaWVudDtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gR3VhY2Ftb2xlQ2xpZW50RmFjdG9yeTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9ndWFjYW1vbGUtY2xpZW50L2d1YWNhbW9sZS1jbGllbnQtZmFjdG9yeS5qc1xuLy8gbW9kdWxlIGlkID0gMTMyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBHdWFjYW1vbGUgPSByZXF1aXJlKCcuL2d1YWNhbW9sZS1jb21tb24tanMtMWMwZWU0MScpO1xyXG52YXIgR3VhY2Ftb2xlU3RhdGVzID0gcmVxdWlyZSgnLi9ndWFjYW1vbGUtc3RhdGVzJyk7XHJcbnZhciBHdWFjYW1vbGVFcnJvciA9IHJlcXVpcmUoXCIuL2d1YWNhbW9sZS1lcnJvclwiKTtcclxudmFyIFByb21pc2UgPSByZXF1aXJlKCdlczYtcHJvbWlzZScpLlByb21pc2U7XHJcbnZhciB3ZWJwRGV0ZWN0ID0gcmVxdWlyZShcIi4vd2VicC1kZXRlY3RcIik7XHJcblxyXG52YXIgR3VhY2Ftb2xlX0Rpc2Nvbm5lY3RlZF9FdmVudF9JZCA9IDU7XHJcblxyXG4vKlxyXG5cdG9wdGlvbnMgPSB7XHJcblx0XHRob3N0bmFtZSxcclxuXHRcdFtub3RTZWN1cmVdLFxyXG5cdFx0W29uc3RhdGVjaGFuZ2UsXVxyXG5cdFx0W29uY2xpcGJvYXJkLF1cclxuXHRcdFtvbmVycm9yXVxyXG5cdH1cclxuKi9cclxuZnVuY3Rpb24gR3VhY2Ftb2xlQ2xpZW50KG9wdGlvbnMpIHtcclxuXHRjaGVja09wdGlvbnMob3B0aW9ucyk7XHJcblx0dGhpcy50dW5uZWwgPSBudWxsO1xyXG5cdHRoaXMuY2xpZW50ID0gbnVsbDtcclxuXHR0aGlzLmVsZW1lbnQgPSBudWxsO1xyXG5cdHRoaXMua2V5Ym9hcmQgPSBudWxsO1xyXG5cdHRoaXMubW91c2UgPSBudWxsO1xyXG5cdHRoaXMuaG9zdG5hbWUgPSBvcHRpb25zLmhvc3RuYW1lO1xyXG5cdHRoaXMubm90U2VjdXJlID0gb3B0aW9ucy5ub3RTZWN1cmU7XHJcblx0dGhpcy5vbnN0YXRlY2hhbmdlID0gb3B0aW9ucy5vbnN0YXRlY2hhbmdlIHx8IGZ1bmN0aW9uKCkge307XHJcblx0dGhpcy5vbmNsaXBib2FyZCA9IG9wdGlvbnMub25jbGlwYm9hcmQgfHwgZnVuY3Rpb24oKSB7fTtcclxuXHR0aGlzLm9uZXJyb3IgPSBvcHRpb25zLm9uZXJyb3IgfHwgZnVuY3Rpb24oKSB7fTtcclxuXHR0aGlzLm9ucmVzaXplID0gb3B0aW9ucy5vbnJlc2l6ZSB8fCBmdW5jdGlvbigpIHt9O1xyXG5cdHRoaXMub25zeW5jID0gb3B0aW9ucy5vbnN5bmMgfHwgZnVuY3Rpb24oKSB7fTtcclxuXHR0aGlzLm9ubG9nc3luYyA9IG9wdGlvbnMub25sb2dzeW5jIHx8IGZ1bmN0aW9uKCkge307XHJcblx0dGhpcy5vbmh0dHBmYWxsYmFjayA9IG9wdGlvbnMub25odHRwZmFsbGJhY2sgfHwgZnVuY3Rpb24oKSB7fTtcclxuXHR0aGlzLmNvbm5lY3RlZE9uSHR0cCA9IGZhbHNlO1xyXG5cdHRoaXMuY3VycmVudFN0YXRlID0gR3VhY2Ftb2xlU3RhdGVzLklETEU7XHJcblx0dGhpcy5yZXNvbHZlRGlzY29ubmVjdCA9IG51bGw7XHJcblx0dGhpcy5yZXNvbHZlQ29ubmVjdCA9IG51bGw7XHJcblx0dGhpcy5yZWplY3RDb25uZWN0ID0gbnVsbDtcclxuXHR0aGlzLmlucHV0c0Rpc2FibGVkID0gZmFsc2U7XHJcblx0dGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcclxuXHR0aGlzLmxhc3RFcnJvciA9IG51bGw7XHJcblx0dGhpcy5ob3N0bmFtZUZvckh0dHBmYWlsb3ZlciA9IG9wdGlvbnMuaG9zdG5hbWVGb3JIdHRwZmFpbG92ZXIgfHwgb3B0aW9ucy5ob3N0bmFtZTtcclxuXHR0aGlzLnNoYXJlUHJvdG9jb2wgPSBvcHRpb25zLnNoYXJlUHJvdG9jb2w7XHJcbiAgICB0aGlzLmlzV2VicFN1cHBvcnRlZCA9IHdlYnBEZXRlY3QuaXNXZWJwU3VwcG9ydGVkO1xyXG5cdHRoaXMuc3luY1RpbWluZ3MgPSBjcmVhdGVTeW5jVGltaW5nc09iamVjdCgpO1xyXG5cdHRoaXMuYmVmb3JlVW5sb2FkSGFuZGxlciA9IG51bGw7XHJcbn1cclxuXHJcbkd1YWNhbW9sZUNsaWVudC5wcm90b3R5cGUuc2V0dXAgPSBmdW5jdGlvbigpIHtcclxuICAgIHRoaXMud3NUdW5uZWwxID0gbmV3IEd1YWNhbW9sZS5XZWJTb2NrZXRUdW5uZWwoY3JlYXRlVXJsKHRoaXMubm90U2VjdXJlLCB0aGlzLmhvc3RuYW1lKSk7XHJcbiAgICB0aGlzLndzVHVubmVsMiA9IG5ldyBHdWFjYW1vbGUuV2ViU29ja2V0VHVubmVsKGNyZWF0ZVVybCh0aGlzLm5vdFNlY3VyZSwgdGhpcy5ob3N0bmFtZSkpO1xyXG4gICAgdGhpcy5odHRwVHVubmVsID0gbmV3IEd1YWNhbW9sZS5IVFRQVHVubmVsKGNyZWF0ZUh0dHBzVXJsKHRoaXMubm90U2VjdXJlLCB0aGlzLmhvc3RuYW1lRm9ySHR0cGZhaWxvdmVyKSwgdHJ1ZSk7XHJcblx0XHJcblxyXG5cdHZhciBvblN0YXRlQ2hhbmdlSGFuZGxlciA9IHRoaXMub25zdGF0ZWNoYW5nZTtcclxuXHJcblx0dGhpcy50dW5uZWwgPSBuZXcgR3VhY2Ftb2xlLkNoYWluZWRUdW5uZWwodGhpcy53c1R1bm5lbDEsIHRoaXMud3NUdW5uZWwyLCB0aGlzLmh0dHBUdW5uZWwpO1xyXG5cclxuXHR0aGlzLmNsaWVudCA9IG5ldyBHdWFjYW1vbGUuQ2xpZW50KHRoaXMudHVubmVsKTtcclxuXHJcbiAgICBzZXRDbGllbnRIYW5kbGVycyh0aGlzKTtcclxuXHR0aGlzLmVsZW1lbnQgPSBjcmVhdGVFbGVtZW50KHRoaXMuY2xpZW50KTtcclxuICAgIHRoaXMua2V5Ym9hcmQgPSBjcmVhdGVHdWFjYW1vbGVLZXlib2FyZCh0aGlzLCB0aGlzLmVsZW1lbnQsIHRoaXMuY2xpZW50KTtcclxuICAgIHRoaXMubW91c2UgPSBjcmVhdGVHdWFjYW1vbGVNb3VzZSh0aGlzLCB0aGlzLmNsaWVudCk7XHJcbiAgICB0aGlzLmNsaWVudC5nZXREaXNwbGF5KCkub25yZXNpemUgPSB0aGlzLm9ucmVzaXplO1xyXG4gICAgdHJ5RW5hYmxpbmdIYXJkd2FyZU1vdXNlQ3Vyc29yKHRoaXMpO1xyXG4gICAgc2V0RGlzY29ubmVjdE9uQmVmb3JlVW5sb2FkKHRoaXMpO1xyXG59O1xyXG5cclxuZnVuY3Rpb24gdHJ5RW5hYmxpbmdIYXJkd2FyZU1vdXNlQ3Vyc29yKHNlbGYpIHtcclxuXHRzZWxmLmNsaWVudC5nZXREaXNwbGF5KCkub25jdXJzb3IgPSBmdW5jdGlvbihjYW52YXMsIHgsIHkpIHtcclxuXHRcdHNlbGYuY2xpZW50LmdldERpc3BsYXkoKS5zaG93Q3Vyc29yKCFzZWxmLm1vdXNlLnNldEN1cnNvcihjYW52YXMsIHgsIHkpKTtcclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVVcmwobm90U2VjdXJlLCBob3N0bmFtZSkge1xyXG5cdHJldHVybiAobm90U2VjdXJlID8gXCJ3czovL1wiIDogXCJ3c3M6Ly9cIikgKyBob3N0bmFtZSArIFwiL2Nsb3Vkc2hhcmUtZ3VhY2Ftb2xlL3dlYnNvY2tldC10dW5uZWxcIjtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlSHR0cHNVcmwobm90U2VjdXJlLCBob3N0bmFtZSkge1xyXG4gICAgcmV0dXJuIChub3RTZWN1cmUgPyBcImh0dHA6Ly9cIiA6IFwiaHR0cHM6Ly9cIikgKyBob3N0bmFtZSArIFwiL2Nsb3Vkc2hhcmUtZ3VhY2Ftb2xlL3R1bm5lbFwiO1xyXG59XHJcblxyXG5HdWFjYW1vbGVDbGllbnQucHJvdG90eXBlLmdldENvbm5lY3Rpb25UeXBlID0gZnVuY3Rpb24oKXtcclxuXHJcbiAgICBpZiAoICh0aGlzLndzVHVubmVsMS5zdGF0ZSAmJiB0aGlzLndzVHVubmVsMS5zdGF0ZSA9PSAxKSB8fCAodGhpcy53c1R1bm5lbDIuc3RhdGUgJiYgdGhpcy53c1R1bm5lbDIuc3RhdGUgPT0gMSkpXHJcbiAgICAgICAgcmV0dXJuICdXZWJTb2NrZXQnO1xyXG5cclxuICAgIGlmICh0aGlzLmh0dHBUdW5uZWwuc3RhdGUgJiYgdGhpcy5odHRwVHVubmVsLnN0YXRlID09IDEpXHJcbiAgICAgICAgcmV0dXJuICdIVFRQJztcclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxufVxyXG5cclxuR3VhY2Ftb2xlQ2xpZW50LnByb3RvdHlwZS5nZXRUdW5uZWxzRGF0YSA9IGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiB7XHJcblx0XHR3c1R1bm5lbDE6IHRoaXMud3NUdW5uZWwxLnN0YXRlLFxyXG5cdFx0d3NUdW5uZWwyOiB0aGlzLndzVHVubmVsMi5zdGF0ZSxcclxuXHRcdGh0dHBUdW5uZWw6IHRoaXMuaHR0cFR1bm5lbC5zdGF0ZVxyXG5cdH07XHJcbn07XHJcblxyXG5HdWFjYW1vbGVDbGllbnQucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbihwYXNzd29yZCwgbm9kZSkge1xyXG5cdHZhciBzZWxmID0gdGhpcztcclxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XHJcblx0XHRzZWxmLnJlc29sdmVDb25uZWN0ID0gcmVzb2x2ZTtcclxuXHRcdHNlbGYucmVqZWN0Q29ubmVjdCA9IHJlamVjdDtcclxuICAgICAgICBpZiAobm9kZSlcclxuICAgICAgICAgICAgc2VsZi5jbGllbnQuY29ubmVjdChcInRva2VuPVwiICsgcGFzc3dvcmQgKyBcIiZub2RlPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KG5vZGUpICsgXCImd2VicD1cIiArIHNlbGYuaXNXZWJwU3VwcG9ydGVkKTtcclxuICAgICAgICBlbHNlXHJcblx0XHQgICAgc2VsZi5jbGllbnQuY29ubmVjdChcInRva2VuPVwiICsgcGFzc3dvcmQgKyBcIiZ3ZWJwPVwiICsgc2VsZi5pc1dlYnBTdXBwb3J0ZWQpO1xyXG5cdH0pO1xyXG59O1xyXG5cclxuR3VhY2Ftb2xlQ2xpZW50LnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIHNlbGYgPSB0aGlzO1xyXG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XHJcblx0XHRpZiAoc2VsZi5jdXJyZW50U3RhdGUgPT09IEd1YWNhbW9sZVN0YXRlcy5ESVNDT05ORUNURUQgfHwgc2VsZi5jdXJyZW50U3RhdGUgPT09IEd1YWNhbW9sZVN0YXRlcy5ESVNDT05ORUNUSU5HKXtcclxuXHRcdFx0cmVzb2x2ZSgpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c2VsZi5yZXNvbHZlRGlzY29ubmVjdCA9IHJlc29sdmU7XHJcblx0XHRcdHNlbGYuY2xpZW50LmRpc2Nvbm5lY3QoKTtcclxuXHRcdH1cclxuXHR9KTtcclxufTtcclxuXHJcbkd1YWNhbW9sZUNsaWVudC5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCkge1xyXG5cdHRoaXMuY2xpZW50LnNlbmRTaXplKHdpZHRoLCBoZWlnaHQpO1xyXG59O1xyXG5cclxuR3VhY2Ftb2xlQ2xpZW50LnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uKHNjYWxlKSB7XHJcblx0dGhpcy5jbGllbnQuZ2V0RGlzcGxheSgpLnNjYWxlKHNjYWxlKTtcclxufTtcclxuXHJcbkd1YWNhbW9sZUNsaWVudC5wcm90b3R5cGUuc2V0Q2xpcGJvYXJkID0gZnVuY3Rpb24odGV4dCkge1xyXG5cdHRoaXMuY2xpZW50LnNldENsaXBib2FyZCh0ZXh0KTtcclxufTtcclxuXHJcbkd1YWNhbW9sZUNsaWVudC5wcm90b3R5cGUuc2VuZFN5bWtleVVwID0gZnVuY3Rpb24oc3lta2V5KSB7XHJcblx0dGhpcy5jbGllbnQuc2VuZEtleUV2ZW50KDAsIHN5bWtleSk7XHJcbn07XHJcblxyXG5HdWFjYW1vbGVDbGllbnQucHJvdG90eXBlLnNlbmRTeW1rZXlEb3duID0gZnVuY3Rpb24oc3lta2V5KSB7XHJcblx0dGhpcy5jbGllbnQuc2VuZEtleUV2ZW50KDEsIHN5bWtleSk7XHJcbn07XHJcblxyXG5HdWFjYW1vbGVDbGllbnQucHJvdG90eXBlLmdldEVsZW1lbnQgPSBmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcy5lbGVtZW50O1xyXG59O1xyXG5cclxuR3VhY2Ftb2xlQ2xpZW50LnByb3RvdHlwZS5nZXRGbGF0dGVuZWRDYW52YXMgPSBmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcy5jbGllbnQuZ2V0RGlzcGxheSgpLmZsYXR0ZW4oKTtcclxufTtcclxuXHJcbkd1YWNhbW9sZUNsaWVudC5wcm90b3R5cGUuZ2V0U2NhbGUgPSBmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcy5jbGllbnQuZ2V0RGlzcGxheSgpLmdldFNjYWxlKCk7XHJcbn07XHJcblxyXG5HdWFjYW1vbGVDbGllbnQucHJvdG90eXBlLmdldFNoYXJlUHJvdG9jb2wgPSBmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcy5zaGFyZVByb3RvY29sIHx8IG51bGw7XHJcbn07XHJcblxyXG5HdWFjYW1vbGVDbGllbnQucHJvdG90eXBlLmRpc2FibGVJbnB1dHMgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmlucHV0c0Rpc2FibGVkID0gdHJ1ZTtcclxufTtcclxuXHJcbkd1YWNhbW9sZUNsaWVudC5wcm90b3R5cGUuZW5hYmxlSW5wdXRzID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5pbnB1dHNEaXNhYmxlZCA9IGZhbHNlO1xyXG59O1xyXG5cclxuZnVuY3Rpb24gY2hlY2tPcHRpb25zKG9wdGlvbnMpIHtcclxuXHRpZiAoIW9wdGlvbnMpXHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgb3B0aW9ucyBvYmplY3QgcGFyYW1ldGVyJyk7XHJcblx0aWYgKCFvcHRpb25zLmhvc3RuYW1lKVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGhvc3RuYW1lIHBhcmFtZXRlcicpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KGNsaWVudCwgb3B0aW9ucykge1xyXG5cdHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcblx0ZWxlbWVudC5hcHBlbmRDaGlsZChjbGllbnQuZ2V0RGlzcGxheSgpLmdldEVsZW1lbnQoKSk7XHJcblx0ZWxlbWVudC5hcHBlbmRDaGlsZChjcmVhdGVUZXh0QXJlYSgpKTtcdFxyXG5cdFxyXG5cdHJldHVybiBlbGVtZW50O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVUZXh0QXJlYSgpIHtcclxuXHR2YXIgdGV4dGFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xyXG5cdHRleHRhcmVhLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xyXG5cdHRleHRhcmVhLnN0eWxlLnRvcCA9ICcwcHgnO1xyXG5cdHRleHRhcmVhLnN0eWxlLmxlZnQgPSAnLTk5OTk5OXB4JztcclxuXHRyZXR1cm4gdGV4dGFyZWE7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZVN5bmNUaW1pbmdzKHNlbGYpIHtcclxuXHR2YXIgdCA9ICtuZXcgRGF0ZSgpO1xyXG5cdHZhciBjID0gc2VsZi5zeW5jVGltaW5ncy5jb3VudDtcclxuXHR2YXIgYSA9IHNlbGYuc3luY1RpbWluZ3MuaW50ZXJ2YWxBdmVyYWdlO1xyXG5cdHZhciBhMiA9IHNlbGYuc3luY1RpbWluZ3MuaW50ZXJ2YWxBdmVyYWdlMjtcclxuXHR2YXIgZHQgPSB0IC0gc2VsZi5zeW5jVGltaW5ncy5sYXN0VGltZTtcclxuXHR2YXIgZHQyID0gZHQgKiBkdDtcclxuXHRhID0gKGR0ICsgYyAqIGEpIC8gKGMgKyAxKTtcclxuXHRhMiA9IChkdDIgKyBjICogYTIpIC8gKGMgKyAxKTtcclxuXHJcblx0c2VsZi5zeW5jVGltaW5ncy5sYXN0VGltZSA9IHQ7XHJcblx0c2VsZi5zeW5jVGltaW5ncy5sYXN0RGVsdGFUaW1lID0gZHQ7XHJcblx0c2VsZi5zeW5jVGltaW5ncy5jb3VudCArPSAxO1xyXG5cdHNlbGYuc3luY1RpbWluZ3MuaW50ZXJ2YWxBdmVyYWdlID0gYTtcclxuXHRzZWxmLnN5bmNUaW1pbmdzLmludGVydmFsQXZlcmFnZTIgPSBhMjtcclxuXHRzZWxmLnN5bmNUaW1pbmdzLmludGVydmFsU3RhbmRhcmREZXZpYXRpb24gPSBNYXRoLnNxcnQoYTIgLSBhKmEpO1xyXG5cclxuXHR2YXIgaXMgPSBPYmplY3Qua2V5cyhzZWxmLnN5bmNUaW1pbmdzLm1heEludGVydmFscyk7XHJcblx0aXMuZm9yRWFjaChmdW5jdGlvbihpKSB7XHJcblx0XHR2YXIgbWkgPSBzZWxmLnN5bmNUaW1pbmdzLm1heEludGVydmFsc1tpXTtcclxuXHRcdGlmIChkdCA+IG1pLnZhbHVlKVxyXG5cdFx0XHRtaS52YWx1ZSA9IGR0O1xyXG5cdH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzdGFydFN5bmNUaW1pbmdzTG9nKHNlbGYpIHtcclxuXHRzZWxmLnN5bmNUaW1pbmdzID0gY3JlYXRlU3luY1RpbWluZ3NPYmplY3QoKTtcclxuXHRzZWxmLmxvZ3N5bmNUaW1lb3V0SWQgPSBydW5JbnRlcnZhbCgpO1xyXG5cclxuXHRmdW5jdGlvbiBydW5JbnRlcnZhbCgpIHtcclxuXHRcdGlmIChzZWxmLmN1cnJlbnRTdGF0ZSAhPT0gR3VhY2Ftb2xlU3RhdGVzLkNPTk5FQ1RFRClcclxuXHRcdFx0cmV0dXJuO1xyXG5cclxuXHRcdHZhciBub3cgPSArbmV3IERhdGUoKTtcclxuXHRcdHZhciBsb2dQYXJhbWV0ZXJzID0ge1xyXG5cdFx0XHRpbnRlcnZhbEF2ZXJhZ2U6IHNlbGYuc3luY1RpbWluZ3MuaW50ZXJ2YWxBdmVyYWdlLFxyXG5cdFx0XHRpbnRlcnZhbFN0YW5kYXJkRGV2aWF0aW9uOiBzZWxmLnN5bmNUaW1pbmdzLmludGVydmFsU3RhbmRhcmREZXZpYXRpb24sXHJcblx0XHRcdG1heEludGVydmFsczoge31cclxuXHRcdH07XHJcblx0XHR2YXIgaXMgPSBPYmplY3Qua2V5cyhzZWxmLnN5bmNUaW1pbmdzLm1heEludGVydmFscyk7XHJcblx0XHRpcy5mb3JFYWNoKGZ1bmN0aW9uKGkpIHtcclxuXHRcdFx0dmFyIG1pID0gc2VsZi5zeW5jVGltaW5ncy5tYXhJbnRlcnZhbHNbaV07XHJcblx0XHRcdHZhciBpbnRlcnZhbE1zID0gaVtpLmxlbmd0aCAtIDFdID09IFwibVwiID8gcGFyc2VJbnQoaSkgKiA2MCAqIDEwMDAgOiBwYXJzZUludChpKSAqIDEwMDA7XHJcblx0XHRcdGlmIChub3cgLSBtaS50aW1lc3RhbXAgPj0gaW50ZXJ2YWxNcykge1xyXG5cdFx0XHRcdGxvZ1BhcmFtZXRlcnMubWF4SW50ZXJ2YWxzW2ldID0gbWkudmFsdWU7XHJcblx0XHRcdFx0bWkudmFsdWUgPSAwO1xyXG5cdFx0XHRcdG1pLnRpbWVzdGFtcCA9IG5vdztcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRzZWxmLm9ubG9nc3luYyhsb2dQYXJhbWV0ZXJzKTtcclxuXHRcdHJldHVybiBzZXRUaW1lb3V0KHJ1bkludGVydmFsLCBzZWxmLnN5bmNUaW1pbmdzLmdjZEludGVydmFsTXMpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gc3RvcFN5bmNUaW1pbmdzTG9nKHNlbGYpIHtcclxuXHRjbGVhclRpbWVvdXQoc2VsZi5sb2dzeW5jVGltZW91dElkKTtcclxuXHRzZWxmLmxvZ3N5bmNUaW1lb3V0SWQgPSAwO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVTeW5jVGltaW5nc09iamVjdCgpIHtcclxuXHR2YXIgbm93ID0gK25ldyBEYXRlKCk7XHJcblx0cmV0dXJuIHtcclxuXHRcdGxhc3RUaW1lOiBub3csXHJcblx0XHRjb3VudDogMCxcclxuXHRcdGludGVydmFsQXZlcmFnZTogMCxcclxuXHRcdGludGVydmFsQXZlcmFnZTI6IDAsXHJcblx0XHRpbnRlcnZhbFN0YW5kYXJkRGV2aWF0aW9uOiAwLFxyXG5cdFx0Z2NkSW50ZXJ2YWxNczogNjAwMDAsXHJcblx0XHRtYXhJbnRlcnZhbHM6IHtcclxuXHRcdFx0XCIxbVwiOiB7IHZhbHVlOiAwLCB0aW1lc3RhbXA6IG5vdyB9LFxyXG5cdFx0XHRcIjJtXCI6IHsgdmFsdWU6IDAsIHRpbWVzdGFtcDogbm93IH0sXHJcblx0XHRcdFwiNW1cIjogeyB2YWx1ZTogMCwgdGltZXN0YW1wOiBub3cgfSxcclxuXHRcdFx0XCIzMG1cIjogeyB2YWx1ZTogMCwgdGltZXN0YW1wOiBub3cgfVxyXG5cdFx0fVxyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldENsaWVudEhhbmRsZXJzKHNlbGYpIHtcclxuXHRzZXRPbkNsaXBib2FyZChzZWxmLmNsaWVudCwgc2VsZi5vbmNsaXBib2FyZCk7XHJcblx0c2VsZi5jbGllbnQub25zdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKHN0YXRlKSB7XHJcblx0XHRoYW5kbGVDbGllbnRTdGF0ZUNoYW5nZShzZWxmLCBzdGF0ZSk7XHJcblx0fTtcclxuXHRzZWxmLmNsaWVudC5vbmVycm9yID0gZXJyb3JIYW5kbGVyO1xyXG5cdHNlbGYudHVubmVsLm9uZXJyb3IgPSBlcnJvckhhbmRsZXI7XHJcblx0c2VsZi5jbGllbnQub25zeW5jID0gZnVuY3Rpb24oYXJnKSB7XHJcblx0XHRpZiAoc2VsZi5jdXJyZW50U3RhdGUgIT09IEd1YWNhbW9sZVN0YXRlcy5DT05ORUNURUQpXHJcblx0XHRcdHJldHVybjtcclxuXHRcdHVwZGF0ZVN5bmNUaW1pbmdzKHNlbGYpO1xyXG5cdFx0aWYgKHdpbmRvdy5wcmludFN5bmMpXHJcblx0XHRcdGNvbnNvbGUuaW5mbyhcImR0OiVkXFx0YXZnOiVkXCIsIHNlbGYuc3luY1RpbWluZ3MubGFzdERlbHRhVGltZSwgc2VsZi5zeW5jVGltaW5ncy5pbnRlcnZhbEF2ZXJhZ2UpO1xyXG5cdFx0c2VsZi5vbnN5bmMoYXJnLCBzZWxmLnN5bmNUaW1pbmdzKTtcclxuXHR9O1xyXG5cclxuXHRmdW5jdGlvbiBlcnJvckhhbmRsZXIoZXJyKSB7XHJcblx0XHRzZWxmLmxhc3RFcnJvciA9IGVycjtcclxuXHRcdHNlbGYub25lcnJvcihuZXcgR3VhY2Ftb2xlRXJyb3IoZXJyLCBzZWxmLmdldFR1bm5lbHNEYXRhKCkpKTtcclxuXHRcdHNlbGYuY2xpZW50LmRpc2Nvbm5lY3QoKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGhhbmRsZUNsaWVudFN0YXRlQ2hhbmdlKHNlbGYsIHN0YXRlKSB7XHJcblx0aWYgKHNlbGYuY3VycmVudFN0YXRlID09PSBzdGF0ZSlcclxuXHRcdHJldHVybjtcclxuXHRzZWxmLmN1cnJlbnRTdGF0ZSA9IHN0YXRlO1xyXG5cdHJlc29sdmVEaXNjb25uZWN0UHJvbWlzZUlmRGlzY29ubmVjdGVkQW5kUmVqZWN0Q29ubmVjdElmTm90Q29ubmVjdGVkKHNlbGYsIHN0YXRlKTtcclxuXHRyZXNvbHZlQ29ubmVjdFByb21pc2VJZkNvbm5lY3RlZChzZWxmLCBzdGF0ZSk7XHJcblx0aWYgKHNlbGYuY3VycmVudFN0YXRlID09PSBHdWFjYW1vbGVTdGF0ZXMuQ09OTkVDVEVEKVxyXG5cdFx0c3RhcnRTeW5jVGltaW5nc0xvZyhzZWxmKTtcclxuXHRlbHNlXHJcblx0XHRzdG9wU3luY1RpbWluZ3NMb2coc2VsZik7XHJcblxyXG5cdGVtaXRIdHRwRmFsbGJhY2tFdmVudChzZWxmKTtcclxuXHJcblx0c2VsZi5vbnN0YXRlY2hhbmdlKHN0YXRlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZW1pdEh0dHBGYWxsYmFja0V2ZW50KHNlbGYpIHtcclxuXHRpZiAoIXNlbGYuY29ubmVjdGVkT25IdHRwICYmXHJcblx0XHRzZWxmLmh0dHBUdW5uZWwuc3RhdGUgIT09IEd1YWNhbW9sZS5UdW5uZWwuU3RhdGUuQ09OTkVDVElORyAmJlxyXG5cdFx0KHNlbGYuY3VycmVudFN0YXRlID09PSBHdWFjYW1vbGVTdGF0ZXMuQ09OTkVDVEVEIHx8XHJcblx0XHQgc2VsZi5jdXJyZW50U3RhdGUgPT09IEd1YWNhbW9sZVN0YXRlcy5ESVNDT05ORUNURUQpKSB7XHJcblx0XHRcclxuXHRcdHNlbGYuY29ubmVjdGVkT25IdHRwID0gdHJ1ZTtcclxuXHRcdHNlbGYub25odHRwZmFsbGJhY2soKTtcclxuXHR9XHJcblxyXG5cdGlmIChzZWxmLmN1cnJlbnRTdGF0ZSA9PT0gR3VhY2Ftb2xlU3RhdGVzLkRJU0NPTk5FQ1RFRCkge1xyXG5cdFx0IHNlbGYuY29ubmVjdGVkT25IdHRwID0gZmFsc2U7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiByZXNvbHZlRGlzY29ubmVjdFByb21pc2VJZkRpc2Nvbm5lY3RlZEFuZFJlamVjdENvbm5lY3RJZk5vdENvbm5lY3RlZChzZWxmLCBzdGF0ZSkge1xyXG5cdGlmIChzdGF0ZSA9PT0gR3VhY2Ftb2xlU3RhdGVzLkRJU0NPTk5FQ1RFRCAmJiBzZWxmLnJlc29sdmVEaXNjb25uZWN0KSB7XHJcblx0XHRpZiAoIXNlbGYuY29ubmVjdGVkICYmIHNlbGYucmVqZWN0Q29ubmVjdClcclxuXHRcdFx0c2VsZi5yZWplY3RDb25uZWN0KHNlbGYubGFzdEVycm9yKTtcclxuXHRcdHNlbGYuY29ubmVjdGVkID0gZmFsc2U7XHJcblx0XHRzZWxmLnByZXZpb3VzRWxlbWVudERpc3BsYXlTdHlsZSA9IHNlbGYuZWxlbWVudC5zdHlsZS5kaXNwbGF5O1xyXG5cdFx0c2VsZi5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuXHRcdHNlbGYucmVzb2x2ZURpc2Nvbm5lY3QoKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlc29sdmVDb25uZWN0UHJvbWlzZUlmQ29ubmVjdGVkKHNlbGYsIHN0YXRlKSB7XHJcblx0aWYgKHN0YXRlID09PSBHdWFjYW1vbGVTdGF0ZXMuQ09OTkVDVEVEICYmIHNlbGYucmVzb2x2ZUNvbm5lY3QpIHtcclxuXHRcdHNlbGYuY29ubmVjdGVkID0gdHJ1ZTtcclxuXHRcdHNlbGYubGFzdEVycm9yID0gbnVsbDtcclxuXHRcdGlmIChzZWxmLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9PT0gXCJub25lXCIpXHJcblx0XHRcdHNlbGYuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gc2VsZi5wcmV2aW91c0VsZW1lbnREaXNwbGF5U3R5bGUgfHwgXCJcIjtcclxuXHRcdHNlbGYucmVzb2x2ZUNvbm5lY3QoKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldE9uQ2xpcGJvYXJkKGNsaWVudCwgb25jbGlwYm9hcmQpIHtcclxuXHRjbGllbnQub25jbGlwYm9hcmQgPSBmdW5jdGlvbihpbnB1dFN0cmVhbSkge1xyXG5cdFx0dmFyIHNyID0gbmV3IEd1YWNhbW9sZS5TdHJpbmdSZWFkZXIoaW5wdXRTdHJlYW0pO1xyXG4gICAgICAgIHNyLm9udGV4dCA9IGZ1bmN0aW9uKHRleHQpIHtcclxuXHRcdFx0b25jbGlwYm9hcmQodGV4dCk7XHJcbiAgICAgICAgfTtcclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVHdWFjYW1vbGVLZXlib2FyZChzZWxmLCBlbGVtZW50LCBjbGllbnQpIHtcclxuXHR2YXIgdGV4dGFyZWEgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3RleHRhcmVhJyk7XHJcblx0dmFyIGtleWJvYXJkID0gbmV3IEd1YWNhbW9sZS5LZXlib2FyZCh0ZXh0YXJlYSk7XHJcblx0a2V5Ym9hcmQub25rZXlkb3duID0gZnVuY3Rpb24oa2V5U3ltKSB7XHJcblx0XHRpZiAoIXNlbGYuaW5wdXRzRGlzYWJsZWQpXHJcblx0XHRcdGNsaWVudC5zZW5kS2V5RXZlbnQoMSwga2V5U3ltKTtcclxuXHR9O1xyXG5cdGtleWJvYXJkLm9ua2V5dXAgPSBmdW5jdGlvbihrZXlTeW0pIHtcclxuXHRcdGlmICghc2VsZi5pbnB1dHNEaXNhYmxlZClcclxuXHRcdFx0Y2xpZW50LnNlbmRLZXlFdmVudCgwLCBrZXlTeW0pO1xyXG5cdH07XHJcblx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xyXG5cdFx0dGV4dGFyZWEuZm9jdXMoKTtcclxuXHR9KTtcclxuXHRyZXR1cm4ga2V5Ym9hcmQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUd1YWNhbW9sZU1vdXNlKHNlbGYsIGNsaWVudCkge1xyXG5cdHZhciBtb3VzZSA9IG5ldyBHdWFjYW1vbGUuTW91c2UoY2xpZW50LmdldERpc3BsYXkoKS5nZXRFbGVtZW50KCkpO1xyXG5cdG1vdXNlLm9ubW91c2Vtb3ZlID0gbW91c2VFdmVudEhhbmRsZXI7XHJcblx0bW91c2Uub25tb3VzZXVwID0gbW91c2VFdmVudEhhbmRsZXI7XHJcblx0bW91c2Uub25tb3VzZWRvd24gPSBtb3VzZUV2ZW50SGFuZGxlcjtcclxuXHRyZXR1cm4gbW91c2U7XHJcblxyXG5cdGZ1bmN0aW9uIG1vdXNlRXZlbnRIYW5kbGVyKG1vdXNlU3RhdGUpIHtcclxuXHRcdGlmIChzZWxmLmlucHV0c0Rpc2FibGVkKVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR2YXIgZWxlbWVudCA9IGNsaWVudC5nZXREaXNwbGF5KCkuZ2V0RWxlbWVudCgpO1xyXG5cdFx0aWYgKG1vdXNlU3RhdGUueCA8IDAgfHwgbW91c2VTdGF0ZS54ID49IGVsZW1lbnQub2Zmc2V0V2lkdGggfHxcclxuXHRcdFx0XHRtb3VzZVN0YXRlLnkgPCAwIHx8IG1vdXNlU3RhdGUueSA+PSBlbGVtZW50Lm9mZnNldEhlaWdodClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cdFx0dmFyIHNjYWxlID0gY2xpZW50LmdldERpc3BsYXkoKS5nZXRTY2FsZSgpO1xyXG5cdFx0Y2xpZW50LnNlbmRNb3VzZVN0YXRlKG5ldyBHdWFjYW1vbGUuTW91c2UuU3RhdGUoXHJcblx0XHRcdFx0XHRcdFx0bW91c2VTdGF0ZS54IC8gc2NhbGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZVN0YXRlLnkgLyBzY2FsZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlU3RhdGUubGVmdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlU3RhdGUubWlkZGxlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VTdGF0ZS5yaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlU3RhdGUudXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZVN0YXRlLmRvd24pKVxyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldERpc2Nvbm5lY3RPbkJlZm9yZVVubG9hZChzZWxmKSB7XHJcblx0aWYgKHNlbGYuYmVmb3JlVW5sb2FkSGFuZGxlcikge1xyXG5cdFx0ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgc2VsZi5iZWZvcmVVbmxvYWRIYW5kbGVyKTtcclxuXHR9XHJcblx0c2VsZi5iZWZvcmVVbmxvYWRIYW5kbGVyID0gZnVuY3Rpb24oKSB7XHJcblx0XHRzZWxmLmNsaWVudC5kaXNjb25uZWN0KCk7XHJcblx0fTtcclxuXHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCBzZWxmLmJlZm9yZVVubG9hZEhhbmRsZXIpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEd1YWNhbW9sZUNsaWVudDtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9ndWFjYW1vbGUtY2xpZW50L2d1YWNhbW9sZS1jbGllbnQuanNcbi8vIG1vZHVsZSBpZCA9IDEzM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgR3VhY2Ftb2xlID0gcmVxdWlyZShcIi4vZ3VhY2Ftb2xlLWNvbW1vbi1qcy0xYzBlZTQxXCIpO1xyXG5cclxuZnVuY3Rpb24gR3VhY2Ftb2xlRXJyb3IoZXJyb3JBcmcsIHR1bm5lbHNEYXRhKSB7XHJcblx0dGhpcy5fZXJyb3JBcmcgPSBlcnJvckFyZztcclxuXHR0aGlzLl90dW5uZWxzRGF0YSA9IHR1bm5lbHNEYXRhO1xyXG59XHJcblxyXG5HdWFjYW1vbGVFcnJvci5wcm90b3R5cGUudG9Mb2dTdHJpbmcgPSBmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcy5fZXJyb3JBcmdUb1N0cmluZygpICsgXCIgOiBcIiArIHRoaXMuX3R1bm5lbHNEYXRhVG9TdHJpbmcoKTtcclxufTtcclxuXHJcbkd1YWNhbW9sZUVycm9yLnByb3RvdHlwZS50b0NsaWVudFN0cmluZyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XHJcblx0aWYgKHRoaXMuX2Vycm9yQXJnIGluc3RhbmNlb2YgR3VhY2Ftb2xlLlN0YXR1cyAmJlxyXG4gICAgICAgIHRoaXMuX2Vycm9yVGFibGVbdGhpcy5fZXJyb3JBcmcuY29kZV0gJiZcclxuICAgICAgICB0aGlzLl9lcnJvclRhYmxlW3RoaXMuX2Vycm9yQXJnLmNvZGVdLmNsaWVudERlc2NyaXB0aW9uKSB7XHJcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5fZXJyb3JUYWJsZVt0aGlzLl9lcnJvckFyZy5jb2RlXS5jbGllbnREZXNjcmlwdGlvbjtcclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn07XHJcblxyXG5HdWFjYW1vbGVFcnJvci5wcm90b3R5cGUuc2hvdWxkUmVjb25uZWN0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICBpZiAodGhpcy5fZXJyb3JBcmcgaW5zdGFuY2VvZiBHdWFjYW1vbGUuU3RhdHVzKVxyXG4gICAgICAgIHJldHVybiAhISh0aGlzLl9lcnJvclRhYmxlW3RoaXMuX2Vycm9yQXJnLmNvZGVdICYmIHRoaXMuX2Vycm9yVGFibGVbdGhpcy5fZXJyb3JBcmcuY29kZV0uc2hvdWxkUmVjb25uZWN0KTtcclxuXHRyZXR1cm4gZmFsc2U7XHJcbn07XHJcblxyXG5HdWFjYW1vbGVFcnJvci5wcm90b3R5cGUuX2Vycm9yQXJnVG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcclxuICAgIHZhciBlcnJvclRhYmxlRW50cnkgPSB0aGlzLl9lcnJvclRhYmxlW3RoaXMuX2Vycm9yQXJnLmNvZGVdO1xyXG5cdGlmIChlcnJvclRhYmxlRW50cnkpXHJcblx0XHRyZXR1cm4gJ1N0YXR1cygnICsgdGhpcy5fZXJyb3JBcmcuY29kZSArICcsICcgKyBlcnJvclRhYmxlRW50cnkubmFtZSArIFwiLCBcIiArIGVycm9yVGFibGVFbnRyeS5sb2dEZXNjcmlwdGlvbiArIFwiLCBcIiArIHRoaXMuX2Vycm9yQXJnLm1lc3NhZ2UgKyAnKSc7XHJcblx0ZWxzZVxyXG5cdFx0cmV0dXJuICdTdGF0dXMoJyArIHRoaXMuX2Vycm9yQXJnLmNvZGUgKyAnLCAnICsgdGhpcy5fZXJyb3JBcmcubWVzc2FnZSArICcpJztcclxufTtcclxuXHJcbkd1YWNhbW9sZUVycm9yLnByb3RvdHlwZS5fdHVubmVsc0RhdGFUb1N0cmluZyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIFwiVHVubmVsc0RhdGEoXCIgKyBcclxuICAgICAgICAgICAgXCJ3c1R1bm5lbDE9XCIgKyB0aGlzLl90dW5uZWxzRGF0YS53c1R1bm5lbDEgKyBcIiwgXCIgK1xyXG4gICAgICAgICAgICBcIndzVHVubmVsMj1cIiArIHRoaXMuX3R1bm5lbHNEYXRhLndzVHVubmVsMiArIFwiLCBcIiArXHJcbiAgICAgICAgICAgIFwiaHR0cFR1bm5lbD1cIiArIHRoaXMuX3R1bm5lbHNEYXRhLmh0dHBUdW5uZWwgKyBcIilcIjtcclxufTtcclxuXHJcbkd1YWNhbW9sZUVycm9yLnByb3RvdHlwZS5fZXJyb3JUYWJsZSA9IHtcclxuICAgIDB4MDAwMDoge1xyXG4gICAgICAgIG5hbWU6IFwiU1VDQ0VTU1wiLFxyXG4gICAgICAgIGxvZ0Rlc2NyaXB0aW9uOiBcIlRoZSBvcGVyYXRpb24gc3VjY2VlZGVkXCIsXHJcbiAgICAgICAgc2hvdWxkUmVjb25uZWN0OiBmYWxzZVxyXG4gICAgfSxcclxuXHJcbiAgICAweDAxMDA6IHtcclxuICAgICAgICBuYW1lOiBcIlVOU1VQUE9SVEVEXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIHJlcXVlc3RlZCBvcGVyYXRpb24gaXMgdW5zdXBwb3J0ZWQuXCIsXHJcbiAgICAgICAgc2hvdWxkUmVjb25uZWN0OiB0cnVlXHJcbiAgICB9LFxyXG5cclxuICAgIDB4MDIwMDoge1xyXG4gICAgICAgIG5hbWU6IFwiU0VSVkVSX0VSUk9SXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGR1ZSB0byBhbiBpbnRlcm5hbCBmYWlsdXJlLlwiLFxyXG4gICAgICAgIHNob3VsZFJlY29ubmVjdDogdHJ1ZVxyXG4gICAgfSxcclxuXHJcbiAgICAweDAyMDE6IHtcclxuICAgICAgICBuYW1lOiBcIlNFUlZFUl9CVVNZXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGFzIHRoZSBzZXJ2ZXIgaXMgYnVzeS5cIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IHRydWVcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMjAyOiB7XHJcbiAgICAgICAgbmFtZTogXCJVUFNUUkVBTV9USU1FT1VUXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGJlY2F1c2UgdGhlIHVwc3RyZWFtIHNlcnZlciBpcyBub3QgcmVzcG9uZGluZy5cIixcclxuICAgICAgICBjbGllbnREZXNjcmlwdGlvbjogXCJUaGUgcmVtb3RlIG1hY2hpbmUgc3RvcHBlZCByZXNwb25kaW5nXCIsXHJcbiAgICAgICAgc2hvdWxkUmVjb25uZWN0OiB0cnVlXHJcbiAgICB9LFxyXG5cclxuICAgIDB4MDIwMzoge1xyXG4gICAgICAgIG5hbWU6IFwiVVBTVFJFQU1fRVJST1JcIixcclxuICAgICAgICBsb2dEZXNjcmlwdGlvbjogXCJUaGUgb3BlcmF0aW9uIHdhcyB1bnN1Y2Nlc3NmdWwgZHVlIHRvIGFuIGVycm9yIG9yIG90aGVyd2lzZSB1bmV4cGVjdGVkIGNvbmRpdGlvbiBvZiB0aGUgdXBzdHJlYW0gc2VydmVyLlwiLFxyXG4gICAgICAgIGNsaWVudERlc2NyaXB0aW9uOiBcIkFuIGVycm9yIG9jY3VycmVkIG9uIHRoZSByZW1vdGUgbWFjaGluZVwiLFxyXG4gICAgICAgIHNob3VsZFJlY29ubmVjdDogdHJ1ZVxyXG4gICAgfSxcclxuXHJcbiAgICAweDAyMDQ6IHtcclxuICAgICAgICBuYW1lOiBcIlJFU09VUkNFX05PVF9GT1VORFwiLFxyXG4gICAgICAgIGxvZ0Rlc2NyaXB0aW9uOiBcIlRoZSBvcGVyYXRpb24gY291bGQgbm90IGJlIHBlcmZvcm1lZCBhcyB0aGUgcmVxdWVzdGVkIHJlc291cmNlIGRvZXMgbm90IGV4aXN0LlwiLFxyXG4gICAgICAgIHNob3VsZFJlY29ubmVjdDogdHJ1ZVxyXG4gICAgfSxcclxuXHJcbiAgICAweDAyMDU6IHtcclxuICAgICAgICBuYW1lOiBcIlJFU09VUkNFX0NPTkZMSUNUXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGFzIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UgaXMgYWxyZWFkeSBpbiB1c2UuXCIsXHJcbiAgICAgICAgc2hvdWxkUmVjb25uZWN0OiB0cnVlXHJcbiAgICB9LFxyXG5cclxuICAgIDB4MDIwNjoge1xyXG4gICAgICAgIG5hbWU6IFwiUkVTT1VSQ0VfQ0xPU0VEXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGFzIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UgaXMgbm93IGNsb3NlZC5cIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IHRydWVcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMjA3OiB7XHJcbiAgICAgICAgbmFtZTogXCJVUFNUUkVBTV9OT1RfRk9VTkRcIixcclxuICAgICAgICBsb2dEZXNjcmlwdGlvbjogXCJUaGUgb3BlcmF0aW9uIGNvdWxkIG5vdCBiZSBwZXJmb3JtZWQgYmVjYXVzZSB0aGUgdXBzdHJlYW0gc2VydmVyIGRvZXMgbm90IGFwcGVhciB0byBleGlzdC5cIixcclxuICAgICAgICBjbGllbnREZXNjcmlwdGlvbjogXCJUaGUgcmVtb3RlIG1hY2hpbmUgd2FzIG5vdCBmb3VuZFwiLFxyXG4gICAgICAgIHNob3VsZFJlY29ubmVjdDogdHJ1ZVxyXG4gICAgfSxcclxuXHJcbiAgICAweDAyMDg6ICB7XHJcbiAgICAgICAgbmFtZTogXCJVUFNUUkVBTV9VTkFWQUlMQUJMRVwiLFxyXG4gICAgICAgIGxvZ0Rlc2NyaXB0aW9uOiBcIlRoZSBvcGVyYXRpb24gY291bGQgbm90IGJlIHBlcmZvcm1lZCBiZWNhdXNlIHRoZSB1cHN0cmVhbSBzZXJ2ZXIgaXMgbm90IGF2YWlsYWJsZSB0byBzZXJ2aWNlIHRoZSByZXF1ZXN0LlwiLFxyXG4gICAgICAgIGNsaWVudERlc2NyaXB0aW9uOiBcIlRoZSByZW1vdGUgbWFjaGluZSBzdG9wcGVkIHJlc3BvbmRpbmdcIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IHRydWVcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMjA5OiB7XHJcbiAgICAgICAgbmFtZTogXCJTRVNTSU9OX0NPTkZMSUNUXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIHNlc3Npb24gd2l0aGluIHRoZSB1cHN0cmVhbSBzZXJ2ZXIgaGFzIGVuZGVkIGJlY2F1c2UgaXQgY29uZmxpY3RlZCB3aXRoIGFub3RoZXIgc2Vzc2lvbi5cIixcclxuICAgICAgICBjbGllbnREZXNjcmlwdGlvbjogXCJZb3UgaGF2ZSBiZWVuIGxvZ2dlZCBvdXQgYmVjYXVzZSBhbm90aGVyIHVzZXIgY29ubmVjdGVkIHRvIHRoZSByZW1vdGUgbWFjaGluZVwiLFxyXG4gICAgICAgIHNob3VsZFJlY29ubmVjdDogZmFsc2VcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMjBBOiB7XHJcbiAgICAgICAgbmFtZTogXCJTRVNTSU9OX1RJTUVPVVRcIixcclxuICAgICAgICBsb2dEZXNjcmlwdGlvbjogXCJUaGUgc2Vzc2lvbiB3aXRoaW4gdGhlIHVwc3RyZWFtIHNlcnZlciBoYXMgZW5kZWQgYmVjYXVzZSBpdCBhcHBlYXJlZCB0byBiZSBpbmFjdGl2ZS5cIixcclxuICAgICAgICBjbGllbnREZXNjcmlwdGlvbjogXCJZb3UgaGF2ZSBiZWVuIGxvZ2dlZCBvdXQgYnkgdGhlIHJlbW90ZSBtYWNoaW5lIGR1ZSB0byBpbmFjdGl2aXR5XCIsXHJcbiAgICAgICAgc2hvdWxkUmVjb25uZWN0OiB0cnVlXHJcbiAgICB9LFxyXG5cclxuICAgIDB4MDIwQjoge1xyXG4gICAgICAgIG5hbWU6IFwiU0VTU0lPTl9DTE9TRURcIixcclxuICAgICAgICBsb2dEZXNjcmlwdGlvbjogXCJUaGUgc2Vzc2lvbiB3aXRoaW4gdGhlIHVwc3RyZWFtIHNlcnZlciBoYXMgYmVlbiBmb3JjaWJseSB0ZXJtaW5hdGVkLlwiLFxyXG4gICAgICAgIGNsaWVudERlc2NyaXB0aW9uOiBcIllvdSBoYXZlIGJlZW4gbG9nZ2VkIG91dCBieSB0aGUgcmVtb3RlIG1hY2hpbmVcIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IGZhbHNlXHJcbiAgICB9LFxyXG5cclxuICAgIDB4MDMwMDoge1xyXG4gICAgICAgIG5hbWU6IFwiQ0xJRU5UX0JBRF9SRVFVRVNUXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiVGhlIG9wZXJhdGlvbiBjb3VsZCBub3QgYmUgcGVyZm9ybWVkIGJlY2F1c2UgYmFkIHBhcmFtZXRlcnMgd2VyZSBnaXZlbi5cIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IHRydWVcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMzAxOiB7XHJcbiAgICAgICAgbmFtZTogXCJDTElFTlRfVU5BVVRIT1JJWkVEXCIsXHJcbiAgICAgICAgbG9nRGVzY3JpcHRpb246IFwiUGVybWlzc2lvbiB3YXMgZGVuaWVkIHRvIHBlcmZvcm0gdGhlIG9wZXJhdGlvbiwgYXMgdGhlIHVzZXIgaXMgbm90IHlldCBhdXRob3JpemVkIChub3QgeWV0IGxvZ2dlZCBpbiwgZm9yIGV4YW1wbGUuXCIsXHJcbiAgICAgICAgc2hvdWxkUmVjb25uZWN0OiBmYWxzZVxyXG4gICAgfSxcclxuXHJcbiAgICAweDAzMDM6IHtcclxuICAgICAgICBuYW1lOiBcIkNMSUVOVF9GT1JCSURERU5cIixcclxuICAgICAgICBsb2dEZXNjcmlwdGlvbjogXCJQZXJtaXNzaW9uIHdhcyBkZW5pZWQgdG8gcGVyZm9ybSB0aGUgb3BlcmF0aW9uLCBhbmQgdGhpcyBwZXJtaXNzaW9uIHdpbGwgbm90IGJlIGdyYW50ZWQgZXZlbiBpZiB0aGUgdXNlciBpcyBhdXRob3JpemVkLlwiLFxyXG4gICAgICAgIHNob3VsZFJlY29ubmVjdDogZmFsc2VcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMzA4OiB7XHJcbiAgICAgICAgbmFtZTogXCJDTElFTlRfVElNRU9VVFwiLFxyXG4gICAgICAgIGxvZ0Rlc2NyaXB0aW9uOiBcImNsaWVudCB0b29rIHRvbyBsb25nIHRvIHJlc3BvbmRcIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IHRydWVcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMzBEOiB7XHJcbiAgICAgICAgbmFtZTogXCJDTElFTlRfT1ZFUlJVTlwiLFxyXG4gICAgICAgIGxvZ0Rlc2NyaXB0aW9uOiBcIlRoZSBjbGllbnQgc2VudCB0b28gbXVjaCBkYXRhLlwiLFxyXG4gICAgICAgIHNob3VsZFJlY29ubmVjdDogdHJ1ZVxyXG4gICAgfSxcclxuXHJcbiAgICAweDAzMEY6IHtcclxuICAgICAgICBuYW1lOiBcIkNMSUVOVF9CQURfVFlQRVwiLFxyXG4gICAgICAgIGxvZ0Rlc2NyaXB0aW9uOiBcIlRoZSBjbGllbnQgc2VudCBkYXRhIG9mIGFuIHVuc3VwcG9ydGVkIG9yIHVuZXhwZWN0ZWQgdHlwZS5cIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IHRydWVcclxuICAgIH0sXHJcblxyXG4gICAgMHgwMzFEOiB7XHJcbiAgICAgICAgbmFtZTogXCJDTElFTlRfVE9PX01BTllcIixcclxuICAgICAgICBsb2dEZXNjcmlwdGlvbjogXCJUaGUgb3BlcmF0aW9uIGZhaWxlZCBiZWNhdXNlIHRoZSBjdXJyZW50IGNsaWVudCBpcyBhbHJlYWR5IHVzaW5nIHRvbyBtYW55IHJlc291cmNlcy5cIixcclxuICAgICAgICBzaG91bGRSZWNvbm5lY3Q6IHRydWVcclxuICAgIH1cclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gR3VhY2Ftb2xlRXJyb3I7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvZ3VhY2Ftb2xlLWNsaWVudC9ndWFjYW1vbGUtZXJyb3IuanNcbi8vIG1vZHVsZSBpZCA9IDEzNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgQ29udHJvbFN5bWtleXMgPSByZXF1aXJlKCcuL2NvbnRyb2wtc3lta2V5cycpO1xyXG5cclxuZnVuY3Rpb24gS2V5U3Ryb2tlc1NlcnZpY2Uoc3lta2V5U2VydmljZSkge1xyXG5cdHRoaXMuc3lta2V5U2VydmljZSA9IHN5bWtleVNlcnZpY2U7XHJcbn1cclxuXHJcbktleVN0cm9rZXNTZXJ2aWNlLnByb3RvdHlwZS50b0tleVN0cm9rZXMgPSBmdW5jdGlvbih0ZXh0KSB7XHJcblx0dmFyIHJlc3VsdCA9IFtdO1xyXG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdGV4dC5sZW5ndGg7ICsraSkge1xyXG5cdFx0dmFyIGMgPSB0ZXh0W2ldO1xyXG5cdFx0aWYgKGlzTGluZUJyZWFrKGMpKVxyXG5cdFx0XHRwdXNoS2V5U3Ryb2tlU3lta2V5KHJlc3VsdCwgQ29udHJvbFN5bWtleXMuRU5URVIpO1xyXG5cdFx0ZWxzZSBpZiAoaXNTaGlmdGVkKGMpKSBcclxuXHRcdFx0cHVzaFNoaWZ0ZWRLZXlTdHJva2VDaGFyKHRoaXMsIHJlc3VsdCwgYyk7XHJcblx0XHRlbHNlXHJcblx0XHRcdHB1c2hLZXlTdHJva2VDaGFyKHRoaXMsIHJlc3VsdCwgYyk7XHJcblx0fVxyXG5cdHJldHVybiByZXN1bHQ7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBwdXNoU2hpZnRlZEtleVN0cm9rZUNoYXIoc2VsZiwgcmVzdWx0LCBjKSB7XHJcblx0cmVzdWx0LnB1c2goZG93bktleVN0cm9rZShDb250cm9sU3lta2V5cy5TSElGVCkpO1xyXG5cdHB1c2hLZXlTdHJva2VDaGFyKHNlbGYsIHJlc3VsdCwgYyk7XHJcblx0cmVzdWx0LnB1c2godXBLZXlTdHJva2UoQ29udHJvbFN5bWtleXMuU0hJRlQpKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcHVzaEtleVN0cm9rZUNoYXIoc2VsZiwgcmVzdWx0LCBjKSB7XHJcblx0cmVzdWx0LnB1c2godG9Eb3duS2V5U3Ryb2tlKHNlbGYsIGMpKTtcclxuXHRyZXN1bHQucHVzaCh0b1VwS2V5U3Ryb2tlKHNlbGYsIGMpKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcHVzaEtleVN0cm9rZVN5bWtleShyZXN1bHQsIHN5bWtleSkge1xyXG5cdHJlc3VsdC5wdXNoKGRvd25LZXlTdHJva2Uoc3lta2V5KSk7XHJcblx0cmVzdWx0LnB1c2godXBLZXlTdHJva2Uoc3lta2V5KSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTGluZUJyZWFrKGMpIHtcclxuXHRyZXR1cm4gYyA9PT0gXCJcXG5cIjtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNTaGlmdGVkKGMpIHtcclxuXHRyZXR1cm4gaXNVcHBlckNhc2UoYykgfHwgaXNTcGVjaWFsKGMpO1x0XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzU3BlY2lhbChjKSB7XHJcblx0cmV0dXJuICchQCMkJV4mKigpXz98Oit7fTw+flwiJy5pbmRleE9mKGMpICE9PSAtMTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNVcHBlckNhc2UoYykge1xyXG5cdHJldHVybiBjID49ICdBJyAmJiBjIDw9ICdaJztcclxufVxyXG5cclxuZnVuY3Rpb24gZG93bktleVN0cm9rZShzeW1rZXkpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0aXNEb3duOiB0cnVlLFxyXG5cdFx0c3lta2V5OiBzeW1rZXlcclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiB1cEtleVN0cm9rZShzeW1rZXkpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0aXNEb3duOiBmYWxzZSxcclxuXHRcdHN5bWtleTogc3lta2V5XHJcblx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gdG9Eb3duS2V5U3Ryb2tlKHNlbGYsIGMpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0aXNEb3duOiB0cnVlLFxyXG5cdFx0c3lta2V5OiBzZWxmLnN5bWtleVNlcnZpY2UudG9TeW1LZXkoYylcclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiB0b1VwS2V5U3Ryb2tlKHNlbGYsIGMpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0aXNEb3duOiBmYWxzZSxcclxuXHRcdHN5bWtleTogc2VsZi5zeW1rZXlTZXJ2aWNlLnRvU3ltS2V5KGMpXHJcblx0fTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBLZXlTdHJva2VzU2VydmljZTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9ndWFjYW1vbGUtY2xpZW50L2tleS1zdHJva2VzLXNlcnZpY2UuanNcbi8vIG1vZHVsZSBpZCA9IDEzNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJmdW5jdGlvbiBTeW1rZXlTZXJ2aWNlKCkge1xyXG5cdFxyXG59XHJcblxyXG5TeW1rZXlTZXJ2aWNlLnByb3RvdHlwZS50b1N5bUtleSA9IGZ1bmN0aW9uKHRleHQpIHtcclxuXHR2YXIgY2hhcmNvZGUgPSB0ZXh0LmNoYXJDb2RlQXQoMCk7XHJcblx0aWYgKGlzQ29udHJvbENoYXJhY3RlcihjaGFyY29kZSkpXHJcblx0XHRyZXR1cm4gMHhGRjAwIHwgY2hhcmNvZGU7XHJcblx0aWYgKGlzQVNDSUkoY2hhcmNvZGUpKVxyXG5cdFx0cmV0dXJuIGNoYXJjb2RlO1xyXG5cdGlmIChpc1VuaWNvZGVDaGFyYWN0ZXIoY2hhcmNvZGUpKVxyXG5cdFx0cmV0dXJuIDB4MDEwMDAwMDAgfCBjaGFyY29kZTtcclxuXHRyZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbmZ1bmN0aW9uIGlzQVNDSUkoY2hhcmNvZGUpIHtcclxuXHRyZXR1cm4gY2hhcmNvZGUgPj0gMHgwMCAmJiBjaGFyY29kZSA8PSAweEZGO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0NvbnRyb2xDaGFyYWN0ZXIoY2hhcmNvZGUpIHtcclxuICAgIHJldHVybiBjaGFyY29kZSA8PSAweDFGIHx8IChjaGFyY29kZSA+PSAweDdGICYmIGNoYXJjb2RlIDw9IDB4OUYpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1VuaWNvZGVDaGFyYWN0ZXIoY2hhcmNvZGUpIHtcclxuXHRyZXR1cm4gY2hhcmNvZGUgPiAweEZGICYmIGNoYXJjb2RlIDwgMHgxMTAwMDA7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gU3lta2V5U2VydmljZTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9ndWFjYW1vbGUtY2xpZW50L3N5bWtleS1zZXJ2aWNlLmpzXG4vLyBtb2R1bGUgaWQgPSAxMzZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIHdlYnBEZXRlY3QgPSB7XHJcbiAgICBpc1dlYnBTdXBwb3J0ZWQ6IGZhbHNlXHJcbn07XHJcblxyXG5mdW5jdGlvbiBoYXNXZWJQKCkge1xyXG4gICAgdmFyIGltZyA9IG5ldyBJbWFnZSgpO1xyXG4gICAgaW1nLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHdlYnBEZXRlY3QuaXNXZWJwU3VwcG9ydGVkID0gdHJ1ZTtcclxuICAgIH07XHJcbiAgICBpbWcub25lcnJvciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHdlYnBEZXRlY3QuaXNXZWJwU3VwcG9ydGVkID0gZmFsc2U7XHJcbiAgICB9O1xyXG4gICAgaW1nLnNyYyA9IFwiZGF0YTppbWFnZS93ZWJwO2Jhc2U2NCxVa2xHUmpJQUFBQlhSVUpRVmxBNElDWUFBQUN5QWdDZEFTb0NBQUVBTG1rMG1rMGlJaUlpSWdCb1N5Z0FCYzZ6YkFBQS92NTZRQUFBQUE9PVwiO1xyXG59XHJcblxyXG5oYXNXZWJQKCk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHdlYnBEZXRlY3Q7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2d1YWNhbW9sZS1jbGllbnQvd2VicC1kZXRlY3QuanNcbi8vIG1vZHVsZSBpZCA9IDEzN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgXyA9IHJlcXVpcmUoXCJ1bmRlcnNjb3JlXCIpO1xyXG5cclxuZnVuY3Rpb24gSGVhcnRiZWF0RGlzcGF0Y2hlcih3ZWJzb2NrZXRzQ29ubmVjdG9yKSB7XHJcbiAgICB0aGlzLndlYnNvY2tldHNDb25uZWN0b3IgPSB3ZWJzb2NrZXRzQ29ubmVjdG9yO1xyXG4gICAgdGhpcy5yZWdpc3RlcmVkQ2FsbGJhY2tzID0ge307XHJcbiAgICB0aGlzLnBlbmRpbmdBY3Rpb25zID0ge307XHJcbiAgICB0aGlzLm5vV2ViU29ja2V0ID0gZmFsc2U7XHJcbiAgICB0aGlzLmluaXRlZCA9IGZhbHNlO1xyXG59XHJcblxyXG5IZWFydGJlYXREaXNwYXRjaGVyLnByb3RvdHlwZS5yZWdpc3RlciA9IGZ1bmN0aW9uKGFjdGlvbiwgY2FsbGJhY2spIHtcclxuXHJcbiAgICBpZiAoIXRoaXMucmVnaXN0ZXJlZENhbGxiYWNrc1thY3Rpb25dKSB7XHJcbiAgICAgICAgdGhpcy5yZWdpc3RlcmVkQ2FsbGJhY2tzW2FjdGlvbl0gPSBbXTtcclxuICAgIH1cclxuICAgIHRoaXMucmVnaXN0ZXJlZENhbGxiYWNrc1thY3Rpb25dLnB1c2goY2FsbGJhY2spO1xyXG5cclxuICAgIC8vIFB1c2ggdG8gcGVuZGluZyBhY3Rpb25zIC0gZm9yIGludmFsaWRhdGluZ1xyXG4gICAgdGhpcy5wZW5kaW5nQWN0aW9uc1thY3Rpb25dID0gYWN0aW9uO1xyXG59O1xyXG5cclxuSGVhcnRiZWF0RGlzcGF0Y2hlci5wcm90b3R5cGUuY2xlYXJSZWdpc3RyYXRpb24gPSBmdW5jdGlvbigpIHtcclxuICAgIHRoaXMucmVnaXN0ZXJlZENhbGxiYWNrcyA9IHt9O1xyXG59O1xyXG5cclxuSGVhcnRiZWF0RGlzcGF0Y2hlci5wcm90b3R5cGUubm90aWZ5UmVnaXN0ZXJzID0gZnVuY3Rpb24oYWN0aW9uKSB7XHJcbiAgICB2YXIgY2FsbGJhY2tzID0gdGhpcy5yZWdpc3RlcmVkQ2FsbGJhY2tzW2FjdGlvbl07XHJcbiAgICBpZiAoY2FsbGJhY2tzKSB7XHJcbiAgICAgICAgXy5lYWNoKGNhbGxiYWNrcywgZnVuY3Rpb24oY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgY2FsbGJhY2soKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufTtcclxuXHJcbkhlYXJ0YmVhdERpc3BhdGNoZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbihkYXRhLCBidWZmZXJUaW1lLCBmYWxsYmFjaykge1xyXG4gICAgdmFyIHRoYXQgPSB0aGlzO1xyXG5cclxuICAgIGlmICh0aGF0LmluaXRlZClcclxuICAgICAgICByZXR1cm47XHJcblxyXG4gICAgdGhhdC5pbml0ZWQgPSB0cnVlO1xyXG5cclxuICAgIGlmICh0aGlzLm5vV2ViU29ja2V0KSB7XHJcbiAgICAgICAgaWYgKGZhbGxiYWNrKSBmYWxsYmFjaygpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWJ1ZmZlclRpbWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCInYnVmZmVyVGltZScgbXVzdCBiZSBwcm92aWRlZCFcIik7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGRvRmFsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKGZhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoYXQubm9XZWJTb2NrZXQgPSB0cnVlO1xyXG4gICAgICAgICAgICBmYWxsYmFjaygpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgY29uc29sZS5pbmZvKFwid3MtaGVhcnRiZWF0czogY29ubmVjdGluZyB3aXRoIFwiICsgYnVmZmVyVGltZSArIFwiIHNlY29uZHMgYnVmZmVyIHRpbWVcIik7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMud2Vic29ja2V0c0Nvbm5lY3Rvci5jb25uZWN0KGRhdGEsIGRvRmFsbGJhY2spLmRvbmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGF0Lm5vV2ViU29ja2V0KSByZXR1cm47XHJcbiAgICAgICAgdGhhdC5idWZmZXJUaW1lID0gdGhhdC5idWZmZXJUaW1lIHx8IDEwMDAwMDA7XHJcblxyXG4gICAgICAgIHRoYXQud2Vic29ja2V0c0Nvbm5lY3Rvci5ub3RpZnkgPSBmdW5jdGlvbiAoYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHRoYXQucGVuZGluZ0FjdGlvbnNbYWN0aW9uXSA9IGFjdGlvbjtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZiAodGhhdC5idWZmZXJUaW1lID4gYnVmZmVyVGltZSkge1xyXG4gICAgICAgICAgICB0aGF0LmJ1ZmZlclRpbWUgPSBidWZmZXJUaW1lO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoYXQucmVmcmVzaEludGVydmFsSWQpIHtcclxuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhhdC5yZWZyZXNoSW50ZXJ2YWxJZCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoYXQucmVmcmVzaEludGVydmFsSWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBfLmVhY2godGhhdC5wZW5kaW5nQWN0aW9ucywgZnVuY3Rpb24gKGFjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQubm90aWZ5UmVnaXN0ZXJzKGFjdGlvbik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHRoYXQucGVuZGluZ0FjdGlvbnMgPSB7fTtcclxuICAgICAgICAgICAgfSwgdGhhdC5idWZmZXJUaW1lICogMTAwMCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn07XHJcblxyXG5IZWFydGJlYXREaXNwYXRjaGVyLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XHJcbiAgICB0aGlzLndlYnNvY2tldHNDb25uZWN0b3Iubm90aWZ5ID0gbnVsbDtcclxuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5yZWZyZXNoSW50ZXJ2YWxJZCk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEhlYXJ0YmVhdERpc3BhdGNoZXI7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2hlYXJ0YmVhdC1vdmVyLXdzL2hlYXJ0YmVhdHMtZGlzcGF0Y2hlci5qc1xuLy8gbW9kdWxlIGlkID0gMTM4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBfID0gcmVxdWlyZShcInVuZGVyc2NvcmVcIik7XHJcblxyXG52YXIgJCA9IHJlcXVpcmUoXCJqUXVlcnlcIik7XHJcblxyXG5mdW5jdGlvbiBXZWJTb2NrZXRzQ29ubmVjdG9yKGNzd3MsIHVybCwgY29udHJvbGxlcikge1xyXG4gICAgdGhpcy5jc3dzID0gY3N3cztcclxuICAgIHRoaXMudXJsID0gdXJsO1xyXG4gICAgdGhpcy5jb250cm9sbGVyID0gY29udHJvbGxlcjtcclxuICAgIHRoaXMud2ViU29ja2V0c0NsaWVudCA9IG51bGw7XHJcbiAgICB0aGlzLm5vdGlmeSA9IG51bGw7XHJcblxyXG4gICAgdGhpcy5SRVRSWV9ERUxBWSA9IDUwMDA7XHJcbn1cclxuXHJcbldlYlNvY2tldHNDb25uZWN0b3IucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiAoZGF0YSwgZmFsbGJhY2spIHtcclxuICAgIHZhciB0aGF0ID0gdGhpcztcclxuICAgIHJldHVybiAkLmFqYXgoe1xyXG4gICAgICAgIHVybDogdGhhdC51cmwsXHJcbiAgICAgICAgZGF0YTogZGF0YVxyXG4gICAgfSkuZG9uZShmdW5jdGlvbiAod2ViU29ja2V0RGF0YSkge1xyXG4gICAgICAgIHRoYXQuX2Nvbm5lY3RUb1dlYnNvY2tldHMod2ViU29ja2V0RGF0YSwgZGF0YSwgZmFsbGJhY2spO1xyXG4gICAgfSk7XHJcbn07XHJcblxyXG5XZWJTb2NrZXRzQ29ubmVjdG9yLnByb3RvdHlwZS5fY29ubmVjdFRvV2Vic29ja2V0cyA9IGZ1bmN0aW9uICh3ZWJTb2NrZXREYXRhLCBjb25uZWN0aW9uRGF0YSwgZmFsbGJhY2spIHtcclxuICAgIHZhciB0aGF0ID0gdGhpcztcclxuXHJcbiAgICB2YXIgZmFsbGJhY2tDYWxsZWQgPSBmYWxzZTtcclxuXHJcbiAgICB0aGlzLmNzd3MubGlzdGVuKHtcclxuICAgICAgICBwcm90b2NvbEFuZEhvc3Q6IHdlYlNvY2tldERhdGEudXJsLFxyXG4gICAgICAgIGRpc3BhdGNoZXJOYW1lOiB0aGlzLmNvbnRyb2xsZXIsXHJcbiAgICAgICAgdG9rZW46IHdlYlNvY2tldERhdGEudG9rZW4sXHJcbiAgICAgICAgdG9rZW5SZWZyZXNoZXI6IHRoaXMuX2NyZWF0ZVRva2VuUmVmcmVzaGVyKGNvbm5lY3Rpb25EYXRhKSxcclxuICAgICAgICBvbm9wZW46IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgY29uc29sZS5pbmZvKFwid3MtaGVhcnRiZWF0czogY29ubmVjdGVkXCIpO1xyXG4gICAgICAgIH0sICBcclxuICAgICAgICBvbnRvcGljTGlzdGVuZXJzOiB7XHJcbiAgICAgICAgICAgIG1lc3NhZ2U6IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGF0Lm5vdGlmeSlcclxuICAgICAgICAgICAgICAgICAgICB0aGF0Lm5vdGlmeShtZXNzYWdlLmFjdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIG9uZXJyb3I6IGNhbGxGYWxsYmFja09uY2VJZkRlZmluZWQsXHJcbiAgICAgICAgb25jbG9zZTogY2FsbEZhbGxiYWNrT25jZUlmRGVmaW5lZCxcclxuICAgICAgICBub1JldHJ5OiAhIWZhbGxiYWNrXHJcbiAgICB9KTtcclxuXHJcbiAgICBmdW5jdGlvbiBjYWxsRmFsbGJhY2tPbmNlSWZEZWZpbmVkKCkge1xyXG4gICAgICAgIGlmIChmYWxsYmFjayAmJiAhZmFsbGJhY2tDYWxsZWQpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIndzLWhlYXJ0YmVhdHM6IGRpc2Nvbm5lY3RlZCwgdXNpbmcgZmFsbGJhY2tcIik7XHJcbiAgICAgICAgICAgIGZhbGxiYWNrQ2FsbGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgZmFsbGJhY2soKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG59O1xyXG5cclxuV2ViU29ja2V0c0Nvbm5lY3Rvci5wcm90b3R5cGUuX2NyZWF0ZVRva2VuUmVmcmVzaGVyID0gZnVuY3Rpb24oZGF0YSkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiAkLmFqYXgoe1xyXG4gICAgICAgICAgICB1cmw6IHRoaXMudXJsLFxyXG4gICAgICAgICAgICBkYXRhOiBkYXRhXHJcbiAgICAgICAgfSlcclxuICAgICAgICAudGhlbihmdW5jdGlvbiAod2ViU29ja2V0RGF0YSkge1xyXG4gICAgICAgICAgICByZXR1cm4gd2ViU29ja2V0RGF0YS50b2tlbjtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gV2ViU29ja2V0c0Nvbm5lY3RvcjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9oZWFydGJlYXQtb3Zlci13cy93ZWJzb2NrZXRzLWNvbm5lY3Rvci5qc1xuLy8gbW9kdWxlIGlkID0gMTM5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID1cbi8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbi8qKioqKiovIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuLyoqKioqKi8gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4vKioqKioqLyBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuLyoqKioqKi8gXHRcdFx0aTogbW9kdWxlSWQsXG4vKioqKioqLyBcdFx0XHRsOiBmYWxzZSxcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9XG4vKioqKioqLyBcdFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbi8qKioqKiovIFx0XHRtb2R1bGUubCA9IHRydWU7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG4vKioqKioqL1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4vKioqKioqLyBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuLyoqKioqKi8gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4vKioqKioqLyBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4vKioqKioqLyBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbi8qKioqKiovIFx0XHR9XG4vKioqKioqLyBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKioqKiovIFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuLyoqKioqKi8gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4vKioqKioqLyBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuLyoqKioqKi8gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4vKioqKioqLyBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4vKioqKioqLyBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbi8qKioqKiovIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuLyoqKioqKi8gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4vKioqKioqLyBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbi8qKioqKiovIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4vKioqKioqLyBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuLyoqKioqKi8gXHRcdHJldHVybiBucztcbi8qKioqKiovIFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuLyoqKioqKi8gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuLyoqKioqKi8gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4vKioqKioqLyBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuLyoqKioqKi8gXHRcdHJldHVybiBnZXR0ZXI7XG4vKioqKioqLyBcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCIvcmVzb3VyY2VzL2pzL2NzQ2xpZW50L21pbi9cIjtcbi8qKioqKiovXG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9pbmRleC5kZXBsb3kuanNcIik7XG4vKioqKioqLyB9KVxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qKioqKiovICh7XG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9iYXNlNjQtanMvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuXG5cbmV4cG9ydHMuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcbmV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheVxuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gZnJvbUJ5dGVBcnJheVxuXG52YXIgbG9va3VwID0gW11cbnZhciByZXZMb29rdXAgPSBbXVxudmFyIEFyciA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyA/IFVpbnQ4QXJyYXkgOiBBcnJheVxuXG52YXIgY29kZSA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJ1xuZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgbG9va3VwW2ldID0gY29kZVtpXVxuICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGlcbn1cblxuLy8gU3VwcG9ydCBkZWNvZGluZyBVUkwtc2FmZSBiYXNlNjQgc3RyaW5ncywgYXMgTm9kZS5qcyBkb2VzLlxuLy8gU2VlOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CYXNlNjQjVVJMX2FwcGxpY2F0aW9uc1xucmV2TG9va3VwWyctJy5jaGFyQ29kZUF0KDApXSA9IDYyXG5yZXZMb29rdXBbJ18nLmNoYXJDb2RlQXQoMCldID0gNjNcblxuZnVuY3Rpb24gZ2V0TGVucyAoYjY0KSB7XG4gIHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cbiAgaWYgKGxlbiAlIDQgPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0JylcbiAgfVxuXG4gIC8vIFRyaW0gb2ZmIGV4dHJhIGJ5dGVzIGFmdGVyIHBsYWNlaG9sZGVyIGJ5dGVzIGFyZSBmb3VuZFxuICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9iZWF0Z2FtbWl0L2Jhc2U2NC1qcy9pc3N1ZXMvNDJcbiAgdmFyIHZhbGlkTGVuID0gYjY0LmluZGV4T2YoJz0nKVxuICBpZiAodmFsaWRMZW4gPT09IC0xKSB2YWxpZExlbiA9IGxlblxuXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSB2YWxpZExlbiA9PT0gbGVuXG4gICAgPyAwXG4gICAgOiA0IC0gKHZhbGlkTGVuICUgNClcblxuICByZXR1cm4gW3ZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW5dXG59XG5cbi8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoYjY0KSB7XG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIF9ieXRlTGVuZ3RoIChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pIHtcbiAgcmV0dXJuICgodmFsaWRMZW4gKyBwbGFjZUhvbGRlcnNMZW4pICogMyAvIDQpIC0gcGxhY2VIb2xkZXJzTGVuXG59XG5cbmZ1bmN0aW9uIHRvQnl0ZUFycmF5IChiNjQpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG5cbiAgdmFyIGFyciA9IG5ldyBBcnIoX2J5dGVMZW5ndGgoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSlcblxuICB2YXIgY3VyQnl0ZSA9IDBcblxuICAvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG4gIHZhciBsZW4gPSBwbGFjZUhvbGRlcnNMZW4gPiAwXG4gICAgPyB2YWxpZExlbiAtIDRcbiAgICA6IHZhbGlkTGVuXG5cbiAgdmFyIGlcbiAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKHVpbnQ4LCBpLCAoaSArIG1heENodW5rTGVuZ3RoKSA+IGxlbjIgPyBsZW4yIDogKGkgKyBtYXhDaHVua0xlbmd0aCkpKVxuICB9XG5cbiAgLy8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuICBpZiAoZXh0cmFCeXRlcyA9PT0gMSkge1xuICAgIHRtcCA9IHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgNCkgJiAweDNGXSArXG4gICAgICAnPT0nXG4gICAgKVxuICB9IGVsc2UgaWYgKGV4dHJhQnl0ZXMgPT09IDIpIHtcbiAgICB0bXAgPSAodWludDhbbGVuIC0gMl0gPDwgOCkgKyB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDEwXSArXG4gICAgICBsb29rdXBbKHRtcCA+PiA0KSAmIDB4M0ZdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDIpICYgMHgzRl0gK1xuICAgICAgJz0nXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIHBhcnRzLmpvaW4oJycpXG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvYnVmZmVyLXNoaW1zL2luZGV4LmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9idWZmZXItc2hpbXMvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovKGZ1bmN0aW9uKGdsb2JhbCkge1xuXG52YXIgYnVmZmVyID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgYnVmZmVyICovIFwiLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzXCIpO1xudmFyIEJ1ZmZlciA9IGJ1ZmZlci5CdWZmZXI7XG52YXIgU2xvd0J1ZmZlciA9IGJ1ZmZlci5TbG93QnVmZmVyO1xudmFyIE1BWF9MRU4gPSBidWZmZXIua01heExlbmd0aCB8fCAyMTQ3NDgzNjQ3O1xuZXhwb3J0cy5hbGxvYyA9IGZ1bmN0aW9uIGFsbG9jKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgQnVmZmVyLmFsbG9jID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYyhzaXplLCBmaWxsLCBlbmNvZGluZyk7XG4gIH1cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IG5vdCBiZSBudW1iZXInKTtcbiAgfVxuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc2l6ZSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKHNpemUgPiBNQVhfTEVOKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NpemUgaXMgdG9vIGxhcmdlJyk7XG4gIH1cbiAgdmFyIGVuYyA9IGVuY29kaW5nO1xuICB2YXIgX2ZpbGwgPSBmaWxsO1xuICBpZiAoX2ZpbGwgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuYyA9IHVuZGVmaW5lZDtcbiAgICBfZmlsbCA9IDA7XG4gIH1cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gIGlmICh0eXBlb2YgX2ZpbGwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIGZpbGxCdWYgPSBuZXcgQnVmZmVyKF9maWxsLCBlbmMpO1xuICAgIHZhciBmbGVuID0gZmlsbEJ1Zi5sZW5ndGg7XG4gICAgdmFyIGkgPSAtMTtcbiAgICB3aGlsZSAoKytpIDwgc2l6ZSkge1xuICAgICAgYnVmW2ldID0gZmlsbEJ1ZltpICUgZmxlbl07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGJ1Zi5maWxsKF9maWxsKTtcbiAgfVxuICByZXR1cm4gYnVmO1xufVxuZXhwb3J0cy5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIGFsbG9jVW5zYWZlKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBCdWZmZXIuYWxsb2NVbnNhZmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlKHNpemUpO1xuICB9XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdzaXplIG11c3QgYmUgYSBudW1iZXInKTtcbiAgfVxuICBpZiAoc2l6ZSA+IE1BWF9MRU4pIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc2l6ZSBpcyB0b28gbGFyZ2UnKTtcbiAgfVxuICByZXR1cm4gbmV3IEJ1ZmZlcihzaXplKTtcbn1cbmV4cG9ydHMuZnJvbSA9IGZ1bmN0aW9uIGZyb20odmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIEJ1ZmZlci5mcm9tID09PSAnZnVuY3Rpb24nICYmICghZ2xvYmFsLlVpbnQ4QXJyYXkgfHwgVWludDhBcnJheS5mcm9tICE9PSBCdWZmZXIuZnJvbSkpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20odmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCk7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKTtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KTtcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgdmFyIG9mZnNldCA9IGVuY29kaW5nT3JPZmZzZXQ7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgIH1cbiAgICB2YXIgbGVuID0gbGVuZ3RoO1xuICAgIGlmICh0eXBlb2YgbGVuID09PSAndW5kZWZpbmVkJykge1xuICAgICAgbGVuID0gdmFsdWUuYnl0ZUxlbmd0aCAtIG9mZnNldDtcbiAgICB9XG4gICAgaWYgKG9mZnNldCA+PSB2YWx1ZS5ieXRlTGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKGxlbiA+IHZhbHVlLmJ5dGVMZW5ndGggLSBvZmZzZXQpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZS5zbGljZShvZmZzZXQsIG9mZnNldCArIGxlbikpO1xuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgdmFyIG91dCA9IG5ldyBCdWZmZXIodmFsdWUubGVuZ3RoKTtcbiAgICB2YWx1ZS5jb3B5KG91dCwgMCwgMCwgdmFsdWUubGVuZ3RoKTtcbiAgICByZXR1cm4gb3V0O1xuICB9XG4gIGlmICh2YWx1ZSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSB8fCAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gdmFsdWUpIHtcbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlLnR5cGUgPT09ICdCdWZmZXInICYmIEFycmF5LmlzQXJyYXkodmFsdWUuZGF0YSkpIHtcbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlLmRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgJyArICdBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpO1xufVxuZXhwb3J0cy5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiBhbGxvY1Vuc2FmZVNsb3coc2l6ZSkge1xuICBpZiAodHlwZW9mIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyhzaXplKTtcbiAgfVxuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc2l6ZSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKHNpemUgPj0gTUFYX0xFTikge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdzaXplIGlzIHRvbyBsYXJnZScpO1xuICB9XG4gIHJldHVybiBuZXcgU2xvd0J1ZmZlcihzaXplKTtcbn1cblxuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovfS5jYWxsKHRoaXMsIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vLi4vd2VicGFjay9idWlsZGluL2dsb2JhbC5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3dlYnBhY2svYnVpbGRpbi9nbG9iYWwuanNcIikpKVxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24oZ2xvYmFsKSB7LyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cblxuXG52YXIgYmFzZTY0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgYmFzZTY0LWpzICovIFwiLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzXCIpXG52YXIgaWVlZTc1NCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGllZWU3NTQgKi8gXCIuL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzXCIpXG52YXIgaXNBcnJheSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGlzYXJyYXkgKi8gXCIuL25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzXCIpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgVXNlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogRHVlIHRvIHZhcmlvdXMgYnJvd3NlciBidWdzLCBzb21ldGltZXMgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHVzZWQgZXZlblxuICogd2hlbiB0aGUgYnJvd3NlciBzdXBwb3J0cyB0eXBlZCBhcnJheXMuXG4gKlxuICogTm90ZTpcbiAqXG4gKiAgIC0gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLFxuICogICAgIFNlZTogaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njk1NDM4LlxuICpcbiAqICAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAgLSBJRTEwIGhhcyBhIGJyb2tlbiBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uIHdoaWNoIHJldHVybnMgYXJyYXlzIG9mXG4gKiAgICAgaW5jb3JyZWN0IGxlbmd0aCBpbiBzb21lIHNpdHVhdGlvbnMuXG5cbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5XG4gKiBnZXQgdGhlIE9iamVjdCBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaXMgc2xvd2VyIGJ1dCBiZWhhdmVzIGNvcnJlY3RseS5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCAhPT0gdW5kZWZpbmVkXG4gID8gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgOiB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbi8qXG4gKiBFeHBvcnQga01heExlbmd0aCBhZnRlciB0eXBlZCBhcnJheSBzdXBwb3J0IGlzIGRldGVybWluZWQuXG4gKi9cbmV4cG9ydHMua01heExlbmd0aCA9IGtNYXhMZW5ndGgoKVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KDEpXG4gICAgYXJyLl9fcHJvdG9fXyA9IHtfX3Byb3RvX186IFVpbnQ4QXJyYXkucHJvdG90eXBlLCBmb286IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDQyIH19XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuZnVuY3Rpb24gY3JlYXRlQnVmZmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKGtNYXhMZW5ndGgoKSA8IGxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aCcpXG4gIH1cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IG5ldyBVaW50OEFycmF5KGxlbmd0aClcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgaWYgKHRoYXQgPT09IG51bGwpIHtcbiAgICAgIHRoYXQgPSBuZXcgQnVmZmVyKGxlbmd0aClcbiAgICB9XG4gICAgdGhhdC5sZW5ndGggPSBsZW5ndGhcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmICEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdJZiBlbmNvZGluZyBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZydcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGFsbG9jVW5zYWZlKHRoaXMsIGFyZylcbiAgfVxuICByZXR1cm4gZnJvbSh0aGlzLCBhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbi8vIFRPRE86IExlZ2FjeSwgbm90IG5lZWRlZCBhbnltb3JlLiBSZW1vdmUgaW4gbmV4dCBtYWpvciB2ZXJzaW9uLlxuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIGZyb20gKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpXG4gIH1cblxuICByZXR1cm4gZnJvbU9iamVjdCh0aGF0LCB2YWx1ZSlcbn1cblxuLyoqXG4gKiBGdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0byBCdWZmZXIoYXJnLCBlbmNvZGluZykgYnV0IHRocm93cyBhIFR5cGVFcnJvclxuICogaWYgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBCdWZmZXIuZnJvbShzdHJbLCBlbmNvZGluZ10pXG4gKiBCdWZmZXIuZnJvbShhcnJheSlcbiAqIEJ1ZmZlci5mcm9tKGJ1ZmZlcilcbiAqIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyWywgYnl0ZU9mZnNldFssIGxlbmd0aF1dKVxuICoqL1xuQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gZnJvbShudWxsLCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5pZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuICBCdWZmZXIuX19wcm90b19fID0gVWludDhBcnJheVxuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgJiZcbiAgICAgIEJ1ZmZlcltTeW1ib2wuc3BlY2llc10gPT09IEJ1ZmZlcikge1xuICAgIC8vIEZpeCBzdWJhcnJheSgpIGluIEVTMjAxNi4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzk3XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlciwgU3ltYm9sLnNwZWNpZXMsIHtcbiAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRTaXplIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfSBlbHNlIGlmIChzaXplIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInNpemVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBuZWdhdGl2ZScpXG4gIH1cbn1cblxuZnVuY3Rpb24gYWxsb2MgKHRoYXQsIHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgaWYgKHNpemUgPD0gMCkge1xuICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbiAgfVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT25seSBwYXkgYXR0ZW50aW9uIHRvIGVuY29kaW5nIGlmIGl0J3MgYSBzdHJpbmcuIFRoaXNcbiAgICAvLyBwcmV2ZW50cyBhY2NpZGVudGFsbHkgc2VuZGluZyBpbiBhIG51bWJlciB0aGF0IHdvdWxkXG4gICAgLy8gYmUgaW50ZXJwcmV0dGVkIGFzIGEgc3RhcnQgb2Zmc2V0LlxuICAgIHJldHVybiB0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnXG4gICAgICA/IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgICAgOiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsKVxuICB9XG4gIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSlcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiBhbGxvYyhzaXplWywgZmlsbFssIGVuY29kaW5nXV0pXG4gKiovXG5CdWZmZXIuYWxsb2MgPSBmdW5jdGlvbiAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGFsbG9jKG51bGwsIHNpemUsIGZpbGwsIGVuY29kaW5nKVxufVxuXG5mdW5jdGlvbiBhbGxvY1Vuc2FmZSAodGhhdCwgc2l6ZSkge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSA8IDAgPyAwIDogY2hlY2tlZChzaXplKSB8IDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkge1xuICAgICAgdGhhdFtpXSA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEJ1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIFNsb3dCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShudWxsLCBzaXplKVxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nICh0aGF0LCBzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnIHx8IGVuY29kaW5nID09PSAnJykge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZW5jb2RpbmdcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGVuY29kaW5nJylcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBieXRlTGVuZ3RoKHN0cmluZywgZW5jb2RpbmcpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcblxuICB2YXIgYWN0dWFsID0gdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuXG4gIGlmIChhY3R1YWwgIT09IGxlbmd0aCkge1xuICAgIC8vIFdyaXRpbmcgYSBoZXggc3RyaW5nLCBmb3IgZXhhbXBsZSwgdGhhdCBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMgd2lsbFxuICAgIC8vIGNhdXNlIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IGludmFsaWQgY2hhcmFjdGVyIHRvIGJlIGlnbm9yZWQuIChlLmcuXG4gICAgLy8gJ2FieHhjZCcgd2lsbCBiZSB0cmVhdGVkIGFzICdhYicpXG4gICAgdGhhdCA9IHRoYXQuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5TGlrZSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChhcnJheS5sZW5ndGgpIHwgMFxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBhcnJheS5ieXRlTGVuZ3RoIC8vIHRoaXMgdGhyb3dzIGlmIGBhcnJheWAgaXMgbm90IGEgdmFsaWQgQXJyYXlCdWZmZXJcblxuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnb2Zmc2V0XFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdsZW5ndGhcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYnl0ZU9mZnNldCA9PT0gdW5kZWZpbmVkICYmIGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IGFycmF5XG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQgPSBmcm9tQXJyYXlMaWtlKHRoYXQsIGFycmF5KVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKHRoYXQsIG9iaikge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIGxlbilcblxuICAgIGlmICh0aGF0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoYXRcbiAgICB9XG5cbiAgICBvYmouY29weSh0aGF0LCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIHRoYXRcbiAgfVxuXG4gIGlmIChvYmopIHtcbiAgICBpZiAoKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fCAnbGVuZ3RoJyBpbiBvYmopIHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgaXNuYW4ob2JqLmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCAwKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqKVxuICAgIH1cblxuICAgIGlmIChvYmoudHlwZSA9PT0gJ0J1ZmZlcicgJiYgaXNBcnJheShvYmouZGF0YSkpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iai5kYXRhKVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCBvciBhcnJheS1saWtlIG9iamVjdC4nKVxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aCgpYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAobGVuZ3RoKSB7XG4gIGlmICgrbGVuZ3RoICE9IGxlbmd0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxuICAgIGxlbmd0aCA9IDBcbiAgfVxuICByZXR1cm4gQnVmZmVyLmFsbG9jKCtsZW5ndGgpXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXVxuICAgICAgeSA9IGJbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV1cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICAgIH1cbiAgICBidWYuY29weShidWZmZXIsIHBvcylcbiAgICBwb3MgKz0gYnVmLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHN0cmluZykpIHtcbiAgICByZXR1cm4gc3RyaW5nLmxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIChBcnJheUJ1ZmZlci5pc1ZpZXcoc3RyaW5nKSB8fCBzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpIHtcbiAgICByZXR1cm4gc3RyaW5nLmJ5dGVMZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHtcbiAgICBzdHJpbmcgPSAnJyArIHN0cmluZ1xuICB9XG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG5mdW5jdGlvbiBzbG93VG9TdHJpbmcgKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG5cbiAgLy8gTm8gbmVlZCB0byB2ZXJpZnkgdGhhdCBcInRoaXMubGVuZ3RoIDw9IE1BWF9VSU5UMzJcIiBzaW5jZSBpdCdzIGEgcmVhZC1vbmx5XG4gIC8vIHByb3BlcnR5IG9mIGEgdHlwZWQgYXJyYXkuXG5cbiAgLy8gVGhpcyBiZWhhdmVzIG5laXRoZXIgbGlrZSBTdHJpbmcgbm9yIFVpbnQ4QXJyYXkgaW4gdGhhdCB3ZSBzZXQgc3RhcnQvZW5kXG4gIC8vIHRvIHRoZWlyIHVwcGVyL2xvd2VyIGJvdW5kcyBpZiB0aGUgdmFsdWUgcGFzc2VkIGlzIG91dCBvZiByYW5nZS5cbiAgLy8gdW5kZWZpbmVkIGlzIGhhbmRsZWQgc3BlY2lhbGx5IGFzIHBlciBFQ01BLTI2MiA2dGggRWRpdGlvbixcbiAgLy8gU2VjdGlvbiAxMy4zLjMuNyBSdW50aW1lIFNlbWFudGljczogS2V5ZWRCaW5kaW5nSW5pdGlhbGl6YXRpb24uXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkIHx8IHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIC8vIFJldHVybiBlYXJseSBpZiBzdGFydCA+IHRoaXMubGVuZ3RoLiBEb25lIGhlcmUgdG8gcHJldmVudCBwb3RlbnRpYWwgdWludDMyXG4gIC8vIGNvZXJjaW9uIGZhaWwgYmVsb3cuXG4gIGlmIChzdGFydCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKGVuZCA8PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBGb3JjZSBjb2Vyc2lvbiB0byB1aW50MzIuIFRoaXMgd2lsbCBhbHNvIGNvZXJjZSBmYWxzZXkvTmFOIHZhbHVlcyB0byAwLlxuICBlbmQgPj4+PSAwXG4gIHN0YXJ0ID4+Pj0gMFxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9IChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG4vLyBUaGUgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCBhbmQgYGlzLWJ1ZmZlcmAgKGluIFNhZmFyaSA1LTcpIHRvIGRldGVjdFxuLy8gQnVmZmVyIGluc3RhbmNlcy5cbkJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyID0gdHJ1ZVxuXG5mdW5jdGlvbiBzd2FwIChiLCBuLCBtKSB7XG4gIHZhciBpID0gYltuXVxuICBiW25dID0gYlttXVxuICBiW21dID0gaVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAxNiA9IGZ1bmN0aW9uIHN3YXAxNiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMikge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDEpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMzIgPSBmdW5jdGlvbiBzd2FwMzIgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDQgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDMyLWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAzKVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyAyKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDY0ID0gZnVuY3Rpb24gc3dhcDY0ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA4ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA2NC1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA4KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgNylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgNilcbiAgICBzd2FwKHRoaXMsIGkgKyAyLCBpICsgNSlcbiAgICBzd2FwKHRoaXMsIGkgKyAzLCBpICsgNClcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xuICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGggfCAwXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKCcgJylcbiAgICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKGlzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogbG9va2luZyBmb3IgZW1wdHkgc3RyaW5nL2J1ZmZlciBhbHdheXMgZmFpbHNcbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAweEZGIC8vIFNlYXJjaCBmb3IgYSBieXRlIHZhbHVlIFswLTI1NV1cbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiZcbiAgICAgICAgdHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgWyB2YWwgXSwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlcicpXG59XG5cbmZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGRpcikge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpIDwgYXJyTGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChyZWFkKGFyciwgaSkgPT09IHJlYWQodmFsLCBmb3VuZEluZGV4ID09PSAtMSA/IDAgOiBpIC0gZm91bmRJbmRleCkpIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggPT09IC0xKSBmb3VuZEluZGV4ID0gaVxuICAgICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiBmb3VuZEluZGV4ICogaW5kZXhTaXplXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZm91bmRJbmRleCAhPT0gLTEpIGkgLT0gaSAtIGZvdW5kSW5kZXhcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChieXRlT2Zmc2V0ICsgdmFsTGVuZ3RoID4gYXJyTGVuZ3RoKSBieXRlT2Zmc2V0ID0gYXJyTGVuZ3RoIC0gdmFsTGVuZ3RoXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBmb3VuZCA9IHRydWVcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKHJlYWQoYXJyLCBpICsgaikgIT09IHJlYWQodmFsLCBqKSkge1xuICAgICAgICAgIGZvdW5kID0gZmFsc2VcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbiBpbmNsdWRlcyAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gdGhpcy5pbmRleE9mKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpICE9PSAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCB0cnVlKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24gbGFzdEluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChzdHJMZW4gJSAyICE9PSAwKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSByZXR1cm4gaVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gbGF0aW4xV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdCdWZmZXIud3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0WywgbGVuZ3RoXSkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCdcbiAgICApXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICAvLyBXYXJuaW5nOiBtYXhMZW5ndGggbm90IHRha2VuIGludG8gYWNjb3VudCBpbiBiYXNlNjRXcml0ZVxuICAgICAgICByZXR1cm4gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHVjczJXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04gKCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdCdWZmZXInLFxuICAgIGRhdGE6IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHRoaXMuX2FyciB8fCB0aGlzLCAwKVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiB1dGY4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG4gIHZhciByZXMgPSBbXVxuXG4gIHZhciBpID0gc3RhcnRcbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgZmlyc3RCeXRlID0gYnVmW2ldXG4gICAgdmFyIGNvZGVQb2ludCA9IG51bGxcbiAgICB2YXIgYnl0ZXNQZXJTZXF1ZW5jZSA9IChmaXJzdEJ5dGUgPiAweEVGKSA/IDRcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4REYpID8gM1xuICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICA6IDFcblxuICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA8PSBlbmQpIHtcbiAgICAgIHZhciBzZWNvbmRCeXRlLCB0aGlyZEJ5dGUsIGZvdXJ0aEJ5dGUsIHRlbXBDb2RlUG9pbnRcblxuICAgICAgc3dpdGNoIChieXRlc1BlclNlcXVlbmNlKSB7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBpZiAoZmlyc3RCeXRlIDwgMHg4MCkge1xuICAgICAgICAgICAgY29kZVBvaW50ID0gZmlyc3RCeXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4MUYpIDw8IDB4NiB8IChzZWNvbmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3Rikge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweEMgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4NiB8ICh0aGlyZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGRiAmJiAodGVtcENvZGVQb2ludCA8IDB4RDgwMCB8fCB0ZW1wQ29kZVBvaW50ID4gMHhERkZGKSkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBzZWNvbmRCeXRlID0gYnVmW2kgKyAxXVxuICAgICAgICAgIHRoaXJkQnl0ZSA9IGJ1ZltpICsgMl1cbiAgICAgICAgICBmb3VydGhCeXRlID0gYnVmW2kgKyAzXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAoZm91cnRoQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHgxMiB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHhDIHwgKHRoaXJkQnl0ZSAmIDB4M0YpIDw8IDB4NiB8IChmb3VydGhCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHhGRkZGICYmIHRlbXBDb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgICAgICAgICBjb2RlUG9pbnQgPSB0ZW1wQ29kZVBvaW50XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb2RlUG9pbnQgPT09IG51bGwpIHtcbiAgICAgIC8vIHdlIGRpZCBub3QgZ2VuZXJhdGUgYSB2YWxpZCBjb2RlUG9pbnQgc28gaW5zZXJ0IGFcbiAgICAgIC8vIHJlcGxhY2VtZW50IGNoYXIgKFUrRkZGRCkgYW5kIGFkdmFuY2Ugb25seSAxIGJ5dGVcbiAgICAgIGNvZGVQb2ludCA9IDB4RkZGRFxuICAgICAgYnl0ZXNQZXJTZXF1ZW5jZSA9IDFcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA+IDB4RkZGRikge1xuICAgICAgLy8gZW5jb2RlIHRvIHV0ZjE2IChzdXJyb2dhdGUgcGFpciBkYW5jZSlcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwXG4gICAgICByZXMucHVzaChjb2RlUG9pbnQgPj4+IDEwICYgMHgzRkYgfCAweEQ4MDApXG4gICAgICBjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRlxuICAgIH1cblxuICAgIHJlcy5wdXNoKGNvZGVQb2ludClcbiAgICBpICs9IGJ5dGVzUGVyU2VxdWVuY2VcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkocmVzKVxufVxuXG4vLyBCYXNlZCBvbiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjc0NzI3Mi82ODA3NDIsIHRoZSBicm93c2VyIHdpdGhcbi8vIHRoZSBsb3dlc3QgbGltaXQgaXMgQ2hyb21lLCB3aXRoIDB4MTAwMDAgYXJncy5cbi8vIFdlIGdvIDEgbWFnbml0dWRlIGxlc3MsIGZvciBzYWZldHlcbnZhciBNQVhfQVJHVU1FTlRTX0xFTkdUSCA9IDB4MTAwMFxuXG5mdW5jdGlvbiBkZWNvZGVDb2RlUG9pbnRzQXJyYXkgKGNvZGVQb2ludHMpIHtcbiAgdmFyIGxlbiA9IGNvZGVQb2ludHMubGVuZ3RoXG4gIGlmIChsZW4gPD0gTUFYX0FSR1VNRU5UU19MRU5HVEgpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNvZGVQb2ludHMpIC8vIGF2b2lkIGV4dHJhIHNsaWNlKClcbiAgfVxuXG4gIC8vIERlY29kZSBpbiBjaHVua3MgdG8gYXZvaWQgXCJjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIi5cbiAgdmFyIHJlcyA9ICcnXG4gIHZhciBpID0gMFxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFxuICAgICAgU3RyaW5nLFxuICAgICAgY29kZVBvaW50cy5zbGljZShpLCBpICs9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKVxuICAgIClcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldICYgMHg3RilcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGxhdGluMVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGhleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYnVmLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHZhciByZXMgPSAnJ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0gKyBieXRlc1tpICsgMV0gKiAyNTYpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpXG4gICAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZClcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyArK2kpIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLypcbiAqIE5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYnVmZmVyIGlzbid0IHRyeWluZyB0byB3cml0ZSBvdXQgb2YgYm91bmRzLlxuICovXG5mdW5jdGlvbiBjaGVja09mZnNldCAob2Zmc2V0LCBleHQsIGxlbmd0aCkge1xuICBpZiAoKG9mZnNldCAlIDEpICE9PSAwIHx8IG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdvZmZzZXQgaXMgbm90IHVpbnQnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gbGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIHJlYWRVSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG4gIH1cblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdXG4gIHZhciBtdWwgPSAxXG4gIHdoaWxlIChieXRlTGVuZ3RoID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbiByZWFkVUludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgOCkgfCB0aGlzW29mZnNldCArIDFdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICgodGhpc1tvZmZzZXRdKSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikpICtcbiAgICAgICh0aGlzW29mZnNldCArIDNdICogMHgxMDAwMDAwKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gcmVhZEludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoXG4gIHZhciBtdWwgPSAxXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0taV1cbiAgd2hpbGUgKGkgPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICB9XG4gIG11bCAqPSAweDgwXG5cbiAgaWYgKHZhbCA+PSBtdWwpIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiByZWFkSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIDFdIHwgKHRoaXNbb2Zmc2V0XSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiByZWFkSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiByZWFkRmxvYXRMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiByZWFkRmxvYXRCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgdHJ1ZSwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24gcmVhZERvdWJsZUJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZmZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgLSAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweDdmLCAtMHg4MClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuZnVuY3Rpb24gY2hlY2tJRUVFNzU0IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksXG4gICAgICB0YXJnZXRTdGFydFxuICAgIClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gVXNhZ2U6XG4vLyAgICBidWZmZXIuZmlsbChudW1iZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKGJ1ZmZlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoc3RyaW5nWywgb2Zmc2V0WywgZW5kXV1bLCBlbmNvZGluZ10pXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWwsIHN0YXJ0LCBlbmQsIGVuY29kaW5nKSB7XG4gIC8vIEhhbmRsZSBzdHJpbmcgY2FzZXM6XG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IHN0YXJ0XG4gICAgICBzdGFydCA9IDBcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZW5kID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmRcbiAgICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gICAgfVxuICAgIGlmICh2YWwubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgY29kZSA9IHZhbC5jaGFyQ29kZUF0KDApXG4gICAgICBpZiAoY29kZSA8IDI1Nikge1xuICAgICAgICB2YWwgPSBjb2RlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3QgYmUgYSBzdHJpbmcnKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMjU1XG4gIH1cblxuICAvLyBJbnZhbGlkIHJhbmdlcyBhcmUgbm90IHNldCB0byBhIGRlZmF1bHQsIHNvIGNhbiByYW5nZSBjaGVjayBlYXJseS5cbiAgaWYgKHN0YXJ0IDwgMCB8fCB0aGlzLmxlbmd0aCA8IHN0YXJ0IHx8IHRoaXMubGVuZ3RoIDwgZW5kKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ091dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHN0YXJ0ID0gc3RhcnQgPj4+IDBcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghdmFsKSB2YWwgPSAwXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgdGhpc1tpXSA9IHZhbFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSBCdWZmZXIuaXNCdWZmZXIodmFsKVxuICAgICAgPyB2YWxcbiAgICAgIDogdXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsIGVuY29kaW5nKS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSAwOyBpIDwgZW5kIC0gc3RhcnQ7ICsraSkge1xuICAgICAgdGhpc1tpICsgc3RhcnRdID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgc3RyaXBzIG91dCBpbnZhbGlkIGNoYXJhY3RlcnMgbGlrZSBcXG4gYW5kIFxcdCBmcm9tIHRoZSBzdHJpbmcsIGJhc2U2NC1qcyBkb2VzIG5vdFxuICBzdHIgPSBzdHJpbmd0cmltKHN0cikucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBpc25hbiAodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IHZhbCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwodGhpcywgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8uLi93ZWJwYWNrL2J1aWxkaW4vZ2xvYmFsLmpzICovIFwiLi9ub2RlX21vZHVsZXMvd2VicGFjay9idWlsZGluL2dsb2JhbC5qc1wiKSkpXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24oQnVmZmVyKSB7Ly8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5cbmZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKTtcbiAgfVxuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoYXJnKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IEJ1ZmZlci5pc0J1ZmZlcjtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwodGhpcywgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8uLi8uLi9idWZmZXIvaW5kZXguanMgKi8gXCIuL25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanNcIikuQnVmZmVyKSlcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5cblxudmFyIFIgPSB0eXBlb2YgUmVmbGVjdCA9PT0gJ29iamVjdCcgPyBSZWZsZWN0IDogbnVsbFxudmFyIFJlZmxlY3RBcHBseSA9IFIgJiYgdHlwZW9mIFIuYXBwbHkgPT09ICdmdW5jdGlvbidcbiAgPyBSLmFwcGx5XG4gIDogZnVuY3Rpb24gUmVmbGVjdEFwcGx5KHRhcmdldCwgcmVjZWl2ZXIsIGFyZ3MpIHtcbiAgICByZXR1cm4gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwodGFyZ2V0LCByZWNlaXZlciwgYXJncyk7XG4gIH1cblxudmFyIFJlZmxlY3RPd25LZXlzXG5pZiAoUiAmJiB0eXBlb2YgUi5vd25LZXlzID09PSAnZnVuY3Rpb24nKSB7XG4gIFJlZmxlY3RPd25LZXlzID0gUi5vd25LZXlzXG59IGVsc2UgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgUmVmbGVjdE93bktleXMgPSBmdW5jdGlvbiBSZWZsZWN0T3duS2V5cyh0YXJnZXQpIHtcbiAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGFyZ2V0KVxuICAgICAgLmNvbmNhdChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHRhcmdldCkpO1xuICB9O1xufSBlbHNlIHtcbiAgUmVmbGVjdE93bktleXMgPSBmdW5jdGlvbiBSZWZsZWN0T3duS2V5cyh0YXJnZXQpIHtcbiAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGFyZ2V0KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gUHJvY2Vzc0VtaXRXYXJuaW5nKHdhcm5pbmcpIHtcbiAgaWYgKGNvbnNvbGUgJiYgY29uc29sZS53YXJuKSBjb25zb2xlLndhcm4od2FybmluZyk7XG59XG5cbnZhciBOdW1iZXJJc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiBOdW1iZXJJc05hTih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIEV2ZW50RW1pdHRlci5pbml0LmNhbGwodGhpcyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbm1vZHVsZS5leHBvcnRzLm9uY2UgPSBvbmNlO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50c0NvdW50ID0gMDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuZnVuY3Rpb24gY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcikge1xuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgRnVuY3Rpb24uIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBsaXN0ZW5lcik7XG4gIH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24oYXJnKSB7XG4gICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgTnVtYmVySXNOYU4oYXJnKSkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcImRlZmF1bHRNYXhMaXN0ZW5lcnNcIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgYXJnICsgJy4nKTtcbiAgICB9XG4gICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgfVxufSk7XG5cbkV2ZW50RW1pdHRlci5pbml0ID0gZnVuY3Rpb24oKSB7XG5cbiAgaWYgKHRoaXMuX2V2ZW50cyA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICB0aGlzLl9ldmVudHMgPT09IE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKS5fZXZlbnRzKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gIH1cblxuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufTtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBOdW1iZXJJc05hTihuKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgb2YgXCJuXCIgaXMgb3V0IG9mIHJhbmdlLiBJdCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlci4gUmVjZWl2ZWQgJyArIG4gKyAnLicpO1xuICB9XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gX2dldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gX2dldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgYXJncyA9IFtdO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZClcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09PSB1bmRlZmluZWQpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIHZhciBlcjtcbiAgICBpZiAoYXJncy5sZW5ndGggPiAwKVxuICAgICAgZXIgPSBhcmdzWzBdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAvLyBOb3RlOiBUaGUgY29tbWVudHMgb24gdGhlIGB0aHJvd2AgbGluZXMgYXJlIGludGVudGlvbmFsLCB0aGV5IHNob3dcbiAgICAgIC8vIHVwIGluIE5vZGUncyBvdXRwdXQgaWYgdGhpcyByZXN1bHRzIGluIGFuIHVuaGFuZGxlZCBleGNlcHRpb24uXG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9XG4gICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBlcnJvci4nICsgKGVyID8gJyAoJyArIGVyLm1lc3NhZ2UgKyAnKScgOiAnJykpO1xuICAgIGVyci5jb250ZXh0ID0gZXI7XG4gICAgdGhyb3cgZXJyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICB9XG5cbiAgdmFyIGhhbmRsZXIgPSBldmVudHNbdHlwZV07XG5cbiAgaWYgKGhhbmRsZXIgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgUmVmbGVjdEFwcGx5KGhhbmRsZXIsIHRoaXMsIGFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBSZWZsZWN0QXBwbHkobGlzdGVuZXJzW2ldLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRhcmdldC5fZXZlbnRzQ291bnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gICAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICAgIGlmIChldmVudHMubmV3TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmIChleGlzdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgIHByZXBlbmQgPyBbbGlzdGVuZXIsIGV4aXN0aW5nXSA6IFtleGlzdGluZywgbGlzdGVuZXJdO1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIH0gZWxzZSBpZiAocHJlcGVuZCkge1xuICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4aXN0aW5nLnB1c2gobGlzdGVuZXIpO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gICAgbSA9IF9nZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICBpZiAobSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSAmJiAhZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgLy8gTm8gZXJyb3IgY29kZSBmb3IgdGhpcyBzaW5jZSBpdCBpcyBhIFdhcm5pbmdcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxuICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgJyArIFN0cmluZyh0eXBlKSArICcgbGlzdGVuZXJzICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQnKTtcbiAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgdy50eXBlID0gdHlwZTtcbiAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICBQcm9jZXNzRW1pdFdhcm5pbmcodyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0KTtcbiAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJndW1lbnRzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfb25jZVdyYXAodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgc3RhdGUgPSB7IGZpcmVkOiBmYWxzZSwgd3JhcEZuOiB1bmRlZmluZWQsIHRhcmdldDogdGFyZ2V0LCB0eXBlOiB0eXBlLCBsaXN0ZW5lcjogbGlzdGVuZXIgfTtcbiAgdmFyIHdyYXBwZWQgPSBvbmNlV3JhcHBlci5iaW5kKHN0YXRlKTtcbiAgd3JhcHBlZC5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICBzdGF0ZS53cmFwRm4gPSB3cmFwcGVkO1xuICByZXR1cm4gd3JhcHBlZDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gb25jZSh0eXBlLCBsaXN0ZW5lcikge1xuICBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKTtcbiAgdGhpcy5vbih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRPbmNlTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHByZXBlbmRPbmNlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmIChsaXN0ID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHwgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHNwbGljZU9uZShsaXN0LCBwb3NpdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID1cbiAgICBmdW5jdGlvbiByZW1vdmVBbGxMaXN0ZW5lcnModHlwZSkge1xuICAgICAgdmFyIGxpc3RlbmVycywgZXZlbnRzLCBpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudHNbdHlwZV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoZXZsaXN0ZW5lciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBbXTtcblxuICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIHVud3JhcCA/IFtldmxpc3RlbmVyLmxpc3RlbmVyIHx8IGV2bGlzdGVuZXJdIDogW2V2bGlzdGVuZXJdO1xuXG4gIHJldHVybiB1bndyYXAgP1xuICAgIHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gMDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5ldmVudE5hbWVzID0gZnVuY3Rpb24gZXZlbnROYW1lcygpIHtcbiAgcmV0dXJuIHRoaXMuX2V2ZW50c0NvdW50ID4gMCA/IFJlZmxlY3RPd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAoOyBpbmRleCArIDEgPCBsaXN0Lmxlbmd0aDsgaW5kZXgrKylcbiAgICBsaXN0W2luZGV4XSA9IGxpc3RbaW5kZXggKyAxXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb25jZShlbWl0dGVyLCBuYW1lKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgZnVuY3Rpb24gZXZlbnRMaXN0ZW5lcigpIHtcbiAgICAgIGlmIChlcnJvckxpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBlcnJvckxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIHJlc29sdmUoW10uc2xpY2UuY2FsbChhcmd1bWVudHMpKTtcbiAgICB9O1xuICAgIHZhciBlcnJvckxpc3RlbmVyO1xuXG4gICAgLy8gQWRkaW5nIGFuIGVycm9yIGxpc3RlbmVyIGlzIG5vdCBvcHRpb25hbCBiZWNhdXNlXG4gICAgLy8gaWYgYW4gZXJyb3IgaXMgdGhyb3duIG9uIGFuIGV2ZW50IGVtaXR0ZXIgd2UgY2Fubm90XG4gICAgLy8gZ3VhcmFudGVlIHRoYXQgdGhlIGFjdHVhbCBldmVudCB3ZSBhcmUgd2FpdGluZyB3aWxsXG4gICAgLy8gYmUgZmlyZWQuIFRoZSByZXN1bHQgY291bGQgYmUgYSBzaWxlbnQgd2F5IHRvIGNyZWF0ZVxuICAgIC8vIG1lbW9yeSBvciBmaWxlIGRlc2NyaXB0b3IgbGVha3MsIHdoaWNoIGlzIHNvbWV0aGluZ1xuICAgIC8vIHdlIHNob3VsZCBhdm9pZC5cbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgZXJyb3JMaXN0ZW5lciA9IGZ1bmN0aW9uIGVycm9yTGlzdGVuZXIoZXJyKSB7XG4gICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIobmFtZSwgZXZlbnRMaXN0ZW5lcik7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfTtcblxuICAgICAgZW1pdHRlci5vbmNlKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgIH1cblxuICAgIGVtaXR0ZXIub25jZShuYW1lLCBldmVudExpc3RlbmVyKTtcbiAgfSk7XG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZXhwb3J0cy1sb2FkZXIvaW5kZXguanM/d2luZG93LmdldFNwYXJrSTE4biEuL25vZGVfbW9kdWxlcy9pbXBvcnRzLWxvYWRlci9pbmRleC5qcz93aW5kb3dzPT50aGlzIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3N0cmluZ3MtZW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZXhwb3J0cy1sb2FkZXI/d2luZG93LmdldFNwYXJrSTE4biEuL25vZGVfbW9kdWxlcy9pbXBvcnRzLWxvYWRlcj93aW5kb3dzPT50aGlzIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3N0cmluZ3MtZW4uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuLyoqKiBJTVBPUlRTIEZST00gaW1wb3J0cy1sb2FkZXIgKioqL1xudmFyIHdpbmRvd3MgPSB0aGlzO1xuXG4oZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGkxOG4gPSB3aW5kb3cuY3NsMTBuIHx8IHtcclxuICAgICAgICB0cmFuc2xhdGU6IGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB4O1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbm90aWZ5UmVhZHk6IGZ1bmN0aW9uICgpIHsgfSxcclxuICAgICAgICBpbml0OiBmdW5jdGlvbihjYWxsYmFjaykgeyBjYWxsYmFjaygpOyB9XHJcbiAgICB9O1xyXG4gICAgdmFyIF8gPSBpMThuLnRyYW5zbGF0ZTtcclxuXHJcbiAgICBpMThuLmluaXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHdpbmRvdy5fX3N2aTE4biA9IHtcclxuICAgICAgICAgICAgbm9hdXRoOiBfKCdTb3JyeSwgeW91IGFyZSBub3QgYXV0aG9yaXplZCcpLFxyXG4gICAgICAgICAgICB3YWl0OiBfKCdQbGVhc2Ugd2FpdCB3aGlsZSBjb25uZWN0aW5nLi4uJyksXHJcbiAgICAgICAgICAgIGVycm9yRGVjb21wcmVzczogXygnRXJyb3Igb24gZGVjb21wcmVzc2luZyBkYXRhLicpLFxyXG4gICAgICAgICAgICBsb2dFcnJvcjogXygnVGhlIGxvZ29uIHByb2Nlc3MgZmFpbGVkLicpLFxyXG4gICAgICAgICAgICByZW1vdGVBcHA6IHtcclxuICAgICAgICAgICAgICAgIHdhcm46IF8oJ1dhcm5pbmc6IFRoaXMgaXMgdGhlIHBhcmVudCB3aW5kb3cgb2YgZm9sbG93aW5nIFJlbW90ZUFwcHM6JyksXHJcbiAgICAgICAgICAgICAgICBjbG9zZTogXyhcIlBsZWFzZSBxdWl0IHRoZSBhcHBsaWNhdGlvbiBmcm9tIGFwcGxpY2F0aW9uJ3MgRmlsZSBtZW51LlwiKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBpbmZvOiB7XHJcbiAgICAgICAgICAgICAgICAnY2xvc2VkJzogXygnQ29ubmVjdGlvbiB3YXMgY2xvc2VkIScpLFxyXG4gICAgICAgICAgICAgICAgJ3JlY29yZGluZyc6IF8oJ1lvdSBzZXNzaW9uIGlzIHJlY29yZGVkIGFuZCBtb25pdG9yZWQuJyksXHJcbiAgICAgICAgICAgICAgICAnbWVudWNvcHknOiBfKFwiUGFzdGluZyBpcyB1bmF2YWlsYWJsZSB2aWEgcmVtb3RlIGNvbXB1dGVyJ3MgRWRpdCBtZW51LCBidXQgeW91IGNhbiB1c2UgQ3RybCtWIG9yIGJyb3dzZXIncyBFZGl0IG1lbnVcIiksXHJcbiAgICAgICAgICAgICAgICAncmVzdGFydCc6IF8oJ1BsZWFzZSByZXN0YXJ0IGdhdGV3YXkuJyksXHJcbiAgICAgICAgICAgICAgICAnZmlsZXMnOiBfKCdNeSBGaWxlcycpLFxyXG4gICAgICAgICAgICAgICAgJ2luZm8nOiBfKCdJbmZvcm1hdGlvbicpLFxyXG4gICAgICAgICAgICAgICAgJ2pvaW5zZXNzaW9uJzogXygnU2Vzc2lvbiAlMSBqb2luZWQsIGZyb20gJTIgJTMnKSwgLy8lMSBzZXNzaW9uSWQsICUyIGhvc3RuYW1lLCAlMyB1c2VyIG5hbWVcclxuICAgICAgICAgICAgICAgICdleGl0c2Vzc2lvbic6IF8oJ1Nlc3Npb24gJTEgZXhpdGVkLCBmcm9tICUyICUzJyksXHJcbiAgICAgICAgICAgICAgICAnZ2l2ZWNvbnRyb2wnOiBfKCdZb3UgaGF2ZSB0aGUgY29udHJvbC4nKSxcclxuICAgICAgICAgICAgICAgICdub2NvbnRyb2wnOiBfKFwiWW91IGRvbid0IGhhdmUgY29udHJvbCBhbnkgbW9yZS5cIiksXHJcbiAgICAgICAgICAgICAgICAndGl0bGUnOiBfKCclMSAlMiBAICUzJyksIC8vdGl0bGUgb2YgcmVxdWVzdCBjb250cmwsICUxIHVzZXIgbmFtZSwgJTIgbnVtYmVyIElELCAlMiBob3N0IG5hbWVcclxuICAgICAgICAgICAgICAgICdyZWNvbnRyb2wnOiBfKCdSZXF1ZXN0aW5nIGNvbnRyb2wnKSxcclxuICAgICAgICAgICAgICAgICd0b3VjaHJlbW90aW5nJzogXygnVG91Y2ggcmVtb3RpbmcgaXMgZW5hYmxlZCcpLFxyXG4gICAgICAgICAgICAgICAgJ3ByaW50cmVhZHknOiBfKCdDbGljayBoZXJlIHRvIHByaW50IGRvY3VtZW50IHRvIGxvY2FsIGRldmljZXMnKSxcclxuICAgICAgICAgICAgICAgICdyZWNvbm5lY3RpbmcnOiBfKCdSZWNvbm5lY3RpbmcuLi4nKSxcclxuICAgICAgICAgICAgICAgICdjb3B5JzogXygnVXNlIEN0cmwrQyBvciBicm93c2VyXFwncyBFZGl0IG1lbnUgdG8gY29weSBjb250ZW50Ljxicj5Gb3IgaW1hZ2UsIHVzZSBcIkNvcHkgaW1hZ2VcIiBtZW51IG9yIHNlbGVjdCB0aGUgaW1hZ2UgYW5kIGNvcHkuPGJyPlVzZSBcInBhc3RlIHNwZWNpYWwgLSBEZXZpY2UgSW5kZXBlbmRlbnQgQml0bWFwXCIgaW4gT2ZmaWNlIGlmIHlvdSBjb3B5IGltYWdlIGZyb20gSUUuJyksXHJcbiAgICAgICAgICAgICAgICAnY29weVdhcm5pbmcnOiBfKCdQbGVhc2UgdXNlIGNvcHkgZGlhbG9nIHRvIGNvcHkgaW1hZ2UvY29udGVudC4nKSxcclxuICAgICAgICAgICAgICAgICdyZXFqb2luJzogXygnUmVxdWVzdGluZyBqb2luaW5nJyksXHJcbiAgICAgICAgICAgICAgICAncmVjcmVhZHknOiBfKCdSZWNvcmRlZCBmaWxlIGlzIHJlYWR5LiBQbGVhc2UgcmlnaHQgY2xpY2sgYW5kIHNhdmUgdGhlIGxpbmsuJyksXHJcbiAgICAgICAgICAgICAgICAnc2Vzc2lvblBhdXNlZCc6IF8oJ1lvdSBzZXNzaW9uIGhhcyBiZWVuIHBhdXNlZCBieSBhZG1pbmlzdHJhdG9yJyksXHJcbiAgICAgICAgICAgICAgICAnc2Vzc2lvblJlc3VtZWQnOiBfKCdZb3Ugc2Vzc2lvbiBoYXMgYmVlbiByZXN1bWVkJyksXHJcbiAgICAgICAgICAgICAgICAnYXV0b3Jlc3VtZSc6IF8oJ0JlIGF3YXJlIHRoYXQgeW91ciBzZXNzaW9uIGlzIHBhdXNlZC4gSWYgeW91IGNsaWNrIFllcyB5b3VyIHNlc3Npb24gd2lsbCBiZSByZXN1bWVkLicpLFxyXG4gICAgICAgICAgICAgICAgJ3VzZXInOiBfKCdsb2dpbiBhczogJyksXHJcbiAgICAgICAgICAgICAgICAncGFzc3dvcmQnOiBfKCdwYXNzd29yZDogJyksXHJcbiAgICAgICAgICAgICAgICAnY29weWxhYmxlJzogXygnQ29weScpLFxyXG4gICAgICAgICAgICAgICAgJ2Rvd25sb2FkJzogXygnRG93bmxvYWQgZmlsZXMnKSxcclxuICAgICAgICAgICAgICAgICdmaWxlUmVhZHknOiBfKCdEb3dubG9hZGluZyBpcyByZWFkeScpLFxyXG4gICAgICAgICAgICAgICAgJ2ltZ0NvcHlEb3dubG9hZCc6IF8oJ1BsZWFzZSBjb3B5IGltYWdlICh2aWEgY29udGV4dCBtZW51KSBvciBzYXZlIGl0IGlmIHlvdXIgYXBwbGljYXRpb24gZG9lc25cXCd0IHN1cHBvcnQgSFRNTCBmb3JtYXQnKSxcclxuICAgICAgICAgICAgICAgICd1c2VyQ29weSc6IF8oJ0ZhaWxlZCB0byBjb3B5IHRoZSBmb2xsb3dpbmdzIHRvIGxvY2FsIGNsaXBib2FyZC4gUGxlYXNlIGNvcHkgaXQgYWdhaW4gdmlhIGNvbnRleHQgbWVudScpLFxyXG4gICAgICAgICAgICAgICAgJ3N1Y2NlZWRlZCc6IF8oJ09wZXJhdGlvbiBzdWNjZWVkZWQuJyksXHJcbiAgICAgICAgICAgICAgICAnZGlnaXQ2JzogXygnSXQgbXVzdCBiZSBhIDYgZGlnaXQgbnVtYmVyJyksXHJcbiAgICAgICAgICAgICAgICAnVHdhaW5Ob3RTdXBwb3J0ZWQnOiBfKCdUaGUgc2VsZWN0ZWQgc2Nhbm5lciBkb2VzIG5vdCBzdXBvb3J0IFRXQUlOIHByb3RvY29sLiBDb3VsZCBub3QgdXNlIFR3YWluLWJhc2VkIERhdGFTb3VyY2UnKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlcnJvckNvZGU6IHtcclxuICAgICAgICAgICAgICAgICcxJzogXygnVGhlIGRpc2Nvbm5lY3Rpb24gd2FzIGluaXRpYXRlZCBieSBhbiBhZG1pbmlzdHJhdGl2ZSB0b29sIG9uIHRoZSBzZXJ2ZXIgaW4gYW5vdGhlciBzZXNzaW9uLicpLFxyXG4gICAgICAgICAgICAgICAgJzInOiBfKCdUaGUgZGlzY29ubmVjdGlvbiB3YXMgZHVlIHRvIGEgZm9yY2VkIGxvZ29mZiBpbml0aWF0ZWQgYnkgYW4gYWRtaW5pc3RyYXRpdmUgdG9vbCBvbiB0aGUgc2VydmVyIGluIGFub3RoZXIgc2Vzc2lvbi4nKSxcclxuICAgICAgICAgICAgICAgICczJzogXygnVGhlIGlkbGUgc2Vzc2lvbiBsaW1pdCB0aW1lciBvbiB0aGUgc2VydmVyIGhhcyBlbGFwc2VkLicpLFxyXG4gICAgICAgICAgICAgICAgJzQnOiBfKCdUaGUgYWN0aXZlIHNlc3Npb24gbGltaXQgdGltZXIgb24gdGhlIHNlcnZlciBoYXMgZWxhcHNlZC4nKSxcclxuICAgICAgICAgICAgICAgICc1JzogXygnQW5vdGhlciB1c2VyIGNvbm5lY3RlZCB0byB0aGUgc2VydmVyLCBmb3JjaW5nIHRoZSBkaXNjb25uZWN0aW9uIG9mIHRoZSBjdXJyZW50IGNvbm5lY3Rpb24uJyksXHJcbiAgICAgICAgICAgICAgICAnNic6IF8oJ1RoZSBzZXJ2ZXIgcmFuIG91dCBvZiBhdmFpbGFibGUgbWVtb3J5IHJlc291cmNlcy4nKSxcclxuICAgICAgICAgICAgICAgICc3JzogXygnVGhlIHNlcnZlciBkZW5pZWQgdGhlIGNvbm5lY3Rpb24uJyksXHJcbiAgICAgICAgICAgICAgICAnOSc6IF8oJ1RoZSB1c2VyIGNhbm5vdCBjb25uZWN0IHRvIHRoZSBzZXJ2ZXIgZHVlIHRvIGluc3VmZmljaWVudCBhY2Nlc3MgcHJpdmlsZWdlcy4nKSxcclxuICAgICAgICAgICAgICAgICdBJzogXygnVGhlIHNlcnZlciBkb2VzIG5vdCBhY2NlcHQgc2F2ZWQgdXNlciBjcmVkZW50aWFscyBhbmQgcmVxdWlyZXMgdGhhdCB0aGUgdXNlciBlbnRlciB0aGVpciBjcmVkZW50aWFscyBmb3IgZWFjaCBjb25uZWN0aW9uLicpLFxyXG4gICAgICAgICAgICAgICAgJ0InOiBfKFwiVGhlIGRpc2Nvbm5lY3Rpb24gd2FzIGluaXRpYXRlZCBieSBhbiBhZG1pbmlzdHJhdGl2ZSB0b29sIG9uIHRoZSBzZXJ2ZXIgcnVubmluZyBpbiB0aGUgdXNlcidzIHNlc3Npb24uXCIpLFxyXG4gICAgICAgICAgICAgICAgJ0MnOiBfKCdUaGUgZGlzY29ubmVjdGlvbiB3YXMgaW5pdGlhdGVkIGJ5IHRoZSB1c2VyIGxvZ2dpbmcgb2ZmIGhpcyBvciBoZXIgc2Vzc2lvbiBvbiB0aGUgc2VydmVyLicpLFxyXG4gICAgICAgICAgICAgICAgLy9Qcm90b2NvbC1pbmRlcGVuZGVudCBsaWNlbnNpbmcgY29kZXM6XHJcbiAgICAgICAgICAgICAgICAnMTAwJzogXygnQW4gaW50ZXJuYWwgZXJyb3IgaGFzIG9jY3VycmVkIGluIHRoZSBUZXJtaW5hbCBTZXJ2aWNlcyBsaWNlbnNpbmcgY29tcG9uZW50LicpLFxyXG4gICAgICAgICAgICAgICAgJzEwMSc6IF8oJ0EgVGVybWluYWwgU2VydmVyIExpY2Vuc2UgU2VydmVyIGNvdWxkIG5vdCBiZSBmb3VuZCB0byBwcm92aWRlIGEgbGljZW5zZS4nKSxcclxuICAgICAgICAgICAgICAgICcxMDInOiBfKCdUaGVyZSBhcmUgbm8gQ2xpZW50IEFjY2VzcyBMaWNlbnNlcyAgYXZhaWxhYmxlIGZvciB0aGUgdGFyZ2V0IHJlbW90ZSBjb21wdXRlci4nKSxcclxuICAgICAgICAgICAgICAgICcxMDMnOiBfKCdUaGUgcmVtb3RlIGNvbXB1dGVyIHJlY2VpdmVkIGFuIGludmFsaWQgbGljZW5zaW5nIG1lc3NhZ2UgZnJvbSB0aGUgY2xpZW50LicpLFxyXG4gICAgICAgICAgICAgICAgJzEwNCc6IF8oJ1RoZSBDbGllbnQgQWNjZXNzIExpY2Vuc2Ugc3RvcmVkIGJ5IHRoZSBjbGllbnQgaGFzIGJlZW4gbW9kaWZpZWQuJyksXHJcbiAgICAgICAgICAgICAgICAnMTA1JzogXygnVGhlIENsaWVudCBBY2Nlc3MgTGljZW5zZSBzdG9yZWQgYnkgdGhlIGNsaWVudCBpcyBpbiBhbiBpbnZhbGlkIGZvcm1hdCcpLFxyXG4gICAgICAgICAgICAgICAgJzEwNic6IF8oJ05ldHdvcmsgcHJvYmxlbXMgaGF2ZSBjYXVzZWQgdGhlIGxpY2Vuc2luZyBwcm90b2NvbCB0byBiZSB0ZXJtaW5hdGVkLicpLFxyXG4gICAgICAgICAgICAgICAgJzEwNyc6IF8oJ1RoZSBjbGllbnQgcHJlbWF0dXJlbHkgZW5kZWQgdGhlIGxpY2Vuc2luZyBwcm90b2NvbC4nKSxcclxuICAgICAgICAgICAgICAgICcxMDgnOiBfKCdBIGxpY2Vuc2luZyBtZXNzYWdlIHdhcyBpbmNvcnJlY3RseSBlbmNyeXB0ZWQuJyksXHJcbiAgICAgICAgICAgICAgICAnMTA5JzogXygnVGhlIENsaWVudCBBY2Nlc3MgTGljZW5zZSBzdG9yZWQgYnkgdGhlIGNsaWVudCBjb3VsZCBub3QgYmUgdXBncmFkZWQgb3IgcmVuZXdlZC4nKSxcclxuICAgICAgICAgICAgICAgICcxMEEnOiBfKCdUaGUgcmVtb3RlIGNvbXB1dGVyIGlzIG5vdCBsaWNlbnNlZCB0byBhY2NlcHQgcmVtb3RlIGNvbm5lY3Rpb25zJyksXHJcbiAgICAgICAgICAgICAgICAnY29ubmVjdGlvbic6IF8oJ0ZhaWxlZCB0byBjb25uZWN0IHRvIEdhdGV3YXkhJyksXHJcbiAgICAgICAgICAgICAgICAncHdkbWF0Y2gnOiBfKCdQYXNzd29yZHMgZG9uXFwndCBtYXRjaCcpLFxyXG4gICAgICAgICAgICAgICAgLy9lcnJvciBjb2RlIGZyb20gc2VydmVyXHJcbiAgICAgICAgICAgICAgICAnUzAnOiBfKCdOZXcgUmVtb3RlQXBwIG9yIGRlc2t0b3AgZm91bmQuIFBsZWFzZSByZWZyZXNoIHlvdXIgbGlzdC4nKSxcclxuICAgICAgICAgICAgICAgICdTMSc6IF8oJ0xpY2Vuc2UgZXhwaXJlZC4nKSxcclxuICAgICAgICAgICAgICAgICdTMic6IF8oJ1lvdSBtdXN0IGxvZyBpbiBmaXJzdC4nKSxcclxuICAgICAgICAgICAgICAgICdTMyc6IF8oJ0Rpc2Nvbm5lY3RlZCBieSBzZXJ2ZXIuJyksXHJcbiAgICAgICAgICAgICAgICAnUzQnOiBfKCdDb250cm9sIHJlcXVlc3Qgd2FzIHJlZnVzZWQnKSxcclxuICAgICAgICAgICAgICAgICdTNic6IF8oJ0pvaW5pbmcgcmVxdWVzdCB3YXMgcmVmdXNlZCcpLFxyXG4gICAgICAgICAgICAgICAgJ1M3JzogXygnVGhlIHBhc3N3b3JkIGlzIG5vdCBjb3JyZWN0JyksXHJcbiAgICAgICAgICAgICAgICAnUzgnOiBfKCdSZW1vdGUgY29udHJvbCB3YXMgZGVuaWVkIGR1ZSB0byBncm91cCBwb2xpY3kgc2V0dGluZ3MnKSxcclxuICAgICAgICAgICAgICAgICdTOSc6IF8oJ1RoZSB1c2VyIGlzIGFscmVhZHkgdW5kZXIgcmVtb3RlIGNvbnRyb2wnKSwgLy8zN1xyXG4gICAgICAgICAgICAgICAgJ1MxMCc6IF8oJ1JlbW90ZSBjb250cm9sIG9mIHRoZSB1c2VyIHNlc3Npb24gaGFzIGVuZGVkLicpLCAvLzMwMlxyXG4gICAgICAgICAgICAgICAgJ1MxMSc6IF8oJ1N0YXR1cyB1cGRhdGUgb2YgcHJpbnRpbmc6ICcpLFxyXG4gICAgICAgICAgICAgICAgJ1MxMDAnOiBfKCdZb3UgcGFzc3dvcmQgaXMgYWJvdXQgdG8gZXhwaXJlLiBEYXlzIGxlZnQ6ICcpLFxyXG4gICAgICAgICAgICAgICAgJ1MzMDAwJzogXygnSW52YWxpZCB1c2VyLicpLFxyXG4gICAgICAgICAgICAgICAgJ1MzMDAxJzogXygnTm8gYWNjZXNzIHJpZ2h0LicpLFxyXG4gICAgICAgICAgICAgICAgJ1MzMDAyJzogXygnRmFpbGVkIHRvIGdlbmVyYXRlIFBERiBmaWxlLicpLFxyXG4gICAgICAgICAgICAgICAgJ1MzMDAzJzogXygnUERGIENvbnZlcnRlciBub3QgZm91bmQuJyksXHJcbiAgICAgICAgICAgICAgICAnUzMwMDQnOiBfKCdVbmtub3duIGhvc3QgbmFtZTogJyksXHJcbiAgICAgICAgICAgICAgICAnUzMwMDUnOiBfKCdFcnJvcjonKSxcclxuICAgICAgICAgICAgICAgICdTMzAwNic6IF8oJ1dyb25nIHVzZXIgbmFtZSBvciBwYXNzd29yZCEnKSxcclxuICAgICAgICAgICAgICAgICdTMzAwNyc6IF8oJ0ZpbGUgbm90IGZvdW5kJyksXHJcbiAgICAgICAgICAgICAgICAnUzMwMDgnOiBfKCdGYWlsZWQgdG8gcGxheSBmaWxlJyksXHJcbiAgICAgICAgICAgICAgICAnUzMwMDknOiBfKCdPbmx5IGFjY2VwdCBjb25uZWN0aW9ucyBmcm9tIGxvY2FsaG9zdC4gWW91IGNhbiB0cnkgbG9jYWxob3N0LCAxMjcuMC4wLjEsIGhvc3QgbmFtZSwgb3IgbG9jYWwgSVAnKSxcclxuICAgICAgICAgICAgICAgICdTMzAxMCc6IF8oJ1Nlc3Npb24gbm90IGZvdW5kIG9yIGNhbm5vdCBiZSBqb2luZWQnKSxcclxuICAgICAgICAgICAgICAgICdTMzAxMSc6IF8oJ01heGltdW0gbnVtYmVyIG9mIGNvbmN1cnJlbnQgdXNlcnMgaXMgcmVhY2hlZC4nKSxcclxuICAgICAgICAgICAgICAgICdTMzAxMic6IF8oJ1VzZXIgc2Vzc2lvbiB0aW1lb3V0JyksXHJcbiAgICAgICAgICAgICAgICAnUzMwMTQnOiBfKCdJbnZhbGlkIHN5bWxpbmsnKSxcclxuICAgICAgICAgICAgICAgICdTMzAxNSc6IF8oJ1dyb25nIHN5bWxpbmsgcGFzc3dvcmQnKSxcclxuICAgICAgICAgICAgICAgICdTMzAxNic6IF8oJ1RoZXJlIGlzIG5vdCBlbm91Z2ggZnJlZSBkaXNrIHNwYWNlLicpLFxyXG4gICAgICAgICAgICAgICAgJ1MzMDE3JzogXygnQ2FuIG5vdCBjb25uZWN0IHRvIHRoZSByZW1vdGUgY29tcHV0ZXI6IGNvbXB1dGVyIGlzIG5vdCBhdmFpbGFibGUgb3IgUmVtb3RlIERlc2t0b3AgaXMgbm90IGVuYWJsZWQuJyksXHJcbiAgICAgICAgICAgICAgICAnUzMwMTgnOiBfKCdGaWxlIGlzIGJsb2NrZWQuJyksXHJcbiAgICAgICAgICAgICAgICAnUzMwMTknOiBfKCdNYXhpbXVtIG51bWJlciBvZiBlbWVyZ2VuY3kgY29uY3VycmVudCB1c2VycyBpcyByZWFjaGVkLicpLFxyXG4gICAgICAgICAgICAgICAgJ1MzMDIwJzogXygnTWF4aW11bSBudW1iZXIgb2YgZW1lcmdlbmN5IGxpY2Vuc2UgZGF5cyBpcyByZWFjaGVkLicpLFxyXG4gICAgICAgICAgICAgICAgJ1MzMDIxJzogXygnV3JvbmcgYXV0aGVudGljYXRpb24gY29kZScpXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHNlcnZlclN0YXR1czoge1xyXG4gICAgICAgICAgICAgICAgJzQwMSc6IF8oJ1RoZSBkZXN0aW5hdGlvbiBjb21wdXRlciBpcyBiZWluZyBsb2NhdGVkLicpLFxyXG4gICAgICAgICAgICAgICAgJzQwMic6IF8oJ1RoZSBkZXN0aW5hdGlvbiBjb21wdXRlciBpcyBiZWluZyBwcmVwYXJlZCBmb3IgdXNlLicpLFxyXG4gICAgICAgICAgICAgICAgJzQwMyc6IF8oJ1RoZSBkZXN0aW5hdGlvbiBjb21wdXRlciBpcyBiZWluZyBwcmVwYXJlZCB0byBhY2NlcHQgYSByZW1vdGUgY29ubmVjdGlvbi4nKSxcclxuICAgICAgICAgICAgICAgICc0MDQnOiBfKCdUaGUgY2xpZW50IGlzIGJlaW5nIHJlZGlyZWN0ZWQgdG8gdGhlIGRlc3RpbmF0aW9uIGNvbXB1dGVyLicpLFxyXG4gICAgICAgICAgICAgICAgJzUwMSc6IF8oJ1RoZSBkZXN0aW5hdGlvbiB2aXJ0dWFsIG1hY2hpbmUgaW1hZ2UgaXMgYmVpbmcgbG9hZGVkLicpLFxyXG4gICAgICAgICAgICAgICAgJzUwMic6IF8oJ1RoZSBkZXN0aW5hdGlvbiB2aXJ0dWFsIG1hY2hpbmUgaXMgYmVpbmcgcmVzdW1lZCBmcm9tIHNsZWVwIG9yIGhpYmVybmF0aW9uLicpLFxyXG4gICAgICAgICAgICAgICAgJzUwMyc6IF8oJ1RoZSBkZXN0aW5hdGlvbiB2aXJ0dWFsIG1hY2hpbmUgaXMgYmVpbmcgYm9vdGVkJylcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZmlsZToge1xyXG4gICAgICAgICAgICAgICAgJ3plcm8nOiBfKCdGaWxlIHNpemUgaXMgMCwgaWdub3JlZCAnKSxcclxuICAgICAgICAgICAgICAgICdzbGljZSc6IF8oXCJGaWxlUmVhZGVyIGRvZXNuJ3Qgc3VwcG9ydCBzbGljZVwiKSxcclxuICAgICAgICAgICAgICAgICd1cGxvYWREb25lJzogXygnRmlsZSB1cGxvYWRpbmcgZmluaXNoZWQuIFBsZWFzZSByZWZyZXNoIHRoZSBzaGFyZWQgZGlzayBpbiBNeSBDb21wdXRlci4nKSxcclxuICAgICAgICAgICAgICAgICdmb2xkZXInOiBfKCdmb2xkZXInKSxcclxuICAgICAgICAgICAgICAgICcxJzogXygnSW52YWxpZCBkaXJlY3RvcnkuJyksXHJcbiAgICAgICAgICAgICAgICAnMic6IF8oJ05vdCBhIGRpcmVjdG9yeScpXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHBsYXllcjoge1xyXG4gICAgICAgICAgICAgICAgJ25vaW5wdXQnOiBfKCdObyBpbnB1dCBmb3VuZC4nKSxcclxuICAgICAgICAgICAgICAgICdmbXRlcnJvcic6IF8oJ0ludmFsaWQgZmlsZSBmb3JtYXQuJylcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdGVtcGxhdGU6IHtcclxuICAgICAgICAgICAgICAgICdmaWxlY29udGFpbmVyJzogXygnPGRpdiBpZD1cInRvdGFsXCIgY2xhc3M9XCJwcm9ncmVzc2JhY2tcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmVcIj5cXFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVwbG9hZGluZy4uLjxkaXYgY2xhc3M9XCJwcm9ncmVzc2Zyb250XCI+PC9kaXY+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGhcIj48YnV0dG9uIGlkPVwiX19zdl9wb3NpdGlvbl9fXCI+WW91ciBQb3NpdGlvbjo8L2J1dHRvbj4gPHNwYW4gaWQ9XCJwYXJlbnRQYXRoXCI+PC9zcGFuPjxpbnB1dCB0eXBlPVwiZmlsZVwiIGlkPVwidXBsb2FkZmlsZVwiIG5hbWU9XCJ1cGxvYWRcIiBtdWx0aXBsZSAvPiBcXFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiYnV0dG9uXCIgaWQ9XCJfX2NhbmNlbFVwbG9hZFwiIHN0eWxlPVwidmlzaWJpbGl0eTpoaWRkZW5cIiB2YWx1ZT1cIkNhbmNlbCB1cGxvYWRpbmdcIj48c3BhbiBpZD1cIl9fZGlza1NwYWNlXCI+PC9zcGFuPjxpbnB1dCBpZD1cIl9fc3ZfZm9sZGVyX25hbWVfXCIgcGxhY2Vob2xkZXI9XCJmb2xkZXIgbmFtZVwiID48aW1nIGlkPVwiX19zdl9mb2xkZXJfX1wiIHNyYz1cIiUxL2ZvbGRlci5wbmdcIiBhbGlnbj1cImNlbnRlclwiIG5hbWU9XCJmb2xkZXJcIiB0aXRsZT1cIk5ldyBmb2xkZXJcIiA+PC9kaXY+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBpZD1cImZpbGVsaXN0XCIgc3VtbWFyeT1cIkZpbGUgTGlzdFwiPlxcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGhlYWQ+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5OYW1lPC90aD5cXFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPlR5cGU8L3RoPlxcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCI+U2l6ZTwvdGg+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5EYXRlIG1vZGlmaWVkPC90aD5cXFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPkFjdGlvbjwvdGg+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RoZWFkPlxcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgc3R5bGU9XCJjdXJzb3I6IHBvaW50ZXJcIj5cXFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+PC90ZD5cXFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+PC90ZD5cXFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgYWxpZ249XCJyaWdodFwiPjwvdGQ+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPjwvdGQ+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPjxpbWcgaWQ9XCJfX3N2X2Rvd25sb2FkX19cIiBzcmM9XCIlMS9kb3dubG9hZC5wbmdcIiB0aXRsZT1cIkRvd25sb2FkXCIgbmFtZT1cImRvd25sb2FkXCI+PGltZyBpZD1cIl9fc3Zfdmlld19fXCIgc3JjPVwiJTEvdmlldy5wbmdcIiBuYW1lPVwidmlld1wiIHRpdGxlPVwiVmlld1wiPjxpbWcgaWQ9XCJfX3N2X2RlbF9fXCIgc3JjPVwiJTEvZGVsLnBuZ1wiIG5hbWU9XCJkZWxldGVcIiB0aXRsZT1cIkRlbGV0ZVwiPjwvdGQ+XFxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxcXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPicpLFxyXG4gICAgICAgICAgICAgICAgJ2xvZ2luJzogXygnRW50ZXIgeW91ciBjcmVkZW50aWFsczo8YnI+XFxcclxuICAgICAgICAgICAgICAgICAgICA8Zm9ybSBpZD0gXCJmcm1Mb2dpblwiPlxcXHJcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgcGxhY2Vob2xkZXI9XCJVc2VyIG5hbWVcIiBpZD1cImxvZ2luVXNlclwiLz48YnI+XFxcclxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInBhc3N3b3JkXCIgcGxhY2Vob2xkZXI9XCJQYXNzd29yZFwiIGlkPVwibG9naW5QYXNzd29yZFwiIGF1dG9jb21wbGV0ZT1cIm9mZlwiLz48YnI+XFxcclxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIkRvbWFpblwiIGlkPVwibG9naW5Eb21haW5cIi8+XFxcclxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInN1Ym1pdFwiIGlkPVwibG9naW5Db25uZWN0XCIvPlxcXHJcbiAgICAgICAgICAgICAgICAgICAgPC9mb3JtPicpLFxyXG4gICAgICAgICAgICAgICAgJ2xvYWRlZCc6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgJ2luaXQnOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZjID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbGVjb250YWluZXInKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHAgPSB3aW5kb3cuX19zdmkxOG4udGVtcGxhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZjKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZjLmlubmVySFRNTCA9IHRwLmZpbGVjb250YWluZXIucmVwbGFjZShcIiUxXCIsIGdldExpYlBhdGgoXCJyZXNvdXJjZS5qc1wiKSk7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2ZpbGUgY29udGFpbmVyIHRlbXBsYXRlIGxvYWRlZC4nKTtcclxuICAgICAgICAgICAgICAgICAgICB9ZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cC5sb2FkZWQpIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB0cC5pbml0LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRwLmxvYWRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHZuYzoge1xyXG4gICAgICAgICAgICAgICAgbm90dm5jOiBfKCdJbnZhbGlkIFJGQiBzZXJ2ZXInKSxcclxuICAgICAgICAgICAgICAgIHNlY3VyaXR5RXJyb3I6IF8oJ1NlY3VyaXR5IHR5cGUgaXMgbm90IHN1cHBvcnRlZCcpLFxyXG4gICAgICAgICAgICAgICAgYXV0aEVycm9yOiBfKCdGYWlsZWQgdG8gYXV0aGVudGljYXRlJylcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgd2luZG93Ll9fc3ZpMThuLnRlbXBsYXRlLmluaXQoKTtcclxuXHJcbiAgICAgICAgaTE4bi5ub3RpZnlSZWFkeSgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgd2luZG93LmdldFNwYXJrSTE4biA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cuX19zdmkxOG47XHJcbiAgICB9O1xyXG59KSgpO1xuXG5cbi8qKiogRVhQT1JUUyBGUk9NIGV4cG9ydHMtbG9hZGVyICoqKi9cbm1vZHVsZS5leHBvcnRzID0gd2luZG93LmdldFNwYXJrSTE4bjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvYXBwY2ZnLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9hcHBjZmcuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9hcHBjZmcuanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvYXVkaW9yZWNvcmRlcl9taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvYXVkaW9yZWNvcmRlcl9taW4uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL2F1ZGlvcmVjb3JkZXJfbWluLmpzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2Nsb3VkLnBuZ1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvY2xvdWQucG5nICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18ucCArIFwic3BhcmtJZnJhbWUvY2xvdWQucG5nXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2RlbC5wbmdcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9kZWwucG5nICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL2RlbC5wbmdcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGFuZGxlLnBuZ1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2hhbmRsZS5wbmcgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18ucCArIFwic3BhcmtJZnJhbWUvaGFuZGxlLnBuZ1wiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9oaTUuY3NzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGk1LmNzcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9oaTUuY3NzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2hpNV9taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9oaTVfbWluLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL2hpNV9taW4uanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGk1Y29yZV9taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGk1Y29yZV9taW4uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL2hpNWNvcmVfbWluLmpzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2luZm8ucG5nXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2luZm8ucG5nICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9pbmZvLnBuZ1wiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9rYmQucG5nXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUva2JkLnBuZyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9rYmQucG5nXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3BsdWdpbi5zd2ZcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9wbHVnaW4uc3dmICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL3BsdWdpbi5zd2ZcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmRwLmNzc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JkcC5jc3MgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18ucCArIFwic3BhcmtJZnJhbWUvcmRwLmNzc1wiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9yZHBfbWluLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmRwX21pbi5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9yZHBfbWluLmpzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JkcGNvcmVfbWluLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JkcGNvcmVfbWluLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9yZHBjb3JlX21pbi5qc1wiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9yZHB3b3JrZXJfbWluLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmRwd29ya2VyX21pbi5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9yZHB3b3JrZXJfbWluLmpzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JlY29yZGluZ19taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9yZWNvcmRpbmdfbWluLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL3JlY29yZGluZ19taW4uanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmVzb3VyY2UuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmVzb3VyY2UuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL3Jlc291cmNlLmpzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3NzaF9taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9zc2hfbWluLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL3NzaF9taW4uanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvc3RyaW5ncy1lbi5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3N0cmluZ3MtZW4uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18ucCArIFwic3BhcmtJZnJhbWUvc3RyaW5ncy1lbi5qc1wiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9zdXJmYWNlX21pbi5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9zdXJmYWNlX21pbi5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18ucCArIFwic3BhcmtJZnJhbWUvc3VyZmFjZV9taW4uanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm13YXJlL2pxdWVyeS0zLjQuMS5taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm13YXJlL2pxdWVyeS0zLjQuMS5taW4uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL2pxdWVyeS0zLjQuMS5taW4uanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm13YXJlL2pxdWVyeS11aS0xLjEyLjAubWluLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS92bXdhcmUvanF1ZXJ5LXVpLTEuMTIuMC5taW4uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9qcXVlcnktdWktMS4xMi4wLm1pbi5qc1wiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS92bXdhcmUvd21rcy5taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3Ztd2FyZS93bWtzLm1pbi5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL3dta3MubWluLmpzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3ZuY19taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS92bmNfbWluLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL3ZuY19taW4uanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm5jdXRpbF9taW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm5jdXRpbF9taW4uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBcInNwYXJrSWZyYW1lL3ZuY3V0aWxfbWluLmpzXCI7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2lmcmFtZS9zcGFya0NsaWVudC5pZnJhbWUuYWRhcHRlci5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaWZyYW1lL3NwYXJrQ2xpZW50LmlmcmFtZS5hZGFwdGVyLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18ucCArIFwic3BhcmtJZnJhbWUvc3BhcmtDbGllbnQuaWZyYW1lLmFkYXB0ZXIuanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaWZyYW1lL3NwYXJrQ2xpZW50LmlmcmFtZS5odG1sXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9pZnJhbWUvc3BhcmtDbGllbnQuaWZyYW1lLmh0bWwgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9zcGFya0NsaWVudC5pZnJhbWUuaHRtbFwiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9pZnJhbWUvc3BhcmtDbGllbnQuaWZyYW1lLndta3NLZXlDb2RlTWFwLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaWZyYW1lL3NwYXJrQ2xpZW50LmlmcmFtZS53bWtzS2V5Q29kZU1hcC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9zcGFya0NsaWVudC5pZnJhbWUud21rc0tleUNvZGVNYXAuanNcIjtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaWZyYW1lL3NwYXJrQ2xpZW50LmlmcmFtZS53bWtzVnNjYW5Db2RlTWFwLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9pZnJhbWUvc3BhcmtDbGllbnQuaWZyYW1lLndta3NWc2NhbkNvZGVNYXAuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgXCJzcGFya0lmcmFtZS9zcGFya0NsaWVudC5pZnJhbWUud21rc1ZzY2FuQ29kZU1hcC5qc1wiO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbi8qISBpZWVlNzU0LiBCU0QtMy1DbGF1c2UgTGljZW5zZS4gRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnL29wZW5zb3VyY2U+ICovXG5leHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IChlICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IChtICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKCh2YWx1ZSAqIGMpIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5pZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbnZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL25vZGUtbGlicy1icm93c2VyL25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9saWIvc3RyaW5nX2RlY29kZXIuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9ub2RlLWxpYnMtYnJvd3Nlci9ub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuXG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBzYWZlLWJ1ZmZlciAqLyBcIi4vbm9kZV9tb2R1bGVzL25vZGUtbGlicy1icm93c2VyL25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9ub2RlX21vZHVsZXMvc2FmZS1idWZmZXIvaW5kZXguanNcIikuQnVmZmVyO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBpc0VuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmcgfHwgZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIGVuY29kaW5nID0gJycgKyBlbmNvZGluZztcbiAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpjYXNlICd1dGY4JzpjYXNlICd1dGYtOCc6Y2FzZSAnYXNjaWknOmNhc2UgJ2JpbmFyeSc6Y2FzZSAnYmFzZTY0JzpjYXNlICd1Y3MyJzpjYXNlICd1Y3MtMic6Y2FzZSAndXRmMTZsZSc6Y2FzZSAndXRmLTE2bGUnOmNhc2UgJ3Jhdyc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIGlmICghZW5jKSByZXR1cm4gJ3V0ZjgnO1xuICB2YXIgcmV0cmllZDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuYykge1xuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiAndXRmOCc7XG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gJ3V0ZjE2bGUnO1xuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiAnbGF0aW4xJztcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gZW5jO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKHJldHJpZWQpIHJldHVybjsgLy8gdW5kZWZpbmVkXG4gICAgICAgIGVuYyA9ICgnJyArIGVuYykudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0cmllZCA9IHRydWU7XG4gICAgfVxuICB9XG59O1xuXG4vLyBEbyBub3QgY2FjaGUgYEJ1ZmZlci5pc0VuY29kaW5nYCB3aGVuIGNoZWNraW5nIGVuY29kaW5nIG5hbWVzIGFzIHNvbWVcbi8vIG1vZHVsZXMgbW9ua2V5LXBhdGNoIGl0IHRvIHN1cHBvcnQgYWRkaXRpb25hbCBlbmNvZGluZ3NcbmZ1bmN0aW9uIG5vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICB2YXIgbmVuYyA9IF9ub3JtYWxpemVFbmNvZGluZyhlbmMpO1xuICBpZiAodHlwZW9mIG5lbmMgIT09ICdzdHJpbmcnICYmIChCdWZmZXIuaXNFbmNvZGluZyA9PT0gaXNFbmNvZGluZyB8fCAhaXNFbmNvZGluZyhlbmMpKSkgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jKTtcbiAgcmV0dXJuIG5lbmMgfHwgZW5jO1xufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuXG5leHBvcnRzLlN0cmluZ0RlY29kZXIgPSBTdHJpbmdEZWNvZGVyO1xuZnVuY3Rpb24gU3RyaW5nRGVjb2RlcihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gbm9ybWFsaXplRW5jb2RpbmcoZW5jb2RpbmcpO1xuICB2YXIgbmI7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgdGhpcy50ZXh0ID0gdXRmMTZUZXh0O1xuICAgICAgdGhpcy5lbmQgPSB1dGYxNkVuZDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgdGhpcy5maWxsTGFzdCA9IHV0ZjhGaWxsTGFzdDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICB0aGlzLnRleHQgPSBiYXNlNjRUZXh0O1xuICAgICAgdGhpcy5lbmQgPSBiYXNlNjRFbmQ7XG4gICAgICBuYiA9IDM7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHNpbXBsZVdyaXRlO1xuICAgICAgdGhpcy5lbmQgPSBzaW1wbGVFbmQ7XG4gICAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIHRoaXMubGFzdFRvdGFsID0gMDtcbiAgdGhpcy5sYXN0Q2hhciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuYik7XG59XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICB2YXIgcjtcbiAgdmFyIGk7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgciA9IHRoaXMuZmlsbExhc3QoYnVmKTtcbiAgICBpZiAociA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XG4gICAgaSA9IHRoaXMubGFzdE5lZWQ7XG4gICAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgaSA9IDA7XG4gIH1cbiAgaWYgKGkgPCBidWYubGVuZ3RoKSByZXR1cm4gciA/IHIgKyB0aGlzLnRleHQoYnVmLCBpKSA6IHRoaXMudGV4dChidWYsIGkpO1xuICByZXR1cm4gciB8fCAnJztcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IHV0ZjhFbmQ7XG5cbi8vIFJldHVybnMgb25seSBjb21wbGV0ZSBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS50ZXh0ID0gdXRmOFRleHQ7XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgcGFydGlhbCBub24tVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmZpbGxMYXN0ID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufTtcblxuLy8gQ2hlY2tzIHRoZSB0eXBlIG9mIGEgVVRGLTggYnl0ZSwgd2hldGhlciBpdCdzIEFTQ0lJLCBhIGxlYWRpbmcgYnl0ZSwgb3IgYVxuLy8gY29udGludWF0aW9uIGJ5dGUuIElmIGFuIGludmFsaWQgYnl0ZSBpcyBkZXRlY3RlZCwgLTIgaXMgcmV0dXJuZWQuXG5mdW5jdGlvbiB1dGY4Q2hlY2tCeXRlKGJ5dGUpIHtcbiAgaWYgKGJ5dGUgPD0gMHg3RikgcmV0dXJuIDA7ZWxzZSBpZiAoYnl0ZSA+PiA1ID09PSAweDA2KSByZXR1cm4gMjtlbHNlIGlmIChieXRlID4+IDQgPT09IDB4MEUpIHJldHVybiAzO2Vsc2UgaWYgKGJ5dGUgPj4gMyA9PT0gMHgxRSkgcmV0dXJuIDQ7XG4gIHJldHVybiBieXRlID4+IDYgPT09IDB4MDIgPyAtMSA6IC0yO1xufVxuXG4vLyBDaGVja3MgYXQgbW9zdCAzIGJ5dGVzIGF0IHRoZSBlbmQgb2YgYSBCdWZmZXIgaW4gb3JkZXIgdG8gZGV0ZWN0IGFuXG4vLyBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyLiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzICgyLCAzLCBvciA0KVxuLy8gbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBVVEYtOCBjaGFyYWN0ZXIgKGlmIGFwcGxpY2FibGUpIGFyZSByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0luY29tcGxldGUoc2VsZiwgYnVmLCBpKSB7XG4gIHZhciBqID0gYnVmLmxlbmd0aCAtIDE7XG4gIGlmIChqIDwgaSkgcmV0dXJuIDA7XG4gIHZhciBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAxO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAyO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSB7XG4gICAgICBpZiAobmIgPT09IDIpIG5iID0gMDtlbHNlIHNlbGYubGFzdE5lZWQgPSBuYiAtIDM7XG4gICAgfVxuICAgIHJldHVybiBuYjtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy8gVmFsaWRhdGVzIGFzIG1hbnkgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIGFzXG4vLyBuZWVkZWQgb3IgYXJlIGF2YWlsYWJsZS4gSWYgd2Ugc2VlIGEgbm9uLWNvbnRpbnVhdGlvbiBieXRlIHdoZXJlIHdlIGV4cGVjdFxuLy8gb25lLCB3ZSBcInJlcGxhY2VcIiB0aGUgdmFsaWRhdGVkIGNvbnRpbnVhdGlvbiBieXRlcyB3ZSd2ZSBzZWVuIHNvIGZhciB3aXRoXG4vLyBhIHNpbmdsZSBVVEYtOCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgKCdcXHVmZmZkJyksIHRvIG1hdGNoIHY4J3MgVVRGLTggZGVjb2Rpbmdcbi8vIGJlaGF2aW9yLiBUaGUgY29udGludWF0aW9uIGJ5dGUgY2hlY2sgaXMgaW5jbHVkZWQgdGhyZWUgdGltZXMgaW4gdGhlIGNhc2Vcbi8vIHdoZXJlIGFsbCBvZiB0aGUgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIGNoYXJhY3RlciBleGlzdCBpbiB0aGUgc2FtZSBidWZmZXIuXG4vLyBJdCBpcyBhbHNvIGRvbmUgdGhpcyB3YXkgYXMgYSBzbGlnaHQgcGVyZm9ybWFuY2UgaW5jcmVhc2UgaW5zdGVhZCBvZiB1c2luZyBhXG4vLyBsb29wLlxuZnVuY3Rpb24gdXRmOENoZWNrRXh0cmFCeXRlcyhzZWxmLCBidWYsIHApIHtcbiAgaWYgKChidWZbMF0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgIHNlbGYubGFzdE5lZWQgPSAwO1xuICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gIH1cbiAgaWYgKHNlbGYubGFzdE5lZWQgPiAxICYmIGJ1Zi5sZW5ndGggPiAxKSB7XG4gICAgaWYgKChidWZbMV0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgc2VsZi5sYXN0TmVlZCA9IDE7XG4gICAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICAgIH1cbiAgICBpZiAoc2VsZi5sYXN0TmVlZCA+IDIgJiYgYnVmLmxlbmd0aCA+IDIpIHtcbiAgICAgIGlmICgoYnVmWzJdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICAgICAgc2VsZi5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlci5cbmZ1bmN0aW9uIHV0ZjhGaWxsTGFzdChidWYpIHtcbiAgdmFyIHAgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gIHZhciByID0gdXRmOENoZWNrRXh0cmFCeXRlcyh0aGlzLCBidWYsIHApO1xuICBpZiAociAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcjtcbiAgaWYgKHRoaXMubGFzdE5lZWQgPD0gYnVmLmxlbmd0aCkge1xuICAgIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufVxuXG4vLyBSZXR1cm5zIGFsbCBjb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyLiBJZiB0aGUgQnVmZmVyIGVuZGVkIG9uIGFcbi8vIHBhcnRpYWwgY2hhcmFjdGVyLCB0aGUgY2hhcmFjdGVyJ3MgYnl0ZXMgYXJlIGJ1ZmZlcmVkIHVudGlsIHRoZSByZXF1aXJlZFxuLy8gbnVtYmVyIG9mIGJ5dGVzIGFyZSBhdmFpbGFibGUuXG5mdW5jdGlvbiB1dGY4VGV4dChidWYsIGkpIHtcbiAgdmFyIHRvdGFsID0gdXRmOENoZWNrSW5jb21wbGV0ZSh0aGlzLCBidWYsIGkpO1xuICBpZiAoIXRoaXMubGFzdE5lZWQpIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpKTtcbiAgdGhpcy5sYXN0VG90YWwgPSB0b3RhbDtcbiAgdmFyIGVuZCA9IGJ1Zi5sZW5ndGggLSAodG90YWwgLSB0aGlzLmxhc3ROZWVkKTtcbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgMCwgZW5kKTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGksIGVuZCk7XG59XG5cbi8vIEZvciBVVEYtOCwgYSByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaXMgYWRkZWQgd2hlbiBlbmRpbmcgb24gYSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIuXG5mdW5jdGlvbiB1dGY4RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArICdcXHVmZmZkJztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFVURi0xNkxFIHR5cGljYWxseSBuZWVkcyB0d28gYnl0ZXMgcGVyIGNoYXJhY3RlciwgYnV0IGV2ZW4gaWYgd2UgaGF2ZSBhbiBldmVuXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlLCB3ZSBuZWVkIHRvIGNoZWNrIGlmIHdlIGVuZCBvbiBhIGxlYWRpbmcvaGlnaFxuLy8gc3Vycm9nYXRlLiBJbiB0aGF0IGNhc2UsIHdlIG5lZWQgdG8gd2FpdCBmb3IgdGhlIG5leHQgdHdvIGJ5dGVzIGluIG9yZGVyIHRvXG4vLyBkZWNvZGUgdGhlIGxhc3QgY2hhcmFjdGVyIHByb3Blcmx5LlxuZnVuY3Rpb24gdXRmMTZUZXh0KGJ1ZiwgaSkge1xuICBpZiAoKGJ1Zi5sZW5ndGggLSBpKSAlIDIgPT09IDApIHtcbiAgICB2YXIgciA9IGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGkpO1xuICAgIGlmIChyKSB7XG4gICAgICB2YXIgYyA9IHIuY2hhckNvZGVBdChyLmxlbmd0aCAtIDEpO1xuICAgICAgaWYgKGMgPj0gMHhEODAwICYmIGMgPD0gMHhEQkZGKSB7XG4gICAgICAgIHRoaXMubGFzdE5lZWQgPSAyO1xuICAgICAgICB0aGlzLmxhc3RUb3RhbCA9IDQ7XG4gICAgICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgICAgICAgcmV0dXJuIHIuc2xpY2UoMCwgLTEpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMTtcbiAgdGhpcy5sYXN0VG90YWwgPSAyO1xuICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGksIGJ1Zi5sZW5ndGggLSAxKTtcbn1cblxuLy8gRm9yIFVURi0xNkxFIHdlIGRvIG5vdCBleHBsaWNpdGx5IGFwcGVuZCBzcGVjaWFsIHJlcGxhY2VtZW50IGNoYXJhY3RlcnMgaWYgd2Vcbi8vIGVuZCBvbiBhIHBhcnRpYWwgY2hhcmFjdGVyLCB3ZSBzaW1wbHkgbGV0IHY4IGhhbmRsZSB0aGF0LlxuZnVuY3Rpb24gdXRmMTZFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICB2YXIgZW5kID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICAgIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygndXRmMTZsZScsIDAsIGVuZCk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRleHQoYnVmLCBpKSB7XG4gIHZhciBuID0gKGJ1Zi5sZW5ndGggLSBpKSAlIDM7XG4gIGlmIChuID09PSAwKSByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpKTtcbiAgdGhpcy5sYXN0TmVlZCA9IDMgLSBuO1xuICB0aGlzLmxhc3RUb3RhbCA9IDM7XG4gIGlmIChuID09PSAxKSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH1cbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSwgYnVmLmxlbmd0aCAtIG4pO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygnYmFzZTY0JywgMCwgMyAtIHRoaXMubGFzdE5lZWQpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gUGFzcyBieXRlcyBvbiB0aHJvdWdoIGZvciBzaW5nbGUtYnl0ZSBlbmNvZGluZ3MgKGUuZy4gYXNjaWksIGxhdGluMSwgaGV4KVxuZnVuY3Rpb24gc2ltcGxlV3JpdGUoYnVmKSB7XG4gIHJldHVybiBidWYudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZUVuZChidWYpIHtcbiAgcmV0dXJuIGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG59XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL25vZGUtbGlicy1icm93c2VyL25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9ub2RlX21vZHVsZXMvc2FmZS1idWZmZXIvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9ub2RlLWxpYnMtYnJvd3Nlci9ub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbm9kZV9tb2R1bGVzL3NhZmUtYnVmZmVyL2luZGV4LmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuLyohIHNhZmUtYnVmZmVyLiBNSVQgTGljZW5zZS4gRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnL29wZW5zb3VyY2U+ICovXG4vKiBlc2xpbnQtZGlzYWJsZSBub2RlL25vLWRlcHJlY2F0ZWQtYXBpICovXG52YXIgYnVmZmVyID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgYnVmZmVyICovIFwiLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzXCIpXG52YXIgQnVmZmVyID0gYnVmZmVyLkJ1ZmZlclxuXG4vLyBhbHRlcm5hdGl2ZSB0byB1c2luZyBPYmplY3Qua2V5cyBmb3Igb2xkIGJyb3dzZXJzXG5mdW5jdGlvbiBjb3B5UHJvcHMgKHNyYywgZHN0KSB7XG4gIGZvciAodmFyIGtleSBpbiBzcmMpIHtcbiAgICBkc3Rba2V5XSA9IHNyY1trZXldXG4gIH1cbn1cbmlmIChCdWZmZXIuZnJvbSAmJiBCdWZmZXIuYWxsb2MgJiYgQnVmZmVyLmFsbG9jVW5zYWZlICYmIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBidWZmZXJcbn0gZWxzZSB7XG4gIC8vIENvcHkgcHJvcGVydGllcyBmcm9tIHJlcXVpcmUoJ2J1ZmZlcicpXG4gIGNvcHlQcm9wcyhidWZmZXIsIGV4cG9ydHMpXG4gIGV4cG9ydHMuQnVmZmVyID0gU2FmZUJ1ZmZlclxufVxuXG5mdW5jdGlvbiBTYWZlQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5TYWZlQnVmZmVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQnVmZmVyLnByb3RvdHlwZSlcblxuLy8gQ29weSBzdGF0aWMgbWV0aG9kcyBmcm9tIEJ1ZmZlclxuY29weVByb3BzKEJ1ZmZlciwgU2FmZUJ1ZmZlcilcblxuU2FmZUJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5TYWZlQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICB2YXIgYnVmID0gQnVmZmVyKHNpemUpXG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykge1xuICAgICAgYnVmLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGJ1Zi5maWxsKDApXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5TYWZlQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBCdWZmZXIoc2l6ZSlcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlci5TbG93QnVmZmVyKHNpemUpXG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24ocHJvY2Vzcykge1xuXG5pZiAoIXByb2Nlc3MudmVyc2lvbiB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MC4nKSA9PT0gMCB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS4nKSA9PT0gMCAmJiBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuOC4nKSAhPT0gMCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IG5leHRUaWNrO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBwcm9jZXNzLm5leHRUaWNrO1xufVxuXG5mdW5jdGlvbiBuZXh0VGljayhmbiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJjYWxsYmFja1wiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG4gIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICB2YXIgYXJncywgaTtcbiAgc3dpdGNoIChsZW4pIHtcbiAgY2FzZSAwOlxuICBjYXNlIDE6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZm4pO1xuICBjYXNlIDI6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrT25lKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxKTtcbiAgICB9KTtcbiAgY2FzZSAzOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1R3bygpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSwgYXJnMik7XG4gICAgfSk7XG4gIGNhc2UgNDpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUaHJlZSgpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gICAgfSk7XG4gIGRlZmF1bHQ6XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzW2krK10gPSBhcmd1bWVudHNbaV07XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGljaygpIHtcbiAgICAgIGZuLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqL30uY2FsbCh0aGlzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuLy4uL3Byb2Nlc3MvYnJvd3Nlci5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qc1wiKSkpXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG4vLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9kdXBsZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9fc3RyZWFtX2R1cGxleC5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanNcIilcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuLy8gYSBkdXBsZXggc3RyZWFtIGlzIGp1c3QgYSBzdHJlYW0gdGhhdCBpcyBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZS5cbi8vIFNpbmNlIEpTIGRvZXNuJ3QgaGF2ZSBtdWx0aXBsZSBwcm90b3R5cGFsIGluaGVyaXRhbmNlLCB0aGlzIGNsYXNzXG4vLyBwcm90b3R5cGFsbHkgaW5oZXJpdHMgZnJvbSBSZWFkYWJsZSwgYW5kIHRoZW4gcGFyYXNpdGljYWxseSBmcm9tXG4vLyBXcml0YWJsZS5cblxuXG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAga2V5cy5wdXNoKGtleSk7XG4gIH1yZXR1cm4ga2V5cztcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgcHJvY2Vzcy1uZXh0aWNrLWFyZ3MgKi8gXCIuL25vZGVfbW9kdWxlcy9wcm9jZXNzLW5leHRpY2stYXJncy9pbmRleC5qc1wiKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBjb3JlLXV0aWwtaXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLXV0aWwtaXMvbGliL3V0aWwuanNcIik7XG51dGlsLmluaGVyaXRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgaW5oZXJpdHMgKi8gXCIuL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzXCIpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBSZWFkYWJsZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmVhbV9yZWFkYWJsZSAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qc1wiKTtcbnZhciBXcml0YWJsZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmVhbV93cml0YWJsZSAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qc1wiKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxudmFyIGtleXMgPSBvYmplY3RLZXlzKFdyaXRhYmxlLnByb3RvdHlwZSk7XG5mb3IgKHZhciB2ID0gMDsgdiA8IGtleXMubGVuZ3RoOyB2KyspIHtcbiAgdmFyIG1ldGhvZCA9IGtleXNbdl07XG4gIGlmICghRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKSBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgcHJvY2Vzc05leHRUaWNrKG9uRW5kTlQsIHRoaXMpO1xufVxuXG5mdW5jdGlvbiBvbkVuZE5UKHNlbGYpIHtcbiAgc2VsZi5lbmQoKTtcbn1cblxuZnVuY3Rpb24gZm9yRWFjaCh4cywgZikge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGYoeHNbaV0sIGkpO1xuICB9XG59XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcbi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG5cblxubW9kdWxlLmV4cG9ydHMgPSBQYXNzVGhyb3VnaDtcblxudmFyIFRyYW5zZm9ybSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vX3N0cmVhbV90cmFuc2Zvcm0gKi8gXCIuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCIpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBjb3JlLXV0aWwtaXMgKi8gXCIuL25vZGVfbW9kdWxlcy9jb3JlLXV0aWwtaXMvbGliL3V0aWwuanNcIik7XG51dGlsLmluaGVyaXRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgaW5oZXJpdHMgKi8gXCIuL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzXCIpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoUGFzc1Rocm91Z2gsIFRyYW5zZm9ybSk7XG5cbmZ1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSkgcmV0dXJuIG5ldyBQYXNzVGhyb3VnaChvcHRpb25zKTtcblxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBvcHRpb25zKTtcbn1cblxuUGFzc1Rocm91Z2gucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihudWxsLCBjaHVuayk7XG59O1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24ocHJvY2Vzcykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHByb2Nlc3MtbmV4dGljay1hcmdzICovIFwiLi9ub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanNcIik7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgaXNhcnJheSAqLyBcIi4vbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanNcIik7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuUmVhZGFibGUuUmVhZGFibGVTdGF0ZSA9IFJlYWRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRUUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBldmVudHMgKi8gXCIuL25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzXCIpLkV2ZW50RW1pdHRlcjtcblxudmFyIEVFbGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uIChlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtO1xuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBTdHJlYW0gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBzdHJlYW0gKi8gXCIuL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qc1wiKTtcbiAgfSBjYXRjaCAoXykge30gZmluYWxseSB7XG4gICAgaWYgKCFTdHJlYW0pIFN0cmVhbSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGV2ZW50cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanNcIikuRXZlbnRFbWl0dGVyO1xuICB9XG59KSgpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBidWZmZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanNcIikuQnVmZmVyO1xuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBidWZmZXJTaGltID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgYnVmZmVyLXNoaW1zICovIFwiLi9ub2RlX21vZHVsZXMvYnVmZmVyLXNoaW1zL2luZGV4LmpzXCIpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGNvcmUtdXRpbC1pcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2NvcmUtdXRpbC1pcy9saWIvdXRpbC5qc1wiKTtcbnV0aWwuaW5oZXJpdHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBpbmhlcml0cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanNcIik7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBkZWJ1Z1V0aWwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISB1dGlsICovIDApO1xudmFyIGRlYnVnID0gdm9pZCAwO1xuaWYgKGRlYnVnVXRpbCAmJiBkZWJ1Z1V0aWwuZGVidWdsb2cpIHtcbiAgZGVidWcgPSBkZWJ1Z1V0aWwuZGVidWdsb2coJ3N0cmVhbScpO1xufSBlbHNlIHtcbiAgZGVidWcgPSBmdW5jdGlvbiAoKSB7fTtcbn1cbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyTGlzdCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vaW50ZXJuYWwvc3RyZWFtcy9CdWZmZXJMaXN0ICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QuanNcIik7XG52YXIgU3RyaW5nRGVjb2RlcjtcblxudXRpbC5pbmhlcml0cyhSZWFkYWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKGVtaXR0ZXIsIGV2ZW50LCBmbikge1xuICAvLyBTYWRseSB0aGlzIGlzIG5vdCBjYWNoZWFibGUgYXMgc29tZSBsaWJyYXJpZXMgYnVuZGxlIHRoZWlyIG93blxuICAvLyBldmVudCBlbWl0dGVyIGltcGxlbWVudGF0aW9uIHdpdGggdGhlbS5cbiAgaWYgKHR5cGVvZiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lcihldmVudCwgZm4pO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYSBoYWNrIHRvIG1ha2Ugc3VyZSB0aGF0IG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSBhbnlcbiAgICAvLyB1c2VybGFuZCBvbmVzLiAgTkVWRVIgRE8gVEhJUy4gVGhpcyBpcyBoZXJlIG9ubHkgYmVjYXVzZSB0aGlzIGNvZGUgbmVlZHNcbiAgICAvLyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgTm9kZS5qcyB0aGF0IGRvIG5vdCBpbmNsdWRlXG4gICAgLy8gdGhlIHByZXBlbmRMaXN0ZW5lcigpIG1ldGhvZC4gVGhlIGdvYWwgaXMgdG8gZXZlbnR1YWxseSByZW1vdmUgdGhpcyBoYWNrLlxuICAgIGlmICghZW1pdHRlci5fZXZlbnRzIHx8ICFlbWl0dGVyLl9ldmVudHNbZXZlbnRdKSBlbWl0dGVyLm9uKGV2ZW50LCBmbik7ZWxzZSBpZiAoaXNBcnJheShlbWl0dGVyLl9ldmVudHNbZXZlbnRdKSkgZW1pdHRlci5fZXZlbnRzW2V2ZW50XS51bnNoaWZ0KGZuKTtlbHNlIGVtaXR0ZXIuX2V2ZW50c1tldmVudF0gPSBbZm4sIGVtaXR0ZXIuX2V2ZW50c1tldmVudF1dO1xuICB9XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJlYW1fZHVwbGV4ICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcuIFVzZWQgdG8gbWFrZSByZWFkKG4pIGlnbm9yZSBuIGFuZCB0b1xuICAvLyBtYWtlIGFsbCB0aGUgYnVmZmVyIG1lcmdpbmcgYW5kIGxlbmd0aCBjaGVja3MgZ28gYXdheVxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfiB+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIC8vIEEgbGlua2VkIGxpc3QgaXMgdXNlZCB0byBzdG9yZSBkYXRhIGNodW5rcyBpbnN0ZWFkIG9mIGFuIGFycmF5IGJlY2F1c2UgdGhlXG4gIC8vIGxpbmtlZCBsaXN0IGNhbiByZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgYmVnaW5uaW5nIGZhc3RlciB0aGFuXG4gIC8vIGFycmF5LnNoaWZ0KClcbiAgdGhpcy5idWZmZXIgPSBuZXcgQnVmZmVyTGlzdCgpO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBudWxsO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyB3aGVuZXZlciB3ZSByZXR1cm4gbnVsbCwgdGhlbiB3ZSBzZXQgYSBmbGFnIHRvIHNheVxuICAvLyB0aGF0IHdlJ3JlIGF3YWl0aW5nIGEgJ3JlYWRhYmxlJyBldmVudCBlbWlzc2lvbi5cbiAgdGhpcy5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgdGhpcy5yZWFkYWJsZUxpc3RlbmluZyA9IGZhbHNlO1xuICB0aGlzLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIHdoZW4gcGlwaW5nLCB3ZSBvbmx5IGNhcmUgYWJvdXQgJ3JlYWRhYmxlJyBldmVudHMgdGhhdCBoYXBwZW5cbiAgLy8gYWZ0ZXIgcmVhZCgpaW5nIGFsbCB0aGUgYnl0ZXMgYW5kIG5vdCBnZXR0aW5nIGFueSBwdXNoYmFjay5cbiAgdGhpcy5yYW5PdXQgPSBmYWxzZTtcblxuICAvLyB0aGUgbnVtYmVyIG9mIHdyaXRlcnMgdGhhdCBhcmUgYXdhaXRpbmcgYSBkcmFpbiBldmVudCBpbiAucGlwZSgpc1xuICB0aGlzLmF3YWl0RHJhaW4gPSAwO1xuXG4gIC8vIGlmIHRydWUsIGEgbWF5YmVSZWFkTW9yZSBoYXMgYmVlbiBzY2hlZHVsZWRcbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuXG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHN0cmluZ19kZWNvZGVyLyAqLyBcIi4vbm9kZV9tb2R1bGVzL25vZGUtbGlicy1icm93c2VyL25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9saWIvc3RyaW5nX2RlY29kZXIuanNcIikuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBSZWFkYWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJlYW1fZHVwbGV4ICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKTtcblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKSByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3lcbiAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMucmVhZCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fcmVhZCA9IG9wdGlvbnMucmVhZDtcblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gTWFudWFsbHkgc2hvdmUgc29tZXRoaW5nIGludG8gdGhlIHJlYWQoKSBidWZmZXIuXG4vLyBUaGlzIHJldHVybnMgdHJ1ZSBpZiB0aGUgaGlnaFdhdGVyTWFyayBoYXMgbm90IGJlZW4gaGl0IHlldCxcbi8vIHNpbWlsYXIgdG8gaG93IFdyaXRhYmxlLndyaXRlKCkgcmV0dXJucyB0cnVlIGlmIHlvdSBzaG91bGRcbi8vIHdyaXRlKCkgc29tZSBtb3JlLlxuUmVhZGFibGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICBpZiAoZW5jb2RpbmcgIT09IHN0YXRlLmVuY29kaW5nKSB7XG4gICAgICBjaHVuayA9IGJ1ZmZlclNoaW0uZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBmYWxzZSk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCAnJywgdHJ1ZSk7XG59O1xuXG5SZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPT09IGZhbHNlO1xufTtcblxuZnVuY3Rpb24gcmVhZGFibGVBZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQpIHtcbiAgdmFyIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2UgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsgJiYgY2h1bmsubGVuZ3RoID4gMCkge1xuICAgIGlmIChzdGF0ZS5lbmRlZCAmJiAhYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoJ3N0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GJyk7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZEVtaXR0ZWQgJiYgYWRkVG9Gcm9udCkge1xuICAgICAgdmFyIF9lID0gbmV3IEVycm9yKCdzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudCcpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgX2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgc2tpcEFkZDtcbiAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFhZGRUb0Zyb250ICYmICFlbmNvZGluZykge1xuICAgICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuICAgICAgICBza2lwQWRkID0gIXN0YXRlLm9iamVjdE1vZGUgJiYgY2h1bmsubGVuZ3RoID09PSAwO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWFkZFRvRnJvbnQpIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcblxuICAgICAgLy8gRG9uJ3QgYWRkIHRvIHRoZSBidWZmZXIgaWYgd2UndmUgZGVjb2RlZCB0byBhbiBlbXB0eSBzdHJpbmcgY2h1bmsgYW5kXG4gICAgICAvLyB3ZSdyZSBub3QgaW4gb2JqZWN0IG1vZGVcbiAgICAgIGlmICghc2tpcEFkZCkge1xuICAgICAgICAvLyBpZiB3ZSB3YW50IHRoZSBkYXRhIG5vdywganVzdCBlbWl0IGl0LlxuICAgICAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICAgICAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgICAgICAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgICAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICAgICAgICBpZiAoYWRkVG9Gcm9udCkgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSkgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWFkZFRvRnJvbnQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKTtcbn1cblxuLy8gaWYgaXQncyBwYXN0IHRoZSBoaWdoIHdhdGVyIG1hcmssIHdlIGNhbiBwdXNoIGluIHNvbWUgbW9yZS5cbi8vIEFsc28sIGlmIHdlIGhhdmUgbm8gZGF0YSB5ZXQsIHdlIGNhbiBzdGFuZCBzb21lXG4vLyBtb3JlIGJ5dGVzLiAgVGhpcyBpcyB0byB3b3JrIGFyb3VuZCBjYXNlcyB3aGVyZSBod209MCxcbi8vIHN1Y2ggYXMgdGhlIHJlcGwuICBBbHNvLCBpZiB0aGUgcHVzaCgpIHRyaWdnZXJlZCBhXG4vLyByZWFkYWJsZSBldmVudCwgYW5kIHRoZSB1c2VyIGNhbGxlZCByZWFkKGxhcmdlTnVtYmVyKSBzdWNoIHRoYXRcbi8vIG5lZWRSZWFkYWJsZSB3YXMgc2V0LCB0aGVuIHdlIG91Z2h0IHRvIHB1c2ggbW9yZSwgc28gdGhhdCBhbm90aGVyXG4vLyAncmVhZGFibGUnIGV2ZW50IHdpbGwgYmUgdHJpZ2dlcmVkLlxuZnVuY3Rpb24gbmVlZE1vcmVEYXRhKHN0YXRlKSB7XG4gIHJldHVybiAhc3RhdGUuZW5kZWQgJiYgKHN0YXRlLm5lZWRSZWFkYWJsZSB8fCBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmxlbmd0aCA9PT0gMCk7XG59XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBzdHJpbmdfZGVjb2Rlci8gKi8gXCIuL25vZGVfbW9kdWxlcy9ub2RlLWxpYnMtYnJvd3Nlci9ub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzXCIpLlN0cmluZ0RlY29kZXI7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYyk7XG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2RpbmcgPSBlbmM7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gRG9uJ3QgcmFpc2UgdGhlIGh3bSA+IDhNQlxudmFyIE1BWF9IV00gPSAweDgwMDAwMDtcbmZ1bmN0aW9uIGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pIHtcbiAgaWYgKG4gPj0gTUFYX0hXTSkge1xuICAgIG4gPSBNQVhfSFdNO1xuICB9IGVsc2Uge1xuICAgIC8vIEdldCB0aGUgbmV4dCBoaWdoZXN0IHBvd2VyIG9mIDIgdG8gcHJldmVudCBpbmNyZWFzaW5nIGh3bSBleGNlc3NpdmVseSBpblxuICAgIC8vIHRpbnkgYW1vdW50c1xuICAgIG4tLTtcbiAgICBuIHw9IG4gPj4+IDE7XG4gICAgbiB8PSBuID4+PiAyO1xuICAgIG4gfD0gbiA+Pj4gNDtcbiAgICBuIHw9IG4gPj4+IDg7XG4gICAgbiB8PSBuID4+PiAxNjtcbiAgICBuKys7XG4gIH1cbiAgcmV0dXJuIG47XG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSkge1xuICBpZiAobiA8PSAwIHx8IHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgcmV0dXJuIDA7XG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKSByZXR1cm4gMTtcbiAgaWYgKG4gIT09IG4pIHtcbiAgICAvLyBPbmx5IGZsb3cgb25lIGJ1ZmZlciBhdCBhIHRpbWVcbiAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGgpIHJldHVybiBzdGF0ZS5idWZmZXIuaGVhZC5kYXRhLmxlbmd0aDtlbHNlIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cbiAgLy8gSWYgd2UncmUgYXNraW5nIGZvciBtb3JlIHRoYW4gdGhlIGN1cnJlbnQgaHdtLCB0aGVuIHJhaXNlIHRoZSBod20uXG4gIGlmIChuID4gc3RhdGUuaGlnaFdhdGVyTWFyaykgc3RhdGUuaGlnaFdhdGVyTWFyayA9IGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pO1xuICBpZiAobiA8PSBzdGF0ZS5sZW5ndGgpIHJldHVybiBuO1xuICAvLyBEb24ndCBoYXZlIGVub3VnaFxuICBpZiAoIXN0YXRlLmVuZGVkKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICByZXR1cm4gMDtcbiAgfVxuICByZXR1cm4gc3RhdGUubGVuZ3RoO1xufVxuXG4vLyB5b3UgY2FuIG92ZXJyaWRlIGVpdGhlciB0aGlzIG1ldGhvZCwgb3IgdGhlIGFzeW5jIF9yZWFkKG4pIGJlbG93LlxuUmVhZGFibGUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbiAobikge1xuICBkZWJ1ZygncmVhZCcsIG4pO1xuICBuID0gcGFyc2VJbnQobiwgMTApO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgbk9yaWcgPSBuO1xuXG4gIGlmIChuICE9PSAwKSBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcblxuICAvLyBpZiB3ZSdyZSBkb2luZyByZWFkKDApIHRvIHRyaWdnZXIgYSByZWFkYWJsZSBldmVudCwgYnV0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhIGJ1bmNoIG9mIGRhdGEgaW4gdGhlIGJ1ZmZlciwgdGhlbiBqdXN0IHRyaWdnZXJcbiAgLy8gdGhlICdyZWFkYWJsZScgZXZlbnQgYW5kIG1vdmUgb24uXG4gIGlmIChuID09PSAwICYmIHN0YXRlLm5lZWRSZWFkYWJsZSAmJiAoc3RhdGUubGVuZ3RoID49IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUuZW5kZWQpKSB7XG4gICAgZGVidWcoJ3JlYWQ6IGVtaXRSZWFkYWJsZScsIHN0YXRlLmxlbmd0aCwgc3RhdGUuZW5kZWQpO1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO2Vsc2UgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbiA9IGhvd011Y2hUb1JlYWQobiwgc3RhdGUpO1xuXG4gIC8vIGlmIHdlJ3ZlIGVuZGVkLCBhbmQgd2UncmUgbm93IGNsZWFyLCB0aGVuIGZpbmlzaCBpdCB1cC5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUuZW5kZWQpIHtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEFsbCB0aGUgYWN0dWFsIGNodW5rIGdlbmVyYXRpb24gbG9naWMgbmVlZHMgdG8gYmVcbiAgLy8gKmJlbG93KiB0aGUgY2FsbCB0byBfcmVhZC4gIFRoZSByZWFzb24gaXMgdGhhdCBpbiBjZXJ0YWluXG4gIC8vIHN5bnRoZXRpYyBzdHJlYW0gY2FzZXMsIHN1Y2ggYXMgcGFzc3Rocm91Z2ggc3RyZWFtcywgX3JlYWRcbiAgLy8gbWF5IGJlIGEgY29tcGxldGVseSBzeW5jaHJvbm91cyBvcGVyYXRpb24gd2hpY2ggbWF5IGNoYW5nZVxuICAvLyB0aGUgc3RhdGUgb2YgdGhlIHJlYWQgYnVmZmVyLCBwcm92aWRpbmcgZW5vdWdoIGRhdGEgd2hlblxuICAvLyBiZWZvcmUgdGhlcmUgd2FzICpub3QqIGVub3VnaC5cbiAgLy9cbiAgLy8gU28sIHRoZSBzdGVwcyBhcmU6XG4gIC8vIDEuIEZpZ3VyZSBvdXQgd2hhdCB0aGUgc3RhdGUgb2YgdGhpbmdzIHdpbGwgYmUgYWZ0ZXIgd2UgZG9cbiAgLy8gYSByZWFkIGZyb20gdGhlIGJ1ZmZlci5cbiAgLy9cbiAgLy8gMi4gSWYgdGhhdCByZXN1bHRpbmcgc3RhdGUgd2lsbCB0cmlnZ2VyIGEgX3JlYWQsIHRoZW4gY2FsbCBfcmVhZC5cbiAgLy8gTm90ZSB0aGF0IHRoaXMgbWF5IGJlIGFzeW5jaHJvbm91cywgb3Igc3luY2hyb25vdXMuICBZZXMsIGl0IGlzXG4gIC8vIGRlZXBseSB1Z2x5IHRvIHdyaXRlIEFQSXMgdGhpcyB3YXksIGJ1dCB0aGF0IHN0aWxsIGRvZXNuJ3QgbWVhblxuICAvLyB0aGF0IHRoZSBSZWFkYWJsZSBjbGFzcyBzaG91bGQgYmVoYXZlIGltcHJvcGVybHksIGFzIHN0cmVhbXMgYXJlXG4gIC8vIGRlc2lnbmVkIHRvIGJlIHN5bmMvYXN5bmMgYWdub3N0aWMuXG4gIC8vIFRha2Ugbm90ZSBpZiB0aGUgX3JlYWQgY2FsbCBpcyBzeW5jIG9yIGFzeW5jIChpZSwgaWYgdGhlIHJlYWQgY2FsbFxuICAvLyBoYXMgcmV0dXJuZWQgeWV0KSwgc28gdGhhdCB3ZSBrbm93IHdoZXRoZXIgb3Igbm90IGl0J3Mgc2FmZSB0byBlbWl0XG4gIC8vICdyZWFkYWJsZScgZXRjLlxuICAvL1xuICAvLyAzLiBBY3R1YWxseSBwdWxsIHRoZSByZXF1ZXN0ZWQgY2h1bmtzIG91dCBvZiB0aGUgYnVmZmVyIGFuZCByZXR1cm4uXG5cbiAgLy8gaWYgd2UgbmVlZCBhIHJlYWRhYmxlIGV2ZW50LCB0aGVuIHdlIG5lZWQgdG8gZG8gc29tZSByZWFkaW5nLlxuICB2YXIgZG9SZWFkID0gc3RhdGUubmVlZFJlYWRhYmxlO1xuICBkZWJ1ZygnbmVlZCByZWFkYWJsZScsIGRvUmVhZCk7XG5cbiAgLy8gaWYgd2UgY3VycmVudGx5IGhhdmUgbGVzcyB0aGFuIHRoZSBoaWdoV2F0ZXJNYXJrLCB0aGVuIGFsc28gcmVhZCBzb21lXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgfHwgc3RhdGUubGVuZ3RoIC0gbiA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkb1JlYWQgPSB0cnVlO1xuICAgIGRlYnVnKCdsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFyaycsIGRvUmVhZCk7XG4gIH1cblxuICAvLyBob3dldmVyLCBpZiB3ZSd2ZSBlbmRlZCwgdGhlbiB0aGVyZSdzIG5vIHBvaW50LCBhbmQgaWYgd2UncmUgYWxyZWFkeVxuICAvLyByZWFkaW5nLCB0aGVuIGl0J3MgdW5uZWNlc3NhcnkuXG4gIGlmIChzdGF0ZS5lbmRlZCB8fCBzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZG9SZWFkID0gZmFsc2U7XG4gICAgZGVidWcoJ3JlYWRpbmcgb3IgZW5kZWQnLCBkb1JlYWQpO1xuICB9IGVsc2UgaWYgKGRvUmVhZCkge1xuICAgIGRlYnVnKCdkbyByZWFkJyk7XG4gICAgc3RhdGUucmVhZGluZyA9IHRydWU7XG4gICAgc3RhdGUuc3luYyA9IHRydWU7XG4gICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBjdXJyZW50bHkgemVybywgdGhlbiB3ZSAqbmVlZCogYSByZWFkYWJsZSBldmVudC5cbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIC8vIGNhbGwgaW50ZXJuYWwgcmVhZCBtZXRob2RcbiAgICB0aGlzLl9yZWFkKHN0YXRlLmhpZ2hXYXRlck1hcmspO1xuICAgIHN0YXRlLnN5bmMgPSBmYWxzZTtcbiAgICAvLyBJZiBfcmVhZCBwdXNoZWQgZGF0YSBzeW5jaHJvbm91c2x5LCB0aGVuIGByZWFkaW5nYCB3aWxsIGJlIGZhbHNlLFxuICAgIC8vIGFuZCB3ZSBuZWVkIHRvIHJlLWV2YWx1YXRlIGhvdyBtdWNoIGRhdGEgd2UgY2FuIHJldHVybiB0byB0aGUgdXNlci5cbiAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIG4gPSBob3dNdWNoVG9SZWFkKG5PcmlnLCBzdGF0ZSk7XG4gIH1cblxuICB2YXIgcmV0O1xuICBpZiAobiA+IDApIHJldCA9IGZyb21MaXN0KG4sIHN0YXRlKTtlbHNlIHJldCA9IG51bGw7XG5cbiAgaWYgKHJldCA9PT0gbnVsbCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgbiA9IDA7XG4gIH0gZWxzZSB7XG4gICAgc3RhdGUubGVuZ3RoIC09IG47XG4gIH1cblxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBub3RoaW5nIGluIHRoZSBidWZmZXIsIHRoZW4gd2Ugd2FudCB0byBrbm93XG4gICAgLy8gYXMgc29vbiBhcyB3ZSAqZG8qIGdldCBzb21ldGhpbmcgaW50byB0aGUgYnVmZmVyLlxuICAgIGlmICghc3RhdGUuZW5kZWQpIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgICAvLyBJZiB3ZSB0cmllZCB0byByZWFkKCkgcGFzdCB0aGUgRU9GLCB0aGVuIGVtaXQgZW5kIG9uIHRoZSBuZXh0IHRpY2suXG4gICAgaWYgKG5PcmlnICE9PSBuICYmIHN0YXRlLmVuZGVkKSBlbmRSZWFkYWJsZSh0aGlzKTtcbiAgfVxuXG4gIGlmIChyZXQgIT09IG51bGwpIHRoaXMuZW1pdCgnZGF0YScsIHJldCk7XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspIHtcbiAgdmFyIGVyID0gbnVsbDtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICB9XG4gIHJldHVybiBlcjtcbn1cblxuZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5lbmRlZCkgcmV0dXJuO1xuICBpZiAoc3RhdGUuZGVjb2Rlcikge1xuICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgIH1cbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG5cbiAgLy8gZW1pdCAncmVhZGFibGUnIG5vdyB0byBtYWtlIHN1cmUgaXQgZ2V0cyBwaWNrZWQgdXAuXG4gIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xufVxuXG4vLyBEb24ndCBlbWl0IHJlYWRhYmxlIHJpZ2h0IGF3YXkgaW4gc3luYyBtb2RlLCBiZWNhdXNlIHRoaXMgY2FuIHRyaWdnZXJcbi8vIGFub3RoZXIgcmVhZCgpIGNhbGwgPT4gc3RhY2sgb3ZlcmZsb3cuICBUaGlzIHdheSwgaXQgbWlnaHQgdHJpZ2dlclxuLy8gYSBuZXh0VGljayByZWN1cnNpb24gd2FybmluZywgYnV0IHRoYXQncyBub3Qgc28gYmFkLlxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHN0YXRlLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICBpZiAoIXN0YXRlLmVtaXR0ZWRSZWFkYWJsZSkge1xuICAgIGRlYnVnKCdlbWl0UmVhZGFibGUnLCBzdGF0ZS5mbG93aW5nKTtcbiAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSB0cnVlO1xuICAgIGlmIChzdGF0ZS5zeW5jKSBwcm9jZXNzTmV4dFRpY2soZW1pdFJlYWRhYmxlXywgc3RyZWFtKTtlbHNlIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGVfKHN0cmVhbSkge1xuICBkZWJ1ZygnZW1pdCByZWFkYWJsZScpO1xuICBzdHJlYW0uZW1pdCgncmVhZGFibGUnKTtcbiAgZmxvdyhzdHJlYW0pO1xufVxuXG4vLyBhdCB0aGlzIHBvaW50LCB0aGUgdXNlciBoYXMgcHJlc3VtYWJseSBzZWVuIHRoZSAncmVhZGFibGUnIGV2ZW50LFxuLy8gYW5kIGNhbGxlZCByZWFkKCkgdG8gY29uc3VtZSBzb21lIGRhdGEuICB0aGF0IG1heSBoYXZlIHRyaWdnZXJlZFxuLy8gaW4gdHVybiBhbm90aGVyIF9yZWFkKG4pIGNhbGwsIGluIHdoaWNoIGNhc2UgcmVhZGluZyA9IHRydWUgaWZcbi8vIGl0J3MgaW4gcHJvZ3Jlc3MuXG4vLyBIb3dldmVyLCBpZiB3ZSdyZSBub3QgZW5kZWQsIG9yIHJlYWRpbmcsIGFuZCB0aGUgbGVuZ3RoIDwgaHdtLFxuLy8gdGhlbiBnbyBhaGVhZCBhbmQgdHJ5IHRvIHJlYWQgc29tZSBtb3JlIHByZWVtcHRpdmVseS5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmdNb3JlKSB7XG4gICAgc3RhdGUucmVhZGluZ01vcmUgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhtYXliZVJlYWRNb3JlXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLmVuZGVkICYmIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkZWJ1ZygnbWF5YmVSZWFkTW9yZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICBpZiAobGVuID09PSBzdGF0ZS5sZW5ndGgpXG4gICAgICAvLyBkaWRuJ3QgZ2V0IGFueSBkYXRhLCBzdG9wIHNwaW5uaW5nLlxuICAgICAgYnJlYWs7ZWxzZSBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIH1cbiAgc3RhdGUucmVhZGluZ01vcmUgPSBmYWxzZTtcbn1cblxuLy8gYWJzdHJhY3QgbWV0aG9kLiAgdG8gYmUgb3ZlcnJpZGRlbiBpbiBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gY2FsbCBjYihlciwgZGF0YSkgd2hlcmUgZGF0YSBpcyA8PSBuIGluIGxlbmd0aC5cbi8vIGZvciB2aXJ0dWFsIChub24tc3RyaW5nLCBub24tYnVmZmVyKSBzdHJlYW1zLCBcImxlbmd0aFwiIGlzIHNvbWV3aGF0XG4vLyBhcmJpdHJhcnksIGFuZCBwZXJoYXBzIG5vdCB2ZXJ5IG1lYW5pbmdmdWwuXG5SZWFkYWJsZS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdfcmVhZCgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKGRlc3QsIHBpcGVPcHRzKSB7XG4gIHZhciBzcmMgPSB0aGlzO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIHN3aXRjaCAoc3RhdGUucGlwZXNDb3VudCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHN0YXRlLnBpcGVzID0gZGVzdDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucGlwZXNDb3VudCArPSAxO1xuICBkZWJ1ZygncGlwZSBjb3VudD0lZCBvcHRzPSVqJywgc3RhdGUucGlwZXNDb3VudCwgcGlwZU9wdHMpO1xuXG4gIHZhciBkb0VuZCA9ICghcGlwZU9wdHMgfHwgcGlwZU9wdHMuZW5kICE9PSBmYWxzZSkgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRvdXQgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRlcnI7XG5cbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IGNsZWFudXA7XG4gIGlmIChzdGF0ZS5lbmRFbWl0dGVkKSBwcm9jZXNzTmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoJ2VuZCcsIGVuZEZuKTtcblxuICBkZXN0Lm9uKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gIGZ1bmN0aW9uIG9udW5waXBlKHJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ29udW5waXBlJyk7XG4gICAgaWYgKHJlYWRhYmxlID09PSBzcmMpIHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICB2YXIgY2xlYW5lZFVwID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG5cbiAgICBjbGVhbmVkVXAgPSB0cnVlO1xuXG4gICAgLy8gaWYgdGhlIHJlYWRlciBpcyB3YWl0aW5nIGZvciBhIGRyYWluIGV2ZW50IGZyb20gdGhpc1xuICAgIC8vIHNwZWNpZmljIHdyaXRlciwgdGhlbiBpdCB3b3VsZCBjYXVzZSBpdCB0byBuZXZlciBzdGFydFxuICAgIC8vIGZsb3dpbmcgYWdhaW4uXG4gICAgLy8gU28sIGlmIHRoaXMgaXMgYXdhaXRpbmcgYSBkcmFpbiwgdGhlbiB3ZSBqdXN0IGNhbGwgaXQgbm93LlxuICAgIC8vIElmIHdlIGRvbid0IGtub3csIHRoZW4gYXNzdW1lIHRoYXQgd2UgYXJlIHdhaXRpbmcgZm9yIG9uZS5cbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiAmJiAoIWRlc3QuX3dyaXRhYmxlU3RhdGUgfHwgZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKSBvbmRyYWluKCk7XG4gIH1cblxuICAvLyBJZiB0aGUgdXNlciBwdXNoZXMgbW9yZSBkYXRhIHdoaWxlIHdlJ3JlIHdyaXRpbmcgdG8gZGVzdCB0aGVuIHdlJ2xsIGVuZCB1cFxuICAvLyBpbiBvbmRhdGEgYWdhaW4uIEhvd2V2ZXIsIHdlIG9ubHkgd2FudCB0byBpbmNyZWFzZSBhd2FpdERyYWluIG9uY2UgYmVjYXVzZVxuICAvLyBkZXN0IHdpbGwgb25seSBlbWl0IG9uZSAnZHJhaW4nIGV2ZW50IGZvciB0aGUgbXVsdGlwbGUgd3JpdGVzLlxuICAvLyA9PiBJbnRyb2R1Y2UgYSBndWFyZCBvbiBpbmNyZWFzaW5nIGF3YWl0RHJhaW4uXG4gIHZhciBpbmNyZWFzZWRBd2FpdERyYWluID0gZmFsc2U7XG4gIHNyYy5vbignZGF0YScsIG9uZGF0YSk7XG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGRlYnVnKCdvbmRhdGEnKTtcbiAgICBpbmNyZWFzZWRBd2FpdERyYWluID0gZmFsc2U7XG4gICAgdmFyIHJldCA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGlmIChmYWxzZSA9PT0gcmV0ICYmICFpbmNyZWFzZWRBd2FpdERyYWluKSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciB1bnBpcGVkIGR1cmluZyBgZGVzdC53cml0ZSgpYCwgaXQgaXMgcG9zc2libGVcbiAgICAgIC8vIHRvIGdldCBzdHVjayBpbiBhIHBlcm1hbmVudGx5IHBhdXNlZCBzdGF0ZSBpZiB0aGF0IHdyaXRlXG4gICAgICAvLyBhbHNvIHJldHVybmVkIGZhbHNlLlxuICAgICAgLy8gPT4gQ2hlY2sgd2hldGhlciBgZGVzdGAgaXMgc3RpbGwgYSBwaXBpbmcgZGVzdGluYXRpb24uXG4gICAgICBpZiAoKHN0YXRlLnBpcGVzQ291bnQgPT09IDEgJiYgc3RhdGUucGlwZXMgPT09IGRlc3QgfHwgc3RhdGUucGlwZXNDb3VudCA+IDEgJiYgaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCkgIT09IC0xKSAmJiAhY2xlYW5lZFVwKSB7XG4gICAgICAgIGRlYnVnKCdmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2UnLCBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbik7XG4gICAgICAgIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7XG4gICAgICAgIGluY3JlYXNlZEF3YWl0RHJhaW4gPSB0cnVlO1xuICAgICAgfVxuICAgICAgc3JjLnBhdXNlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGRlYnVnKCdvbmVycm9yJywgZXIpO1xuICAgIHVucGlwZSgpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgaWYgKEVFbGlzdGVuZXJDb3VudChkZXN0LCAnZXJyb3InKSA9PT0gMCkgZGVzdC5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfVxuXG4gIC8vIE1ha2Ugc3VyZSBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgdXNlcmxhbmQgb25lcy5cbiAgcHJlcGVuZExpc3RlbmVyKGRlc3QsICdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIEJvdGggY2xvc2UgYW5kIGZpbmlzaCBzaG91bGQgdHJpZ2dlciB1bnBpcGUsIGJ1dCBvbmx5IG9uY2UuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgZGVidWcoJ29uZmluaXNoJyk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcblxuICBmdW5jdGlvbiB1bnBpcGUoKSB7XG4gICAgZGVidWcoJ3VucGlwZScpO1xuICAgIHNyYy51bnBpcGUoZGVzdCk7XG4gIH1cblxuICAvLyB0ZWxsIHRoZSBkZXN0IHRoYXQgaXQncyBiZWluZyBwaXBlZCB0b1xuICBkZXN0LmVtaXQoJ3BpcGUnLCBzcmMpO1xuXG4gIC8vIHN0YXJ0IHRoZSBmbG93IGlmIGl0IGhhc24ndCBiZWVuIHN0YXJ0ZWQgYWxyZWFkeS5cbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BpcGUgcmVzdW1lJyk7XG4gICAgc3JjLnJlc3VtZSgpO1xuICB9XG5cbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG5mdW5jdGlvbiBwaXBlT25EcmFpbihzcmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhdGUgPSBzcmMuX3JlYWRhYmxlU3RhdGU7XG4gICAgZGVidWcoJ3BpcGVPbkRyYWluJywgc3RhdGUuYXdhaXREcmFpbik7XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4pIHN0YXRlLmF3YWl0RHJhaW4tLTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA9PT0gMCAmJiBFRWxpc3RlbmVyQ291bnQoc3JjLCAnZGF0YScpKSB7XG4gICAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICAgIGZsb3coc3JjKTtcbiAgICB9XG4gIH07XG59XG5cblJlYWRhYmxlLnByb3RvdHlwZS51bnBpcGUgPSBmdW5jdGlvbiAoZGVzdCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApIHJldHVybiB0aGlzO1xuXG4gIC8vIGp1c3Qgb25lIGRlc3RpbmF0aW9uLiAgbW9zdCBjb21tb24gY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHtcbiAgICAvLyBwYXNzZWQgaW4gb25lLCBidXQgaXQncyBub3QgdGhlIHJpZ2h0IG9uZS5cbiAgICBpZiAoZGVzdCAmJiBkZXN0ICE9PSBzdGF0ZS5waXBlcykgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpIGRlc3QgPSBzdGF0ZS5waXBlcztcblxuICAgIC8vIGdvdCBhIG1hdGNoLlxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIH1yZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpbmRleCA9IGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpO1xuICBpZiAoaW5kZXggPT09IC0xKSByZXR1cm4gdGhpcztcblxuICBzdGF0ZS5waXBlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgaWYgKGV2ID09PSAnZGF0YScpIHtcbiAgICAvLyBTdGFydCBmbG93aW5nIG9uIG5leHQgdGljayBpZiBzdHJlYW0gaXNuJ3QgZXhwbGljaXRseSBwYXVzZWRcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nICE9PSBmYWxzZSkgdGhpcy5yZXN1bWUoKTtcbiAgfSBlbHNlIGlmIChldiA9PT0gJ3JlYWRhYmxlJykge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmICFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcHJvY2Vzc05leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssIHRoaXMpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMsIHN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IFJlYWRhYmxlLnByb3RvdHlwZS5vbjtcblxuZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKSB7XG4gIGRlYnVnKCdyZWFkYWJsZSBuZXh0dGljayByZWFkIDAnKTtcbiAgc2VsZi5yZWFkKDApO1xufVxuXG4vLyBwYXVzZSgpIGFuZCByZXN1bWUoKSBhcmUgcmVtbmFudHMgb2YgdGhlIGxlZ2FjeSByZWFkYWJsZSBzdHJlYW0gQVBJXG4vLyBJZiB0aGUgdXNlciB1c2VzIHRoZW0sIHRoZW4gc3dpdGNoIGludG8gb2xkIG1vZGUuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lJyk7XG4gICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgcmVzdW1lKHRoaXMsIHN0YXRlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlc3VtZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVzdW1lU2NoZWR1bGVkKSB7XG4gICAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2socmVzdW1lXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdW1lXyhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZykge1xuICAgIGRlYnVnKCdyZXN1bWUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gIH1cblxuICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgc3RhdGUuYXdhaXREcmFpbiA9IDA7XG4gIHN0cmVhbS5lbWl0KCdyZXN1bWUnKTtcbiAgZmxvdyhzdHJlYW0pO1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUucmVhZGluZykgc3RyZWFtLnJlYWQoMCk7XG59XG5cblJlYWRhYmxlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ2NhbGwgcGF1c2UgZmxvd2luZz0laicsIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7XG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BhdXNlJyk7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdwYXVzZScpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZmxvdyhzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZmxvdycsIHN0YXRlLmZsb3dpbmcpO1xuICB3aGlsZSAoc3RhdGUuZmxvd2luZyAmJiBzdHJlYW0ucmVhZCgpICE9PSBudWxsKSB7fVxufVxuXG4vLyB3cmFwIGFuIG9sZC1zdHlsZSBzdHJlYW0gYXMgdGhlIGFzeW5jIGRhdGEgc291cmNlLlxuLy8gVGhpcyBpcyAqbm90KiBwYXJ0IG9mIHRoZSByZWFkYWJsZSBzdHJlYW0gaW50ZXJmYWNlLlxuLy8gSXQgaXMgYW4gdWdseSB1bmZvcnR1bmF0ZSBtZXNzIG9mIGhpc3RvcnkuXG5SZWFkYWJsZS5wcm90b3R5cGUud3JhcCA9IGZ1bmN0aW9uIChzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHBhdXNlZCA9IGZhbHNlO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgc3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZW5kJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkgc2VsZi5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBzZWxmLnB1c2gobnVsbCk7XG4gIH0pO1xuXG4gIHN0cmVhbS5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgIGRlYnVnKCd3cmFwcGVkIGRhdGEnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcblxuICAgIC8vIGRvbid0IHNraXAgb3ZlciBmYWxzeSB2YWx1ZXMgaW4gb2JqZWN0TW9kZVxuICAgIGlmIChzdGF0ZS5vYmplY3RNb2RlICYmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSkgcmV0dXJuO2Vsc2UgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmICghY2h1bmsgfHwgIWNodW5rLmxlbmd0aCkpIHJldHVybjtcblxuICAgIHZhciByZXQgPSBzZWxmLnB1c2goY2h1bmspO1xuICAgIGlmICghcmV0KSB7XG4gICAgICBwYXVzZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuICBmb3IgKHZhciBpIGluIHN0cmVhbSkge1xuICAgIGlmICh0aGlzW2ldID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIHN0cmVhbVtpXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpc1tpXSA9IGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgfShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIHZhciBldmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbiAoZXYpIHtcbiAgICBzdHJlYW0ub24oZXYsIHNlbGYuZW1pdC5iaW5kKHNlbGYsIGV2KSk7XG4gIH0pO1xuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHNlbGYuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICAgIGRlYnVnKCd3cmFwcGVkIF9yZWFkJywgbik7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuLy8gZXhwb3NlZCBmb3IgdGVzdGluZyBwdXJwb3NlcyBvbmx5LlxuUmVhZGFibGUuX2Zyb21MaXN0ID0gZnJvbUxpc3Q7XG5cbi8vIFBsdWNrIG9mZiBuIGJ5dGVzIGZyb20gYW4gYXJyYXkgb2YgYnVmZmVycy5cbi8vIExlbmd0aCBpcyB0aGUgY29tYmluZWQgbGVuZ3RocyBvZiBhbGwgdGhlIGJ1ZmZlcnMgaW4gdGhlIGxpc3QuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGZyb21MaXN0KG4sIHN0YXRlKSB7XG4gIC8vIG5vdGhpbmcgYnVmZmVyZWRcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG5cbiAgdmFyIHJldDtcbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldCA9IHN0YXRlLmJ1ZmZlci5zaGlmdCgpO2Vsc2UgaWYgKCFuIHx8IG4gPj0gc3RhdGUubGVuZ3RoKSB7XG4gICAgLy8gcmVhZCBpdCBhbGwsIHRydW5jYXRlIHRoZSBsaXN0XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIHJldCA9IHN0YXRlLmJ1ZmZlci5qb2luKCcnKTtlbHNlIGlmIChzdGF0ZS5idWZmZXIubGVuZ3RoID09PSAxKSByZXQgPSBzdGF0ZS5idWZmZXIuaGVhZC5kYXRhO2Vsc2UgcmV0ID0gc3RhdGUuYnVmZmVyLmNvbmNhdChzdGF0ZS5sZW5ndGgpO1xuICAgIHN0YXRlLmJ1ZmZlci5jbGVhcigpO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQgcGFydCBvZiBsaXN0XG4gICAgcmV0ID0gZnJvbUxpc3RQYXJ0aWFsKG4sIHN0YXRlLmJ1ZmZlciwgc3RhdGUuZGVjb2Rlcik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG4vLyBFeHRyYWN0cyBvbmx5IGVub3VnaCBidWZmZXJlZCBkYXRhIHRvIHNhdGlzZnkgdGhlIGFtb3VudCByZXF1ZXN0ZWQuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGZyb21MaXN0UGFydGlhbChuLCBsaXN0LCBoYXNTdHJpbmdzKSB7XG4gIHZhciByZXQ7XG4gIGlmIChuIDwgbGlzdC5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgLy8gc2xpY2UgaXMgdGhlIHNhbWUgZm9yIGJ1ZmZlcnMgYW5kIHN0cmluZ3NcbiAgICByZXQgPSBsaXN0LmhlYWQuZGF0YS5zbGljZSgwLCBuKTtcbiAgICBsaXN0LmhlYWQuZGF0YSA9IGxpc3QuaGVhZC5kYXRhLnNsaWNlKG4pO1xuICB9IGVsc2UgaWYgKG4gPT09IGxpc3QuaGVhZC5kYXRhLmxlbmd0aCkge1xuICAgIC8vIGZpcnN0IGNodW5rIGlzIGEgcGVyZmVjdCBtYXRjaFxuICAgIHJldCA9IGxpc3Quc2hpZnQoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyByZXN1bHQgc3BhbnMgbW9yZSB0aGFuIG9uZSBidWZmZXJcbiAgICByZXQgPSBoYXNTdHJpbmdzID8gY29weUZyb21CdWZmZXJTdHJpbmcobiwgbGlzdCkgOiBjb3B5RnJvbUJ1ZmZlcihuLCBsaXN0KTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG4vLyBDb3BpZXMgYSBzcGVjaWZpZWQgYW1vdW50IG9mIGNoYXJhY3RlcnMgZnJvbSB0aGUgbGlzdCBvZiBidWZmZXJlZCBkYXRhXG4vLyBjaHVua3MuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyU3RyaW5nKG4sIGxpc3QpIHtcbiAgdmFyIHAgPSBsaXN0LmhlYWQ7XG4gIHZhciBjID0gMTtcbiAgdmFyIHJldCA9IHAuZGF0YTtcbiAgbiAtPSByZXQubGVuZ3RoO1xuICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgIHZhciBzdHIgPSBwLmRhdGE7XG4gICAgdmFyIG5iID0gbiA+IHN0ci5sZW5ndGggPyBzdHIubGVuZ3RoIDogbjtcbiAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHJldCArPSBzdHI7ZWxzZSByZXQgKz0gc3RyLnNsaWNlKDAsIG4pO1xuICAgIG4gLT0gbmI7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChuYiA9PT0gc3RyLmxlbmd0aCkge1xuICAgICAgICArK2M7XG4gICAgICAgIGlmIChwLm5leHQpIGxpc3QuaGVhZCA9IHAubmV4dDtlbHNlIGxpc3QuaGVhZCA9IGxpc3QudGFpbCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaXN0LmhlYWQgPSBwO1xuICAgICAgICBwLmRhdGEgPSBzdHIuc2xpY2UobmIpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsrYztcbiAgfVxuICBsaXN0Lmxlbmd0aCAtPSBjO1xuICByZXR1cm4gcmV0O1xufVxuXG4vLyBDb3BpZXMgYSBzcGVjaWZpZWQgYW1vdW50IG9mIGJ5dGVzIGZyb20gdGhlIGxpc3Qgb2YgYnVmZmVyZWQgZGF0YSBjaHVua3MuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyKG4sIGxpc3QpIHtcbiAgdmFyIHJldCA9IGJ1ZmZlclNoaW0uYWxsb2NVbnNhZmUobik7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHAuZGF0YS5jb3B5KHJldCk7XG4gIG4gLT0gcC5kYXRhLmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgYnVmID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBidWYubGVuZ3RoID8gYnVmLmxlbmd0aCA6IG47XG4gICAgYnVmLmNvcHkocmV0LCByZXQubGVuZ3RoIC0gbiwgMCwgbmIpO1xuICAgIG4gLT0gbmI7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChuYiA9PT0gYnVmLmxlbmd0aCkge1xuICAgICAgICArK2M7XG4gICAgICAgIGlmIChwLm5leHQpIGxpc3QuaGVhZCA9IHAubmV4dDtlbHNlIGxpc3QuaGVhZCA9IGxpc3QudGFpbCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaXN0LmhlYWQgPSBwO1xuICAgICAgICBwLmRhdGEgPSBidWYuc2xpY2UobmIpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsrYztcbiAgfVxuICBsaXN0Lmxlbmd0aCAtPSBjO1xuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIElmIHdlIGdldCBoZXJlIGJlZm9yZSBjb25zdW1pbmcgYWxsIHRoZSBieXRlcywgdGhlbiB0aGF0IGlzIGFcbiAgLy8gYnVnIGluIG5vZGUuICBTaG91bGQgbmV2ZXIgaGFwcGVuLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZvckVhY2goeHMsIGYpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBmKHhzW2ldLCBpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmRleE9mKHhzLCB4KSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59XG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwodGhpcywgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8uLi8uLi9wcm9jZXNzL2Jyb3dzZXIuanMgKi8gXCIuL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanNcIikpKVxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG5cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2Zvcm07XG5cbnZhciBEdXBsZXggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL19zdHJlYW1fZHVwbGV4ICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgY29yZS11dGlsLWlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzXCIpO1xudXRpbC5pbmhlcml0cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGluaGVyaXRzICovIFwiLi9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qc1wiKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG51dGlsLmluaGVyaXRzKFRyYW5zZm9ybSwgRHVwbGV4KTtcblxuZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUoc3RyZWFtKSB7XG4gIHRoaXMuYWZ0ZXJUcmFuc2Zvcm0gPSBmdW5jdGlvbiAoZXIsIGRhdGEpIHtcbiAgICByZXR1cm4gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSk7XG4gIH07XG5cbiAgdGhpcy5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHRoaXMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG4gIHRoaXMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRoaXMud3JpdGVlbmNvZGluZyA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG5cbiAgdmFyIGNiID0gdHMud3JpdGVjYjtcblxuICBpZiAoIWNiKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdubyB3cml0ZWNiIGluIFRyYW5zZm9ybSBjbGFzcycpKTtcblxuICB0cy53cml0ZWNodW5rID0gbnVsbDtcbiAgdHMud3JpdGVjYiA9IG51bGw7XG5cbiAgaWYgKGRhdGEgIT09IG51bGwgJiYgZGF0YSAhPT0gdW5kZWZpbmVkKSBzdHJlYW0ucHVzaChkYXRhKTtcblxuICBjYihlcik7XG5cbiAgdmFyIHJzID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBycy5yZWFkaW5nID0gZmFsc2U7XG4gIGlmIChycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykge1xuICAgIHN0cmVhbS5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSkgcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7XG5cbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUgPSBuZXcgVHJhbnNmb3JtU3RhdGUodGhpcyk7XG5cbiAgdmFyIHN0cmVhbSA9IHRoaXM7XG5cbiAgLy8gc3RhcnQgb3V0IGFza2luZyBmb3IgYSByZWFkYWJsZSBldmVudCBvbmNlIGRhdGEgaXMgdHJhbnNmb3JtZWQuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAvLyB3ZSBoYXZlIGltcGxlbWVudGVkIHRoZSBfcmVhZCBtZXRob2QsIGFuZCBkb25lIHRoZSBvdGhlciB0aGluZ3NcbiAgLy8gdGhhdCBSZWFkYWJsZSB3YW50cyBiZWZvcmUgdGhlIGZpcnN0IF9yZWFkIGNhbGwsIHNvIHVuc2V0IHRoZVxuICAvLyBzeW5jIGd1YXJkIGZsYWcuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUuc3luYyA9IGZhbHNlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnRyYW5zZm9ybSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fdHJhbnNmb3JtID0gb3B0aW9ucy50cmFuc2Zvcm07XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmx1c2ggPT09ICdmdW5jdGlvbicpIHRoaXMuX2ZsdXNoID0gb3B0aW9ucy5mbHVzaDtcbiAgfVxuXG4gIC8vIFdoZW4gdGhlIHdyaXRhYmxlIHNpZGUgZmluaXNoZXMsIHRoZW4gZmx1c2ggb3V0IGFueXRoaW5nIHJlbWFpbmluZy5cbiAgdGhpcy5vbmNlKCdwcmVmaW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9mbHVzaCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmx1c2goZnVuY3Rpb24gKGVyLCBkYXRhKSB7XG4gICAgICBkb25lKHN0cmVhbSwgZXIsIGRhdGEpO1xuICAgIH0pO2Vsc2UgZG9uZShzdHJlYW0pO1xuICB9KTtcbn1cblxuVHJhbnNmb3JtLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZS5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHJldHVybiBEdXBsZXgucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLCBjaHVuaywgZW5jb2RpbmcpO1xufTtcblxuLy8gVGhpcyBpcyB0aGUgcGFydCB3aGVyZSB5b3UgZG8gc3R1ZmYhXG4vLyBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGluIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyAnY2h1bmsnIGlzIGFuIGlucHV0IGNodW5rLlxuLy9cbi8vIENhbGwgYHB1c2gobmV3Q2h1bmspYCB0byBwYXNzIGFsb25nIHRyYW5zZm9ybWVkIG91dHB1dFxuLy8gdG8gdGhlIHJlYWRhYmxlIHNpZGUuICBZb3UgbWF5IGNhbGwgJ3B1c2gnIHplcm8gb3IgbW9yZSB0aW1lcy5cbi8vXG4vLyBDYWxsIGBjYihlcnIpYCB3aGVuIHlvdSBhcmUgZG9uZSB3aXRoIHRoaXMgY2h1bmsuICBJZiB5b3UgcGFzc1xuLy8gYW4gZXJyb3IsIHRoZW4gdGhhdCdsbCBwdXQgdGhlIGh1cnQgb24gdGhlIHdob2xlIG9wZXJhdGlvbi4gIElmIHlvdVxuLy8gbmV2ZXIgY2FsbCBjYigpLCB0aGVuIHlvdSdsbCBuZXZlciBnZXQgYW5vdGhlciBjaHVuay5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcignX3RyYW5zZm9ybSgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuVHJhbnNmb3JtLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMud3JpdGVjYiA9IGNiO1xuICB0cy53cml0ZWNodW5rID0gY2h1bms7XG4gIHRzLndyaXRlZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgaWYgKCF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB2YXIgcnMgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICh0cy5uZWVkVHJhbnNmb3JtIHx8IHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59O1xuXG4vLyBEb2Vzbid0IG1hdHRlciB3aGF0IHRoZSBhcmdzIGFyZSBoZXJlLlxuLy8gX3RyYW5zZm9ybSBkb2VzIGFsbCB0aGUgd29yay5cbi8vIFRoYXQgd2UgZ290IGhlcmUgbWVhbnMgdGhhdCB0aGUgcmVhZGFibGUgc2lkZSB3YW50cyBtb3JlIGRhdGEuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHRzLndyaXRlY2h1bmsgIT09IG51bGwgJiYgdHMud3JpdGVjYiAmJiAhdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdHMudHJhbnNmb3JtaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuaywgdHMud3JpdGVlbmNvZGluZywgdHMuYWZ0ZXJUcmFuc2Zvcm0pO1xuICB9IGVsc2Uge1xuICAgIC8vIG1hcmsgdGhhdCB3ZSBuZWVkIGEgdHJhbnNmb3JtLCBzbyB0aGF0IGFueSBkYXRhIHRoYXQgY29tZXMgaW5cbiAgICAvLyB3aWxsIGdldCBwcm9jZXNzZWQsIG5vdyB0aGF0IHdlJ3ZlIGFza2VkIGZvciBpdC5cbiAgICB0cy5uZWVkVHJhbnNmb3JtID0gdHJ1ZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZG9uZShzdHJlYW0sIGVyLCBkYXRhKSB7XG4gIGlmIChlcikgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcblxuICBpZiAoZGF0YSAhPT0gbnVsbCAmJiBkYXRhICE9PSB1bmRlZmluZWQpIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG4gIHZhciB3cyA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAod3MubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiB3cy5sZW5ndGggIT0gMCcpO1xuXG4gIGlmICh0cy50cmFuc2Zvcm1pbmcpIHRocm93IG5ldyBFcnJvcignQ2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHN0aWxsIHRyYW5zZm9ybWluZycpO1xuXG4gIHJldHVybiBzdHJlYW0ucHVzaChudWxsKTtcbn1cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fd3JpdGFibGUuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovKGZ1bmN0aW9uKHByb2Nlc3MsIHNldEltbWVkaWF0ZSkgey8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBjYiksIGFuZCBpdCdsbCBoYW5kbGUgYWxsXG4vLyB0aGUgZHJhaW4gZXZlbnQgZW1pc3Npb24gYW5kIGJ1ZmZlcmluZy5cblxuXG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgcHJvY2Vzcy1uZXh0aWNrLWFyZ3MgKi8gXCIuL25vZGVfbW9kdWxlcy9wcm9jZXNzLW5leHRpY2stYXJncy9pbmRleC5qc1wiKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGFzeW5jV3JpdGUgPSAhcHJvY2Vzcy5icm93c2VyICYmIFsndjAuMTAnLCAndjAuOS4nXS5pbmRleE9mKHByb2Nlc3MudmVyc2lvbi5zbGljZSgwLCA1KSkgPiAtMSA/IHNldEltbWVkaWF0ZSA6IHByb2Nlc3NOZXh0VGljaztcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIER1cGxleDtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5Xcml0YWJsZS5Xcml0YWJsZVN0YXRlID0gV3JpdGFibGVTdGF0ZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgY29yZS11dGlsLWlzICovIFwiLi9ub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzXCIpO1xudXRpbC5pbmhlcml0cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGluaGVyaXRzICovIFwiLi9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qc1wiKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGludGVybmFsVXRpbCA9IHtcbiAgZGVwcmVjYXRlOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISB1dGlsLWRlcHJlY2F0ZSAqLyBcIi4vbm9kZV9tb2R1bGVzL3V0aWwtZGVwcmVjYXRlL2Jyb3dzZXIuanNcIilcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW07XG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIFN0cmVhbSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHN0cmVhbSAqLyBcIi4vbm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzXCIpO1xuICB9IGNhdGNoIChfKSB7fSBmaW5hbGx5IHtcbiAgICBpZiAoIVN0cmVhbSkgU3RyZWFtID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZXZlbnRzICovIFwiLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qc1wiKS5FdmVudEVtaXR0ZXI7XG4gIH1cbn0pKCk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGJ1ZmZlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qc1wiKS5CdWZmZXI7XG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGJ1ZmZlclNoaW0gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBidWZmZXItc2hpbXMgKi8gXCIuL25vZGVfbW9kdWxlcy9idWZmZXItc2hpbXMvaW5kZXguanNcIik7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhXcml0YWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gbm9wKCkge31cblxuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xuICB0aGlzLm5leHQgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyZWFtX2R1cGxleCAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanNcIik7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IHRoaXMgc3RyZWFtXG4gIC8vIGNvbnRhaW5zIGJ1ZmZlcnMgb3Igb2JqZWN0cy5cbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfiB+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIC8vIGRyYWluIGV2ZW50IGZsYWcuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGFsbG9jYXRlIHRoZSBmaXJzdCBDb3JrZWRSZXF1ZXN0LCB0aGVyZSBpcyBhbHdheXNcbiAgLy8gb25lIGFsbG9jYXRlZCBhbmQgZnJlZSB0byB1c2UsIGFuZCB3ZSBtYWludGFpbiBhdCBtb3N0IHR3b1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiBnZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgICAgIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nKVxuICAgIH0pO1xuICB9IGNhdGNoIChfKSB7fVxufSkoKTtcblxuLy8gVGVzdCBfd3JpdGFibGVTdGF0ZSBmb3IgaW5oZXJpdGFuY2UgdG8gYWNjb3VudCBmb3IgRHVwbGV4IHN0cmVhbXMsXG4vLyB3aG9zZSBwcm90b3R5cGUgY2hhaW4gb25seSBwb2ludHMgdG8gUmVhZGFibGUuXG52YXIgcmVhbEhhc0luc3RhbmNlO1xuaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLmhhc0luc3RhbmNlICYmIHR5cGVvZiBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXSA9PT0gJ2Z1bmN0aW9uJykge1xuICByZWFsSGFzSW5zdGFuY2UgPSBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLCBTeW1ib2wuaGFzSW5zdGFuY2UsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgaWYgKHJlYWxIYXNJbnN0YW5jZS5jYWxsKHRoaXMsIG9iamVjdCkpIHJldHVybiB0cnVlO1xuXG4gICAgICByZXR1cm4gb2JqZWN0ICYmIG9iamVjdC5fd3JpdGFibGVTdGF0ZSBpbnN0YW5jZW9mIFdyaXRhYmxlU3RhdGU7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgdGhpcztcbiAgfTtcbn1cblxuZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9fc3RyZWFtX2R1cGxleCAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanNcIik7XG5cbiAgLy8gV3JpdGFibGUgY3RvciBpcyBhcHBsaWVkIHRvIER1cGxleGVzLCB0b28uXG4gIC8vIGByZWFsSGFzSW5zdGFuY2VgIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHVzaW5nIHBsYWluIGBpbnN0YW5jZW9mYFxuICAvLyB3b3VsZCByZXR1cm4gZmFsc2UsIGFzIG5vIGBfd3JpdGFibGVTdGF0ZWAgcHJvcGVydHkgaXMgYXR0YWNoZWQuXG5cbiAgLy8gVHJ5aW5nIHRvIHVzZSB0aGUgY3VzdG9tIGBpbnN0YW5jZW9mYCBmb3IgV3JpdGFibGUgaGVyZSB3aWxsIGFsc28gYnJlYWsgdGhlXG4gIC8vIE5vZGUuanMgTGF6eVRyYW5zZm9ybSBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaGFzIGEgbm9uLXRyaXZpYWwgZ2V0dGVyIGZvclxuICAvLyBgX3dyaXRhYmxlU3RhdGVgIHRoYXQgd291bGQgbGVhZCB0byBpbmZpbml0ZSByZWN1cnNpb24uXG4gIGlmICghcmVhbEhhc0luc3RhbmNlLmNhbGwoV3JpdGFibGUsIHRoaXMpICYmICEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHtcbiAgICByZXR1cm4gbmV3IFdyaXRhYmxlKG9wdGlvbnMpO1xuICB9XG5cbiAgdGhpcy5fd3JpdGFibGVTdGF0ZSA9IG5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeS5cbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGUgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRlID0gb3B0aW9ucy53cml0ZTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZXYgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRldiA9IG9wdGlvbnMud3JpdGV2O1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdDYW5ub3QgcGlwZSwgbm90IHJlYWRhYmxlJykpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVBZnRlckVuZChzdHJlYW0sIGNiKSB7XG4gIHZhciBlciA9IG5ldyBFcnJvcignd3JpdGUgYWZ0ZXIgZW5kJyk7XG4gIC8vIFRPRE86IGRlZmVyIGVycm9yIGV2ZW50cyBjb25zaXN0ZW50bHkgZXZlcnl3aGVyZSwgbm90IGp1c3QgdGhlIGNiXG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7XG59XG5cbi8vIElmIHdlIGdldCBzb21ldGhpbmcgdGhhdCBpcyBub3QgYSBidWZmZXIsIHN0cmluZywgbnVsbCwgb3IgdW5kZWZpbmVkLFxuLy8gYW5kIHdlJ3JlIG5vdCBpbiBvYmplY3RNb2RlLCB0aGVuIHRoYXQncyBhbiBlcnJvci5cbi8vIE90aGVyd2lzZSBzdHJlYW0gY2h1bmtzIGFyZSBhbGwgY29uc2lkZXJlZCB0byBiZSBvZiBsZW5ndGg9MSwgYW5kIHRoZVxuLy8gd2F0ZXJtYXJrcyBkZXRlcm1pbmUgaG93IG1hbnkgb2JqZWN0cyB0byBrZWVwIGluIHRoZSBidWZmZXIsIHJhdGhlciB0aGFuXG4vLyBob3cgbWFueSBieXRlcyBvciBjaGFyYWN0ZXJzLlxuZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgY2IpIHtcbiAgdmFyIHZhbGlkID0gdHJ1ZTtcbiAgdmFyIGVyID0gZmFsc2U7XG4gIC8vIEFsd2F5cyB0aHJvdyBlcnJvciBpZiBhIG51bGwgaXMgd3JpdHRlblxuICAvLyBpZiB3ZSBhcmUgbm90IGluIG9iamVjdCBtb2RlIHRoZW4gdGhyb3dcbiAgLy8gaWYgaXQgaXMgbm90IGEgYnVmZmVyLCBzdHJpbmcsIG9yIHVuZGVmaW5lZC5cbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdNYXkgbm90IHdyaXRlIG51bGwgdmFsdWVzIHRvIHN0cmVhbScpO1xuICB9IGVsc2UgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICB9XG4gIGlmIChlcikge1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgICBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtcbiAgICB2YWxpZCA9IGZhbHNlO1xuICB9XG4gIHJldHVybiB2YWxpZDtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHJldCA9IGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSBlbmNvZGluZyA9ICdidWZmZXInO2Vsc2UgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgY2IgPSBub3A7XG5cbiAgaWYgKHN0YXRlLmVuZGVkKSB3cml0ZUFmdGVyRW5kKHRoaXMsIGNiKTtlbHNlIGlmICh2YWxpZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgY2IpKSB7XG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgcmV0ID0gd3JpdGVPckJ1ZmZlcih0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgc3RhdGUuY29ya2VkKys7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUudW5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQtLTtcblxuICAgIGlmICghc3RhdGUud3JpdGluZyAmJiAhc3RhdGUuY29ya2VkICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIGNsZWFyQnVmZmVyKHRoaXMsIHN0YXRlKTtcbiAgfVxufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnNldERlZmF1bHRFbmNvZGluZyA9IGZ1bmN0aW9uIHNldERlZmF1bHRFbmNvZGluZyhlbmNvZGluZykge1xuICAvLyBub2RlOjpQYXJzZUVuY29kaW5nKCkgcmVxdWlyZXMgbG93ZXIgY2FzZS5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIGVuY29kaW5nID0gZW5jb2RpbmcudG9Mb3dlckNhc2UoKTtcbiAgaWYgKCEoWydoZXgnLCAndXRmOCcsICd1dGYtOCcsICdhc2NpaScsICdiaW5hcnknLCAnYmFzZTY0JywgJ3VjczInLCAndWNzLTInLCAndXRmMTZsZScsICd1dGYtMTZsZScsICdyYXcnXS5pbmRleE9mKChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpKSA+IC0xKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKTtcbiAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZWZhdWx0RW5jb2RpbmcgPSBlbmNvZGluZztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgY2h1bmsgPSBidWZmZXJTaGltLmZyb20oY2h1bmssIGVuY29kaW5nKTtcbiAgfVxuICByZXR1cm4gY2h1bms7XG59XG5cbi8vIGlmIHdlJ3JlIGFscmVhZHkgd3JpdGluZyBzb21ldGhpbmcsIHRoZW4ganVzdCBwdXQgdGhpc1xuLy8gaW4gdGhlIHF1ZXVlLCBhbmQgd2FpdCBvdXIgdHVybi4gIE90aGVyd2lzZSwgY2FsbCBfd3JpdGVcbi8vIElmIHdlIHJldHVybiBmYWxzZSwgdGhlbiB3ZSBuZWVkIGEgZHJhaW4gZXZlbnQsIHNvIHNldCB0aGF0IGZsYWcuXG5mdW5jdGlvbiB3cml0ZU9yQnVmZmVyKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gIHN0YXRlLmxlbmd0aCArPSBsZW47XG5cbiAgdmFyIHJldCA9IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIC8vIHdlIG11c3QgZW5zdXJlIHRoYXQgcHJldmlvdXMgbmVlZERyYWluIHdpbGwgbm90IGJlIHJlc2V0IHRvIGZhbHNlLlxuICBpZiAoIXJldCkgc3RhdGUubmVlZERyYWluID0gdHJ1ZTtcblxuICBpZiAoc3RhdGUud3JpdGluZyB8fCBzdGF0ZS5jb3JrZWQpIHtcbiAgICB2YXIgbGFzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG5ldyBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICBpZiAobGFzdCkge1xuICAgICAgbGFzdC5uZXh0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgKz0gMTtcbiAgfSBlbHNlIHtcbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB3cml0ZXYsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBzdGF0ZS53cml0ZWxlbiA9IGxlbjtcbiAgc3RhdGUud3JpdGVjYiA9IGNiO1xuICBzdGF0ZS53cml0aW5nID0gdHJ1ZTtcbiAgc3RhdGUuc3luYyA9IHRydWU7XG4gIGlmICh3cml0ZXYpIHN0cmVhbS5fd3JpdGV2KGNodW5rLCBzdGF0ZS5vbndyaXRlKTtlbHNlIHN0cmVhbS5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBzdGF0ZS5vbndyaXRlKTtcbiAgc3RhdGUuc3luYyA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKSB7XG4gIC0tc3RhdGUucGVuZGluZ2NiO1xuICBpZiAoc3luYykgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7ZWxzZSBjYihlcik7XG5cbiAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbn1cblxuZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKSB7XG4gIHN0YXRlLndyaXRpbmcgPSBmYWxzZTtcbiAgc3RhdGUud3JpdGVjYiA9IG51bGw7XG4gIHN0YXRlLmxlbmd0aCAtPSBzdGF0ZS53cml0ZWxlbjtcbiAgc3RhdGUud3JpdGVsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlKHN0cmVhbSwgZXIpIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgc3luYyA9IHN0YXRlLnN5bmM7XG4gIHZhciBjYiA9IHN0YXRlLndyaXRlY2I7XG5cbiAgb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKTtcblxuICBpZiAoZXIpIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO2Vsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG5cbiAgICBpZiAoIWZpbmlzaGVkICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSB7XG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG5cbiAgICBpZiAoc3luYykge1xuICAgICAgLyo8cmVwbGFjZW1lbnQ+Ki9cbiAgICAgIGFzeW5jV3JpdGUoYWZ0ZXJXcml0ZSwgc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICAgIC8qPC9yZXBsYWNlbWVudD4qL1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYikge1xuICBpZiAoIWZpbmlzaGVkKSBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSk7XG4gIHN0YXRlLnBlbmRpbmdjYi0tO1xuICBjYigpO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuLy8gTXVzdCBmb3JjZSBjYWxsYmFjayB0byBiZSBjYWxsZWQgb24gbmV4dFRpY2ssIHNvIHRoYXQgd2UgZG9uJ3Rcbi8vIGVtaXQgJ2RyYWluJyBiZWZvcmUgdGhlIHdyaXRlKCkgY29uc3VtZXIgZ2V0cyB0aGUgJ2ZhbHNlJyByZXR1cm5cbi8vIHZhbHVlLCBhbmQgaGFzIGEgY2hhbmNlIHRvIGF0dGFjaCBhICdkcmFpbicgbGlzdGVuZXIuXG5mdW5jdGlvbiBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLm5lZWREcmFpbikge1xuICAgIHN0YXRlLm5lZWREcmFpbiA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdkcmFpbicpO1xuICB9XG59XG5cbi8vIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGluIHRoZSBidWZmZXIgd2FpdGluZywgdGhlbiBwcm9jZXNzIGl0XG5mdW5jdGlvbiBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKSB7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSB0cnVlO1xuICB2YXIgZW50cnkgPSBzdGF0ZS5idWZmZXJlZFJlcXVlc3Q7XG5cbiAgaWYgKHN0cmVhbS5fd3JpdGV2ICYmIGVudHJ5ICYmIGVudHJ5Lm5leHQpIHtcbiAgICAvLyBGYXN0IGNhc2UsIHdyaXRlIGV2ZXJ5dGhpbmcgdXNpbmcgX3dyaXRldigpXG4gICAgdmFyIGwgPSBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudDtcbiAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5KGwpO1xuICAgIHZhciBob2xkZXIgPSBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU7XG4gICAgaG9sZGVyLmVudHJ5ID0gZW50cnk7XG5cbiAgICB2YXIgY291bnQgPSAwO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgYnVmZmVyW2NvdW50XSA9IGVudHJ5O1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgY291bnQgKz0gMTtcbiAgICB9XG5cbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHRydWUsIHN0YXRlLmxlbmd0aCwgYnVmZmVyLCAnJywgaG9sZGVyLmZpbmlzaCk7XG5cbiAgICAvLyBkb1dyaXRlIGlzIGFsbW9zdCBhbHdheXMgYXN5bmMsIGRlZmVyIHRoZXNlIHRvIHNhdmUgYSBiaXQgb2YgdGltZVxuICAgIC8vIGFzIHRoZSBob3QgcGF0aCBlbmRzIHdpdGggZG9Xcml0ZVxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIGlmIChob2xkZXIubmV4dCkge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gaG9sZGVyLm5leHQ7XG4gICAgICBob2xkZXIubmV4dCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHN0YXRlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gU2xvdyBjYXNlLCB3cml0ZSBjaHVua3Mgb25lLWJ5LW9uZVxuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNodW5rID0gZW50cnkuY2h1bms7XG4gICAgICB2YXIgZW5jb2RpbmcgPSBlbnRyeS5lbmNvZGluZztcbiAgICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgICAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gICAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAgIC8vIGl0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0IGRvZXMuXG4gICAgICAvLyBhbHNvLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGNodW5rIGFuZCBjYiBhcmUgY3VycmVudGx5XG4gICAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cbiAgICAgIGlmIChzdGF0ZS53cml0aW5nKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbnRyeSA9PT0gbnVsbCkgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIH1cblxuICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCA9IDA7XG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRXJyb3IoJ193cml0ZSgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2ID0gbnVsbDtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2h1bms7XG4gICAgY2h1bmsgPSBudWxsO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkKSB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZCA9IDE7XG4gICAgdGhpcy51bmNvcmsoKTtcbiAgfVxuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKSBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xufTtcblxuZnVuY3Rpb24gbmVlZEZpbmlzaChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuZW5kaW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPT09IG51bGwgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS53cml0aW5nO1xufVxuXG5mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnByZWZpbmlzaGVkKSB7XG4gICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBuZWVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgaWYgKHN0YXRlLnBlbmRpbmdjYiA9PT0gMCkge1xuICAgICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgc3RhdGUuZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ2ZpbmlzaCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZWVkO1xufVxuXG5mdW5jdGlvbiBlbmRXcml0YWJsZShzdHJlYW0sIHN0YXRlLCBjYikge1xuICBzdGF0ZS5lbmRpbmcgPSB0cnVlO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgaWYgKGNiKSB7XG4gICAgaWYgKHN0YXRlLmZpbmlzaGVkKSBwcm9jZXNzTmV4dFRpY2soY2IpO2Vsc2Ugc3RyZWFtLm9uY2UoJ2ZpbmlzaCcsIGNiKTtcbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gIHN0cmVhbS53cml0YWJsZSA9IGZhbHNlO1xufVxuXG4vLyBJdCBzZWVtcyBhIGxpbmtlZCBsaXN0IGJ1dCBpdCBpcyBub3Rcbi8vIHRoZXJlIHdpbGwgYmUgb25seSAyIG9mIHRoZXNlIGZvciBlYWNoIHN0cmVhbVxuZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMuZW50cnkgPSBudWxsO1xuXG4gIHRoaXMuZmluaXNoID0gZnVuY3Rpb24gKGVycikge1xuICAgIHZhciBlbnRyeSA9IF90aGlzLmVudHJ5O1xuICAgIF90aGlzLmVudHJ5ID0gbnVsbDtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgICBjYihlcnIpO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgIH1cbiAgICBpZiAoc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlKSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IF90aGlzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBfdGhpcztcbiAgICB9XG4gIH07XG59XG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwodGhpcywgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8uLi8uLi9wcm9jZXNzL2Jyb3dzZXIuanMgKi8gXCIuL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanNcIiksIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vLi4vLi4vdGltZXJzLWJyb3dzZXJpZnkvbWFpbi5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanNcIikuc2V0SW1tZWRpYXRlKSlcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5cblxudmFyIEJ1ZmZlciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGJ1ZmZlciAqLyBcIi4vbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qc1wiKS5CdWZmZXI7XG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGJ1ZmZlclNoaW0gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBidWZmZXItc2hpbXMgKi8gXCIuL25vZGVfbW9kdWxlcy9idWZmZXItc2hpbXMvaW5kZXguanNcIik7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJMaXN0O1xuXG5mdW5jdGlvbiBCdWZmZXJMaXN0KCkge1xuICB0aGlzLmhlYWQgPSBudWxsO1xuICB0aGlzLnRhaWwgPSBudWxsO1xuICB0aGlzLmxlbmd0aCA9IDA7XG59XG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAodikge1xuICB2YXIgZW50cnkgPSB7IGRhdGE6IHYsIG5leHQ6IG51bGwgfTtcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkgdGhpcy50YWlsLm5leHQgPSBlbnRyeTtlbHNlIHRoaXMuaGVhZCA9IGVudHJ5O1xuICB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgKyt0aGlzLmxlbmd0aDtcbn07XG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAodikge1xuICB2YXIgZW50cnkgPSB7IGRhdGE6IHYsIG5leHQ6IHRoaXMuaGVhZCB9O1xuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHRoaXMudGFpbCA9IGVudHJ5O1xuICB0aGlzLmhlYWQgPSBlbnRyeTtcbiAgKyt0aGlzLmxlbmd0aDtcbn07XG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgdmFyIHJldCA9IHRoaXMuaGVhZC5kYXRhO1xuICBpZiAodGhpcy5sZW5ndGggPT09IDEpIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7ZWxzZSB0aGlzLmhlYWQgPSB0aGlzLmhlYWQubmV4dDtcbiAgLS10aGlzLmxlbmd0aDtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICB0aGlzLmxlbmd0aCA9IDA7XG59O1xuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5qb2luID0gZnVuY3Rpb24gKHMpIHtcbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gIHZhciBwID0gdGhpcy5oZWFkO1xuICB2YXIgcmV0ID0gJycgKyBwLmRhdGE7XG4gIHdoaWxlIChwID0gcC5uZXh0KSB7XG4gICAgcmV0ICs9IHMgKyBwLmRhdGE7XG4gIH1yZXR1cm4gcmV0O1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuY29uY2F0ID0gZnVuY3Rpb24gKG4pIHtcbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gYnVmZmVyU2hpbS5hbGxvYygwKTtcbiAgaWYgKHRoaXMubGVuZ3RoID09PSAxKSByZXR1cm4gdGhpcy5oZWFkLmRhdGE7XG4gIHZhciByZXQgPSBidWZmZXJTaGltLmFsbG9jVW5zYWZlKG4gPj4+IDApO1xuICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgdmFyIGkgPSAwO1xuICB3aGlsZSAocCkge1xuICAgIHAuZGF0YS5jb3B5KHJldCwgaSk7XG4gICAgaSArPSBwLmRhdGEubGVuZ3RoO1xuICAgIHAgPSBwLm5leHQ7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn07XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMgKi8gXCIuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIilcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovKGZ1bmN0aW9uKHByb2Nlc3MpIHt2YXIgU3RyZWFtID0gKGZ1bmN0aW9uICgpe1xuICB0cnkge1xuICAgIHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBzdHJlYW0gKi8gXCIuL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qc1wiKTsgLy8gaGFjayB0byBmaXggYSBjaXJjdWxhciBkZXBlbmRlbmN5IGlzc3VlIHdoZW4gdXNlZCB3aXRoIGJyb3dzZXJpZnlcbiAgfSBjYXRjaChfKXt9XG59KCkpO1xuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qc1wiKTtcbmV4cG9ydHMuU3RyZWFtID0gU3RyZWFtIHx8IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCIpO1xuZXhwb3J0cy5EdXBsZXggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9fc3RyZWFtX2R1cGxleC5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanNcIik7XG5leHBvcnRzLlRyYW5zZm9ybSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKTtcbmV4cG9ydHMuUGFzc1Rocm91Z2ggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCIpO1xuXG5pZiAoIXByb2Nlc3MuYnJvd3NlciAmJiBwcm9jZXNzLmVudi5SRUFEQUJMRV9TVFJFQU0gPT09ICdkaXNhYmxlJyAmJiBTdHJlYW0pIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG59XG5cbi8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqL30uY2FsbCh0aGlzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuLy4uL3Byb2Nlc3MvYnJvd3Nlci5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qc1wiKSkpXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanNcIilcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS93cml0YWJsZS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCIpXG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9pbmRleC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG52YXIgaHRtbHBhcnNlciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGh0bWxwYXJzZXIyICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL2luZGV4LmpzXCIpO1xudmFyIGV4dGVuZCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHh0ZW5kICovIFwiLi9ub2RlX21vZHVsZXMveHRlbmQvaW1tdXRhYmxlLmpzXCIpO1xudmFyIHF1b3RlUmVnZXhwID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgcmVnZXhwLXF1b3RlICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvcmVnZXhwLXF1b3RlL3JlZ2V4cC1xdW90ZS5qc1wiKTtcblxuZnVuY3Rpb24gZWFjaChvYmosIGNiKSB7XG4gIGlmIChvYmopIE9iamVjdC5rZXlzKG9iaikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgY2Iob2JqW2tleV0sIGtleSk7XG4gIH0pO1xufVxuXG4vLyBBdm9pZCBmYWxzZSBwb3NpdGl2ZXMgd2l0aCAuX19wcm90b19fLCAuaGFzT3duUHJvcGVydHksIGV0Yy5cbmZ1bmN0aW9uIGhhcyhvYmosIGtleSkge1xuICByZXR1cm4gKHt9KS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzYW5pdGl6ZUh0bWw7XG5cbi8vIElnbm9yZSB0aGUgX3JlY3Vyc2luZyBmbGFnOyBpdCdzIHRoZXJlIGZvciByZWN1cnNpdmVcbi8vIGludm9jYXRpb24gYXMgYSBndWFyZCBhZ2FpbnN0IHRoaXMgZXhwbG9pdDpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYjU1L2h0bWxwYXJzZXIyL2lzc3Vlcy8xMDVcblxuZnVuY3Rpb24gc2FuaXRpemVIdG1sKGh0bWwsIG9wdGlvbnMsIF9yZWN1cnNpbmcpIHtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuXG4gIGZ1bmN0aW9uIEZyYW1lKHRhZywgYXR0cmlicykge1xuICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICB0aGlzLnRhZyA9IHRhZztcbiAgICB0aGlzLmF0dHJpYnMgPSBhdHRyaWJzIHx8IHt9O1xuICAgIHRoaXMudGFnUG9zaXRpb24gPSByZXN1bHQubGVuZ3RoO1xuICAgIHRoaXMudGV4dCA9ICcnOyAvLyBOb2RlIGlubmVyIHRleHRcblxuICAgIHRoaXMudXBkYXRlUGFyZW50Tm9kZVRleHQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChzdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICB2YXIgcGFyZW50RnJhbWUgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcbiAgICAgICAgICBwYXJlbnRGcmFtZS50ZXh0ICs9IHRoYXQudGV4dDtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHNhbml0aXplSHRtbC5kZWZhdWx0cztcbiAgICBvcHRpb25zLnBhcnNlciA9IGh0bWxQYXJzZXJEZWZhdWx0cztcbiAgfSBlbHNlIHtcbiAgICBvcHRpb25zID0gZXh0ZW5kKHNhbml0aXplSHRtbC5kZWZhdWx0cywgb3B0aW9ucyk7XG4gICAgaWYgKG9wdGlvbnMucGFyc2VyKSB7XG4gICAgICBvcHRpb25zLnBhcnNlciA9IGV4dGVuZChodG1sUGFyc2VyRGVmYXVsdHMsIG9wdGlvbnMucGFyc2VyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucy5wYXJzZXIgPSBodG1sUGFyc2VyRGVmYXVsdHM7XG4gICAgfVxuICB9XG5cbiAgLy8gVGFncyB0aGF0IGNvbnRhaW4gc29tZXRoaW5nIG90aGVyIHRoYW4gSFRNTCwgb3Igd2hlcmUgZGlzY2FyZGluZ1xuICAvLyB0aGUgdGV4dCB3aGVuIHRoZSB0YWcgaXMgZGlzYWxsb3dlZCBtYWtlcyBzZW5zZSBmb3Igb3RoZXIgcmVhc29ucy5cbiAgLy8gSWYgd2UgYXJlIG5vdCBhbGxvd2luZyB0aGVzZSB0YWdzLCB3ZSBzaG91bGQgZHJvcCB0aGVpciBjb250ZW50IHRvby5cbiAgLy8gRm9yIG90aGVyIHRhZ3MgeW91IHdvdWxkIGRyb3AgdGhlIHRhZyBidXQga2VlcCBpdHMgY29udGVudC5cbiAgdmFyIG5vblRleHRUYWdzQXJyYXkgPSBvcHRpb25zLm5vblRleHRUYWdzIHx8IFsgJ3NjcmlwdCcsICdzdHlsZScsICd0ZXh0YXJlYScgXTtcbiAgdmFyIGFsbG93ZWRBdHRyaWJ1dGVzTWFwO1xuICB2YXIgYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwO1xuICBpZihvcHRpb25zLmFsbG93ZWRBdHRyaWJ1dGVzKSB7XG4gICAgYWxsb3dlZEF0dHJpYnV0ZXNNYXAgPSB7fTtcbiAgICBhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXAgPSB7fTtcbiAgICBlYWNoKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMsIGZ1bmN0aW9uKGF0dHJpYnV0ZXMsIHRhZykge1xuICAgICAgYWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXSA9IFtdO1xuICAgICAgdmFyIGdsb2JSZWdleCA9IFtdO1xuICAgICAgYXR0cmlidXRlcy5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgaWYobmFtZS5pbmRleE9mKCcqJykgPj0gMCkge1xuICAgICAgICAgIGdsb2JSZWdleC5wdXNoKHF1b3RlUmVnZXhwKG5hbWUpLnJlcGxhY2UoL1xcXFxcXCovZywgJy4qJykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ10ucHVzaChuYW1lKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXBbdGFnXSA9IG5ldyBSZWdFeHAoJ14oJyArIGdsb2JSZWdleC5qb2luKCd8JykgKyAnKSQnKTtcbiAgICB9KTtcbiAgfVxuICB2YXIgYWxsb3dlZENsYXNzZXNNYXAgPSB7fTtcbiAgZWFjaChvcHRpb25zLmFsbG93ZWRDbGFzc2VzLCBmdW5jdGlvbihjbGFzc2VzLCB0YWcpIHtcbiAgICAvLyBJbXBsaWNpdGx5IGFsbG93cyB0aGUgY2xhc3MgYXR0cmlidXRlXG4gICAgaWYoYWxsb3dlZEF0dHJpYnV0ZXNNYXApIHtcbiAgICAgIGlmICghaGFzKGFsbG93ZWRBdHRyaWJ1dGVzTWFwLCB0YWcpKSB7XG4gICAgICAgIGFsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ10gPSBbXTtcbiAgICAgIH1cbiAgICAgIGFsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ10ucHVzaCgnY2xhc3MnKTtcbiAgICB9XG5cbiAgICBhbGxvd2VkQ2xhc3Nlc01hcFt0YWddID0gY2xhc3NlcztcbiAgfSk7XG5cbiAgdmFyIHRyYW5zZm9ybVRhZ3NNYXAgPSB7fTtcbiAgdmFyIHRyYW5zZm9ybVRhZ3NBbGw7XG4gIGVhY2gob3B0aW9ucy50cmFuc2Zvcm1UYWdzLCBmdW5jdGlvbih0cmFuc2Zvcm0sIHRhZykge1xuICAgIHZhciB0cmFuc0Z1bjtcbiAgICBpZiAodHlwZW9mIHRyYW5zZm9ybSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdHJhbnNGdW4gPSB0cmFuc2Zvcm07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdHJhbnNmb3JtID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0cmFuc0Z1biA9IHNhbml0aXplSHRtbC5zaW1wbGVUcmFuc2Zvcm0odHJhbnNmb3JtKTtcbiAgICB9XG4gICAgaWYgKHRhZyA9PT0gJyonKSB7XG4gICAgICB0cmFuc2Zvcm1UYWdzQWxsID0gdHJhbnNGdW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyYW5zZm9ybVRhZ3NNYXBbdGFnXSA9IHRyYW5zRnVuO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIGRlcHRoID0gMDtcbiAgdmFyIHN0YWNrID0gW107XG4gIHZhciBza2lwTWFwID0ge307XG4gIHZhciB0cmFuc2Zvcm1NYXAgPSB7fTtcbiAgdmFyIHNraXBUZXh0ID0gZmFsc2U7XG4gIHZhciBza2lwVGV4dERlcHRoID0gMDtcblxuICB2YXIgcGFyc2VyID0gbmV3IGh0bWxwYXJzZXIuUGFyc2VyKHtcbiAgICBvbm9wZW50YWc6IGZ1bmN0aW9uKG5hbWUsIGF0dHJpYnMpIHtcbiAgICAgIGlmIChza2lwVGV4dCkge1xuICAgICAgICBza2lwVGV4dERlcHRoKys7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBmcmFtZSA9IG5ldyBGcmFtZShuYW1lLCBhdHRyaWJzKTtcbiAgICAgIHN0YWNrLnB1c2goZnJhbWUpO1xuXG4gICAgICB2YXIgc2tpcCA9IGZhbHNlO1xuICAgICAgdmFyIGhhc1RleHQgPSBmcmFtZS50ZXh0ID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgdmFyIHRyYW5zZm9ybWVkVGFnO1xuICAgICAgaWYgKGhhcyh0cmFuc2Zvcm1UYWdzTWFwLCBuYW1lKSkge1xuICAgICAgICB0cmFuc2Zvcm1lZFRhZyA9IHRyYW5zZm9ybVRhZ3NNYXBbbmFtZV0obmFtZSwgYXR0cmlicyk7XG5cbiAgICAgICAgZnJhbWUuYXR0cmlicyA9IGF0dHJpYnMgPSB0cmFuc2Zvcm1lZFRhZy5hdHRyaWJzO1xuXG4gICAgICAgIGlmICh0cmFuc2Zvcm1lZFRhZy50ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBmcmFtZS5pbm5lclRleHQgPSB0cmFuc2Zvcm1lZFRhZy50ZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5hbWUgIT09IHRyYW5zZm9ybWVkVGFnLnRhZ05hbWUpIHtcbiAgICAgICAgICBmcmFtZS5uYW1lID0gbmFtZSA9IHRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7XG4gICAgICAgICAgdHJhbnNmb3JtTWFwW2RlcHRoXSA9IHRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0cmFuc2Zvcm1UYWdzQWxsKSB7XG4gICAgICAgIHRyYW5zZm9ybWVkVGFnID0gdHJhbnNmb3JtVGFnc0FsbChuYW1lLCBhdHRyaWJzKTtcblxuICAgICAgICBmcmFtZS5hdHRyaWJzID0gYXR0cmlicyA9IHRyYW5zZm9ybWVkVGFnLmF0dHJpYnM7XG4gICAgICAgIGlmIChuYW1lICE9PSB0cmFuc2Zvcm1lZFRhZy50YWdOYW1lKSB7XG4gICAgICAgICAgZnJhbWUubmFtZSA9IG5hbWUgPSB0cmFuc2Zvcm1lZFRhZy50YWdOYW1lO1xuICAgICAgICAgIHRyYW5zZm9ybU1hcFtkZXB0aF0gPSB0cmFuc2Zvcm1lZFRhZy50YWdOYW1lO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmFsbG93ZWRUYWdzICYmIG9wdGlvbnMuYWxsb3dlZFRhZ3MuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgICAgc2tpcCA9IHRydWU7XG4gICAgICAgIGlmIChub25UZXh0VGFnc0FycmF5LmluZGV4T2YobmFtZSkgIT09IC0xKSB7XG4gICAgICAgICAgc2tpcFRleHQgPSB0cnVlO1xuICAgICAgICAgIHNraXBUZXh0RGVwdGggPSAxO1xuICAgICAgICB9XG4gICAgICAgIHNraXBNYXBbZGVwdGhdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGRlcHRoKys7XG4gICAgICBpZiAoc2tpcCkge1xuICAgICAgICAvLyBXZSB3YW50IHRoZSBjb250ZW50cyBidXQgbm90IHRoaXMgdGFnXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCArPSAnPCcgKyBuYW1lO1xuICAgICAgaWYgKCFhbGxvd2VkQXR0cmlidXRlc01hcCB8fCBoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsIG5hbWUpIHx8IGFsbG93ZWRBdHRyaWJ1dGVzTWFwWycqJ10pIHtcbiAgICAgICAgZWFjaChhdHRyaWJzLCBmdW5jdGlvbih2YWx1ZSwgYSkge1xuICAgICAgICAgIGlmICghYWxsb3dlZEF0dHJpYnV0ZXNNYXAgfHxcbiAgICAgICAgICAgICAgKGhhcyhhbGxvd2VkQXR0cmlidXRlc01hcCwgbmFtZSkgJiYgYWxsb3dlZEF0dHJpYnV0ZXNNYXBbbmFtZV0uaW5kZXhPZihhKSAhPT0gLTEgKSB8fFxuICAgICAgICAgICAgICAoYWxsb3dlZEF0dHJpYnV0ZXNNYXBbJyonXSAmJiBhbGxvd2VkQXR0cmlidXRlc01hcFsnKiddLmluZGV4T2YoYSkgIT09IC0xICkgfHxcbiAgICAgICAgICAgICAgKGhhcyhhbGxvd2VkQXR0cmlidXRlc0dsb2JNYXAsIG5hbWUpICYmIGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtuYW1lXS50ZXN0KGEpKSB8fFxuICAgICAgICAgICAgICAoYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwWycqJ10gJiYgYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwWycqJ10udGVzdChhKSkpIHtcbiAgICAgICAgICAgIGlmICgoYSA9PT0gJ2hyZWYnKSB8fCAoYSA9PT0gJ3NyYycpKSB7XG4gICAgICAgICAgICAgIGlmIChuYXVnaHR5SHJlZihuYW1lLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgZnJhbWUuYXR0cmlic1thXTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhID09PSAnY2xhc3MnKSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gZmlsdGVyQ2xhc3Nlcyh2YWx1ZSwgYWxsb3dlZENsYXNzZXNNYXBbbmFtZV0pO1xuICAgICAgICAgICAgICBpZiAoIXZhbHVlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBmcmFtZS5hdHRyaWJzW2FdO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0ICs9ICcgJyArIGE7XG4gICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJlc3VsdCArPSAnPVwiJyArIGVzY2FwZUh0bWwodmFsdWUpICsgJ1wiJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLnNlbGZDbG9zaW5nLmluZGV4T2YobmFtZSkgIT09IC0xKSB7XG4gICAgICAgIHJlc3VsdCArPSBcIiAvPlwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ICs9IFwiPlwiO1xuICAgICAgICBpZiAoZnJhbWUuaW5uZXJUZXh0ICYmICFoYXNUZXh0ICYmICFvcHRpb25zLnRleHRGaWx0ZXIpIHtcbiAgICAgICAgICByZXN1bHQgKz0gZnJhbWUuaW5uZXJUZXh0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBvbnRleHQ6IGZ1bmN0aW9uKHRleHQpIHtcbiAgICAgIGlmIChza2lwVGV4dCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgbGFzdEZyYW1lID0gc3RhY2tbc3RhY2subGVuZ3RoLTFdO1xuICAgICAgdmFyIHRhZztcblxuICAgICAgaWYgKGxhc3RGcmFtZSkge1xuICAgICAgICB0YWcgPSBsYXN0RnJhbWUudGFnO1xuICAgICAgICAvLyBJZiBpbm5lciB0ZXh0IHdhcyBzZXQgYnkgdHJhbnNmb3JtIGZ1bmN0aW9uIHRoZW4gbGV0J3MgdXNlIGl0XG4gICAgICAgIHRleHQgPSBsYXN0RnJhbWUuaW5uZXJUZXh0ICE9PSB1bmRlZmluZWQgPyBsYXN0RnJhbWUuaW5uZXJUZXh0IDogdGV4dDtcbiAgICAgIH1cblxuICAgICAgaWYgKCh0YWcgPT09ICdzY3JpcHQnKSB8fCAodGFnID09PSAnc3R5bGUnKSkge1xuICAgICAgICAvLyBodG1scGFyc2VyMiBnaXZlcyB1cyB0aGVzZSBhcy1pcy4gRXNjYXBpbmcgdGhlbSBydWlucyB0aGUgY29udGVudC4gQWxsb3dpbmdcbiAgICAgICAgLy8gc2NyaXB0IHRhZ3MgaXMsIGJ5IGRlZmluaXRpb24sIGdhbWUgb3ZlciBmb3IgWFNTIHByb3RlY3Rpb24sIHNvIGlmIHRoYXQnc1xuICAgICAgICAvLyB5b3VyIGNvbmNlcm4sIGRvbid0IGFsbG93IHRoZW0uIFRoZSBzYW1lIGlzIGVzc2VudGlhbGx5IHRydWUgZm9yIHN0eWxlIHRhZ3NcbiAgICAgICAgLy8gd2hpY2ggaGF2ZSB0aGVpciBvd24gY29sbGVjdGlvbiBvZiBYU1MgdmVjdG9ycy5cbiAgICAgICAgcmVzdWx0ICs9IHRleHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgZXNjYXBlZCA9IGVzY2FwZUh0bWwodGV4dCk7XG4gICAgICAgIGlmIChvcHRpb25zLnRleHRGaWx0ZXIpIHtcbiAgICAgICAgICByZXN1bHQgKz0gb3B0aW9ucy50ZXh0RmlsdGVyKGVzY2FwZWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdCArPSBlc2NhcGVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgIHZhciBmcmFtZSA9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICBmcmFtZS50ZXh0ICs9IHRleHQ7XG4gICAgICB9XG4gICAgfSxcbiAgICBvbmNsb3NldGFnOiBmdW5jdGlvbihuYW1lKSB7XG5cbiAgICAgIGlmIChza2lwVGV4dCkge1xuICAgICAgICBza2lwVGV4dERlcHRoLS07XG4gICAgICAgIGlmICghc2tpcFRleHREZXB0aCkge1xuICAgICAgICAgIHNraXBUZXh0ID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBmcmFtZSA9IHN0YWNrLnBvcCgpO1xuICAgICAgaWYgKCFmcmFtZSkge1xuICAgICAgICAvLyBEbyBub3QgY3Jhc2ggb24gYmFkIG1hcmt1cFxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBza2lwVGV4dCA9IGZhbHNlO1xuICAgICAgZGVwdGgtLTtcbiAgICAgIGlmIChza2lwTWFwW2RlcHRoXSkge1xuICAgICAgICBkZWxldGUgc2tpcE1hcFtkZXB0aF07XG4gICAgICAgIGZyYW1lLnVwZGF0ZVBhcmVudE5vZGVUZXh0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRyYW5zZm9ybU1hcFtkZXB0aF0pIHtcbiAgICAgICAgbmFtZSA9IHRyYW5zZm9ybU1hcFtkZXB0aF07XG4gICAgICAgIGRlbGV0ZSB0cmFuc2Zvcm1NYXBbZGVwdGhdO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5leGNsdXNpdmVGaWx0ZXIgJiYgb3B0aW9ucy5leGNsdXNpdmVGaWx0ZXIoZnJhbWUpKSB7XG4gICAgICAgICByZXN1bHQgPSByZXN1bHQuc3Vic3RyKDAsIGZyYW1lLnRhZ1Bvc2l0aW9uKTtcbiAgICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZnJhbWUudXBkYXRlUGFyZW50Tm9kZVRleHQoKTtcblxuICAgICAgaWYgKG9wdGlvbnMuc2VsZkNsb3NpbmcuaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgIC8vIEFscmVhZHkgb3V0cHV0IC8+XG4gICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdCArPSBcIjwvXCIgKyBuYW1lICsgXCI+XCI7XG4gICAgfVxuICB9LCBvcHRpb25zLnBhcnNlcik7XG4gIHBhcnNlci53cml0ZShodG1sKTtcbiAgcGFyc2VyLmVuZCgpO1xuXG4gIHJldHVybiByZXN1bHQ7XG5cbiAgZnVuY3Rpb24gZXNjYXBlSHRtbChzKSB7XG4gICAgaWYgKHR5cGVvZihzKSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHMgPSBzICsgJyc7XG4gICAgfVxuICAgIHJldHVybiBzLnJlcGxhY2UoL1xcJi9nLCAnJmFtcDsnKS5yZXBsYWNlKC88L2csICcmbHQ7JykucmVwbGFjZSgvXFw+L2csICcmZ3Q7JykucmVwbGFjZSgvXFxcIi9nLCAnJnF1b3Q7Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBuYXVnaHR5SHJlZihuYW1lLCBocmVmKSB7XG4gICAgLy8gQnJvd3NlcnMgaWdub3JlIGNoYXJhY3RlciBjb2RlcyBvZiAzMiAoc3BhY2UpIGFuZCBiZWxvdyBpbiBhIHN1cnByaXNpbmdcbiAgICAvLyBudW1iZXIgb2Ygc2l0dWF0aW9ucy4gU3RhcnQgcmVhZGluZyBoZXJlOlxuICAgIC8vIGh0dHBzOi8vd3d3Lm93YXNwLm9yZy9pbmRleC5waHAvWFNTX0ZpbHRlcl9FdmFzaW9uX0NoZWF0X1NoZWV0I0VtYmVkZGVkX3RhYlxuICAgIGhyZWYgPSBocmVmLnJlcGxhY2UoL1tcXHgwMC1cXHgyMF0rL2csICcnKTtcbiAgICAvLyBDbG9iYmVyIGFueSBjb21tZW50cyBpbiBVUkxzLCB3aGljaCB0aGUgYnJvd3NlciBtaWdodFxuICAgIC8vIGludGVycHJldCBpbnNpZGUgYW4gWE1MIGRhdGEgaXNsYW5kLCBhbGxvd2luZ1xuICAgIC8vIGEgamF2YXNjcmlwdDogVVJMIHRvIGJlIHNudWNrIHRocm91Z2hcbiAgICBocmVmID0gaHJlZi5yZXBsYWNlKC88XFwhXFwtXFwtLio/XFwtXFwtXFw+L2csICcnKTtcbiAgICAvLyBDYXNlIGluc2Vuc2l0aXZlIHNvIHdlIGRvbid0IGdldCBmYWtlZCBvdXQgYnkgSkFWQVNDUklQVCAjMVxuICAgIHZhciBtYXRjaGVzID0gaHJlZi5tYXRjaCgvXihbYS16QS1aXSspXFw6Lyk7XG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICAvLyBObyBzY2hlbWUgPSBubyB3YXkgdG8gaW5qZWN0IGpzIChyaWdodD8pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBzY2hlbWUgPSBtYXRjaGVzWzFdLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAoaGFzKG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZywgbmFtZSkpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLmFsbG93ZWRTY2hlbWVzQnlUYWdbbmFtZV0uaW5kZXhPZihzY2hlbWUpID09PSAtMTtcbiAgICB9XG5cbiAgICByZXR1cm4gIW9wdGlvbnMuYWxsb3dlZFNjaGVtZXMgfHwgb3B0aW9ucy5hbGxvd2VkU2NoZW1lcy5pbmRleE9mKHNjaGVtZSkgPT09IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gZmlsdGVyQ2xhc3NlcyhjbGFzc2VzLCBhbGxvd2VkKSB7XG4gICAgaWYgKCFhbGxvd2VkKSB7XG4gICAgICAvLyBUaGUgY2xhc3MgYXR0cmlidXRlIGlzIGFsbG93ZWQgd2l0aG91dCBmaWx0ZXJpbmcgb24gdGhpcyB0YWdcbiAgICAgIHJldHVybiBjbGFzc2VzO1xuICAgIH1cbiAgICBjbGFzc2VzID0gY2xhc3Nlcy5zcGxpdCgvXFxzKy8pO1xuICAgIHJldHVybiBjbGFzc2VzLmZpbHRlcihmdW5jdGlvbihjbHNzKSB7XG4gICAgICByZXR1cm4gYWxsb3dlZC5pbmRleE9mKGNsc3MpICE9PSAtMTtcbiAgICB9KS5qb2luKCcgJyk7XG4gIH1cbn1cblxuLy8gRGVmYXVsdHMgYXJlIGFjY2Vzc2libGUgdG8geW91IHNvIHRoYXQgeW91IGNhbiB1c2UgdGhlbSBhcyBhIHN0YXJ0aW5nIHBvaW50XG4vLyBwcm9ncmFtbWF0aWNhbGx5IGlmIHlvdSB3aXNoXG5cbnZhciBodG1sUGFyc2VyRGVmYXVsdHMgPSB7XG4gIGRlY29kZUVudGl0aWVzOiB0cnVlXG59O1xuc2FuaXRpemVIdG1sLmRlZmF1bHRzID0ge1xuICBhbGxvd2VkVGFnczogWyAnaDMnLCAnaDQnLCAnaDUnLCAnaDYnLCAnYmxvY2txdW90ZScsICdwJywgJ2EnLCAndWwnLCAnb2wnLFxuICAgICdubCcsICdsaScsICdiJywgJ2knLCAnc3Ryb25nJywgJ2VtJywgJ3N0cmlrZScsICdjb2RlJywgJ2hyJywgJ2JyJywgJ2RpdicsXG4gICAgJ3RhYmxlJywgJ3RoZWFkJywgJ2NhcHRpb24nLCAndGJvZHknLCAndHInLCAndGgnLCAndGQnLCAncHJlJyBdLFxuICBhbGxvd2VkQXR0cmlidXRlczoge1xuICAgIGE6IFsgJ2hyZWYnLCAnbmFtZScsICd0YXJnZXQnIF0sXG4gICAgLy8gV2UgZG9uJ3QgY3VycmVudGx5IGFsbG93IGltZyBpdHNlbGYgYnkgZGVmYXVsdCwgYnV0IHRoaXNcbiAgICAvLyB3b3VsZCBtYWtlIHNlbnNlIGlmIHdlIGRpZFxuICAgIGltZzogWyAnc3JjJyBdXG4gIH0sXG4gIC8vIExvdHMgb2YgdGhlc2Ugd29uJ3QgY29tZSB1cCBieSBkZWZhdWx0IGJlY2F1c2Ugd2UgZG9uJ3QgYWxsb3cgdGhlbVxuICBzZWxmQ2xvc2luZzogWyAnaW1nJywgJ2JyJywgJ2hyJywgJ2FyZWEnLCAnYmFzZScsICdiYXNlZm9udCcsICdpbnB1dCcsICdsaW5rJywgJ21ldGEnIF0sXG4gIC8vIFVSTCBzY2hlbWVzIHdlIHBlcm1pdFxuICBhbGxvd2VkU2NoZW1lczogWyAnaHR0cCcsICdodHRwcycsICdmdHAnLCAnbWFpbHRvJyBdLFxuICBhbGxvd2VkU2NoZW1lc0J5VGFnOiB7fVxufTtcblxuc2FuaXRpemVIdG1sLnNpbXBsZVRyYW5zZm9ybSA9IGZ1bmN0aW9uKG5ld1RhZ05hbWUsIG5ld0F0dHJpYnMsIG1lcmdlKSB7XG4gIG1lcmdlID0gKG1lcmdlID09PSB1bmRlZmluZWQpID8gdHJ1ZSA6IG1lcmdlO1xuICBuZXdBdHRyaWJzID0gbmV3QXR0cmlicyB8fCB7fTtcblxuICByZXR1cm4gZnVuY3Rpb24odGFnTmFtZSwgYXR0cmlicykge1xuICAgIHZhciBhdHRyaWI7XG4gICAgaWYgKG1lcmdlKSB7XG4gICAgICBmb3IgKGF0dHJpYiBpbiBuZXdBdHRyaWJzKSB7XG4gICAgICAgIGF0dHJpYnNbYXR0cmliXSA9IG5ld0F0dHJpYnNbYXR0cmliXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYXR0cmlicyA9IG5ld0F0dHJpYnM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRhZ05hbWU6IG5ld1RhZ05hbWUsXG4gICAgICBhdHRyaWJzOiBhdHRyaWJzXG4gICAgfTtcbiAgfTtcbn07XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL0NvbGxlY3RpbmdIYW5kbGVyLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvQ29sbGVjdGluZ0hhbmRsZXIuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29sbGVjdGluZ0hhbmRsZXI7XG5cbmZ1bmN0aW9uIENvbGxlY3RpbmdIYW5kbGVyKGNicyl7XG5cdHRoaXMuX2NicyA9IGNicyB8fCB7fTtcblx0dGhpcy5ldmVudHMgPSBbXTtcbn1cblxudmFyIEVWRU5UUyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL2luZGV4LmpzXCIpLkVWRU5UUztcbk9iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtcblx0aWYoRVZFTlRTW25hbWVdID09PSAwKXtcblx0XHRuYW1lID0gXCJvblwiICsgbmFtZTtcblx0XHRDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpe1xuXHRcdFx0dGhpcy5ldmVudHMucHVzaChbbmFtZV0pO1xuXHRcdFx0aWYodGhpcy5fY2JzW25hbWVdKSB0aGlzLl9jYnNbbmFtZV0oKTtcblx0XHR9O1xuXHR9IGVsc2UgaWYoRVZFTlRTW25hbWVdID09PSAxKXtcblx0XHRuYW1lID0gXCJvblwiICsgbmFtZTtcblx0XHRDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbihhKXtcblx0XHRcdHRoaXMuZXZlbnRzLnB1c2goW25hbWUsIGFdKTtcblx0XHRcdGlmKHRoaXMuX2Nic1tuYW1lXSkgdGhpcy5fY2JzW25hbWVdKGEpO1xuXHRcdH07XG5cdH0gZWxzZSBpZihFVkVOVFNbbmFtZV0gPT09IDIpe1xuXHRcdG5hbWUgPSBcIm9uXCIgKyBuYW1lO1xuXHRcdENvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKGEsIGIpe1xuXHRcdFx0dGhpcy5ldmVudHMucHVzaChbbmFtZSwgYSwgYl0pO1xuXHRcdFx0aWYodGhpcy5fY2JzW25hbWVdKSB0aGlzLl9jYnNbbmFtZV0oYSwgYik7XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHR0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHNcIik7XG5cdH1cbn0pO1xuXG5Db2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGUub25yZXNldCA9IGZ1bmN0aW9uKCl7XG5cdHRoaXMuZXZlbnRzID0gW107XG5cdGlmKHRoaXMuX2Nicy5vbnJlc2V0KSB0aGlzLl9jYnMub25yZXNldCgpO1xufTtcblxuQ29sbGVjdGluZ0hhbmRsZXIucHJvdG90eXBlLnJlc3RhcnQgPSBmdW5jdGlvbigpe1xuXHRpZih0aGlzLl9jYnMub25yZXNldCkgdGhpcy5fY2JzLm9ucmVzZXQoKTtcblxuXHRmb3IodmFyIGkgPSAwLCBsZW4gPSB0aGlzLmV2ZW50cy5sZW5ndGg7IGkgPCBsZW47IGkrKyl7XG5cdFx0aWYodGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSl7XG5cblx0XHRcdHZhciBudW0gPSB0aGlzLmV2ZW50c1tpXS5sZW5ndGg7XG5cblx0XHRcdGlmKG51bSA9PT0gMSl7XG5cdFx0XHRcdHRoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0oKTtcblx0XHRcdH0gZWxzZSBpZihudW0gPT09IDIpe1xuXHRcdFx0XHR0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKHRoaXMuZXZlbnRzW2ldWzFdKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuX2Nic1t0aGlzLmV2ZW50c1tpXVswXV0odGhpcy5ldmVudHNbaV1bMV0sIHRoaXMuZXZlbnRzW2ldWzJdKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL0ZlZWRIYW5kbGVyLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvRmVlZEhhbmRsZXIuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbnZhciBpbmRleCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vaW5kZXguanMgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvaW5kZXguanNcIiksXG4gICAgRG9tSGFuZGxlciA9IGluZGV4LkRvbUhhbmRsZXIsXG4gICAgRG9tVXRpbHMgPSBpbmRleC5Eb21VdGlscztcblxuLy9UT0RPOiBtYWtlIHRoaXMgYSBzdHJlYW1hYmxlIGhhbmRsZXJcbmZ1bmN0aW9uIEZlZWRIYW5kbGVyKGNhbGxiYWNrLCBvcHRpb25zKXtcblx0dGhpcy5pbml0KGNhbGxiYWNrLCBvcHRpb25zKTtcbn1cblxuX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgaW5oZXJpdHMgKi8gXCIuL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzXCIpKEZlZWRIYW5kbGVyLCBEb21IYW5kbGVyKTtcblxuRmVlZEhhbmRsZXIucHJvdG90eXBlLmluaXQgPSBEb21IYW5kbGVyO1xuXG5mdW5jdGlvbiBnZXRFbGVtZW50cyh3aGF0LCB3aGVyZSl7XG5cdHJldHVybiBEb21VdGlscy5nZXRFbGVtZW50c0J5VGFnTmFtZSh3aGF0LCB3aGVyZSwgdHJ1ZSk7XG59XG5mdW5jdGlvbiBnZXRPbmVFbGVtZW50KHdoYXQsIHdoZXJlKXtcblx0cmV0dXJuIERvbVV0aWxzLmdldEVsZW1lbnRzQnlUYWdOYW1lKHdoYXQsIHdoZXJlLCB0cnVlLCAxKVswXTtcbn1cbmZ1bmN0aW9uIGZldGNoKHdoYXQsIHdoZXJlLCByZWN1cnNlKXtcblx0cmV0dXJuIERvbVV0aWxzLmdldFRleHQoXG5cdFx0RG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCwgd2hlcmUsIHJlY3Vyc2UsIDEpXG5cdCkudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBhZGRDb25kaXRpb25hbGx5KG9iaiwgcHJvcCwgd2hhdCwgd2hlcmUsIHJlY3Vyc2Upe1xuXHR2YXIgdG1wID0gZmV0Y2god2hhdCwgd2hlcmUsIHJlY3Vyc2UpO1xuXHRpZih0bXApIG9ialtwcm9wXSA9IHRtcDtcbn1cblxudmFyIGlzVmFsaWRGZWVkID0gZnVuY3Rpb24odmFsdWUpe1xuXHRyZXR1cm4gdmFsdWUgPT09IFwicnNzXCIgfHwgdmFsdWUgPT09IFwiZmVlZFwiIHx8IHZhbHVlID09PSBcInJkZjpSREZcIjtcbn07XG5cbkZlZWRIYW5kbGVyLnByb3RvdHlwZS5vbmVuZCA9IGZ1bmN0aW9uKCl7XG5cdHZhciBmZWVkID0ge30sXG5cdCAgICBmZWVkUm9vdCA9IGdldE9uZUVsZW1lbnQoaXNWYWxpZEZlZWQsIHRoaXMuZG9tKSxcblx0ICAgIHRtcCwgY2hpbGRzO1xuXG5cdGlmKGZlZWRSb290KXtcblx0XHRpZihmZWVkUm9vdC5uYW1lID09PSBcImZlZWRcIil7XG5cdFx0XHRjaGlsZHMgPSBmZWVkUm9vdC5jaGlsZHJlbjtcblxuXHRcdFx0ZmVlZC50eXBlID0gXCJhdG9tXCI7XG5cdFx0XHRhZGRDb25kaXRpb25hbGx5KGZlZWQsIFwiaWRcIiwgXCJpZFwiLCBjaGlsZHMpO1xuXHRcdFx0YWRkQ29uZGl0aW9uYWxseShmZWVkLCBcInRpdGxlXCIsIFwidGl0bGVcIiwgY2hpbGRzKTtcblx0XHRcdGlmKCh0bXAgPSBnZXRPbmVFbGVtZW50KFwibGlua1wiLCBjaGlsZHMpKSAmJiAodG1wID0gdG1wLmF0dHJpYnMpICYmICh0bXAgPSB0bXAuaHJlZikpIGZlZWQubGluayA9IHRtcDtcblx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZmVlZCwgXCJkZXNjcmlwdGlvblwiLCBcInN1YnRpdGxlXCIsIGNoaWxkcyk7XG5cdFx0XHRpZigodG1wID0gZmV0Y2goXCJ1cGRhdGVkXCIsIGNoaWxkcykpKSBmZWVkLnVwZGF0ZWQgPSBuZXcgRGF0ZSh0bXApO1xuXHRcdFx0YWRkQ29uZGl0aW9uYWxseShmZWVkLCBcImF1dGhvclwiLCBcImVtYWlsXCIsIGNoaWxkcywgdHJ1ZSk7XG5cblx0XHRcdGZlZWQuaXRlbXMgPSBnZXRFbGVtZW50cyhcImVudHJ5XCIsIGNoaWxkcykubWFwKGZ1bmN0aW9uKGl0ZW0pe1xuXHRcdFx0XHR2YXIgZW50cnkgPSB7fSwgdG1wO1xuXG5cdFx0XHRcdGl0ZW0gPSBpdGVtLmNoaWxkcmVuO1xuXG5cdFx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZW50cnksIFwiaWRcIiwgXCJpZFwiLCBpdGVtKTtcblx0XHRcdFx0YWRkQ29uZGl0aW9uYWxseShlbnRyeSwgXCJ0aXRsZVwiLCBcInRpdGxlXCIsIGl0ZW0pO1xuXHRcdFx0XHRpZigodG1wID0gZ2V0T25lRWxlbWVudChcImxpbmtcIiwgaXRlbSkpICYmICh0bXAgPSB0bXAuYXR0cmlicykgJiYgKHRtcCA9IHRtcC5ocmVmKSkgZW50cnkubGluayA9IHRtcDtcblx0XHRcdFx0aWYoKHRtcCA9IGZldGNoKFwic3VtbWFyeVwiLCBpdGVtKSB8fCBmZXRjaChcImNvbnRlbnRcIiwgaXRlbSkpKSBlbnRyeS5kZXNjcmlwdGlvbiA9IHRtcDtcblx0XHRcdFx0aWYoKHRtcCA9IGZldGNoKFwidXBkYXRlZFwiLCBpdGVtKSkpIGVudHJ5LnB1YkRhdGUgPSBuZXcgRGF0ZSh0bXApO1xuXHRcdFx0XHRyZXR1cm4gZW50cnk7XG5cdFx0XHR9KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y2hpbGRzID0gZ2V0T25lRWxlbWVudChcImNoYW5uZWxcIiwgZmVlZFJvb3QuY2hpbGRyZW4pLmNoaWxkcmVuO1xuXG5cdFx0XHRmZWVkLnR5cGUgPSBmZWVkUm9vdC5uYW1lLnN1YnN0cigwLCAzKTtcblx0XHRcdGZlZWQuaWQgPSBcIlwiO1xuXHRcdFx0YWRkQ29uZGl0aW9uYWxseShmZWVkLCBcInRpdGxlXCIsIFwidGl0bGVcIiwgY2hpbGRzKTtcblx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZmVlZCwgXCJsaW5rXCIsIFwibGlua1wiLCBjaGlsZHMpO1xuXHRcdFx0YWRkQ29uZGl0aW9uYWxseShmZWVkLCBcImRlc2NyaXB0aW9uXCIsIFwiZGVzY3JpcHRpb25cIiwgY2hpbGRzKTtcblx0XHRcdGlmKCh0bXAgPSBmZXRjaChcImxhc3RCdWlsZERhdGVcIiwgY2hpbGRzKSkpIGZlZWQudXBkYXRlZCA9IG5ldyBEYXRlKHRtcCk7XG5cdFx0XHRhZGRDb25kaXRpb25hbGx5KGZlZWQsIFwiYXV0aG9yXCIsIFwibWFuYWdpbmdFZGl0b3JcIiwgY2hpbGRzLCB0cnVlKTtcblxuXHRcdFx0ZmVlZC5pdGVtcyA9IGdldEVsZW1lbnRzKFwiaXRlbVwiLCBmZWVkUm9vdC5jaGlsZHJlbikubWFwKGZ1bmN0aW9uKGl0ZW0pe1xuXHRcdFx0XHR2YXIgZW50cnkgPSB7fSwgdG1wO1xuXG5cdFx0XHRcdGl0ZW0gPSBpdGVtLmNoaWxkcmVuO1xuXG5cdFx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZW50cnksIFwiaWRcIiwgXCJndWlkXCIsIGl0ZW0pO1xuXHRcdFx0XHRhZGRDb25kaXRpb25hbGx5KGVudHJ5LCBcInRpdGxlXCIsIFwidGl0bGVcIiwgaXRlbSk7XG5cdFx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZW50cnksIFwibGlua1wiLCBcImxpbmtcIiwgaXRlbSk7XG5cdFx0XHRcdGFkZENvbmRpdGlvbmFsbHkoZW50cnksIFwiZGVzY3JpcHRpb25cIiwgXCJkZXNjcmlwdGlvblwiLCBpdGVtKTtcblx0XHRcdFx0aWYoKHRtcCA9IGZldGNoKFwicHViRGF0ZVwiLCBpdGVtKSkpIGVudHJ5LnB1YkRhdGUgPSBuZXcgRGF0ZSh0bXApO1xuXHRcdFx0XHRyZXR1cm4gZW50cnk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblx0dGhpcy5kb20gPSBmZWVkO1xuXHREb21IYW5kbGVyLnByb3RvdHlwZS5faGFuZGxlQ2FsbGJhY2suY2FsbChcblx0XHR0aGlzLCBmZWVkUm9vdCA/IG51bGwgOiBFcnJvcihcImNvdWxkbid0IGZpbmQgcm9vdCBvZiBmZWVkXCIpXG5cdCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZlZWRIYW5kbGVyO1xuXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL2xpYi9QYXJzZXIuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvUGFyc2VyLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxudmFyIFRva2VuaXplciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vVG9rZW5pemVyLmpzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL1Rva2VuaXplci5qc1wiKTtcblxuLypcblx0T3B0aW9uczpcblxuXHR4bWxNb2RlOiBEaXNhYmxlcyB0aGUgc3BlY2lhbCBiZWhhdmlvciBmb3Igc2NyaXB0L3N0eWxlIHRhZ3MgKGZhbHNlIGJ5IGRlZmF1bHQpXG5cdGxvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzOiBjYWxsIC50b0xvd2VyQ2FzZSBmb3IgZWFjaCBhdHRyaWJ1dGUgbmFtZSAodHJ1ZSBpZiB4bWxNb2RlIGlzIGBmYWxzZWApXG5cdGxvd2VyQ2FzZVRhZ3M6IGNhbGwgLnRvTG93ZXJDYXNlIGZvciBlYWNoIHRhZyBuYW1lICh0cnVlIGlmIHhtbE1vZGUgaXMgYGZhbHNlYClcbiovXG5cbi8qXG5cdENhbGxiYWNrczpcblxuXHRvbmNkYXRhZW5kLFxuXHRvbmNkYXRhc3RhcnQsXG5cdG9uY2xvc2V0YWcsXG5cdG9uY29tbWVudCxcblx0b25jb21tZW50ZW5kLFxuXHRvbmVycm9yLFxuXHRvbm9wZW50YWcsXG5cdG9ucHJvY2Vzc2luZ2luc3RydWN0aW9uLFxuXHRvbnJlc2V0LFxuXHRvbnRleHRcbiovXG5cbnZhciBmb3JtVGFncyA9IHtcblx0aW5wdXQ6IHRydWUsXG5cdG9wdGlvbjogdHJ1ZSxcblx0b3B0Z3JvdXA6IHRydWUsXG5cdHNlbGVjdDogdHJ1ZSxcblx0YnV0dG9uOiB0cnVlLFxuXHRkYXRhbGlzdDogdHJ1ZSxcblx0dGV4dGFyZWE6IHRydWVcbn07XG5cbnZhciBvcGVuSW1wbGllc0Nsb3NlID0ge1xuXHR0ciAgICAgIDogeyB0cjp0cnVlLCB0aDp0cnVlLCB0ZDp0cnVlIH0sXG5cdHRoICAgICAgOiB7IHRoOnRydWUgfSxcblx0dGQgICAgICA6IHsgdGhlYWQ6dHJ1ZSwgdGg6dHJ1ZSwgdGQ6dHJ1ZSB9LFxuXHRib2R5ICAgIDogeyBoZWFkOnRydWUsIGxpbms6dHJ1ZSwgc2NyaXB0OnRydWUgfSxcblx0bGkgICAgICA6IHsgbGk6dHJ1ZSB9LFxuXHRwICAgICAgIDogeyBwOnRydWUgfSxcblx0aDEgICAgICA6IHsgcDp0cnVlIH0sXG5cdGgyICAgICAgOiB7IHA6dHJ1ZSB9LFxuXHRoMyAgICAgIDogeyBwOnRydWUgfSxcblx0aDQgICAgICA6IHsgcDp0cnVlIH0sXG5cdGg1ICAgICAgOiB7IHA6dHJ1ZSB9LFxuXHRoNiAgICAgIDogeyBwOnRydWUgfSxcblx0c2VsZWN0ICA6IGZvcm1UYWdzLFxuXHRpbnB1dCAgIDogZm9ybVRhZ3MsXG5cdG91dHB1dCAgOiBmb3JtVGFncyxcblx0YnV0dG9uICA6IGZvcm1UYWdzLFxuXHRkYXRhbGlzdDogZm9ybVRhZ3MsXG5cdHRleHRhcmVhOiBmb3JtVGFncyxcblx0b3B0aW9uICA6IHsgb3B0aW9uOnRydWUgfSxcblx0b3B0Z3JvdXA6IHsgb3B0Z3JvdXA6dHJ1ZSB9XG59O1xuXG52YXIgdm9pZEVsZW1lbnRzID0ge1xuXHRfX3Byb3RvX186IG51bGwsXG5cdGFyZWE6IHRydWUsXG5cdGJhc2U6IHRydWUsXG5cdGJhc2Vmb250OiB0cnVlLFxuXHRicjogdHJ1ZSxcblx0Y29sOiB0cnVlLFxuXHRjb21tYW5kOiB0cnVlLFxuXHRlbWJlZDogdHJ1ZSxcblx0ZnJhbWU6IHRydWUsXG5cdGhyOiB0cnVlLFxuXHRpbWc6IHRydWUsXG5cdGlucHV0OiB0cnVlLFxuXHRpc2luZGV4OiB0cnVlLFxuXHRrZXlnZW46IHRydWUsXG5cdGxpbms6IHRydWUsXG5cdG1ldGE6IHRydWUsXG5cdHBhcmFtOiB0cnVlLFxuXHRzb3VyY2U6IHRydWUsXG5cdHRyYWNrOiB0cnVlLFxuXHR3YnI6IHRydWUsXG5cblx0Ly9jb21tb24gc2VsZiBjbG9zaW5nIHN2ZyBlbGVtZW50c1xuXHRwYXRoOiB0cnVlLFxuXHRjaXJjbGU6IHRydWUsXG5cdGVsbGlwc2U6IHRydWUsXG5cdGxpbmU6IHRydWUsXG5cdHJlY3Q6IHRydWUsXG5cdHVzZTogdHJ1ZSxcblx0c3RvcDogdHJ1ZSxcblx0cG9seWxpbmU6IHRydWUsXG5cdHBvbHlnb246IHRydWVcbn07XG5cbnZhciByZV9uYW1lRW5kID0gL1xcc3xcXC8vO1xuXG5mdW5jdGlvbiBQYXJzZXIoY2JzLCBvcHRpb25zKXtcblx0dGhpcy5fb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdHRoaXMuX2NicyA9IGNicyB8fCB7fTtcblxuXHR0aGlzLl90YWduYW1lID0gXCJcIjtcblx0dGhpcy5fYXR0cmlibmFtZSA9IFwiXCI7XG5cdHRoaXMuX2F0dHJpYnZhbHVlID0gXCJcIjtcblx0dGhpcy5fYXR0cmlicyA9IG51bGw7XG5cdHRoaXMuX3N0YWNrID0gW107XG5cblx0dGhpcy5zdGFydEluZGV4ID0gMDtcblx0dGhpcy5lbmRJbmRleCA9IG51bGw7XG5cblx0dGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMgPSBcImxvd2VyQ2FzZVRhZ3NcIiBpbiB0aGlzLl9vcHRpb25zID9cblx0XHRcdFx0XHRcdFx0XHRcdCEhdGhpcy5fb3B0aW9ucy5sb3dlckNhc2VUYWdzIDpcblx0XHRcdFx0XHRcdFx0XHRcdCF0aGlzLl9vcHRpb25zLnhtbE1vZGU7XG5cdHRoaXMuX2xvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzID0gXCJsb3dlckNhc2VBdHRyaWJ1dGVOYW1lc1wiIGluIHRoaXMuX29wdGlvbnMgP1xuXHRcdFx0XHRcdFx0XHRcdFx0ISF0aGlzLl9vcHRpb25zLmxvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzIDpcblx0XHRcdFx0XHRcdFx0XHRcdCF0aGlzLl9vcHRpb25zLnhtbE1vZGU7XG5cblx0aWYodGhpcy5fb3B0aW9ucy5Ub2tlbml6ZXIpIHtcblx0XHRUb2tlbml6ZXIgPSB0aGlzLl9vcHRpb25zLlRva2VuaXplcjtcblx0fVxuXHR0aGlzLl90b2tlbml6ZXIgPSBuZXcgVG9rZW5pemVyKHRoaXMuX29wdGlvbnMsIHRoaXMpO1xuXG5cdGlmKHRoaXMuX2Nicy5vbnBhcnNlcmluaXQpIHRoaXMuX2Nicy5vbnBhcnNlcmluaXQodGhpcyk7XG59XG5cbl9fd2VicGFja19yZXF1aXJlX18oLyohIGluaGVyaXRzICovIFwiLi9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qc1wiKShQYXJzZXIsIF9fd2VicGFja19yZXF1aXJlX18oLyohIGV2ZW50cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanNcIikuRXZlbnRFbWl0dGVyKTtcblxuUGFyc2VyLnByb3RvdHlwZS5fdXBkYXRlUG9zaXRpb24gPSBmdW5jdGlvbihpbml0aWFsT2Zmc2V0KXtcblx0aWYodGhpcy5lbmRJbmRleCA9PT0gbnVsbCl7XG5cdFx0aWYodGhpcy5fdG9rZW5pemVyLl9zZWN0aW9uU3RhcnQgPD0gaW5pdGlhbE9mZnNldCl7XG5cdFx0XHR0aGlzLnN0YXJ0SW5kZXggPSAwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnN0YXJ0SW5kZXggPSB0aGlzLl90b2tlbml6ZXIuX3NlY3Rpb25TdGFydCAtIGluaXRpYWxPZmZzZXQ7XG5cdFx0fVxuXHR9XG5cdGVsc2UgdGhpcy5zdGFydEluZGV4ID0gdGhpcy5lbmRJbmRleCArIDE7XG5cdHRoaXMuZW5kSW5kZXggPSB0aGlzLl90b2tlbml6ZXIuZ2V0QWJzb2x1dGVJbmRleCgpO1xufTtcblxuLy9Ub2tlbml6ZXIgZXZlbnQgaGFuZGxlcnNcblBhcnNlci5wcm90b3R5cGUub250ZXh0ID0gZnVuY3Rpb24oZGF0YSl7XG5cdHRoaXMuX3VwZGF0ZVBvc2l0aW9uKDEpO1xuXHR0aGlzLmVuZEluZGV4LS07XG5cblx0aWYodGhpcy5fY2JzLm9udGV4dCkgdGhpcy5fY2JzLm9udGV4dChkYXRhKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25vcGVudGFnbmFtZSA9IGZ1bmN0aW9uKG5hbWUpe1xuXHRpZih0aGlzLl9sb3dlckNhc2VUYWdOYW1lcyl7XG5cdFx0bmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fVxuXG5cdHRoaXMuX3RhZ25hbWUgPSBuYW1lO1xuXG5cdGlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUgJiYgbmFtZSBpbiBvcGVuSW1wbGllc0Nsb3NlKSB7XG5cdFx0Zm9yKFxuXHRcdFx0dmFyIGVsO1xuXHRcdFx0KGVsID0gdGhpcy5fc3RhY2tbdGhpcy5fc3RhY2subGVuZ3RoIC0gMV0pIGluIG9wZW5JbXBsaWVzQ2xvc2VbbmFtZV07XG5cdFx0XHR0aGlzLm9uY2xvc2V0YWcoZWwpXG5cdFx0KTtcblx0fVxuXG5cdGlmKHRoaXMuX29wdGlvbnMueG1sTW9kZSB8fCAhKG5hbWUgaW4gdm9pZEVsZW1lbnRzKSl7XG5cdFx0dGhpcy5fc3RhY2sucHVzaChuYW1lKTtcblx0fVxuXG5cdGlmKHRoaXMuX2Nicy5vbm9wZW50YWduYW1lKSB0aGlzLl9jYnMub25vcGVudGFnbmFtZShuYW1lKTtcblx0aWYodGhpcy5fY2JzLm9ub3BlbnRhZykgdGhpcy5fYXR0cmlicyA9IHt9O1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5vbm9wZW50YWdlbmQgPSBmdW5jdGlvbigpe1xuXHR0aGlzLl91cGRhdGVQb3NpdGlvbigxKTtcblxuXHRpZih0aGlzLl9hdHRyaWJzKXtcblx0XHRpZih0aGlzLl9jYnMub25vcGVudGFnKSB0aGlzLl9jYnMub25vcGVudGFnKHRoaXMuX3RhZ25hbWUsIHRoaXMuX2F0dHJpYnMpO1xuXHRcdHRoaXMuX2F0dHJpYnMgPSBudWxsO1xuXHR9XG5cblx0aWYoIXRoaXMuX29wdGlvbnMueG1sTW9kZSAmJiB0aGlzLl9jYnMub25jbG9zZXRhZyAmJiB0aGlzLl90YWduYW1lIGluIHZvaWRFbGVtZW50cyl7XG5cdFx0dGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fdGFnbmFtZSk7XG5cdH1cblxuXHR0aGlzLl90YWduYW1lID0gXCJcIjtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25jbG9zZXRhZyA9IGZ1bmN0aW9uKG5hbWUpe1xuXHR0aGlzLl91cGRhdGVQb3NpdGlvbigxKTtcblxuXHRpZih0aGlzLl9sb3dlckNhc2VUYWdOYW1lcyl7XG5cdFx0bmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fVxuXG5cdGlmKHRoaXMuX3N0YWNrLmxlbmd0aCAmJiAoIShuYW1lIGluIHZvaWRFbGVtZW50cykgfHwgdGhpcy5fb3B0aW9ucy54bWxNb2RlKSl7XG5cdFx0dmFyIHBvcyA9IHRoaXMuX3N0YWNrLmxhc3RJbmRleE9mKG5hbWUpO1xuXHRcdGlmKHBvcyAhPT0gLTEpe1xuXHRcdFx0aWYodGhpcy5fY2JzLm9uY2xvc2V0YWcpe1xuXHRcdFx0XHRwb3MgPSB0aGlzLl9zdGFjay5sZW5ndGggLSBwb3M7XG5cdFx0XHRcdHdoaWxlKHBvcy0tKSB0aGlzLl9jYnMub25jbG9zZXRhZyh0aGlzLl9zdGFjay5wb3AoKSk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHRoaXMuX3N0YWNrLmxlbmd0aCA9IHBvcztcblx0XHR9IGVsc2UgaWYobmFtZSA9PT0gXCJwXCIgJiYgIXRoaXMuX29wdGlvbnMueG1sTW9kZSl7XG5cdFx0XHR0aGlzLm9ub3BlbnRhZ25hbWUobmFtZSk7XG5cdFx0XHR0aGlzLl9jbG9zZUN1cnJlbnRUYWcoKTtcblx0XHR9XG5cdH0gZWxzZSBpZighdGhpcy5fb3B0aW9ucy54bWxNb2RlICYmIChuYW1lID09PSBcImJyXCIgfHwgbmFtZSA9PT0gXCJwXCIpKXtcblx0XHR0aGlzLm9ub3BlbnRhZ25hbWUobmFtZSk7XG5cdFx0dGhpcy5fY2xvc2VDdXJyZW50VGFnKCk7XG5cdH1cbn07XG5cblBhcnNlci5wcm90b3R5cGUub25zZWxmY2xvc2luZ3RhZyA9IGZ1bmN0aW9uKCl7XG5cdGlmKHRoaXMuX29wdGlvbnMueG1sTW9kZSB8fCB0aGlzLl9vcHRpb25zLnJlY29nbml6ZVNlbGZDbG9zaW5nKXtcblx0XHR0aGlzLl9jbG9zZUN1cnJlbnRUYWcoKTtcblx0fSBlbHNlIHtcblx0XHR0aGlzLm9ub3BlbnRhZ2VuZCgpO1xuXHR9XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLl9jbG9zZUN1cnJlbnRUYWcgPSBmdW5jdGlvbigpe1xuXHR2YXIgbmFtZSA9IHRoaXMuX3RhZ25hbWU7XG5cblx0dGhpcy5vbm9wZW50YWdlbmQoKTtcblxuXHQvL3NlbGYtY2xvc2luZyB0YWdzIHdpbGwgYmUgb24gdGhlIHRvcCBvZiB0aGUgc3RhY2tcblx0Ly8oY2hlYXBlciBjaGVjayB0aGFuIGluIG9uY2xvc2V0YWcpXG5cdGlmKHRoaXMuX3N0YWNrW3RoaXMuX3N0YWNrLmxlbmd0aCAtIDFdID09PSBuYW1lKXtcblx0XHRpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7XG5cdFx0XHR0aGlzLl9jYnMub25jbG9zZXRhZyhuYW1lKTtcblx0XHR9XG5cdFx0dGhpcy5fc3RhY2sucG9wKCk7XG5cdH1cbn07XG5cblBhcnNlci5wcm90b3R5cGUub25hdHRyaWJuYW1lID0gZnVuY3Rpb24obmFtZSl7XG5cdGlmKHRoaXMuX2xvd2VyQ2FzZUF0dHJpYnV0ZU5hbWVzKXtcblx0XHRuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXHR9XG5cdHRoaXMuX2F0dHJpYm5hbWUgPSBuYW1lO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5vbmF0dHJpYmRhdGEgPSBmdW5jdGlvbih2YWx1ZSl7XG5cdHRoaXMuX2F0dHJpYnZhbHVlICs9IHZhbHVlO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5vbmF0dHJpYmVuZCA9IGZ1bmN0aW9uKCl7XG5cdGlmKHRoaXMuX2Nicy5vbmF0dHJpYnV0ZSkgdGhpcy5fY2JzLm9uYXR0cmlidXRlKHRoaXMuX2F0dHJpYm5hbWUsIHRoaXMuX2F0dHJpYnZhbHVlKTtcblx0aWYoXG5cdFx0dGhpcy5fYXR0cmlicyAmJlxuXHRcdCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5fYXR0cmlicywgdGhpcy5fYXR0cmlibmFtZSlcblx0KXtcblx0XHR0aGlzLl9hdHRyaWJzW3RoaXMuX2F0dHJpYm5hbWVdID0gdGhpcy5fYXR0cmlidmFsdWU7XG5cdH1cblx0dGhpcy5fYXR0cmlibmFtZSA9IFwiXCI7XG5cdHRoaXMuX2F0dHJpYnZhbHVlID0gXCJcIjtcbn07XG5cblBhcnNlci5wcm90b3R5cGUuX2dldEluc3RydWN0aW9uTmFtZSA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0dmFyIGlkeCA9IHZhbHVlLnNlYXJjaChyZV9uYW1lRW5kKSxcblx0ICAgIG5hbWUgPSBpZHggPCAwID8gdmFsdWUgOiB2YWx1ZS5zdWJzdHIoMCwgaWR4KTtcblxuXHRpZih0aGlzLl9sb3dlckNhc2VUYWdOYW1lcyl7XG5cdFx0bmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fVxuXG5cdHJldHVybiBuYW1lO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5vbmRlY2xhcmF0aW9uID0gZnVuY3Rpb24odmFsdWUpe1xuXHRpZih0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24pe1xuXHRcdHZhciBuYW1lID0gdGhpcy5fZ2V0SW5zdHJ1Y3Rpb25OYW1lKHZhbHVlKTtcblx0XHR0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24oXCIhXCIgKyBuYW1lLCBcIiFcIiArIHZhbHVlKTtcblx0fVxufTtcblxuUGFyc2VyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0aWYodGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKXtcblx0XHR2YXIgbmFtZSA9IHRoaXMuX2dldEluc3RydWN0aW9uTmFtZSh2YWx1ZSk7XG5cdFx0dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKFwiP1wiICsgbmFtZSwgXCI/XCIgKyB2YWx1ZSk7XG5cdH1cbn07XG5cblBhcnNlci5wcm90b3R5cGUub25jb21tZW50ID0gZnVuY3Rpb24odmFsdWUpe1xuXHR0aGlzLl91cGRhdGVQb3NpdGlvbig0KTtcblxuXHRpZih0aGlzLl9jYnMub25jb21tZW50KSB0aGlzLl9jYnMub25jb21tZW50KHZhbHVlKTtcblx0aWYodGhpcy5fY2JzLm9uY29tbWVudGVuZCkgdGhpcy5fY2JzLm9uY29tbWVudGVuZCgpO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS5vbmNkYXRhID0gZnVuY3Rpb24odmFsdWUpe1xuXHR0aGlzLl91cGRhdGVQb3NpdGlvbigxKTtcblxuXHRpZih0aGlzLl9vcHRpb25zLnhtbE1vZGUgfHwgdGhpcy5fb3B0aW9ucy5yZWNvZ25pemVDREFUQSl7XG5cdFx0aWYodGhpcy5fY2JzLm9uY2RhdGFzdGFydCkgdGhpcy5fY2JzLm9uY2RhdGFzdGFydCgpO1xuXHRcdGlmKHRoaXMuX2Nicy5vbnRleHQpIHRoaXMuX2Nicy5vbnRleHQodmFsdWUpO1xuXHRcdGlmKHRoaXMuX2Nicy5vbmNkYXRhZW5kKSB0aGlzLl9jYnMub25jZGF0YWVuZCgpO1xuXHR9IGVsc2Uge1xuXHRcdHRoaXMub25jb21tZW50KFwiW0NEQVRBW1wiICsgdmFsdWUgKyBcIl1dXCIpO1xuXHR9XG59O1xuXG5QYXJzZXIucHJvdG90eXBlLm9uZXJyb3IgPSBmdW5jdGlvbihlcnIpe1xuXHRpZih0aGlzLl9jYnMub25lcnJvcikgdGhpcy5fY2JzLm9uZXJyb3IoZXJyKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUub25lbmQgPSBmdW5jdGlvbigpe1xuXHRpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7XG5cdFx0Zm9yKFxuXHRcdFx0dmFyIGkgPSB0aGlzLl9zdGFjay5sZW5ndGg7XG5cdFx0XHRpID4gMDtcblx0XHRcdHRoaXMuX2Nicy5vbmNsb3NldGFnKHRoaXMuX3N0YWNrWy0taV0pXG5cdFx0KTtcblx0fVxuXHRpZih0aGlzLl9jYnMub25lbmQpIHRoaXMuX2Nicy5vbmVuZCgpO1xufTtcblxuXG4vL1Jlc2V0cyB0aGUgcGFyc2VyIHRvIGEgYmxhbmsgc3RhdGUsIHJlYWR5IHRvIHBhcnNlIGEgbmV3IEhUTUwgZG9jdW1lbnRcblBhcnNlci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpe1xuXHRpZih0aGlzLl9jYnMub25yZXNldCkgdGhpcy5fY2JzLm9ucmVzZXQoKTtcblx0dGhpcy5fdG9rZW5pemVyLnJlc2V0KCk7XG5cblx0dGhpcy5fdGFnbmFtZSA9IFwiXCI7XG5cdHRoaXMuX2F0dHJpYm5hbWUgPSBcIlwiO1xuXHR0aGlzLl9hdHRyaWJzID0gbnVsbDtcblx0dGhpcy5fc3RhY2sgPSBbXTtcblxuXHRpZih0aGlzLl9jYnMub25wYXJzZXJpbml0KSB0aGlzLl9jYnMub25wYXJzZXJpbml0KHRoaXMpO1xufTtcblxuLy9QYXJzZXMgYSBjb21wbGV0ZSBIVE1MIGRvY3VtZW50IGFuZCBwdXNoZXMgaXQgdG8gdGhlIGhhbmRsZXJcblBhcnNlci5wcm90b3R5cGUucGFyc2VDb21wbGV0ZSA9IGZ1bmN0aW9uKGRhdGEpe1xuXHR0aGlzLnJlc2V0KCk7XG5cdHRoaXMuZW5kKGRhdGEpO1xufTtcblxuUGFyc2VyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGNodW5rKXtcblx0dGhpcy5fdG9rZW5pemVyLndyaXRlKGNodW5rKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oY2h1bmspe1xuXHR0aGlzLl90b2tlbml6ZXIuZW5kKGNodW5rKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpe1xuXHR0aGlzLl90b2tlbml6ZXIucGF1c2UoKTtcbn07XG5cblBhcnNlci5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fdG9rZW5pemVyLnJlc3VtZSgpO1xufTtcblxuLy9hbGlhcyBmb3IgYmFja3dhcmRzIGNvbXBhdFxuUGFyc2VyLnByb3RvdHlwZS5wYXJzZUNodW5rID0gUGFyc2VyLnByb3RvdHlwZS53cml0ZTtcblBhcnNlci5wcm90b3R5cGUuZG9uZSA9IFBhcnNlci5wcm90b3R5cGUuZW5kO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhcnNlcjtcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvUHJveHlIYW5kbGVyLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL1Byb3h5SGFuZGxlci5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gUHJveHlIYW5kbGVyO1xuXG5mdW5jdGlvbiBQcm94eUhhbmRsZXIoY2JzKXtcblx0dGhpcy5fY2JzID0gY2JzIHx8IHt9O1xufVxuXG52YXIgRVZFTlRTID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8gKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvaW5kZXguanNcIikuRVZFTlRTO1xuT2JqZWN0LmtleXMoRVZFTlRTKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe1xuXHRpZihFVkVOVFNbbmFtZV0gPT09IDApe1xuXHRcdG5hbWUgPSBcIm9uXCIgKyBuYW1lO1xuXHRcdFByb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpe1xuXHRcdFx0aWYodGhpcy5fY2JzW25hbWVdKSB0aGlzLl9jYnNbbmFtZV0oKTtcblx0XHR9O1xuXHR9IGVsc2UgaWYoRVZFTlRTW25hbWVdID09PSAxKXtcblx0XHRuYW1lID0gXCJvblwiICsgbmFtZTtcblx0XHRQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oYSl7XG5cdFx0XHRpZih0aGlzLl9jYnNbbmFtZV0pIHRoaXMuX2Nic1tuYW1lXShhKTtcblx0XHR9O1xuXHR9IGVsc2UgaWYoRVZFTlRTW25hbWVdID09PSAyKXtcblx0XHRuYW1lID0gXCJvblwiICsgbmFtZTtcblx0XHRQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oYSwgYil7XG5cdFx0XHRpZih0aGlzLl9jYnNbbmFtZV0pIHRoaXMuX2Nic1tuYW1lXShhLCBiKTtcblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdHRocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50c1wiKTtcblx0fVxufSk7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL2xpYi9TdHJlYW0uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvU3RyZWFtLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBQYXJzZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL1dyaXRhYmxlU3RyZWFtLmpzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL1dyaXRhYmxlU3RyZWFtLmpzXCIpO1xuXG5mdW5jdGlvbiBTdHJlYW0ob3B0aW9ucyl7XG5cdFBhcnNlci5jYWxsKHRoaXMsIG5ldyBDYnModGhpcyksIG9wdGlvbnMpO1xufVxuXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBpbmhlcml0cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanNcIikoU3RyZWFtLCBQYXJzZXIpO1xuXG5TdHJlYW0ucHJvdG90eXBlLnJlYWRhYmxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gQ2JzKHNjb3BlKXtcblx0dGhpcy5zY29wZSA9IHNjb3BlO1xufVxuXG52YXIgRVZFTlRTID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi4vICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL2luZGV4LmpzXCIpLkVWRU5UUztcblxuT2JqZWN0LmtleXMoRVZFTlRTKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe1xuXHRpZihFVkVOVFNbbmFtZV0gPT09IDApe1xuXHRcdENicy5wcm90b3R5cGVbXCJvblwiICsgbmFtZV0gPSBmdW5jdGlvbigpe1xuXHRcdFx0dGhpcy5zY29wZS5lbWl0KG5hbWUpO1xuXHRcdH07XG5cdH0gZWxzZSBpZihFVkVOVFNbbmFtZV0gPT09IDEpe1xuXHRcdENicy5wcm90b3R5cGVbXCJvblwiICsgbmFtZV0gPSBmdW5jdGlvbihhKXtcblx0XHRcdHRoaXMuc2NvcGUuZW1pdChuYW1lLCBhKTtcblx0XHR9O1xuXHR9IGVsc2UgaWYoRVZFTlRTW25hbWVdID09PSAyKXtcblx0XHRDYnMucHJvdG90eXBlW1wib25cIiArIG5hbWVdID0gZnVuY3Rpb24oYSwgYil7XG5cdFx0XHR0aGlzLnNjb3BlLmVtaXQobmFtZSwgYSwgYik7XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHR0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHMhXCIpO1xuXHR9XG59KTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL1Rva2VuaXplci5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL2xpYi9Ub2tlbml6ZXIuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRva2VuaXplcjtcblxudmFyIGRlY29kZUNvZGVQb2ludCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGVudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzXCIpLFxuICAgIGVudGl0eU1hcCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGVudGl0aWVzL21hcHMvZW50aXRpZXMuanNvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb25cIiksXG4gICAgbGVnYWN5TWFwID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZW50aXRpZXMvbWFwcy9sZWdhY3kuanNvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9tYXBzL2xlZ2FjeS5qc29uXCIpLFxuICAgIHhtbE1hcCAgICA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGVudGl0aWVzL21hcHMveG1sLmpzb24gKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZW50aXRpZXMvbWFwcy94bWwuanNvblwiKSxcblxuICAgIGkgPSAwLFxuXG4gICAgVEVYVCAgICAgICAgICAgICAgICAgICAgICA9IGkrKyxcbiAgICBCRUZPUkVfVEFHX05BTUUgICAgICAgICAgID0gaSsrLCAvL2FmdGVyIDxcbiAgICBJTl9UQUdfTkFNRSAgICAgICAgICAgICAgID0gaSsrLFxuICAgIElOX1NFTEZfQ0xPU0lOR19UQUcgICAgICAgPSBpKyssXG4gICAgQkVGT1JFX0NMT1NJTkdfVEFHX05BTUUgICA9IGkrKyxcbiAgICBJTl9DTE9TSU5HX1RBR19OQU1FICAgICAgID0gaSsrLFxuICAgIEFGVEVSX0NMT1NJTkdfVEFHX05BTUUgICAgPSBpKyssXG5cbiAgICAvL2F0dHJpYnV0ZXNcbiAgICBCRUZPUkVfQVRUUklCVVRFX05BTUUgICAgID0gaSsrLFxuICAgIElOX0FUVFJJQlVURV9OQU1FICAgICAgICAgPSBpKyssXG4gICAgQUZURVJfQVRUUklCVVRFX05BTUUgICAgICA9IGkrKyxcbiAgICBCRUZPUkVfQVRUUklCVVRFX1ZBTFVFICAgID0gaSsrLFxuICAgIElOX0FUVFJJQlVURV9WQUxVRV9EUSAgICAgPSBpKyssIC8vIFwiXG4gICAgSU5fQVRUUklCVVRFX1ZBTFVFX1NRICAgICA9IGkrKywgLy8gJ1xuICAgIElOX0FUVFJJQlVURV9WQUxVRV9OUSAgICAgPSBpKyssXG5cbiAgICAvL2RlY2xhcmF0aW9uc1xuICAgIEJFRk9SRV9ERUNMQVJBVElPTiAgICAgICAgPSBpKyssIC8vICFcbiAgICBJTl9ERUNMQVJBVElPTiAgICAgICAgICAgID0gaSsrLFxuXG4gICAgLy9wcm9jZXNzaW5nIGluc3RydWN0aW9uc1xuICAgIElOX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04gPSBpKyssIC8vID9cblxuICAgIC8vY29tbWVudHNcbiAgICBCRUZPUkVfQ09NTUVOVCAgICAgICAgICAgID0gaSsrLFxuICAgIElOX0NPTU1FTlQgICAgICAgICAgICAgICAgPSBpKyssXG4gICAgQUZURVJfQ09NTUVOVF8xICAgICAgICAgICA9IGkrKyxcbiAgICBBRlRFUl9DT01NRU5UXzIgICAgICAgICAgID0gaSsrLFxuXG4gICAgLy9jZGF0YVxuICAgIEJFRk9SRV9DREFUQV8xICAgICAgICAgICAgPSBpKyssIC8vIFtcbiAgICBCRUZPUkVfQ0RBVEFfMiAgICAgICAgICAgID0gaSsrLCAvLyBDXG4gICAgQkVGT1JFX0NEQVRBXzMgICAgICAgICAgICA9IGkrKywgLy8gRFxuICAgIEJFRk9SRV9DREFUQV80ICAgICAgICAgICAgPSBpKyssIC8vIEFcbiAgICBCRUZPUkVfQ0RBVEFfNSAgICAgICAgICAgID0gaSsrLCAvLyBUXG4gICAgQkVGT1JFX0NEQVRBXzYgICAgICAgICAgICA9IGkrKywgLy8gQVxuICAgIElOX0NEQVRBICAgICAgICAgICAgICAgICAgPSBpKyssIC8vIFtcbiAgICBBRlRFUl9DREFUQV8xICAgICAgICAgICAgID0gaSsrLCAvLyBdXG4gICAgQUZURVJfQ0RBVEFfMiAgICAgICAgICAgICA9IGkrKywgLy8gXVxuXG4gICAgLy9zcGVjaWFsIHRhZ3NcbiAgICBCRUZPUkVfU1BFQ0lBTCAgICAgICAgICAgID0gaSsrLCAvL1NcbiAgICBCRUZPUkVfU1BFQ0lBTF9FTkQgICAgICAgID0gaSsrLCAgIC8vU1xuXG4gICAgQkVGT1JFX1NDUklQVF8xICAgICAgICAgICA9IGkrKywgLy9DXG4gICAgQkVGT1JFX1NDUklQVF8yICAgICAgICAgICA9IGkrKywgLy9SXG4gICAgQkVGT1JFX1NDUklQVF8zICAgICAgICAgICA9IGkrKywgLy9JXG4gICAgQkVGT1JFX1NDUklQVF80ICAgICAgICAgICA9IGkrKywgLy9QXG4gICAgQkVGT1JFX1NDUklQVF81ICAgICAgICAgICA9IGkrKywgLy9UXG4gICAgQUZURVJfU0NSSVBUXzEgICAgICAgICAgICA9IGkrKywgLy9DXG4gICAgQUZURVJfU0NSSVBUXzIgICAgICAgICAgICA9IGkrKywgLy9SXG4gICAgQUZURVJfU0NSSVBUXzMgICAgICAgICAgICA9IGkrKywgLy9JXG4gICAgQUZURVJfU0NSSVBUXzQgICAgICAgICAgICA9IGkrKywgLy9QXG4gICAgQUZURVJfU0NSSVBUXzUgICAgICAgICAgICA9IGkrKywgLy9UXG5cbiAgICBCRUZPUkVfU1RZTEVfMSAgICAgICAgICAgID0gaSsrLCAvL1RcbiAgICBCRUZPUkVfU1RZTEVfMiAgICAgICAgICAgID0gaSsrLCAvL1lcbiAgICBCRUZPUkVfU1RZTEVfMyAgICAgICAgICAgID0gaSsrLCAvL0xcbiAgICBCRUZPUkVfU1RZTEVfNCAgICAgICAgICAgID0gaSsrLCAvL0VcbiAgICBBRlRFUl9TVFlMRV8xICAgICAgICAgICAgID0gaSsrLCAvL1RcbiAgICBBRlRFUl9TVFlMRV8yICAgICAgICAgICAgID0gaSsrLCAvL1lcbiAgICBBRlRFUl9TVFlMRV8zICAgICAgICAgICAgID0gaSsrLCAvL0xcbiAgICBBRlRFUl9TVFlMRV80ICAgICAgICAgICAgID0gaSsrLCAvL0VcblxuICAgIEJFRk9SRV9FTlRJVFkgICAgICAgICAgICAgPSBpKyssIC8vJlxuICAgIEJFRk9SRV9OVU1FUklDX0VOVElUWSAgICAgPSBpKyssIC8vI1xuICAgIElOX05BTUVEX0VOVElUWSAgICAgICAgICAgPSBpKyssXG4gICAgSU5fTlVNRVJJQ19FTlRJVFkgICAgICAgICA9IGkrKyxcbiAgICBJTl9IRVhfRU5USVRZICAgICAgICAgICAgID0gaSsrLCAvL1hcblxuICAgIGogPSAwLFxuXG4gICAgU1BFQ0lBTF9OT05FICAgICAgICAgICAgICA9IGorKyxcbiAgICBTUEVDSUFMX1NDUklQVCAgICAgICAgICAgID0gaisrLFxuICAgIFNQRUNJQUxfU1RZTEUgICAgICAgICAgICAgPSBqKys7XG5cbmZ1bmN0aW9uIHdoaXRlc3BhY2UoYyl7XG5cdHJldHVybiBjID09PSBcIiBcIiB8fCBjID09PSBcIlxcblwiIHx8IGMgPT09IFwiXFx0XCIgfHwgYyA9PT0gXCJcXGZcIiB8fCBjID09PSBcIlxcclwiO1xufVxuXG5mdW5jdGlvbiBjaGFyYWN0ZXJTdGF0ZShjaGFyLCBTVUNDRVNTKXtcblx0cmV0dXJuIGZ1bmN0aW9uKGMpe1xuXHRcdGlmKGMgPT09IGNoYXIpIHRoaXMuX3N0YXRlID0gU1VDQ0VTUztcblx0fTtcbn1cblxuZnVuY3Rpb24gaWZFbHNlU3RhdGUodXBwZXIsIFNVQ0NFU1MsIEZBSUxVUkUpe1xuXHR2YXIgbG93ZXIgPSB1cHBlci50b0xvd2VyQ2FzZSgpO1xuXG5cdGlmKHVwcGVyID09PSBsb3dlcil7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGMpe1xuXHRcdFx0aWYoYyA9PT0gbG93ZXIpe1xuXHRcdFx0XHR0aGlzLl9zdGF0ZSA9IFNVQ0NFU1M7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLl9zdGF0ZSA9IEZBSUxVUkU7XG5cdFx0XHRcdHRoaXMuX2luZGV4LS07XG5cdFx0XHR9XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oYyl7XG5cdFx0XHRpZihjID09PSBsb3dlciB8fCBjID09PSB1cHBlcil7XG5cdFx0XHRcdHRoaXMuX3N0YXRlID0gU1VDQ0VTUztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuX3N0YXRlID0gRkFJTFVSRTtcblx0XHRcdFx0dGhpcy5faW5kZXgtLTtcblx0XHRcdH1cblx0XHR9O1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvbnN1bWVTcGVjaWFsTmFtZUNoYXIodXBwZXIsIE5FWFRfU1RBVEUpe1xuXHR2YXIgbG93ZXIgPSB1cHBlci50b0xvd2VyQ2FzZSgpO1xuXG5cdHJldHVybiBmdW5jdGlvbihjKXtcblx0XHRpZihjID09PSBsb3dlciB8fCBjID09PSB1cHBlcil7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IE5FWFRfU1RBVEU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX3N0YXRlID0gSU5fVEFHX05BTUU7XG5cdFx0XHR0aGlzLl9pbmRleC0tOyAvL2NvbnN1bWUgdGhlIHRva2VuIGFnYWluXG5cdFx0fVxuXHR9O1xufVxuXG5mdW5jdGlvbiBUb2tlbml6ZXIob3B0aW9ucywgY2JzKXtcblx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHR0aGlzLl9idWZmZXIgPSBcIlwiO1xuXHR0aGlzLl9zZWN0aW9uU3RhcnQgPSAwO1xuXHR0aGlzLl9pbmRleCA9IDA7XG5cdHRoaXMuX2J1ZmZlck9mZnNldCA9IDA7IC8vY2hhcnMgcmVtb3ZlZCBmcm9tIF9idWZmZXJcblx0dGhpcy5fYmFzZVN0YXRlID0gVEVYVDtcblx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfTk9ORTtcblx0dGhpcy5fY2JzID0gY2JzO1xuXHR0aGlzLl9ydW5uaW5nID0gdHJ1ZTtcblx0dGhpcy5fZW5kZWQgPSBmYWxzZTtcblx0dGhpcy5feG1sTW9kZSA9ICEhKG9wdGlvbnMgJiYgb3B0aW9ucy54bWxNb2RlKTtcblx0dGhpcy5fZGVjb2RlRW50aXRpZXMgPSAhIShvcHRpb25zICYmIG9wdGlvbnMuZGVjb2RlRW50aXRpZXMpO1xufVxuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZVRleHQgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI8XCIpe1xuXHRcdGlmKHRoaXMuX2luZGV4ID4gdGhpcy5fc2VjdGlvblN0YXJ0KXtcblx0XHRcdHRoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKTtcblx0XHR9XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiB0aGlzLl9zcGVjaWFsID09PSBTUEVDSUFMX05PTkUgJiYgYyA9PT0gXCImXCIpe1xuXHRcdGlmKHRoaXMuX2luZGV4ID4gdGhpcy5fc2VjdGlvblN0YXJ0KXtcblx0XHRcdHRoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKTtcblx0XHR9XG5cdFx0dGhpcy5fYmFzZVN0YXRlID0gVEVYVDtcblx0XHR0aGlzLl9zdGF0ZSA9IEJFRk9SRV9FTlRJVFk7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlVGFnTmFtZSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi9cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQ0xPU0lOR19UQUdfTkFNRTtcblx0fSBlbHNlIGlmKGMgPT09IFwiPFwiKXtcblx0XHR0aGlzLl9jYnMub250ZXh0KHRoaXMuX2dldFNlY3Rpb24oKSk7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH0gZWxzZSBpZihjID09PSBcIj5cIiB8fCB0aGlzLl9zcGVjaWFsICE9PSBTUEVDSUFMX05PTkUgfHwgd2hpdGVzcGFjZShjKSkge1xuXHRcdHRoaXMuX3N0YXRlID0gVEVYVDtcblx0fSBlbHNlIGlmKGMgPT09IFwiIVwiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IEJFRk9SRV9ERUNMQVJBVElPTjtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleCArIDE7XG5cdH0gZWxzZSBpZihjID09PSBcIj9cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIHtcblx0XHR0aGlzLl9zdGF0ZSA9ICghdGhpcy5feG1sTW9kZSAmJiAoYyA9PT0gXCJzXCIgfHwgYyA9PT0gXCJTXCIpKSA/XG5cdFx0XHRcdFx0XHRCRUZPUkVfU1BFQ0lBTCA6IElOX1RBR19OQU1FO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4O1xuXHR9XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluVGFnTmFtZSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi9cIiB8fCBjID09PSBcIj5cIiB8fCB3aGl0ZXNwYWNlKGMpKXtcblx0XHR0aGlzLl9lbWl0VG9rZW4oXCJvbm9wZW50YWduYW1lXCIpO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9OQU1FO1xuXHRcdHRoaXMuX2luZGV4LS07XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2xvc2VpbmdUYWdOYW1lID0gZnVuY3Rpb24oYyl7XG5cdGlmKHdoaXRlc3BhY2UoYykpO1xuXHRlbHNlIGlmKGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdH0gZWxzZSBpZih0aGlzLl9zcGVjaWFsICE9PSBTUEVDSUFMX05PTkUpe1xuXHRcdGlmKGMgPT09IFwic1wiIHx8IGMgPT09IFwiU1wiKXtcblx0XHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX1NQRUNJQUxfRU5EO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdFx0XHR0aGlzLl9pbmRleC0tO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DbG9zZWluZ1RhZ05hbWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25jbG9zZXRhZ1wiKTtcblx0XHR0aGlzLl9zdGF0ZSA9IEFGVEVSX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZSA9IGZ1bmN0aW9uKGMpe1xuXHQvL3NraXAgZXZlcnl0aGluZyB1bnRpbCBcIj5cIlxuXHRpZihjID09PSBcIj5cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVOYW1lID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9jYnMub25vcGVudGFnZW5kKCk7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIGlmKGMgPT09IFwiL1wiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX1NFTEZfQ0xPU0lOR19UQUc7XG5cdH0gZWxzZSBpZighd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9BVFRSSUJVVEVfTkFNRTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJblNlbGZDbG9zaW5nVGFnID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9jYnMub25zZWxmY2xvc2luZ3RhZygpO1xuXHRcdHRoaXMuX3N0YXRlID0gVEVYVDtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleCArIDE7XG5cdH0gZWxzZSBpZighd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQVRUUklCVVRFX05BTUU7XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZU5hbWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI9XCIgfHwgYyA9PT0gXCIvXCIgfHwgYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fY2JzLm9uYXR0cmlibmFtZSh0aGlzLl9nZXRTZWN0aW9uKCkpO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IC0xO1xuXHRcdHRoaXMuX3N0YXRlID0gQUZURVJfQVRUUklCVVRFX05BTUU7XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckF0dHJpYnV0ZU5hbWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI9XCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9WQUxVRTtcblx0fSBlbHNlIGlmKGMgPT09IFwiL1wiIHx8IGMgPT09IFwiPlwiKXtcblx0XHR0aGlzLl9jYnMub25hdHRyaWJlbmQoKTtcblx0XHR0aGlzLl9zdGF0ZSA9IEJFRk9SRV9BVFRSSUJVVEVfTkFNRTtcblx0XHR0aGlzLl9pbmRleC0tO1xuXHR9IGVsc2UgaWYoIXdoaXRlc3BhY2UoYykpe1xuXHRcdHRoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fQVRUUklCVVRFX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQXR0cmlidXRlVmFsdWUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCJcXFwiXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fQVRUUklCVVRFX1ZBTFVFX0RRO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIGlmKGMgPT09IFwiJ1wiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0FUVFJJQlVURV9WQUxVRV9TUTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleCArIDE7XG5cdH0gZWxzZSBpZighd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9BVFRSSUJVVEVfVkFMVUVfTlE7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXg7XG5cdFx0dGhpcy5faW5kZXgtLTsgLy9yZWNvbnN1bWUgdG9rZW5cblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiXFxcIlwiKXtcblx0XHR0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7XG5cdFx0dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQVRUUklCVVRFX05BTUU7XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiBjID09PSBcIiZcIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Jhc2VTdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0VOVElUWTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlU2luZ2xlUXVvdGVzID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiJ1wiKXtcblx0XHR0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7XG5cdFx0dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7XG5cdFx0dGhpcy5fc3RhdGUgPSBCRUZPUkVfQVRUUklCVVRFX05BTUU7XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiBjID09PSBcIiZcIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Jhc2VTdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0VOVElUWTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXMgPSBmdW5jdGlvbihjKXtcblx0aWYod2hpdGVzcGFjZShjKSB8fCBjID09PSBcIj5cIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Nicy5vbmF0dHJpYmVuZCgpO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0FUVFJJQlVURV9OQU1FO1xuXHRcdHRoaXMuX2luZGV4LS07XG5cdH0gZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyAmJiBjID09PSBcIiZcIil7XG5cdFx0dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO1xuXHRcdHRoaXMuX2Jhc2VTdGF0ZSA9IHRoaXMuX3N0YXRlO1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX0VOVElUWTtcblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSB0aGlzLl9pbmRleDtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVEZWNsYXJhdGlvbiA9IGZ1bmN0aW9uKGMpe1xuXHR0aGlzLl9zdGF0ZSA9IGMgPT09IFwiW1wiID8gQkVGT1JFX0NEQVRBXzEgOlxuXHRcdFx0XHRcdGMgPT09IFwiLVwiID8gQkVGT1JFX0NPTU1FTlQgOlxuXHRcdFx0XHRcdFx0SU5fREVDTEFSQVRJT047XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluRGVjbGFyYXRpb24gPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIpe1xuXHRcdHRoaXMuX2Nicy5vbmRlY2xhcmF0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJblByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIj5cIil7XG5cdFx0dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7XG5cdFx0dGhpcy5fc3RhdGUgPSBURVhUO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDb21tZW50ID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiLVwiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NPTU1FTlQ7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHR9IGVsc2Uge1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fREVDTEFSQVRJT047XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5Db21tZW50ID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiLVwiKSB0aGlzLl9zdGF0ZSA9IEFGVEVSX0NPTU1FTlRfMTtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDb21tZW50MSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi1cIil7XG5cdFx0dGhpcy5fc3RhdGUgPSBBRlRFUl9DT01NRU5UXzI7XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9DT01NRU5UO1xuXHR9XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ29tbWVudDIgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIpe1xuXHRcdC8vcmVtb3ZlIDIgdHJhaWxpbmcgY2hhcnNcblx0XHR0aGlzLl9jYnMub25jb21tZW50KHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LCB0aGlzLl9pbmRleCAtIDIpKTtcblx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHR9IGVsc2UgaWYoYyAhPT0gXCItXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gSU5fQ09NTUVOVDtcblx0fVxuXHQvLyBlbHNlOiBzdGF5IGluIEFGVEVSX0NPTU1FTlRfMiAoYC0tLT5gKVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTEgPSBpZkVsc2VTdGF0ZShcIkNcIiwgQkVGT1JFX0NEQVRBXzIsIElOX0RFQ0xBUkFUSU9OKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGEyID0gaWZFbHNlU3RhdGUoXCJEXCIsIEJFRk9SRV9DREFUQV8zLCBJTl9ERUNMQVJBVElPTik7XG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhMyA9IGlmRWxzZVN0YXRlKFwiQVwiLCBCRUZPUkVfQ0RBVEFfNCwgSU5fREVDTEFSQVRJT04pO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTQgPSBpZkVsc2VTdGF0ZShcIlRcIiwgQkVGT1JFX0NEQVRBXzUsIElOX0RFQ0xBUkFUSU9OKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE1ID0gaWZFbHNlU3RhdGUoXCJBXCIsIEJFRk9SRV9DREFUQV82LCBJTl9ERUNMQVJBVElPTik7XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE2ID0gZnVuY3Rpb24oYyl7XG5cdGlmKGMgPT09IFwiW1wiKXtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NEQVRBO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4ICsgMTtcblx0fSBlbHNlIHtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0RFQ0xBUkFUSU9OO1xuXHRcdHRoaXMuX2luZGV4LS07XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DZGF0YSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIl1cIikgdGhpcy5fc3RhdGUgPSBBRlRFUl9DREFUQV8xO1xufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMSA9IGNoYXJhY3RlclN0YXRlKFwiXVwiLCBBRlRFUl9DREFUQV8yKTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMiA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIj5cIil7XG5cdFx0Ly9yZW1vdmUgMiB0cmFpbGluZyBjaGFyc1xuXHRcdHRoaXMuX2Nicy5vbmNkYXRhKHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LCB0aGlzLl9pbmRleCAtIDIpKTtcblx0XHR0aGlzLl9zdGF0ZSA9IFRFWFQ7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHR9IGVsc2UgaWYoYyAhPT0gXCJdXCIpIHtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NEQVRBO1xuXHR9XG5cdC8vZWxzZTogc3RheSBpbiBBRlRFUl9DREFUQV8yIChgXV1dPmApXG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNwZWNpYWwgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCJjXCIgfHwgYyA9PT0gXCJDXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX1NDUklQVF8xO1xuXHR9IGVsc2UgaWYoYyA9PT0gXCJ0XCIgfHwgYyA9PT0gXCJUXCIpe1xuXHRcdHRoaXMuX3N0YXRlID0gQkVGT1JFX1NUWUxFXzE7XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5fc3RhdGUgPSBJTl9UQUdfTkFNRTtcblx0XHR0aGlzLl9pbmRleC0tOyAvL2NvbnN1bWUgdGhlIHRva2VuIGFnYWluXG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3BlY2lhbEVuZCA9IGZ1bmN0aW9uKGMpe1xuXHRpZih0aGlzLl9zcGVjaWFsID09PSBTUEVDSUFMX1NDUklQVCAmJiAoYyA9PT0gXCJjXCIgfHwgYyA9PT0gXCJDXCIpKXtcblx0XHR0aGlzLl9zdGF0ZSA9IEFGVEVSX1NDUklQVF8xO1xuXHR9IGVsc2UgaWYodGhpcy5fc3BlY2lhbCA9PT0gU1BFQ0lBTF9TVFlMRSAmJiAoYyA9PT0gXCJ0XCIgfHwgYyA9PT0gXCJUXCIpKXtcblx0XHR0aGlzLl9zdGF0ZSA9IEFGVEVSX1NUWUxFXzE7XG5cdH1cblx0ZWxzZSB0aGlzLl9zdGF0ZSA9IFRFWFQ7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDEgPSBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiUlwiLCBCRUZPUkVfU0NSSVBUXzIpO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQyID0gY29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIklcIiwgQkVGT1JFX1NDUklQVF8zKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0MyA9IGNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJQXCIsIEJFRk9SRV9TQ1JJUFRfNCk7XG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDQgPSBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiVFwiLCBCRUZPUkVfU0NSSVBUXzUpO1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCIvXCIgfHwgYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfU0NSSVBUO1xuXHR9XG5cdHRoaXMuX3N0YXRlID0gSU5fVEFHX05BTUU7XG5cdHRoaXMuX2luZGV4LS07IC8vY29uc3VtZSB0aGUgdG9rZW4gYWdhaW5cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQxID0gaWZFbHNlU3RhdGUoXCJSXCIsIEFGVEVSX1NDUklQVF8yLCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQyID0gaWZFbHNlU3RhdGUoXCJJXCIsIEFGVEVSX1NDUklQVF8zLCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQzID0gaWZFbHNlU3RhdGUoXCJQXCIsIEFGVEVSX1NDUklQVF80LCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ0ID0gaWZFbHNlU3RhdGUoXCJUXCIsIEFGVEVSX1NDUklQVF81LCBURVhUKTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclNjcmlwdDUgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfTk9ORTtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggLSA2O1xuXHRcdHRoaXMuX2luZGV4LS07IC8vcmVjb25zdW1lIHRoZSB0b2tlblxuXHR9XG5cdGVsc2UgdGhpcy5fc3RhdGUgPSBURVhUO1xufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTEgPSBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiWVwiLCBCRUZPUkVfU1RZTEVfMik7XG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlMiA9IGNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJMXCIsIEJFRk9SRV9TVFlMRV8zKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU3R5bGUzID0gY29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkVcIiwgQkVGT1JFX1NUWUxFXzQpO1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVN0eWxlNCA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIi9cIiB8fCBjID09PSBcIj5cIiB8fCB3aGl0ZXNwYWNlKGMpKXtcblx0XHR0aGlzLl9zcGVjaWFsID0gU1BFQ0lBTF9TVFlMRTtcblx0fVxuXHR0aGlzLl9zdGF0ZSA9IElOX1RBR19OQU1FO1xuXHR0aGlzLl9pbmRleC0tOyAvL2NvbnN1bWUgdGhlIHRva2VuIGFnYWluXG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGUxID0gaWZFbHNlU3RhdGUoXCJZXCIsIEFGVEVSX1NUWUxFXzIsIFRFWFQpO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlMiA9IGlmRWxzZVN0YXRlKFwiTFwiLCBBRlRFUl9TVFlMRV8zLCBURVhUKTtcblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTMgPSBpZkVsc2VTdGF0ZShcIkVcIiwgQUZURVJfU1RZTEVfNCwgVEVYVCk7XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTQgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI+XCIgfHwgd2hpdGVzcGFjZShjKSl7XG5cdFx0dGhpcy5fc3BlY2lhbCA9IFNQRUNJQUxfTk9ORTtcblx0XHR0aGlzLl9zdGF0ZSA9IElOX0NMT1NJTkdfVEFHX05BTUU7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggLSA1O1xuXHRcdHRoaXMuX2luZGV4LS07IC8vcmVjb25zdW1lIHRoZSB0b2tlblxuXHR9XG5cdGVsc2UgdGhpcy5fc3RhdGUgPSBURVhUO1xufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVFbnRpdHkgPSBpZkVsc2VTdGF0ZShcIiNcIiwgQkVGT1JFX05VTUVSSUNfRU5USVRZLCBJTl9OQU1FRF9FTlRJVFkpO1xuVG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5ID0gaWZFbHNlU3RhdGUoXCJYXCIsIElOX0hFWF9FTlRJVFksIElOX05VTUVSSUNfRU5USVRZKTtcblxuLy9mb3IgZW50aXRpZXMgdGVybWluYXRlZCB3aXRoIGEgc2VtaWNvbG9uXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9wYXJzZU5hbWVkRW50aXR5U3RyaWN0ID0gZnVuY3Rpb24oKXtcblx0Ly9vZmZzZXQgPSAxXG5cdGlmKHRoaXMuX3NlY3Rpb25TdGFydCArIDEgPCB0aGlzLl9pbmRleCl7XG5cdFx0dmFyIGVudGl0eSA9IHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0ICsgMSwgdGhpcy5faW5kZXgpLFxuXHRcdCAgICBtYXAgPSB0aGlzLl94bWxNb2RlID8geG1sTWFwIDogZW50aXR5TWFwO1xuXG5cdFx0aWYobWFwLmhhc093blByb3BlcnR5KGVudGl0eSkpe1xuXHRcdFx0dGhpcy5fZW1pdFBhcnRpYWwobWFwW2VudGl0eV0pO1xuXHRcdFx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gdGhpcy5faW5kZXggKyAxO1xuXHRcdH1cblx0fVxufTtcblxuXG4vL3BhcnNlcyBsZWdhY3kgZW50aXRpZXMgKHdpdGhvdXQgdHJhaWxpbmcgc2VtaWNvbG9uKVxuVG9rZW5pemVyLnByb3RvdHlwZS5fcGFyc2VMZWdhY3lFbnRpdHkgPSBmdW5jdGlvbigpe1xuXHR2YXIgc3RhcnQgPSB0aGlzLl9zZWN0aW9uU3RhcnQgKyAxLFxuXHQgICAgbGltaXQgPSB0aGlzLl9pbmRleCAtIHN0YXJ0O1xuXG5cdGlmKGxpbWl0ID4gNikgbGltaXQgPSA2OyAvL3RoZSBtYXggbGVuZ3RoIG9mIGxlZ2FjeSBlbnRpdGllcyBpcyA2XG5cblx0d2hpbGUobGltaXQgPj0gMil7IC8vdGhlIG1pbiBsZW5ndGggb2YgbGVnYWN5IGVudGl0aWVzIGlzIDJcblx0XHR2YXIgZW50aXR5ID0gdGhpcy5fYnVmZmVyLnN1YnN0cihzdGFydCwgbGltaXQpO1xuXG5cdFx0aWYobGVnYWN5TWFwLmhhc093blByb3BlcnR5KGVudGl0eSkpe1xuXHRcdFx0dGhpcy5fZW1pdFBhcnRpYWwobGVnYWN5TWFwW2VudGl0eV0pO1xuXHRcdFx0dGhpcy5fc2VjdGlvblN0YXJ0ICs9IGxpbWl0ICsgMTtcblx0XHRcdHJldHVybjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGltaXQtLTtcblx0XHR9XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5OYW1lZEVudGl0eSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIjtcIil7XG5cdFx0dGhpcy5fcGFyc2VOYW1lZEVudGl0eVN0cmljdCgpO1xuXHRcdGlmKHRoaXMuX3NlY3Rpb25TdGFydCArIDEgPCB0aGlzLl9pbmRleCAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0XHR0aGlzLl9wYXJzZUxlZ2FjeUVudGl0eSgpO1xuXHRcdH1cblx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0fSBlbHNlIGlmKChjIDwgXCJhXCIgfHwgYyA+IFwielwiKSAmJiAoYyA8IFwiQVwiIHx8IGMgPiBcIlpcIikgJiYgKGMgPCBcIjBcIiB8fCBjID4gXCI5XCIpKXtcblx0XHRpZih0aGlzLl94bWxNb2RlKTtcblx0XHRlbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydCArIDEgPT09IHRoaXMuX2luZGV4KTtcblx0XHRlbHNlIGlmKHRoaXMuX2Jhc2VTdGF0ZSAhPT0gVEVYVCl7XG5cdFx0XHRpZihjICE9PSBcIj1cIil7XG5cdFx0XHRcdHRoaXMuX3BhcnNlTmFtZWRFbnRpdHlTdHJpY3QoKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKTtcblx0XHR9XG5cblx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0XHR0aGlzLl9pbmRleC0tO1xuXHR9XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9kZWNvZGVOdW1lcmljRW50aXR5ID0gZnVuY3Rpb24ob2Zmc2V0LCBiYXNlKXtcblx0dmFyIHNlY3Rpb25TdGFydCA9IHRoaXMuX3NlY3Rpb25TdGFydCArIG9mZnNldDtcblxuXHRpZihzZWN0aW9uU3RhcnQgIT09IHRoaXMuX2luZGV4KXtcblx0XHQvL3BhcnNlIGVudGl0eVxuXHRcdHZhciBlbnRpdHkgPSB0aGlzLl9idWZmZXIuc3Vic3RyaW5nKHNlY3Rpb25TdGFydCwgdGhpcy5faW5kZXgpO1xuXHRcdHZhciBwYXJzZWQgPSBwYXJzZUludChlbnRpdHksIGJhc2UpO1xuXG5cdFx0dGhpcy5fZW1pdFBhcnRpYWwoZGVjb2RlQ29kZVBvaW50KHBhcnNlZCkpO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCA9IHRoaXMuX2luZGV4O1xuXHR9IGVsc2Uge1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydC0tO1xuXHR9XG5cblx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluTnVtZXJpY0VudGl0eSA9IGZ1bmN0aW9uKGMpe1xuXHRpZihjID09PSBcIjtcIil7XG5cdFx0dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLCAxMCk7XG5cdFx0dGhpcy5fc2VjdGlvblN0YXJ0Kys7XG5cdH0gZWxzZSBpZihjIDwgXCIwXCIgfHwgYyA+IFwiOVwiKXtcblx0XHRpZighdGhpcy5feG1sTW9kZSl7XG5cdFx0XHR0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDIsIDEwKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cdFx0fVxuXHRcdHRoaXMuX2luZGV4LS07XG5cdH1cbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5IZXhFbnRpdHkgPSBmdW5jdGlvbihjKXtcblx0aWYoYyA9PT0gXCI7XCIpe1xuXHRcdHRoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywgMTYpO1xuXHRcdHRoaXMuX3NlY3Rpb25TdGFydCsrO1xuXHR9IGVsc2UgaWYoKGMgPCBcImFcIiB8fCBjID4gXCJmXCIpICYmIChjIDwgXCJBXCIgfHwgYyA+IFwiRlwiKSAmJiAoYyA8IFwiMFwiIHx8IGMgPiBcIjlcIikpe1xuXHRcdGlmKCF0aGlzLl94bWxNb2RlKXtcblx0XHRcdHRoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywgMTYpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0XHR9XG5cdFx0dGhpcy5faW5kZXgtLTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5fY2xlYW51cCA9IGZ1bmN0aW9uICgpe1xuXHRpZih0aGlzLl9zZWN0aW9uU3RhcnQgPCAwKXtcblx0XHR0aGlzLl9idWZmZXIgPSBcIlwiO1xuXHRcdHRoaXMuX2luZGV4ID0gMDtcblx0XHR0aGlzLl9idWZmZXJPZmZzZXQgKz0gdGhpcy5faW5kZXg7XG5cdH0gZWxzZSBpZih0aGlzLl9ydW5uaW5nKXtcblx0XHRpZih0aGlzLl9zdGF0ZSA9PT0gVEVYVCl7XG5cdFx0XHRpZih0aGlzLl9zZWN0aW9uU3RhcnQgIT09IHRoaXMuX2luZGV4KXtcblx0XHRcdFx0dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9idWZmZXIuc3Vic3RyKHRoaXMuX3NlY3Rpb25TdGFydCkpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5fYnVmZmVyID0gXCJcIjtcblx0XHRcdHRoaXMuX2J1ZmZlck9mZnNldCArPSB0aGlzLl9pbmRleDtcblx0XHRcdHRoaXMuX2luZGV4ID0gMDtcblx0XHR9IGVsc2UgaWYodGhpcy5fc2VjdGlvblN0YXJ0ID09PSB0aGlzLl9pbmRleCl7XG5cdFx0XHQvL3RoZSBzZWN0aW9uIGp1c3Qgc3RhcnRlZFxuXHRcdFx0dGhpcy5fYnVmZmVyID0gXCJcIjtcblx0XHRcdHRoaXMuX2J1ZmZlck9mZnNldCArPSB0aGlzLl9pbmRleDtcblx0XHRcdHRoaXMuX2luZGV4ID0gMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly9yZW1vdmUgZXZlcnl0aGluZyB1bm5lY2Vzc2FyeVxuXHRcdFx0dGhpcy5fYnVmZmVyID0gdGhpcy5fYnVmZmVyLnN1YnN0cih0aGlzLl9zZWN0aW9uU3RhcnQpO1xuXHRcdFx0dGhpcy5faW5kZXggLT0gdGhpcy5fc2VjdGlvblN0YXJ0O1xuXHRcdFx0dGhpcy5fYnVmZmVyT2Zmc2V0ICs9IHRoaXMuX3NlY3Rpb25TdGFydDtcblx0XHR9XG5cblx0XHR0aGlzLl9zZWN0aW9uU3RhcnQgPSAwO1xuXHR9XG59O1xuXG4vL1RPRE8gbWFrZSBldmVudHMgY29uZGl0aW9uYWxcblRva2VuaXplci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihjaHVuayl7XG5cdGlmKHRoaXMuX2VuZGVkKSB0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi53cml0ZSgpIGFmdGVyIGRvbmUhXCIpKTtcblxuXHR0aGlzLl9idWZmZXIgKz0gY2h1bms7XG5cdHRoaXMuX3BhcnNlKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9wYXJzZSA9IGZ1bmN0aW9uKCl7XG5cdHdoaWxlKHRoaXMuX2luZGV4IDwgdGhpcy5fYnVmZmVyLmxlbmd0aCAmJiB0aGlzLl9ydW5uaW5nKXtcblx0XHR2YXIgYyA9IHRoaXMuX2J1ZmZlci5jaGFyQXQodGhpcy5faW5kZXgpO1xuXHRcdGlmKHRoaXMuX3N0YXRlID09PSBURVhUKSB7XG5cdFx0XHR0aGlzLl9zdGF0ZVRleHQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfVEFHX05BTUUpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVUYWdOYW1lKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fVEFHX05BTUUpIHtcblx0XHRcdHRoaXMuX3N0YXRlSW5UYWdOYW1lKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0NMT1NJTkdfVEFHX05BTUUpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVDbG9zZWluZ1RhZ05hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9DTE9TSU5HX1RBR19OQU1FKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5DbG9zZWluZ1RhZ05hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBBRlRFUl9DTE9TSU5HX1RBR19OQU1FKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJDbG9zZWluZ1RhZ05hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9TRUxGX0NMT1NJTkdfVEFHKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5TZWxmQ2xvc2luZ1RhZyhjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCpcdGF0dHJpYnV0ZXNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9BVFRSSUJVVEVfTkFNRSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZU5hbWUoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9BVFRSSUJVVEVfTkFNRSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUluQXR0cmlidXRlTmFtZShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX0FUVFJJQlVURV9OQU1FKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJBdHRyaWJ1dGVOYW1lKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0FUVFJJQlVURV9WQUxVRSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZVZhbHVlKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fQVRUUklCVVRFX1ZBTFVFX0RRKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZURvdWJsZVF1b3RlcyhjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX0FUVFJJQlVURV9WQUxVRV9TUSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVTaW5nbGVRdW90ZXMoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9BVFRSSUJVVEVfVkFMVUVfTlEpe1xuXHRcdFx0dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXMoYyk7XG5cdFx0fVxuXG5cdFx0Lypcblx0XHQqXHRkZWNsYXJhdGlvbnNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9ERUNMQVJBVElPTil7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZURlY2xhcmF0aW9uKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fREVDTEFSQVRJT04pe1xuXHRcdFx0dGhpcy5fc3RhdGVJbkRlY2xhcmF0aW9uKGMpO1xuXHRcdH1cblxuXHRcdC8qXG5cdFx0Klx0cHJvY2Vzc2luZyBpbnN0cnVjdGlvbnNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX1BST0NFU1NJTkdfSU5TVFJVQ1RJT04pe1xuXHRcdFx0dGhpcy5fc3RhdGVJblByb2Nlc3NpbmdJbnN0cnVjdGlvbihjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCpcdGNvbW1lbnRzXG5cdFx0Ki9cblx0XHRlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfQ09NTUVOVCl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUNvbW1lbnQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9DT01NRU5UKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5Db21tZW50KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ09NTUVOVF8xKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJDb21tZW50MShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX0NPTU1FTlRfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyQ29tbWVudDIoYyk7XG5cdFx0fVxuXG5cdFx0Lypcblx0XHQqXHRjZGF0YVxuXHRcdCovXG5cdFx0ZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0NEQVRBXzEpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTEoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfQ0RBVEFfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhMihjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9DREFUQV8zKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlQ2RhdGEzKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX0NEQVRBXzQpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfQ0RBVEFfNSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhNShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9DREFUQV82KXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlQ2RhdGE2KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fQ0RBVEEpe1xuXHRcdFx0dGhpcy5fc3RhdGVJbkNkYXRhKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ0RBVEFfMSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyQ2RhdGExKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ0RBVEFfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyQ2RhdGEyKGMpO1xuXHRcdH1cblxuXHRcdC8qXG5cdFx0KiBzcGVjaWFsIHRhZ3Ncblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TUEVDSUFMKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU3BlY2lhbChjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TUEVDSUFMX0VORCl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVNwZWNpYWxFbmQoYyk7XG5cdFx0fVxuXG5cdFx0Lypcblx0XHQqIHNjcmlwdFxuXHRcdCovXG5cdFx0ZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX1NDUklQVF8xKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU2NyaXB0MShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TQ1JJUFRfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDIoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfU0NSSVBUXzMpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQzKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX1NDUklQVF80KXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU2NyaXB0NChjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TQ1JJUFRfNSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDUoYyk7XG5cdFx0fVxuXG5cdFx0ZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfU0NSSVBUXzEpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclNjcmlwdDEoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBBRlRFUl9TQ1JJUFRfMil7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0MihjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NDUklQVF8zKXtcblx0XHRcdHRoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQzKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQUZURVJfU0NSSVBUXzQpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclNjcmlwdDQoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBBRlRFUl9TQ1JJUFRfNSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0NShjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCogc3R5bGVcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TVFlMRV8xKXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU3R5bGUxKGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gQkVGT1JFX1NUWUxFXzIpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTIoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfU1RZTEVfMyl7XG5cdFx0XHR0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlMyhjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9TVFlMRV80KXtcblx0XHRcdHRoaXMuX3N0YXRlQmVmb3JlU3R5bGU0KGMpO1xuXHRcdH1cblxuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzEpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlMShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzIpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlMihjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzMpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlMyhjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEFGVEVSX1NUWUxFXzQpe1xuXHRcdFx0dGhpcy5fc3RhdGVBZnRlclN0eWxlNChjKTtcblx0XHR9XG5cblx0XHQvKlxuXHRcdCogZW50aXRpZXNcblx0XHQqL1xuXHRcdGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IEJFRk9SRV9FTlRJVFkpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVFbnRpdHkoYyk7XG5cdFx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBCRUZPUkVfTlVNRVJJQ19FTlRJVFkpe1xuXHRcdFx0dGhpcy5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fTkFNRURfRU5USVRZKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5OYW1lZEVudGl0eShjKTtcblx0XHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX05VTUVSSUNfRU5USVRZKXtcblx0XHRcdHRoaXMuX3N0YXRlSW5OdW1lcmljRW50aXR5KGMpO1xuXHRcdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fSEVYX0VOVElUWSl7XG5cdFx0XHR0aGlzLl9zdGF0ZUluSGV4RW50aXR5KGMpO1xuXHRcdH1cblxuXHRcdGVsc2Uge1xuXHRcdFx0dGhpcy5fY2JzLm9uZXJyb3IoRXJyb3IoXCJ1bmtub3duIF9zdGF0ZVwiKSwgdGhpcy5fc3RhdGUpO1xuXHRcdH1cblxuXHRcdHRoaXMuX2luZGV4Kys7XG5cdH1cblxuXHR0aGlzLl9jbGVhbnVwKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fcnVubmluZyA9IGZhbHNlO1xufTtcblRva2VuaXplci5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24oKXtcblx0dGhpcy5fcnVubmluZyA9IHRydWU7XG5cblx0aWYodGhpcy5faW5kZXggPCB0aGlzLl9idWZmZXIubGVuZ3RoKXtcblx0XHR0aGlzLl9wYXJzZSgpO1xuXHR9XG5cdGlmKHRoaXMuX2VuZGVkKXtcblx0XHR0aGlzLl9maW5pc2goKTtcblx0fVxufTtcblxuVG9rZW5pemVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihjaHVuayl7XG5cdGlmKHRoaXMuX2VuZGVkKSB0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi5lbmQoKSBhZnRlciBkb25lIVwiKSk7XG5cdGlmKGNodW5rKSB0aGlzLndyaXRlKGNodW5rKTtcblxuXHR0aGlzLl9lbmRlZCA9IHRydWU7XG5cblx0aWYodGhpcy5fcnVubmluZykgdGhpcy5fZmluaXNoKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9maW5pc2ggPSBmdW5jdGlvbigpe1xuXHQvL2lmIHRoZXJlIGlzIHJlbWFpbmluZyBkYXRhLCBlbWl0IGl0IGluIGEgcmVhc29uYWJsZSB3YXlcblx0aWYodGhpcy5fc2VjdGlvblN0YXJ0IDwgdGhpcy5faW5kZXgpe1xuXHRcdHRoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpO1xuXHR9XG5cblx0dGhpcy5fY2JzLm9uZW5kKCk7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9oYW5kbGVUcmFpbGluZ0RhdGEgPSBmdW5jdGlvbigpe1xuXHR2YXIgZGF0YSA9IHRoaXMuX2J1ZmZlci5zdWJzdHIodGhpcy5fc2VjdGlvblN0YXJ0KTtcblxuXHRpZih0aGlzLl9zdGF0ZSA9PT0gSU5fQ0RBVEEgfHwgdGhpcy5fc3RhdGUgPT09IEFGVEVSX0NEQVRBXzEgfHwgdGhpcy5fc3RhdGUgPT09IEFGVEVSX0NEQVRBXzIpe1xuXHRcdHRoaXMuX2Nicy5vbmNkYXRhKGRhdGEpO1xuXHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX0NPTU1FTlQgfHwgdGhpcy5fc3RhdGUgPT09IEFGVEVSX0NPTU1FTlRfMSB8fCB0aGlzLl9zdGF0ZSA9PT0gQUZURVJfQ09NTUVOVF8yKXtcblx0XHR0aGlzLl9jYnMub25jb21tZW50KGRhdGEpO1xuXHR9IGVsc2UgaWYodGhpcy5fc3RhdGUgPT09IElOX05BTUVEX0VOVElUWSAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKTtcblx0XHRpZih0aGlzLl9zZWN0aW9uU3RhcnQgPCB0aGlzLl9pbmRleCl7XG5cdFx0XHR0aGlzLl9zdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblx0XHRcdHRoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpO1xuXHRcdH1cblx0fSBlbHNlIGlmKHRoaXMuX3N0YXRlID09PSBJTl9OVU1FUklDX0VOVElUWSAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLCAxMCk7XG5cdFx0aWYodGhpcy5fc2VjdGlvblN0YXJ0IDwgdGhpcy5faW5kZXgpe1xuXHRcdFx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cdFx0XHR0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKTtcblx0XHR9XG5cdH0gZWxzZSBpZih0aGlzLl9zdGF0ZSA9PT0gSU5fSEVYX0VOVElUWSAmJiAhdGhpcy5feG1sTW9kZSl7XG5cdFx0dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgzLCAxNik7XG5cdFx0aWYodGhpcy5fc2VjdGlvblN0YXJ0IDwgdGhpcy5faW5kZXgpe1xuXHRcdFx0dGhpcy5fc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cdFx0XHR0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKTtcblx0XHR9XG5cdH0gZWxzZSBpZihcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fVEFHX05BTUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gQkVGT1JFX0FUVFJJQlVURV9OQU1FICYmXG5cdFx0dGhpcy5fc3RhdGUgIT09IEJFRk9SRV9BVFRSSUJVVEVfVkFMVUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gQUZURVJfQVRUUklCVVRFX05BTUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fQVRUUklCVVRFX05BTUUgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fQVRUUklCVVRFX1ZBTFVFX1NRICYmXG5cdFx0dGhpcy5fc3RhdGUgIT09IElOX0FUVFJJQlVURV9WQUxVRV9EUSAmJlxuXHRcdHRoaXMuX3N0YXRlICE9PSBJTl9BVFRSSUJVVEVfVkFMVUVfTlEgJiZcblx0XHR0aGlzLl9zdGF0ZSAhPT0gSU5fQ0xPU0lOR19UQUdfTkFNRVxuXHQpe1xuXHRcdHRoaXMuX2Nicy5vbnRleHQoZGF0YSk7XG5cdH1cblx0Ly9lbHNlLCBpZ25vcmUgcmVtYWluaW5nIGRhdGFcblx0Ly9UT0RPIGFkZCBhIHdheSB0byByZW1vdmUgY3VycmVudCB0YWdcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpe1xuXHRUb2tlbml6ZXIuY2FsbCh0aGlzLCB7eG1sTW9kZTogdGhpcy5feG1sTW9kZSwgZGVjb2RlRW50aXRpZXM6IHRoaXMuX2RlY29kZUVudGl0aWVzfSwgdGhpcy5fY2JzKTtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuZ2V0QWJzb2x1dGVJbmRleCA9IGZ1bmN0aW9uKCl7XG5cdHJldHVybiB0aGlzLl9idWZmZXJPZmZzZXQgKyB0aGlzLl9pbmRleDtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX2dldFNlY3Rpb24gPSBmdW5jdGlvbigpe1xuXHRyZXR1cm4gdGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQsIHRoaXMuX2luZGV4KTtcbn07XG5cblRva2VuaXplci5wcm90b3R5cGUuX2VtaXRUb2tlbiA9IGZ1bmN0aW9uKG5hbWUpe1xuXHR0aGlzLl9jYnNbbmFtZV0odGhpcy5fZ2V0U2VjdGlvbigpKTtcblx0dGhpcy5fc2VjdGlvblN0YXJ0ID0gLTE7XG59O1xuXG5Ub2tlbml6ZXIucHJvdG90eXBlLl9lbWl0UGFydGlhbCA9IGZ1bmN0aW9uKHZhbHVlKXtcblx0aWYodGhpcy5fYmFzZVN0YXRlICE9PSBURVhUKXtcblx0XHR0aGlzLl9jYnMub25hdHRyaWJkYXRhKHZhbHVlKTsgLy9UT0RPIGltcGxlbWVudCB0aGUgbmV3IGV2ZW50XG5cdH0gZWxzZSB7XG5cdFx0dGhpcy5fY2JzLm9udGV4dCh2YWx1ZSk7XG5cdH1cbn07XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL1dyaXRhYmxlU3RyZWFtLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvV3JpdGFibGVTdHJlYW0uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG52YXIgUGFyc2VyID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9QYXJzZXIuanMgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvUGFyc2VyLmpzXCIpLFxuICAgIFdyaXRhYmxlU3RyZWFtID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgc3RyZWFtICovIFwiLi9ub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvaW5kZXguanNcIikuV3JpdGFibGUgfHwgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgcmVhZGFibGUtc3RyZWFtICovIDEpLldyaXRhYmxlLFxuICAgIFN0cmluZ0RlY29kZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBzdHJpbmdfZGVjb2RlciAqLyBcIi4vbm9kZV9tb2R1bGVzL25vZGUtbGlicy1icm93c2VyL25vZGVfbW9kdWxlcy9zdHJpbmdfZGVjb2Rlci9saWIvc3RyaW5nX2RlY29kZXIuanNcIikuU3RyaW5nRGVjb2RlcixcbiAgICBCdWZmZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBidWZmZXIgKi8gXCIuL25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanNcIikuQnVmZmVyO1xuXG5mdW5jdGlvbiBTdHJlYW0oY2JzLCBvcHRpb25zKXtcblx0dmFyIHBhcnNlciA9IHRoaXMuX3BhcnNlciA9IG5ldyBQYXJzZXIoY2JzLCBvcHRpb25zKTtcblx0dmFyIGRlY29kZXIgPSB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoKTtcblxuXHRXcml0YWJsZVN0cmVhbS5jYWxsKHRoaXMsIHtkZWNvZGVTdHJpbmdzOiBmYWxzZX0pO1xuXG5cdHRoaXMub25jZShcImZpbmlzaFwiLCBmdW5jdGlvbigpe1xuXHRcdHBhcnNlci5lbmQoZGVjb2Rlci5lbmQoKSk7XG5cdH0pO1xufVxuXG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBpbmhlcml0cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanNcIikoU3RyZWFtLCBXcml0YWJsZVN0cmVhbSk7XG5cbldyaXRhYmxlU3RyZWFtLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKXtcblx0aWYoY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIpIGNodW5rID0gdGhpcy5fZGVjb2Rlci53cml0ZShjaHVuayk7XG5cdHRoaXMuX3BhcnNlci53cml0ZShjaHVuayk7XG5cdGNiKCk7XG59O1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9saWIvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL2xpYi9pbmRleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxudmFyIFBhcnNlciA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vUGFyc2VyLmpzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL1BhcnNlci5qc1wiKSxcbiAgICBEb21IYW5kbGVyID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZG9taGFuZGxlciAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb21oYW5kbGVyL2luZGV4LmpzXCIpO1xuXG5mdW5jdGlvbiBkZWZpbmVQcm9wKG5hbWUsIHZhbHVlKXtcblx0ZGVsZXRlIG1vZHVsZS5leHBvcnRzW25hbWVdO1xuXHRtb2R1bGUuZXhwb3J0c1tuYW1lXSA9IHZhbHVlO1xuXHRyZXR1cm4gdmFsdWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRQYXJzZXI6IFBhcnNlcixcblx0VG9rZW5pemVyOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL1Rva2VuaXplci5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL2xpYi9Ub2tlbml6ZXIuanNcIiksXG5cdEVsZW1lbnRUeXBlOiBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBkb21lbGVtZW50dHlwZSAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb21lbGVtZW50dHlwZS9pbmRleC5qc1wiKSxcblx0RG9tSGFuZGxlcjogRG9tSGFuZGxlcixcblx0Z2V0IEZlZWRIYW5kbGVyKCl7XG5cdFx0cmV0dXJuIGRlZmluZVByb3AoXCJGZWVkSGFuZGxlclwiLCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL0ZlZWRIYW5kbGVyLmpzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL0ZlZWRIYW5kbGVyLmpzXCIpKTtcblx0fSxcblx0Z2V0IFN0cmVhbSgpe1xuXHRcdHJldHVybiBkZWZpbmVQcm9wKFwiU3RyZWFtXCIsIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vU3RyZWFtLmpzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL1N0cmVhbS5qc1wiKSk7XG5cdH0sXG5cdGdldCBXcml0YWJsZVN0cmVhbSgpe1xuXHRcdHJldHVybiBkZWZpbmVQcm9wKFwiV3JpdGFibGVTdHJlYW1cIiwgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9Xcml0YWJsZVN0cmVhbS5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL2xpYi9Xcml0YWJsZVN0cmVhbS5qc1wiKSk7XG5cdH0sXG5cdGdldCBQcm94eUhhbmRsZXIoKXtcblx0XHRyZXR1cm4gZGVmaW5lUHJvcChcIlByb3h5SGFuZGxlclwiLCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL1Byb3h5SGFuZGxlci5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL2xpYi9Qcm94eUhhbmRsZXIuanNcIikpO1xuXHR9LFxuXHRnZXQgRG9tVXRpbHMoKXtcblx0XHRyZXR1cm4gZGVmaW5lUHJvcChcIkRvbVV0aWxzXCIsIF9fd2VicGFja19yZXF1aXJlX18oLyohIGRvbXV0aWxzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL2luZGV4LmpzXCIpKTtcblx0fSxcblx0Z2V0IENvbGxlY3RpbmdIYW5kbGVyKCl7XG5cdFx0cmV0dXJuIGRlZmluZVByb3AoXCJDb2xsZWN0aW5nSGFuZGxlclwiLCBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL0NvbGxlY3RpbmdIYW5kbGVyLmpzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbGliL0NvbGxlY3RpbmdIYW5kbGVyLmpzXCIpKTtcblx0fSxcblx0Ly8gRm9yIGxlZ2FjeSBzdXBwb3J0XG5cdERlZmF1bHRIYW5kbGVyOiBEb21IYW5kbGVyLFxuXHRnZXQgUnNzSGFuZGxlcigpe1xuXHRcdHJldHVybiBkZWZpbmVQcm9wKFwiUnNzSGFuZGxlclwiLCB0aGlzLkZlZWRIYW5kbGVyKTtcblx0fSxcblx0Ly9oZWxwZXIgbWV0aG9kc1xuXHRwYXJzZURPTTogZnVuY3Rpb24oZGF0YSwgb3B0aW9ucyl7XG5cdFx0dmFyIGhhbmRsZXIgPSBuZXcgRG9tSGFuZGxlcihvcHRpb25zKTtcblx0XHRuZXcgUGFyc2VyKGhhbmRsZXIsIG9wdGlvbnMpLmVuZChkYXRhKTtcblx0XHRyZXR1cm4gaGFuZGxlci5kb207XG5cdH0sXG5cdHBhcnNlRmVlZDogZnVuY3Rpb24oZmVlZCwgb3B0aW9ucyl7XG5cdFx0dmFyIGhhbmRsZXIgPSBuZXcgbW9kdWxlLmV4cG9ydHMuRmVlZEhhbmRsZXIob3B0aW9ucyk7XG5cdFx0bmV3IFBhcnNlcihoYW5kbGVyLCBvcHRpb25zKS5lbmQoZmVlZCk7XG5cdFx0cmV0dXJuIGhhbmRsZXIuZG9tO1xuXHR9LFxuXHRjcmVhdGVEb21TdHJlYW06IGZ1bmN0aW9uKGNiLCBvcHRpb25zLCBlbGVtZW50Q2Ipe1xuXHRcdHZhciBoYW5kbGVyID0gbmV3IERvbUhhbmRsZXIoY2IsIG9wdGlvbnMsIGVsZW1lbnRDYik7XG5cdFx0cmV0dXJuIG5ldyBQYXJzZXIoaGFuZGxlciwgb3B0aW9ucyk7XG5cdH0sXG5cdC8vIExpc3Qgb2YgYWxsIGV2ZW50cyB0aGF0IHRoZSBwYXJzZXIgZW1pdHNcblx0RVZFTlRTOiB7IC8qIEZvcm1hdDogZXZlbnRuYW1lOiBudW1iZXIgb2YgYXJndW1lbnRzICovXG5cdFx0YXR0cmlidXRlOiAyLFxuXHRcdGNkYXRhc3RhcnQ6IDAsXG5cdFx0Y2RhdGFlbmQ6IDAsXG5cdFx0dGV4dDogMSxcblx0XHRwcm9jZXNzaW5naW5zdHJ1Y3Rpb246IDIsXG5cdFx0Y29tbWVudDogMSxcblx0XHRjb21tZW50ZW5kOiAwLFxuXHRcdGNsb3NldGFnOiAxLFxuXHRcdG9wZW50YWc6IDIsXG5cdFx0b3BlbnRhZ25hbWU6IDEsXG5cdFx0ZXJyb3I6IDEsXG5cdFx0ZW5kOiAwXG5cdH1cbn07XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbWVsZW1lbnR0eXBlL2luZGV4LmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tZWxlbWVudHR5cGUvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbi8vVHlwZXMgb2YgZWxlbWVudHMgZm91bmQgaW4gdGhlIERPTVxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdFRleHQ6IFwidGV4dFwiLCAvL1RleHRcblx0RGlyZWN0aXZlOiBcImRpcmVjdGl2ZVwiLCAvLzw/IC4uLiA/PlxuXHRDb21tZW50OiBcImNvbW1lbnRcIiwgLy88IS0tIC4uLiAtLT5cblx0U2NyaXB0OiBcInNjcmlwdFwiLCAvLzxzY3JpcHQ+IHRhZ3Ncblx0U3R5bGU6IFwic3R5bGVcIiwgLy88c3R5bGU+IHRhZ3Ncblx0VGFnOiBcInRhZ1wiLCAvL0FueSB0YWdcblx0Q0RBVEE6IFwiY2RhdGFcIiwgLy88IVtDREFUQVsgLi4uIF1dPlxuXHREb2N0eXBlOiBcImRvY3R5cGVcIixcblxuXHRpc1RhZzogZnVuY3Rpb24oZWxlbSl7XG5cdFx0cmV0dXJuIGVsZW0udHlwZSA9PT0gXCJ0YWdcIiB8fCBlbGVtLnR5cGUgPT09IFwic2NyaXB0XCIgfHwgZWxlbS50eXBlID09PSBcInN0eWxlXCI7XG5cdH1cbn07XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbWhhbmRsZXIvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbWhhbmRsZXIvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxudmFyIEVsZW1lbnRUeXBlID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZG9tZWxlbWVudHR5cGUgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tZWxlbWVudHR5cGUvaW5kZXguanNcIik7XG5cbnZhciByZV93aGl0ZXNwYWNlID0gL1xccysvZztcbnZhciBOb2RlUHJvdG90eXBlID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9saWIvbm9kZSAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb21oYW5kbGVyL2xpYi9ub2RlLmpzXCIpO1xudmFyIEVsZW1lbnRQcm90b3R5cGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9lbGVtZW50ICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbWhhbmRsZXIvbGliL2VsZW1lbnQuanNcIik7XG5cbmZ1bmN0aW9uIERvbUhhbmRsZXIoY2FsbGJhY2ssIG9wdGlvbnMsIGVsZW1lbnRDQil7XG5cdGlmKHR5cGVvZiBjYWxsYmFjayA9PT0gXCJvYmplY3RcIil7XG5cdFx0ZWxlbWVudENCID0gb3B0aW9ucztcblx0XHRvcHRpb25zID0gY2FsbGJhY2s7XG5cdFx0Y2FsbGJhY2sgPSBudWxsO1xuXHR9IGVsc2UgaWYodHlwZW9mIG9wdGlvbnMgPT09IFwiZnVuY3Rpb25cIil7XG5cdFx0ZWxlbWVudENCID0gb3B0aW9ucztcblx0XHRvcHRpb25zID0gZGVmYXVsdE9wdHM7XG5cdH1cblx0dGhpcy5fY2FsbGJhY2sgPSBjYWxsYmFjaztcblx0dGhpcy5fb3B0aW9ucyA9IG9wdGlvbnMgfHwgZGVmYXVsdE9wdHM7XG5cdHRoaXMuX2VsZW1lbnRDQiA9IGVsZW1lbnRDQjtcblx0dGhpcy5kb20gPSBbXTtcblx0dGhpcy5fZG9uZSA9IGZhbHNlO1xuXHR0aGlzLl90YWdTdGFjayA9IFtdO1xuXHR0aGlzLl9wYXJzZXIgPSB0aGlzLl9wYXJzZXIgfHwgbnVsbDtcbn1cblxuLy9kZWZhdWx0IG9wdGlvbnNcbnZhciBkZWZhdWx0T3B0cyA9IHtcblx0bm9ybWFsaXplV2hpdGVzcGFjZTogZmFsc2UsIC8vUmVwbGFjZSBhbGwgd2hpdGVzcGFjZSB3aXRoIHNpbmdsZSBzcGFjZXNcblx0d2l0aFN0YXJ0SW5kaWNlczogZmFsc2UsIC8vQWRkIHN0YXJ0SW5kZXggcHJvcGVydGllcyB0byBub2Rlc1xufTtcblxuRG9tSGFuZGxlci5wcm90b3R5cGUub25wYXJzZXJpbml0ID0gZnVuY3Rpb24ocGFyc2VyKXtcblx0dGhpcy5fcGFyc2VyID0gcGFyc2VyO1xufTtcblxuLy9SZXNldHMgdGhlIGhhbmRsZXIgYmFjayB0byBzdGFydGluZyBzdGF0ZVxuRG9tSGFuZGxlci5wcm90b3R5cGUub25yZXNldCA9IGZ1bmN0aW9uKCl7XG5cdERvbUhhbmRsZXIuY2FsbCh0aGlzLCB0aGlzLl9jYWxsYmFjaywgdGhpcy5fb3B0aW9ucywgdGhpcy5fZWxlbWVudENCKTtcbn07XG5cbi8vU2lnbmFscyB0aGUgaGFuZGxlciB0aGF0IHBhcnNpbmcgaXMgZG9uZVxuRG9tSGFuZGxlci5wcm90b3R5cGUub25lbmQgPSBmdW5jdGlvbigpe1xuXHRpZih0aGlzLl9kb25lKSByZXR1cm47XG5cdHRoaXMuX2RvbmUgPSB0cnVlO1xuXHR0aGlzLl9wYXJzZXIgPSBudWxsO1xuXHR0aGlzLl9oYW5kbGVDYWxsYmFjayhudWxsKTtcbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLl9oYW5kbGVDYWxsYmFjayA9XG5Eb21IYW5kbGVyLnByb3RvdHlwZS5vbmVycm9yID0gZnVuY3Rpb24oZXJyb3Ipe1xuXHRpZih0eXBlb2YgdGhpcy5fY2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIil7XG5cdFx0dGhpcy5fY2FsbGJhY2soZXJyb3IsIHRoaXMuZG9tKTtcblx0fSBlbHNlIHtcblx0XHRpZihlcnJvcikgdGhyb3cgZXJyb3I7XG5cdH1cbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9uY2xvc2V0YWcgPSBmdW5jdGlvbigpe1xuXHQvL2lmKHRoaXMuX3RhZ1N0YWNrLnBvcCgpLm5hbWUgIT09IG5hbWUpIHRoaXMuX2hhbmRsZUNhbGxiYWNrKEVycm9yKFwiVGFnbmFtZSBkaWRuJ3QgbWF0Y2ghXCIpKTtcblx0dmFyIGVsZW0gPSB0aGlzLl90YWdTdGFjay5wb3AoKTtcblx0aWYodGhpcy5fZWxlbWVudENCKSB0aGlzLl9lbGVtZW50Q0IoZWxlbSk7XG59O1xuXG5Eb21IYW5kbGVyLnByb3RvdHlwZS5fYWRkRG9tRWxlbWVudCA9IGZ1bmN0aW9uKGVsZW1lbnQpe1xuXHR2YXIgcGFyZW50ID0gdGhpcy5fdGFnU3RhY2tbdGhpcy5fdGFnU3RhY2subGVuZ3RoIC0gMV07XG5cdHZhciBzaWJsaW5ncyA9IHBhcmVudCA/IHBhcmVudC5jaGlsZHJlbiA6IHRoaXMuZG9tO1xuXHR2YXIgcHJldmlvdXNTaWJsaW5nID0gc2libGluZ3Nbc2libGluZ3MubGVuZ3RoIC0gMV07XG5cblx0ZWxlbWVudC5uZXh0ID0gbnVsbDtcblxuXHRpZih0aGlzLl9vcHRpb25zLndpdGhTdGFydEluZGljZXMpe1xuXHRcdGVsZW1lbnQuc3RhcnRJbmRleCA9IHRoaXMuX3BhcnNlci5zdGFydEluZGV4O1xuXHR9XG5cblx0aWYgKHRoaXMuX29wdGlvbnMud2l0aERvbUx2bDEpIHtcblx0XHRlbGVtZW50Ll9fcHJvdG9fXyA9IGVsZW1lbnQudHlwZSA9PT0gXCJ0YWdcIiA/IEVsZW1lbnRQcm90b3R5cGUgOiBOb2RlUHJvdG90eXBlO1xuXHR9XG5cblx0aWYocHJldmlvdXNTaWJsaW5nKXtcblx0XHRlbGVtZW50LnByZXYgPSBwcmV2aW91c1NpYmxpbmc7XG5cdFx0cHJldmlvdXNTaWJsaW5nLm5leHQgPSBlbGVtZW50O1xuXHR9IGVsc2Uge1xuXHRcdGVsZW1lbnQucHJldiA9IG51bGw7XG5cdH1cblxuXHRzaWJsaW5ncy5wdXNoKGVsZW1lbnQpO1xuXHRlbGVtZW50LnBhcmVudCA9IHBhcmVudCB8fCBudWxsO1xufTtcblxuRG9tSGFuZGxlci5wcm90b3R5cGUub25vcGVudGFnID0gZnVuY3Rpb24obmFtZSwgYXR0cmlicyl7XG5cdHZhciBlbGVtZW50ID0ge1xuXHRcdHR5cGU6IG5hbWUgPT09IFwic2NyaXB0XCIgPyBFbGVtZW50VHlwZS5TY3JpcHQgOiBuYW1lID09PSBcInN0eWxlXCIgPyBFbGVtZW50VHlwZS5TdHlsZSA6IEVsZW1lbnRUeXBlLlRhZyxcblx0XHRuYW1lOiBuYW1lLFxuXHRcdGF0dHJpYnM6IGF0dHJpYnMsXG5cdFx0Y2hpbGRyZW46IFtdXG5cdH07XG5cblx0dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTtcblxuXHR0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpO1xufTtcblxuRG9tSGFuZGxlci5wcm90b3R5cGUub250ZXh0ID0gZnVuY3Rpb24oZGF0YSl7XG5cdC8vdGhlIGlnbm9yZVdoaXRlc3BhY2UgaXMgb2ZmaWNpYWxseSBkcm9wcGVkLCBidXQgZm9yIG5vdyxcblx0Ly9pdCdzIGFuIGFsaWFzIGZvciBub3JtYWxpemVXaGl0ZXNwYWNlXG5cdHZhciBub3JtYWxpemUgPSB0aGlzLl9vcHRpb25zLm5vcm1hbGl6ZVdoaXRlc3BhY2UgfHwgdGhpcy5fb3B0aW9ucy5pZ25vcmVXaGl0ZXNwYWNlO1xuXG5cdHZhciBsYXN0VGFnO1xuXG5cdGlmKCF0aGlzLl90YWdTdGFjay5sZW5ndGggJiYgdGhpcy5kb20ubGVuZ3RoICYmIChsYXN0VGFnID0gdGhpcy5kb21bdGhpcy5kb20ubGVuZ3RoLTFdKS50eXBlID09PSBFbGVtZW50VHlwZS5UZXh0KXtcblx0XHRpZihub3JtYWxpemUpe1xuXHRcdFx0bGFzdFRhZy5kYXRhID0gKGxhc3RUYWcuZGF0YSArIGRhdGEpLnJlcGxhY2UocmVfd2hpdGVzcGFjZSwgXCIgXCIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRsYXN0VGFnLmRhdGEgKz0gZGF0YTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0aWYoXG5cdFx0XHR0aGlzLl90YWdTdGFjay5sZW5ndGggJiZcblx0XHRcdChsYXN0VGFnID0gdGhpcy5fdGFnU3RhY2tbdGhpcy5fdGFnU3RhY2subGVuZ3RoIC0gMV0pICYmXG5cdFx0XHQobGFzdFRhZyA9IGxhc3RUYWcuY2hpbGRyZW5bbGFzdFRhZy5jaGlsZHJlbi5sZW5ndGggLSAxXSkgJiZcblx0XHRcdGxhc3RUYWcudHlwZSA9PT0gRWxlbWVudFR5cGUuVGV4dFxuXHRcdCl7XG5cdFx0XHRpZihub3JtYWxpemUpe1xuXHRcdFx0XHRsYXN0VGFnLmRhdGEgPSAobGFzdFRhZy5kYXRhICsgZGF0YSkucmVwbGFjZShyZV93aGl0ZXNwYWNlLCBcIiBcIik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsYXN0VGFnLmRhdGEgKz0gZGF0YTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYobm9ybWFsaXplKXtcblx0XHRcdFx0ZGF0YSA9IGRhdGEucmVwbGFjZShyZV93aGl0ZXNwYWNlLCBcIiBcIik7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuX2FkZERvbUVsZW1lbnQoe1xuXHRcdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0XHR0eXBlOiBFbGVtZW50VHlwZS5UZXh0XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9uY29tbWVudCA9IGZ1bmN0aW9uKGRhdGEpe1xuXHR2YXIgbGFzdFRhZyA9IHRoaXMuX3RhZ1N0YWNrW3RoaXMuX3RhZ1N0YWNrLmxlbmd0aCAtIDFdO1xuXG5cdGlmKGxhc3RUYWcgJiYgbGFzdFRhZy50eXBlID09PSBFbGVtZW50VHlwZS5Db21tZW50KXtcblx0XHRsYXN0VGFnLmRhdGEgKz0gZGF0YTtcblx0XHRyZXR1cm47XG5cdH1cblxuXHR2YXIgZWxlbWVudCA9IHtcblx0XHRkYXRhOiBkYXRhLFxuXHRcdHR5cGU6IEVsZW1lbnRUeXBlLkNvbW1lbnRcblx0fTtcblxuXHR0aGlzLl9hZGREb21FbGVtZW50KGVsZW1lbnQpO1xuXHR0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpO1xufTtcblxuRG9tSGFuZGxlci5wcm90b3R5cGUub25jZGF0YXN0YXJ0ID0gZnVuY3Rpb24oKXtcblx0dmFyIGVsZW1lbnQgPSB7XG5cdFx0Y2hpbGRyZW46IFt7XG5cdFx0XHRkYXRhOiBcIlwiLFxuXHRcdFx0dHlwZTogRWxlbWVudFR5cGUuVGV4dFxuXHRcdH1dLFxuXHRcdHR5cGU6IEVsZW1lbnRUeXBlLkNEQVRBXG5cdH07XG5cblx0dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTtcblx0dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KTtcbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9uY29tbWVudGVuZCA9IERvbUhhbmRsZXIucHJvdG90eXBlLm9uY2RhdGFlbmQgPSBmdW5jdGlvbigpe1xuXHR0aGlzLl90YWdTdGFjay5wb3AoKTtcbn07XG5cbkRvbUhhbmRsZXIucHJvdG90eXBlLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uID0gZnVuY3Rpb24obmFtZSwgZGF0YSl7XG5cdHRoaXMuX2FkZERvbUVsZW1lbnQoe1xuXHRcdG5hbWU6IG5hbWUsXG5cdFx0ZGF0YTogZGF0YSxcblx0XHR0eXBlOiBFbGVtZW50VHlwZS5EaXJlY3RpdmVcblx0fSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IERvbUhhbmRsZXI7XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbWhhbmRsZXIvbGliL2VsZW1lbnQuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbWhhbmRsZXIvbGliL2VsZW1lbnQuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuLy8gRE9NLUxldmVsLTEtY29tcGxpYW50IHN0cnVjdHVyZVxudmFyIE5vZGVQcm90b3R5cGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL25vZGUgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9taGFuZGxlci9saWIvbm9kZS5qc1wiKTtcbnZhciBFbGVtZW50UHJvdG90eXBlID0gbW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuY3JlYXRlKE5vZGVQcm90b3R5cGUpO1xuXG52YXIgZG9tTHZsMSA9IHtcblx0dGFnTmFtZTogXCJuYW1lXCJcbn07XG5cbk9iamVjdC5rZXlzKGRvbUx2bDEpLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG5cdHZhciBzaG9ydGhhbmQgPSBkb21MdmwxW2tleV07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFbGVtZW50UHJvdG90eXBlLCBrZXksIHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRoaXNbc2hvcnRoYW5kXSB8fCBudWxsO1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbih2YWwpIHtcblx0XHRcdHRoaXNbc2hvcnRoYW5kXSA9IHZhbDtcblx0XHRcdHJldHVybiB2YWw7XG5cdFx0fVxuXHR9KTtcbn0pO1xuXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb21oYW5kbGVyL2xpYi9ub2RlLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb21oYW5kbGVyL2xpYi9ub2RlLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbi8vIFRoaXMgb2JqZWN0IHdpbGwgYmUgdXNlZCBhcyB0aGUgcHJvdG90eXBlIGZvciBOb2RlcyB3aGVuIGNyZWF0aW5nIGFcbi8vIERPTS1MZXZlbC0xLWNvbXBsaWFudCBzdHJ1Y3R1cmUuXG52YXIgTm9kZVByb3RvdHlwZSA9IG1vZHVsZS5leHBvcnRzID0ge1xuXHRnZXQgZmlyc3RDaGlsZCgpIHtcblx0XHR2YXIgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuO1xuXHRcdHJldHVybiBjaGlsZHJlbiAmJiBjaGlsZHJlblswXSB8fCBudWxsO1xuXHR9LFxuXHRnZXQgbGFzdENoaWxkKCkge1xuXHRcdHZhciBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG5cdFx0cmV0dXJuIGNoaWxkcmVuICYmIGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdIHx8IG51bGw7XG5cdH0sXG5cdGdldCBub2RlVHlwZSgpIHtcblx0XHRyZXR1cm4gbm9kZVR5cGVzW3RoaXMudHlwZV0gfHwgbm9kZVR5cGVzLmVsZW1lbnQ7XG5cdH1cbn07XG5cbnZhciBkb21MdmwxID0ge1xuXHR0YWdOYW1lOiBcIm5hbWVcIixcblx0Y2hpbGROb2RlczogXCJjaGlsZHJlblwiLFxuXHRwYXJlbnROb2RlOiBcInBhcmVudFwiLFxuXHRwcmV2aW91c1NpYmxpbmc6IFwicHJldlwiLFxuXHRuZXh0U2libGluZzogXCJuZXh0XCIsXG5cdG5vZGVWYWx1ZTogXCJkYXRhXCJcbn07XG5cbnZhciBub2RlVHlwZXMgPSB7XG5cdGVsZW1lbnQ6IDEsXG5cdHRleHQ6IDMsXG5cdGNkYXRhOiA0LFxuXHRjb21tZW50OiA4XG59O1xuXG5PYmplY3Qua2V5cyhkb21MdmwxKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuXHR2YXIgc2hvcnRoYW5kID0gZG9tTHZsMVtrZXldO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoTm9kZVByb3RvdHlwZSwga2V5LCB7XG5cdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzW3Nob3J0aGFuZF0gfHwgbnVsbDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24odmFsKSB7XG5cdFx0XHR0aGlzW3Nob3J0aGFuZF0gPSB2YWw7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0fSk7XG59KTtcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9pbmRleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxudmFyIERvbVV0aWxzID0gbW9kdWxlLmV4cG9ydHM7XG5cbltcblx0X193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9saWIvc3RyaW5naWZ5ICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL2xpYi9zdHJpbmdpZnkuanNcIiksXG5cdF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbGliL3RyYXZlcnNhbCAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9saWIvdHJhdmVyc2FsLmpzXCIpLFxuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9tYW5pcHVsYXRpb24gKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL21hbmlwdWxhdGlvbi5qc1wiKSxcblx0X193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9saWIvcXVlcnlpbmcgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL3F1ZXJ5aW5nLmpzXCIpLFxuXHRfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2xpYi9sZWdhY3kgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL2xlZ2FjeS5qc1wiKSxcblx0X193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9saWIvaGVscGVycyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9saWIvaGVscGVycy5qc1wiKVxuXS5mb3JFYWNoKGZ1bmN0aW9uKGV4dCl7XG5cdE9iamVjdC5rZXlzKGV4dCkuZm9yRWFjaChmdW5jdGlvbihrZXkpe1xuXHRcdERvbVV0aWxzW2tleV0gPSBleHRba2V5XS5iaW5kKERvbVV0aWxzKTtcblx0fSk7XG59KTtcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL2hlbHBlcnMuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9saWIvaGVscGVycy5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuLy8gcmVtb3ZlU3Vic2V0c1xuLy8gR2l2ZW4gYW4gYXJyYXkgb2Ygbm9kZXMsIHJlbW92ZSBhbnkgbWVtYmVyIHRoYXQgaXMgY29udGFpbmVkIGJ5IGFub3RoZXIuXG5leHBvcnRzLnJlbW92ZVN1YnNldHMgPSBmdW5jdGlvbihub2Rlcykge1xuXHR2YXIgaWR4ID0gbm9kZXMubGVuZ3RoLCBub2RlLCBhbmNlc3RvciwgcmVwbGFjZTtcblxuXHQvLyBDaGVjayBpZiBlYWNoIG5vZGUgKG9yIG9uZSBvZiBpdHMgYW5jZXN0b3JzKSBpcyBhbHJlYWR5IGNvbnRhaW5lZCBpbiB0aGVcblx0Ly8gYXJyYXkuXG5cdHdoaWxlICgtLWlkeCA+IC0xKSB7XG5cdFx0bm9kZSA9IGFuY2VzdG9yID0gbm9kZXNbaWR4XTtcblxuXHRcdC8vIFRlbXBvcmFyaWx5IHJlbW92ZSB0aGUgbm9kZSB1bmRlciBjb25zaWRlcmF0aW9uXG5cdFx0bm9kZXNbaWR4XSA9IG51bGw7XG5cdFx0cmVwbGFjZSA9IHRydWU7XG5cblx0XHR3aGlsZSAoYW5jZXN0b3IpIHtcblx0XHRcdGlmIChub2Rlcy5pbmRleE9mKGFuY2VzdG9yKSA+IC0xKSB7XG5cdFx0XHRcdHJlcGxhY2UgPSBmYWxzZTtcblx0XHRcdFx0bm9kZXMuc3BsaWNlKGlkeCwgMSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0YW5jZXN0b3IgPSBhbmNlc3Rvci5wYXJlbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlIG5vZGUgaGFzIGJlZW4gZm91bmQgdG8gYmUgdW5pcXVlLCByZS1pbnNlcnQgaXQuXG5cdFx0aWYgKHJlcGxhY2UpIHtcblx0XHRcdG5vZGVzW2lkeF0gPSBub2RlO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBub2Rlcztcbn07XG5cbi8vIFNvdXJjZTogaHR0cDovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2RvbS1ub2RlLWNvbXBhcmVkb2N1bWVudHBvc2l0aW9uXG52YXIgUE9TSVRJT04gPSB7XG5cdERJU0NPTk5FQ1RFRDogMSxcblx0UFJFQ0VESU5HOiAyLFxuXHRGT0xMT1dJTkc6IDQsXG5cdENPTlRBSU5TOiA4LFxuXHRDT05UQUlORURfQlk6IDE2XG59O1xuXG4vLyBDb21wYXJlIHRoZSBwb3NpdGlvbiBvZiBvbmUgbm9kZSBhZ2FpbnN0IGFub3RoZXIgbm9kZSBpbiBhbnkgb3RoZXIgZG9jdW1lbnQuXG4vLyBUaGUgcmV0dXJuIHZhbHVlIGlzIGEgYml0bWFzayB3aXRoIHRoZSBmb2xsb3dpbmcgdmFsdWVzOlxuLy9cbi8vIGRvY3VtZW50IG9yZGVyOlxuLy8gPiBUaGVyZSBpcyBhbiBvcmRlcmluZywgZG9jdW1lbnQgb3JkZXIsIGRlZmluZWQgb24gYWxsIHRoZSBub2RlcyBpbiB0aGVcbi8vID4gZG9jdW1lbnQgY29ycmVzcG9uZGluZyB0byB0aGUgb3JkZXIgaW4gd2hpY2ggdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGVcbi8vID4gWE1MIHJlcHJlc2VudGF0aW9uIG9mIGVhY2ggbm9kZSBvY2N1cnMgaW4gdGhlIFhNTCByZXByZXNlbnRhdGlvbiBvZiB0aGVcbi8vID4gZG9jdW1lbnQgYWZ0ZXIgZXhwYW5zaW9uIG9mIGdlbmVyYWwgZW50aXRpZXMuIFRodXMsIHRoZSBkb2N1bWVudCBlbGVtZW50XG4vLyA+IG5vZGUgd2lsbCBiZSB0aGUgZmlyc3Qgbm9kZS4gRWxlbWVudCBub2RlcyBvY2N1ciBiZWZvcmUgdGhlaXIgY2hpbGRyZW4uXG4vLyA+IFRodXMsIGRvY3VtZW50IG9yZGVyIG9yZGVycyBlbGVtZW50IG5vZGVzIGluIG9yZGVyIG9mIHRoZSBvY2N1cnJlbmNlIG9mXG4vLyA+IHRoZWlyIHN0YXJ0LXRhZyBpbiB0aGUgWE1MIChhZnRlciBleHBhbnNpb24gb2YgZW50aXRpZXMpLiBUaGUgYXR0cmlidXRlXG4vLyA+IG5vZGVzIG9mIGFuIGVsZW1lbnQgb2NjdXIgYWZ0ZXIgdGhlIGVsZW1lbnQgYW5kIGJlZm9yZSBpdHMgY2hpbGRyZW4uIFRoZVxuLy8gPiByZWxhdGl2ZSBvcmRlciBvZiBhdHRyaWJ1dGUgbm9kZXMgaXMgaW1wbGVtZW50YXRpb24tZGVwZW5kZW50Li9cbi8vIFNvdXJjZTpcbi8vIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUNvcmUvZ2xvc3NhcnkuaHRtbCNkdC1kb2N1bWVudC1vcmRlclxuLy9cbi8vIEBhcmd1bWVudCB7Tm9kZX0gbm9kYUEgVGhlIGZpcnN0IG5vZGUgdG8gdXNlIGluIHRoZSBjb21wYXJpc29uXG4vLyBAYXJndW1lbnQge05vZGV9IG5vZGVCIFRoZSBzZWNvbmQgbm9kZSB0byB1c2UgaW4gdGhlIGNvbXBhcmlzb25cbi8vXG4vLyBAcmV0dXJuIHtOdW1iZXJ9IEEgYml0bWFzayBkZXNjcmliaW5nIHRoZSBpbnB1dCBub2RlcycgcmVsYXRpdmUgcG9zaXRpb24uXG4vLyAgICAgICAgIFNlZSBodHRwOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jZG9tLW5vZGUtY29tcGFyZWRvY3VtZW50cG9zaXRpb24gZm9yXG4vLyAgICAgICAgIGEgZGVzY3JpcHRpb24gb2YgdGhlc2UgdmFsdWVzLlxudmFyIGNvbXBhcmVQb3MgPSBleHBvcnRzLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uID0gZnVuY3Rpb24obm9kZUEsIG5vZGVCKSB7XG5cdHZhciBhUGFyZW50cyA9IFtdO1xuXHR2YXIgYlBhcmVudHMgPSBbXTtcblx0dmFyIGN1cnJlbnQsIHNoYXJlZFBhcmVudCwgc2libGluZ3MsIGFTaWJsaW5nLCBiU2libGluZywgaWR4O1xuXG5cdGlmIChub2RlQSA9PT0gbm9kZUIpIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdGN1cnJlbnQgPSBub2RlQTtcblx0d2hpbGUgKGN1cnJlbnQpIHtcblx0XHRhUGFyZW50cy51bnNoaWZ0KGN1cnJlbnQpO1xuXHRcdGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDtcblx0fVxuXHRjdXJyZW50ID0gbm9kZUI7XG5cdHdoaWxlIChjdXJyZW50KSB7XG5cdFx0YlBhcmVudHMudW5zaGlmdChjdXJyZW50KTtcblx0XHRjdXJyZW50ID0gY3VycmVudC5wYXJlbnQ7XG5cdH1cblxuXHRpZHggPSAwO1xuXHR3aGlsZSAoYVBhcmVudHNbaWR4XSA9PT0gYlBhcmVudHNbaWR4XSkge1xuXHRcdGlkeCsrO1xuXHR9XG5cblx0aWYgKGlkeCA9PT0gMCkge1xuXHRcdHJldHVybiBQT1NJVElPTi5ESVNDT05ORUNURUQ7XG5cdH1cblxuXHRzaGFyZWRQYXJlbnQgPSBhUGFyZW50c1tpZHggLSAxXTtcblx0c2libGluZ3MgPSBzaGFyZWRQYXJlbnQuY2hpbGRyZW47XG5cdGFTaWJsaW5nID0gYVBhcmVudHNbaWR4XTtcblx0YlNpYmxpbmcgPSBiUGFyZW50c1tpZHhdO1xuXG5cdGlmIChzaWJsaW5ncy5pbmRleE9mKGFTaWJsaW5nKSA+IHNpYmxpbmdzLmluZGV4T2YoYlNpYmxpbmcpKSB7XG5cdFx0aWYgKHNoYXJlZFBhcmVudCA9PT0gbm9kZUIpIHtcblx0XHRcdHJldHVybiBQT1NJVElPTi5GT0xMT1dJTkcgfCBQT1NJVElPTi5DT05UQUlORURfQlk7XG5cdFx0fVxuXHRcdHJldHVybiBQT1NJVElPTi5GT0xMT1dJTkc7XG5cdH0gZWxzZSB7XG5cdFx0aWYgKHNoYXJlZFBhcmVudCA9PT0gbm9kZUEpIHtcblx0XHRcdHJldHVybiBQT1NJVElPTi5QUkVDRURJTkcgfCBQT1NJVElPTi5DT05UQUlOUztcblx0XHR9XG5cdFx0cmV0dXJuIFBPU0lUSU9OLlBSRUNFRElORztcblx0fVxufTtcblxuLy8gU29ydCBhbiBhcnJheSBvZiBub2RlcyBiYXNlZCBvbiB0aGVpciByZWxhdGl2ZSBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQgYW5kXG4vLyByZW1vdmUgYW55IGR1cGxpY2F0ZSBub2Rlcy4gSWYgdGhlIGFycmF5IGNvbnRhaW5zIG5vZGVzIHRoYXQgZG8gbm90IGJlbG9uZ1xuLy8gdG8gdGhlIHNhbWUgZG9jdW1lbnQsIHNvcnQgb3JkZXIgaXMgdW5zcGVjaWZpZWQuXG4vL1xuLy8gQGFyZ3VtZW50IHtBcnJheX0gbm9kZXMgQXJyYXkgb2YgRE9NIG5vZGVzXG4vL1xuLy8gQHJldHVybnMge0FycmF5fSBjb2xsZWN0aW9uIG9mIHVuaXF1ZSBub2Rlcywgc29ydGVkIGluIGRvY3VtZW50IG9yZGVyXG5leHBvcnRzLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbihub2Rlcykge1xuXHR2YXIgaWR4ID0gbm9kZXMubGVuZ3RoLCBub2RlLCBwb3NpdGlvbjtcblxuXHRub2RlcyA9IG5vZGVzLnNsaWNlKCk7XG5cblx0d2hpbGUgKC0taWR4ID4gLTEpIHtcblx0XHRub2RlID0gbm9kZXNbaWR4XTtcblx0XHRwb3NpdGlvbiA9IG5vZGVzLmluZGV4T2Yobm9kZSk7XG5cdFx0aWYgKHBvc2l0aW9uID4gLTEgJiYgcG9zaXRpb24gPCBpZHgpIHtcblx0XHRcdG5vZGVzLnNwbGljZShpZHgsIDEpO1xuXHRcdH1cblx0fVxuXHRub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcblx0XHR2YXIgcmVsYXRpdmUgPSBjb21wYXJlUG9zKGEsIGIpO1xuXHRcdGlmIChyZWxhdGl2ZSAmIFBPU0lUSU9OLlBSRUNFRElORykge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH0gZWxzZSBpZiAocmVsYXRpdmUgJiBQT1NJVElPTi5GT0xMT1dJTkcpIHtcblx0XHRcdHJldHVybiAxO1xuXHRcdH1cblx0XHRyZXR1cm4gMDtcblx0fSk7XG5cblx0cmV0dXJuIG5vZGVzO1xufTtcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL2xlZ2FjeS5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL2xlZ2FjeS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG52YXIgRWxlbWVudFR5cGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBkb21lbGVtZW50dHlwZSAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb21lbGVtZW50dHlwZS9pbmRleC5qc1wiKTtcbnZhciBpc1RhZyA9IGV4cG9ydHMuaXNUYWcgPSBFbGVtZW50VHlwZS5pc1RhZztcblxuZXhwb3J0cy50ZXN0RWxlbWVudCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGVsZW1lbnQpe1xuXHRmb3IodmFyIGtleSBpbiBvcHRpb25zKXtcblx0XHRpZighb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShrZXkpKTtcblx0XHRlbHNlIGlmKGtleSA9PT0gXCJ0YWdfbmFtZVwiKXtcblx0XHRcdGlmKCFpc1RhZyhlbGVtZW50KSB8fCAhb3B0aW9ucy50YWdfbmFtZShlbGVtZW50Lm5hbWUpKXtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZihrZXkgPT09IFwidGFnX3R5cGVcIil7XG5cdFx0XHRpZighb3B0aW9ucy50YWdfdHlwZShlbGVtZW50LnR5cGUpKSByZXR1cm4gZmFsc2U7XG5cdFx0fSBlbHNlIGlmKGtleSA9PT0gXCJ0YWdfY29udGFpbnNcIil7XG5cdFx0XHRpZihpc1RhZyhlbGVtZW50KSB8fCAhb3B0aW9ucy50YWdfY29udGFpbnMoZWxlbWVudC5kYXRhKSl7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYoIWVsZW1lbnQuYXR0cmlicyB8fCAhb3B0aW9uc1trZXldKGVsZW1lbnQuYXR0cmlic1trZXldKSl7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdHJldHVybiB0cnVlO1xufTtcblxudmFyIENoZWNrcyA9IHtcblx0dGFnX25hbWU6IGZ1bmN0aW9uKG5hbWUpe1xuXHRcdGlmKHR5cGVvZiBuYW1lID09PSBcImZ1bmN0aW9uXCIpe1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKGVsZW0peyByZXR1cm4gaXNUYWcoZWxlbSkgJiYgbmFtZShlbGVtLm5hbWUpOyB9O1xuXHRcdH0gZWxzZSBpZihuYW1lID09PSBcIipcIil7XG5cdFx0XHRyZXR1cm4gaXNUYWc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuIGlzVGFnKGVsZW0pICYmIGVsZW0ubmFtZSA9PT0gbmFtZTsgfTtcblx0XHR9XG5cdH0sXG5cdHRhZ190eXBlOiBmdW5jdGlvbih0eXBlKXtcblx0XHRpZih0eXBlb2YgdHlwZSA9PT0gXCJmdW5jdGlvblwiKXtcblx0XHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuIHR5cGUoZWxlbS50eXBlKTsgfTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKGVsZW0peyByZXR1cm4gZWxlbS50eXBlID09PSB0eXBlOyB9O1xuXHRcdH1cblx0fSxcblx0dGFnX2NvbnRhaW5zOiBmdW5jdGlvbihkYXRhKXtcblx0XHRpZih0eXBlb2YgZGF0YSA9PT0gXCJmdW5jdGlvblwiKXtcblx0XHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuICFpc1RhZyhlbGVtKSAmJiBkYXRhKGVsZW0uZGF0YSk7IH07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuICFpc1RhZyhlbGVtKSAmJiBlbGVtLmRhdGEgPT09IGRhdGE7IH07XG5cdFx0fVxuXHR9XG59O1xuXG5mdW5jdGlvbiBnZXRBdHRyaWJDaGVjayhhdHRyaWIsIHZhbHVlKXtcblx0aWYodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpe1xuXHRcdHJldHVybiBmdW5jdGlvbihlbGVtKXsgcmV0dXJuIGVsZW0uYXR0cmlicyAmJiB2YWx1ZShlbGVtLmF0dHJpYnNbYXR0cmliXSk7IH07XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGVsZW0peyByZXR1cm4gZWxlbS5hdHRyaWJzICYmIGVsZW0uYXR0cmlic1thdHRyaWJdID09PSB2YWx1ZTsgfTtcblx0fVxufVxuXG5mdW5jdGlvbiBjb21iaW5lRnVuY3MoYSwgYil7XG5cdHJldHVybiBmdW5jdGlvbihlbGVtKXtcblx0XHRyZXR1cm4gYShlbGVtKSB8fCBiKGVsZW0pO1xuXHR9O1xufVxuXG5leHBvcnRzLmdldEVsZW1lbnRzID0gZnVuY3Rpb24ob3B0aW9ucywgZWxlbWVudCwgcmVjdXJzZSwgbGltaXQpe1xuXHR2YXIgZnVuY3MgPSBPYmplY3Qua2V5cyhvcHRpb25zKS5tYXAoZnVuY3Rpb24oa2V5KXtcblx0XHR2YXIgdmFsdWUgPSBvcHRpb25zW2tleV07XG5cdFx0cmV0dXJuIGtleSBpbiBDaGVja3MgPyBDaGVja3Nba2V5XSh2YWx1ZSkgOiBnZXRBdHRyaWJDaGVjayhrZXksIHZhbHVlKTtcblx0fSk7XG5cblx0cmV0dXJuIGZ1bmNzLmxlbmd0aCA9PT0gMCA/IFtdIDogdGhpcy5maWx0ZXIoXG5cdFx0ZnVuY3MucmVkdWNlKGNvbWJpbmVGdW5jcyksXG5cdFx0ZWxlbWVudCwgcmVjdXJzZSwgbGltaXRcblx0KTtcbn07XG5cbmV4cG9ydHMuZ2V0RWxlbWVudEJ5SWQgPSBmdW5jdGlvbihpZCwgZWxlbWVudCwgcmVjdXJzZSl7XG5cdGlmKCFBcnJheS5pc0FycmF5KGVsZW1lbnQpKSBlbGVtZW50ID0gW2VsZW1lbnRdO1xuXHRyZXR1cm4gdGhpcy5maW5kT25lKGdldEF0dHJpYkNoZWNrKFwiaWRcIiwgaWQpLCBlbGVtZW50LCByZWN1cnNlICE9PSBmYWxzZSk7XG59O1xuXG5leHBvcnRzLmdldEVsZW1lbnRzQnlUYWdOYW1lID0gZnVuY3Rpb24obmFtZSwgZWxlbWVudCwgcmVjdXJzZSwgbGltaXQpe1xuXHRyZXR1cm4gdGhpcy5maWx0ZXIoQ2hlY2tzLnRhZ19uYW1lKG5hbWUpLCBlbGVtZW50LCByZWN1cnNlLCBsaW1pdCk7XG59O1xuXG5leHBvcnRzLmdldEVsZW1lbnRzQnlUYWdUeXBlID0gZnVuY3Rpb24odHlwZSwgZWxlbWVudCwgcmVjdXJzZSwgbGltaXQpe1xuXHRyZXR1cm4gdGhpcy5maWx0ZXIoQ2hlY2tzLnRhZ190eXBlKHR5cGUpLCBlbGVtZW50LCByZWN1cnNlLCBsaW1pdCk7XG59O1xuXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9saWIvbWFuaXB1bGF0aW9uLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9saWIvbWFuaXB1bGF0aW9uLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmV4cG9ydHMucmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKGVsZW0pe1xuXHRpZihlbGVtLnByZXYpIGVsZW0ucHJldi5uZXh0ID0gZWxlbS5uZXh0O1xuXHRpZihlbGVtLm5leHQpIGVsZW0ubmV4dC5wcmV2ID0gZWxlbS5wcmV2O1xuXG5cdGlmKGVsZW0ucGFyZW50KXtcblx0XHR2YXIgY2hpbGRzID0gZWxlbS5wYXJlbnQuY2hpbGRyZW47XG5cdFx0Y2hpbGRzLnNwbGljZShjaGlsZHMubGFzdEluZGV4T2YoZWxlbSksIDEpO1xuXHR9XG59O1xuXG5leHBvcnRzLnJlcGxhY2VFbGVtZW50ID0gZnVuY3Rpb24oZWxlbSwgcmVwbGFjZW1lbnQpe1xuXHR2YXIgcHJldiA9IHJlcGxhY2VtZW50LnByZXYgPSBlbGVtLnByZXY7XG5cdGlmKHByZXYpe1xuXHRcdHByZXYubmV4dCA9IHJlcGxhY2VtZW50O1xuXHR9XG5cblx0dmFyIG5leHQgPSByZXBsYWNlbWVudC5uZXh0ID0gZWxlbS5uZXh0O1xuXHRpZihuZXh0KXtcblx0XHRuZXh0LnByZXYgPSByZXBsYWNlbWVudDtcblx0fVxuXG5cdHZhciBwYXJlbnQgPSByZXBsYWNlbWVudC5wYXJlbnQgPSBlbGVtLnBhcmVudDtcblx0aWYocGFyZW50KXtcblx0XHR2YXIgY2hpbGRzID0gcGFyZW50LmNoaWxkcmVuO1xuXHRcdGNoaWxkc1tjaGlsZHMubGFzdEluZGV4T2YoZWxlbSldID0gcmVwbGFjZW1lbnQ7XG5cdH1cbn07XG5cbmV4cG9ydHMuYXBwZW5kQ2hpbGQgPSBmdW5jdGlvbihlbGVtLCBjaGlsZCl7XG5cdGNoaWxkLnBhcmVudCA9IGVsZW07XG5cblx0aWYoZWxlbS5jaGlsZHJlbi5wdXNoKGNoaWxkKSAhPT0gMSl7XG5cdFx0dmFyIHNpYmxpbmcgPSBlbGVtLmNoaWxkcmVuW2VsZW0uY2hpbGRyZW4ubGVuZ3RoIC0gMl07XG5cdFx0c2libGluZy5uZXh0ID0gY2hpbGQ7XG5cdFx0Y2hpbGQucHJldiA9IHNpYmxpbmc7XG5cdFx0Y2hpbGQubmV4dCA9IG51bGw7XG5cdH1cbn07XG5cbmV4cG9ydHMuYXBwZW5kID0gZnVuY3Rpb24oZWxlbSwgbmV4dCl7XG5cdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudCxcblx0XHRjdXJyTmV4dCA9IGVsZW0ubmV4dDtcblxuXHRuZXh0Lm5leHQgPSBjdXJyTmV4dDtcblx0bmV4dC5wcmV2ID0gZWxlbTtcblx0ZWxlbS5uZXh0ID0gbmV4dDtcblx0bmV4dC5wYXJlbnQgPSBwYXJlbnQ7XG5cblx0aWYoY3Vyck5leHQpe1xuXHRcdGN1cnJOZXh0LnByZXYgPSBuZXh0O1xuXHRcdGlmKHBhcmVudCl7XG5cdFx0XHR2YXIgY2hpbGRzID0gcGFyZW50LmNoaWxkcmVuO1xuXHRcdFx0Y2hpbGRzLnNwbGljZShjaGlsZHMubGFzdEluZGV4T2YoY3Vyck5leHQpLCAwLCBuZXh0KTtcblx0XHR9XG5cdH0gZWxzZSBpZihwYXJlbnQpe1xuXHRcdHBhcmVudC5jaGlsZHJlbi5wdXNoKG5leHQpO1xuXHR9XG59O1xuXG5leHBvcnRzLnByZXBlbmQgPSBmdW5jdGlvbihlbGVtLCBwcmV2KXtcblx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50O1xuXHRpZihwYXJlbnQpe1xuXHRcdHZhciBjaGlsZHMgPSBwYXJlbnQuY2hpbGRyZW47XG5cdFx0Y2hpbGRzLnNwbGljZShjaGlsZHMubGFzdEluZGV4T2YoZWxlbSksIDAsIHByZXYpO1xuXHR9XG5cblx0aWYoZWxlbS5wcmV2KXtcblx0XHRlbGVtLnByZXYubmV4dCA9IHByZXY7XG5cdH1cblx0XG5cdHByZXYucGFyZW50ID0gcGFyZW50O1xuXHRwcmV2LnByZXYgPSBlbGVtLnByZXY7XG5cdHByZXYubmV4dCA9IGVsZW07XG5cdGVsZW0ucHJldiA9IHByZXY7XG59O1xuXG5cblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL3F1ZXJ5aW5nLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL2xpYi9xdWVyeWluZy5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbnZhciBpc1RhZyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGRvbWVsZW1lbnR0eXBlICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbWVsZW1lbnR0eXBlL2luZGV4LmpzXCIpLmlzVGFnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0ZmlsdGVyOiBmaWx0ZXIsXG5cdGZpbmQ6IGZpbmQsXG5cdGZpbmRPbmVDaGlsZDogZmluZE9uZUNoaWxkLFxuXHRmaW5kT25lOiBmaW5kT25lLFxuXHRleGlzdHNPbmU6IGV4aXN0c09uZSxcblx0ZmluZEFsbDogZmluZEFsbFxufTtcblxuZnVuY3Rpb24gZmlsdGVyKHRlc3QsIGVsZW1lbnQsIHJlY3Vyc2UsIGxpbWl0KXtcblx0aWYoIUFycmF5LmlzQXJyYXkoZWxlbWVudCkpIGVsZW1lbnQgPSBbZWxlbWVudF07XG5cblx0aWYodHlwZW9mIGxpbWl0ICE9PSBcIm51bWJlclwiIHx8ICFpc0Zpbml0ZShsaW1pdCkpe1xuXHRcdGxpbWl0ID0gSW5maW5pdHk7XG5cdH1cblx0cmV0dXJuIGZpbmQodGVzdCwgZWxlbWVudCwgcmVjdXJzZSAhPT0gZmFsc2UsIGxpbWl0KTtcbn1cblxuZnVuY3Rpb24gZmluZCh0ZXN0LCBlbGVtcywgcmVjdXJzZSwgbGltaXQpe1xuXHR2YXIgcmVzdWx0ID0gW10sIGNoaWxkcztcblxuXHRmb3IodmFyIGkgPSAwLCBqID0gZWxlbXMubGVuZ3RoOyBpIDwgajsgaSsrKXtcblx0XHRpZih0ZXN0KGVsZW1zW2ldKSl7XG5cdFx0XHRyZXN1bHQucHVzaChlbGVtc1tpXSk7XG5cdFx0XHRpZigtLWxpbWl0IDw9IDApIGJyZWFrO1xuXHRcdH1cblxuXHRcdGNoaWxkcyA9IGVsZW1zW2ldLmNoaWxkcmVuO1xuXHRcdGlmKHJlY3Vyc2UgJiYgY2hpbGRzICYmIGNoaWxkcy5sZW5ndGggPiAwKXtcblx0XHRcdGNoaWxkcyA9IGZpbmQodGVzdCwgY2hpbGRzLCByZWN1cnNlLCBsaW1pdCk7XG5cdFx0XHRyZXN1bHQgPSByZXN1bHQuY29uY2F0KGNoaWxkcyk7XG5cdFx0XHRsaW1pdCAtPSBjaGlsZHMubGVuZ3RoO1xuXHRcdFx0aWYobGltaXQgPD0gMCkgYnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZmluZE9uZUNoaWxkKHRlc3QsIGVsZW1zKXtcblx0Zm9yKHZhciBpID0gMCwgbCA9IGVsZW1zLmxlbmd0aDsgaSA8IGw7IGkrKyl7XG5cdFx0aWYodGVzdChlbGVtc1tpXSkpIHJldHVybiBlbGVtc1tpXTtcblx0fVxuXG5cdHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaW5kT25lKHRlc3QsIGVsZW1zKXtcblx0dmFyIGVsZW0gPSBudWxsO1xuXG5cdGZvcih2YXIgaSA9IDAsIGwgPSBlbGVtcy5sZW5ndGg7IGkgPCBsICYmICFlbGVtOyBpKyspe1xuXHRcdGlmKCFpc1RhZyhlbGVtc1tpXSkpe1xuXHRcdFx0Y29udGludWU7XG5cdFx0fSBlbHNlIGlmKHRlc3QoZWxlbXNbaV0pKXtcblx0XHRcdGVsZW0gPSBlbGVtc1tpXTtcblx0XHR9IGVsc2UgaWYoZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoID4gMCl7XG5cdFx0XHRlbGVtID0gZmluZE9uZSh0ZXN0LCBlbGVtc1tpXS5jaGlsZHJlbik7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmZ1bmN0aW9uIGV4aXN0c09uZSh0ZXN0LCBlbGVtcyl7XG5cdGZvcih2YXIgaSA9IDAsIGwgPSBlbGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspe1xuXHRcdGlmKFxuXHRcdFx0aXNUYWcoZWxlbXNbaV0pICYmIChcblx0XHRcdFx0dGVzdChlbGVtc1tpXSkgfHwgKFxuXHRcdFx0XHRcdGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aCA+IDAgJiZcblx0XHRcdFx0XHRleGlzdHNPbmUodGVzdCwgZWxlbXNbaV0uY2hpbGRyZW4pXG5cdFx0XHRcdClcblx0XHRcdClcblx0XHQpe1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBmaW5kQWxsKHRlc3QsIGVsZW1zKXtcblx0dmFyIHJlc3VsdCA9IFtdO1xuXHRmb3IodmFyIGkgPSAwLCBqID0gZWxlbXMubGVuZ3RoOyBpIDwgajsgaSsrKXtcblx0XHRpZighaXNUYWcoZWxlbXNbaV0pKSBjb250aW51ZTtcblx0XHRpZih0ZXN0KGVsZW1zW2ldKSkgcmVzdWx0LnB1c2goZWxlbXNbaV0pO1xuXG5cdFx0aWYoZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoID4gMCl7XG5cdFx0XHRyZXN1bHQgPSByZXN1bHQuY29uY2F0KGZpbmRBbGwodGVzdCwgZWxlbXNbaV0uY2hpbGRyZW4pKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn1cblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL3N0cmluZ2lmeS5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbGliL3N0cmluZ2lmeS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG52YXIgRWxlbWVudFR5cGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBkb21lbGVtZW50dHlwZSAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb21lbGVtZW50dHlwZS9pbmRleC5qc1wiKSxcbiAgICBnZXRPdXRlckhUTUwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBkb20tc2VyaWFsaXplciAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9ub2RlX21vZHVsZXMvZG9tLXNlcmlhbGl6ZXIvaW5kZXguanNcIiksXG4gICAgaXNUYWcgPSBFbGVtZW50VHlwZS5pc1RhZztcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGdldElubmVySFRNTDogZ2V0SW5uZXJIVE1MLFxuXHRnZXRPdXRlckhUTUw6IGdldE91dGVySFRNTCxcblx0Z2V0VGV4dDogZ2V0VGV4dFxufTtcblxuZnVuY3Rpb24gZ2V0SW5uZXJIVE1MKGVsZW0sIG9wdHMpe1xuXHRyZXR1cm4gZWxlbS5jaGlsZHJlbiA/IGVsZW0uY2hpbGRyZW4ubWFwKGZ1bmN0aW9uKGVsZW0pe1xuXHRcdHJldHVybiBnZXRPdXRlckhUTUwoZWxlbSwgb3B0cyk7XG5cdH0pLmpvaW4oXCJcIikgOiBcIlwiO1xufVxuXG5mdW5jdGlvbiBnZXRUZXh0KGVsZW0pe1xuXHRpZihBcnJheS5pc0FycmF5KGVsZW0pKSByZXR1cm4gZWxlbS5tYXAoZ2V0VGV4dCkuam9pbihcIlwiKTtcblx0aWYoaXNUYWcoZWxlbSkgfHwgZWxlbS50eXBlID09PSBFbGVtZW50VHlwZS5DREFUQSkgcmV0dXJuIGdldFRleHQoZWxlbS5jaGlsZHJlbik7XG5cdGlmKGVsZW0udHlwZSA9PT0gRWxlbWVudFR5cGUuVGV4dCkgcmV0dXJuIGVsZW0uZGF0YTtcblx0cmV0dXJuIFwiXCI7XG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL2xpYi90cmF2ZXJzYWwuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL2xpYi90cmF2ZXJzYWwuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxudmFyIGdldENoaWxkcmVuID0gZXhwb3J0cy5nZXRDaGlsZHJlbiA9IGZ1bmN0aW9uKGVsZW0pe1xuXHRyZXR1cm4gZWxlbS5jaGlsZHJlbjtcbn07XG5cbnZhciBnZXRQYXJlbnQgPSBleHBvcnRzLmdldFBhcmVudCA9IGZ1bmN0aW9uKGVsZW0pe1xuXHRyZXR1cm4gZWxlbS5wYXJlbnQ7XG59O1xuXG5leHBvcnRzLmdldFNpYmxpbmdzID0gZnVuY3Rpb24oZWxlbSl7XG5cdHZhciBwYXJlbnQgPSBnZXRQYXJlbnQoZWxlbSk7XG5cdHJldHVybiBwYXJlbnQgPyBnZXRDaGlsZHJlbihwYXJlbnQpIDogW2VsZW1dO1xufTtcblxuZXhwb3J0cy5nZXRBdHRyaWJ1dGVWYWx1ZSA9IGZ1bmN0aW9uKGVsZW0sIG5hbWUpe1xuXHRyZXR1cm4gZWxlbS5hdHRyaWJzICYmIGVsZW0uYXR0cmlic1tuYW1lXTtcbn07XG5cbmV4cG9ydHMuaGFzQXR0cmliID0gZnVuY3Rpb24oZWxlbSwgbmFtZSl7XG5cdHJldHVybiAhIWVsZW0uYXR0cmlicyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGVsZW0uYXR0cmlicywgbmFtZSk7XG59O1xuXG5leHBvcnRzLmdldE5hbWUgPSBmdW5jdGlvbihlbGVtKXtcblx0cmV0dXJuIGVsZW0ubmFtZTtcbn07XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL25vZGVfbW9kdWxlcy9kb20tc2VyaWFsaXplci9pbmRleC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9kb211dGlscy9ub2RlX21vZHVsZXMvZG9tLXNlcmlhbGl6ZXIvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG4vKlxuICBNb2R1bGUgZGVwZW5kZW5jaWVzXG4qL1xudmFyIEVsZW1lbnRUeXBlID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZG9tZWxlbWVudHR5cGUgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZG9tdXRpbHMvbm9kZV9tb2R1bGVzL2RvbS1zZXJpYWxpemVyL25vZGVfbW9kdWxlcy9kb21lbGVtZW50dHlwZS9pbmRleC5qc1wiKTtcbnZhciBlbnRpdGllcyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGVudGl0aWVzICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL2luZGV4LmpzXCIpO1xuXG4vKlxuICBCb29sZWFuIEF0dHJpYnV0ZXNcbiovXG52YXIgYm9vbGVhbkF0dHJpYnV0ZXMgPSB7XG4gIF9fcHJvdG9fXzogbnVsbCxcbiAgYWxsb3dmdWxsc2NyZWVuOiB0cnVlLFxuICBhc3luYzogdHJ1ZSxcbiAgYXV0b2ZvY3VzOiB0cnVlLFxuICBhdXRvcGxheTogdHJ1ZSxcbiAgY2hlY2tlZDogdHJ1ZSxcbiAgY29udHJvbHM6IHRydWUsXG4gIGRlZmF1bHQ6IHRydWUsXG4gIGRlZmVyOiB0cnVlLFxuICBkaXNhYmxlZDogdHJ1ZSxcbiAgaGlkZGVuOiB0cnVlLFxuICBpc21hcDogdHJ1ZSxcbiAgbG9vcDogdHJ1ZSxcbiAgbXVsdGlwbGU6IHRydWUsXG4gIG11dGVkOiB0cnVlLFxuICBvcGVuOiB0cnVlLFxuICByZWFkb25seTogdHJ1ZSxcbiAgcmVxdWlyZWQ6IHRydWUsXG4gIHJldmVyc2VkOiB0cnVlLFxuICBzY29wZWQ6IHRydWUsXG4gIHNlYW1sZXNzOiB0cnVlLFxuICBzZWxlY3RlZDogdHJ1ZSxcbiAgdHlwZW11c3RtYXRjaDogdHJ1ZVxufTtcblxudmFyIHVuZW5jb2RlZEVsZW1lbnRzID0ge1xuICBfX3Byb3RvX186IG51bGwsXG4gIHN0eWxlOiB0cnVlLFxuICBzY3JpcHQ6IHRydWUsXG4gIHhtcDogdHJ1ZSxcbiAgaWZyYW1lOiB0cnVlLFxuICBub2VtYmVkOiB0cnVlLFxuICBub2ZyYW1lczogdHJ1ZSxcbiAgcGxhaW50ZXh0OiB0cnVlLFxuICBub3NjcmlwdDogdHJ1ZVxufTtcblxuLypcbiAgRm9ybWF0IGF0dHJpYnV0ZXNcbiovXG5mdW5jdGlvbiBmb3JtYXRBdHRycyhhdHRyaWJ1dGVzLCBvcHRzKSB7XG4gIGlmICghYXR0cmlidXRlcykgcmV0dXJuO1xuXG4gIHZhciBvdXRwdXQgPSAnJyxcbiAgICAgIHZhbHVlO1xuXG4gIC8vIExvb3AgdGhyb3VnaCB0aGUgYXR0cmlidXRlc1xuICBmb3IgKHZhciBrZXkgaW4gYXR0cmlidXRlcykge1xuICAgIHZhbHVlID0gYXR0cmlidXRlc1trZXldO1xuICAgIGlmIChvdXRwdXQpIHtcbiAgICAgIG91dHB1dCArPSAnICc7XG4gICAgfVxuXG4gICAgaWYgKCF2YWx1ZSAmJiBib29sZWFuQXR0cmlidXRlc1trZXldKSB7XG4gICAgICBvdXRwdXQgKz0ga2V5O1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQgKz0ga2V5ICsgJz1cIicgKyAob3B0cy5kZWNvZGVFbnRpdGllcyA/IGVudGl0aWVzLmVuY29kZVhNTCh2YWx1ZSkgOiB2YWx1ZSkgKyAnXCInO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbi8qXG4gIFNlbGYtZW5jbG9zaW5nIHRhZ3MgKHN0b2xlbiBmcm9tIG5vZGUtaHRtbHBhcnNlcilcbiovXG52YXIgc2luZ2xlVGFnID0ge1xuICBfX3Byb3RvX186IG51bGwsXG4gIGFyZWE6IHRydWUsXG4gIGJhc2U6IHRydWUsXG4gIGJhc2Vmb250OiB0cnVlLFxuICBicjogdHJ1ZSxcbiAgY29sOiB0cnVlLFxuICBjb21tYW5kOiB0cnVlLFxuICBlbWJlZDogdHJ1ZSxcbiAgZnJhbWU6IHRydWUsXG4gIGhyOiB0cnVlLFxuICBpbWc6IHRydWUsXG4gIGlucHV0OiB0cnVlLFxuICBpc2luZGV4OiB0cnVlLFxuICBrZXlnZW46IHRydWUsXG4gIGxpbms6IHRydWUsXG4gIG1ldGE6IHRydWUsXG4gIHBhcmFtOiB0cnVlLFxuICBzb3VyY2U6IHRydWUsXG4gIHRyYWNrOiB0cnVlLFxuICB3YnI6IHRydWUsXG59O1xuXG5cbnZhciByZW5kZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGRvbSwgb3B0cykge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoZG9tKSAmJiAhZG9tLmNoZWVyaW8pIGRvbSA9IFtkb21dO1xuICBvcHRzID0gb3B0cyB8fCB7fTtcblxuICB2YXIgb3V0cHV0ID0gJyc7XG5cbiAgZm9yKHZhciBpID0gMDsgaSA8IGRvbS5sZW5ndGg7IGkrKyl7XG4gICAgdmFyIGVsZW0gPSBkb21baV07XG5cbiAgICBpZiAoZWxlbS50eXBlID09PSAncm9vdCcpXG4gICAgICBvdXRwdXQgKz0gcmVuZGVyKGVsZW0uY2hpbGRyZW4sIG9wdHMpO1xuICAgIGVsc2UgaWYgKEVsZW1lbnRUeXBlLmlzVGFnKGVsZW0pKVxuICAgICAgb3V0cHV0ICs9IHJlbmRlclRhZyhlbGVtLCBvcHRzKTtcbiAgICBlbHNlIGlmIChlbGVtLnR5cGUgPT09IEVsZW1lbnRUeXBlLkRpcmVjdGl2ZSlcbiAgICAgIG91dHB1dCArPSByZW5kZXJEaXJlY3RpdmUoZWxlbSk7XG4gICAgZWxzZSBpZiAoZWxlbS50eXBlID09PSBFbGVtZW50VHlwZS5Db21tZW50KVxuICAgICAgb3V0cHV0ICs9IHJlbmRlckNvbW1lbnQoZWxlbSk7XG4gICAgZWxzZSBpZiAoZWxlbS50eXBlID09PSBFbGVtZW50VHlwZS5DREFUQSlcbiAgICAgIG91dHB1dCArPSByZW5kZXJDZGF0YShlbGVtKTtcbiAgICBlbHNlXG4gICAgICBvdXRwdXQgKz0gcmVuZGVyVGV4dChlbGVtLCBvcHRzKTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5mdW5jdGlvbiByZW5kZXJUYWcoZWxlbSwgb3B0cykge1xuICAvLyBIYW5kbGUgU1ZHXG4gIGlmIChlbGVtLm5hbWUgPT09IFwic3ZnXCIpIG9wdHMgPSB7ZGVjb2RlRW50aXRpZXM6IG9wdHMuZGVjb2RlRW50aXRpZXMsIHhtbE1vZGU6IHRydWV9O1xuXG4gIHZhciB0YWcgPSAnPCcgKyBlbGVtLm5hbWUsXG4gICAgICBhdHRyaWJzID0gZm9ybWF0QXR0cnMoZWxlbS5hdHRyaWJzLCBvcHRzKTtcblxuICBpZiAoYXR0cmlicykge1xuICAgIHRhZyArPSAnICcgKyBhdHRyaWJzO1xuICB9XG5cbiAgaWYgKFxuICAgIG9wdHMueG1sTW9kZVxuICAgICYmICghZWxlbS5jaGlsZHJlbiB8fCBlbGVtLmNoaWxkcmVuLmxlbmd0aCA9PT0gMClcbiAgKSB7XG4gICAgdGFnICs9ICcvPic7XG4gIH0gZWxzZSB7XG4gICAgdGFnICs9ICc+JztcbiAgICBpZiAoZWxlbS5jaGlsZHJlbikge1xuICAgICAgdGFnICs9IHJlbmRlcihlbGVtLmNoaWxkcmVuLCBvcHRzKTtcbiAgICB9XG5cbiAgICBpZiAoIXNpbmdsZVRhZ1tlbGVtLm5hbWVdIHx8IG9wdHMueG1sTW9kZSkge1xuICAgICAgdGFnICs9ICc8LycgKyBlbGVtLm5hbWUgKyAnPic7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhZztcbn1cblxuZnVuY3Rpb24gcmVuZGVyRGlyZWN0aXZlKGVsZW0pIHtcbiAgcmV0dXJuICc8JyArIGVsZW0uZGF0YSArICc+Jztcbn1cblxuZnVuY3Rpb24gcmVuZGVyVGV4dChlbGVtLCBvcHRzKSB7XG4gIHZhciBkYXRhID0gZWxlbS5kYXRhIHx8ICcnO1xuXG4gIC8vIGlmIGVudGl0aWVzIHdlcmVuJ3QgZGVjb2RlZCwgbm8gbmVlZCB0byBlbmNvZGUgdGhlbSBiYWNrXG4gIGlmIChvcHRzLmRlY29kZUVudGl0aWVzICYmICEoZWxlbS5wYXJlbnQgJiYgZWxlbS5wYXJlbnQubmFtZSBpbiB1bmVuY29kZWRFbGVtZW50cykpIHtcbiAgICBkYXRhID0gZW50aXRpZXMuZW5jb2RlWE1MKGRhdGEpO1xuICB9XG5cbiAgcmV0dXJuIGRhdGE7XG59XG5cbmZ1bmN0aW9uIHJlbmRlckNkYXRhKGVsZW0pIHtcbiAgcmV0dXJuICc8IVtDREFUQVsnICsgZWxlbS5jaGlsZHJlblswXS5kYXRhICsgJ11dPic7XG59XG5cbmZ1bmN0aW9uIHJlbmRlckNvbW1lbnQoZWxlbSkge1xuICByZXR1cm4gJzwhLS0nICsgZWxlbS5kYXRhICsgJy0tPic7XG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL25vZGVfbW9kdWxlcy9kb20tc2VyaWFsaXplci9ub2RlX21vZHVsZXMvZG9tZWxlbWVudHR5cGUvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2RvbXV0aWxzL25vZGVfbW9kdWxlcy9kb20tc2VyaWFsaXplci9ub2RlX21vZHVsZXMvZG9tZWxlbWVudHR5cGUvaW5kZXguanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuLy9UeXBlcyBvZiBlbGVtZW50cyBmb3VuZCBpbiB0aGUgRE9NXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0VGV4dDogXCJ0ZXh0XCIsIC8vVGV4dFxuXHREaXJlY3RpdmU6IFwiZGlyZWN0aXZlXCIsIC8vPD8gLi4uID8+XG5cdENvbW1lbnQ6IFwiY29tbWVudFwiLCAvLzwhLS0gLi4uIC0tPlxuXHRTY3JpcHQ6IFwic2NyaXB0XCIsIC8vPHNjcmlwdD4gdGFnc1xuXHRTdHlsZTogXCJzdHlsZVwiLCAvLzxzdHlsZT4gdGFnc1xuXHRUYWc6IFwidGFnXCIsIC8vQW55IHRhZ1xuXHRDREFUQTogXCJjZGF0YVwiLCAvLzwhW0NEQVRBWyAuLi4gXV0+XG5cblx0aXNUYWc6IGZ1bmN0aW9uKGVsZW0pe1xuXHRcdHJldHVybiBlbGVtLnR5cGUgPT09IFwidGFnXCIgfHwgZWxlbS50eXBlID09PSBcInNjcmlwdFwiIHx8IGVsZW0udHlwZSA9PT0gXCJzdHlsZVwiO1xuXHR9XG59O1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZW50aXRpZXMvaW5kZXguanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9pbmRleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxudmFyIGVuY29kZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbGliL2VuY29kZS5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9saWIvZW5jb2RlLmpzXCIpLFxuICAgIGRlY29kZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vbGliL2RlY29kZS5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9saWIvZGVjb2RlLmpzXCIpO1xuXG5leHBvcnRzLmRlY29kZSA9IGZ1bmN0aW9uKGRhdGEsIGxldmVsKXtcblx0cmV0dXJuICghbGV2ZWwgfHwgbGV2ZWwgPD0gMCA/IGRlY29kZS5YTUwgOiBkZWNvZGUuSFRNTCkoZGF0YSk7XG59O1xuXG5leHBvcnRzLmRlY29kZVN0cmljdCA9IGZ1bmN0aW9uKGRhdGEsIGxldmVsKXtcblx0cmV0dXJuICghbGV2ZWwgfHwgbGV2ZWwgPD0gMCA/IGRlY29kZS5YTUwgOiBkZWNvZGUuSFRNTFN0cmljdCkoZGF0YSk7XG59O1xuXG5leHBvcnRzLmVuY29kZSA9IGZ1bmN0aW9uKGRhdGEsIGxldmVsKXtcblx0cmV0dXJuICghbGV2ZWwgfHwgbGV2ZWwgPD0gMCA/IGVuY29kZS5YTUwgOiBlbmNvZGUuSFRNTCkoZGF0YSk7XG59O1xuXG5leHBvcnRzLmVuY29kZVhNTCA9IGVuY29kZS5YTUw7XG5cbmV4cG9ydHMuZW5jb2RlSFRNTDQgPVxuZXhwb3J0cy5lbmNvZGVIVE1MNSA9XG5leHBvcnRzLmVuY29kZUhUTUwgID0gZW5jb2RlLkhUTUw7XG5cbmV4cG9ydHMuZGVjb2RlWE1MID1cbmV4cG9ydHMuZGVjb2RlWE1MU3RyaWN0ID0gZGVjb2RlLlhNTDtcblxuZXhwb3J0cy5kZWNvZGVIVE1MNCA9XG5leHBvcnRzLmRlY29kZUhUTUw1ID1cbmV4cG9ydHMuZGVjb2RlSFRNTCA9IGRlY29kZS5IVE1MO1xuXG5leHBvcnRzLmRlY29kZUhUTUw0U3RyaWN0ID1cbmV4cG9ydHMuZGVjb2RlSFRNTDVTdHJpY3QgPVxuZXhwb3J0cy5kZWNvZGVIVE1MU3RyaWN0ID0gZGVjb2RlLkhUTUxTdHJpY3Q7XG5cbmV4cG9ydHMuZXNjYXBlID0gZW5jb2RlLmVzY2FwZTtcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZW50aXRpZXMvbGliL2RlY29kZS5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZW50aXRpZXMvbGliL2RlY29kZS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG52YXIgZW50aXR5TWFwID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi4vbWFwcy9lbnRpdGllcy5qc29uICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL21hcHMvZW50aXRpZXMuanNvblwiKSxcbiAgICBsZWdhY3lNYXAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuLi9tYXBzL2xlZ2FjeS5qc29uICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL21hcHMvbGVnYWN5Lmpzb25cIiksXG4gICAgeG1sTWFwICAgID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi4vbWFwcy94bWwuanNvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9tYXBzL3htbC5qc29uXCIpLFxuICAgIGRlY29kZUNvZGVQb2ludCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vZGVjb2RlX2NvZGVwb2ludC5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9saWIvZGVjb2RlX2NvZGVwb2ludC5qc1wiKTtcblxudmFyIGRlY29kZVhNTFN0cmljdCAgPSBnZXRTdHJpY3REZWNvZGVyKHhtbE1hcCksXG4gICAgZGVjb2RlSFRNTFN0cmljdCA9IGdldFN0cmljdERlY29kZXIoZW50aXR5TWFwKTtcblxuZnVuY3Rpb24gZ2V0U3RyaWN0RGVjb2RlcihtYXApe1xuXHR2YXIga2V5cyA9IE9iamVjdC5rZXlzKG1hcCkuam9pbihcInxcIiksXG5cdCAgICByZXBsYWNlID0gZ2V0UmVwbGFjZXIobWFwKTtcblxuXHRrZXlzICs9IFwifCNbeFhdW1xcXFxkYS1mQS1GXSt8I1xcXFxkK1wiO1xuXG5cdHZhciByZSA9IG5ldyBSZWdFeHAoXCImKD86XCIgKyBrZXlzICsgXCIpO1wiLCBcImdcIik7XG5cblx0cmV0dXJuIGZ1bmN0aW9uKHN0cil7XG5cdFx0cmV0dXJuIFN0cmluZyhzdHIpLnJlcGxhY2UocmUsIHJlcGxhY2UpO1xuXHR9O1xufVxuXG52YXIgZGVjb2RlSFRNTCA9IChmdW5jdGlvbigpe1xuXHR2YXIgbGVnYWN5ID0gT2JqZWN0LmtleXMobGVnYWN5TWFwKVxuXHRcdC5zb3J0KHNvcnRlcik7XG5cblx0dmFyIGtleXMgPSBPYmplY3Qua2V5cyhlbnRpdHlNYXApXG5cdFx0LnNvcnQoc29ydGVyKTtcblxuXHRmb3IodmFyIGkgPSAwLCBqID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspe1xuXHRcdGlmKGxlZ2FjeVtqXSA9PT0ga2V5c1tpXSl7XG5cdFx0XHRrZXlzW2ldICs9IFwiOz9cIjtcblx0XHRcdGorKztcblx0XHR9IGVsc2Uge1xuXHRcdFx0a2V5c1tpXSArPSBcIjtcIjtcblx0XHR9XG5cdH1cblxuXHR2YXIgcmUgPSBuZXcgUmVnRXhwKFwiJig/OlwiICsga2V5cy5qb2luKFwifFwiKSArIFwifCNbeFhdW1xcXFxkYS1mQS1GXSs7P3wjXFxcXGQrOz8pXCIsIFwiZ1wiKSxcblx0ICAgIHJlcGxhY2UgPSBnZXRSZXBsYWNlcihlbnRpdHlNYXApO1xuXG5cdGZ1bmN0aW9uIHJlcGxhY2VyKHN0cil7XG5cdFx0aWYoc3RyLnN1YnN0cigtMSkgIT09IFwiO1wiKSBzdHIgKz0gXCI7XCI7XG5cdFx0cmV0dXJuIHJlcGxhY2Uoc3RyKTtcblx0fVxuXG5cdC8vVE9ETyBjb25zaWRlciBjcmVhdGluZyBhIG1lcmdlZCBtYXBcblx0cmV0dXJuIGZ1bmN0aW9uKHN0cil7XG5cdFx0cmV0dXJuIFN0cmluZyhzdHIpLnJlcGxhY2UocmUsIHJlcGxhY2VyKTtcblx0fTtcbn0oKSk7XG5cbmZ1bmN0aW9uIHNvcnRlcihhLCBiKXtcblx0cmV0dXJuIGEgPCBiID8gMSA6IC0xO1xufVxuXG5mdW5jdGlvbiBnZXRSZXBsYWNlcihtYXApe1xuXHRyZXR1cm4gZnVuY3Rpb24gcmVwbGFjZShzdHIpe1xuXHRcdGlmKHN0ci5jaGFyQXQoMSkgPT09IFwiI1wiKXtcblx0XHRcdGlmKHN0ci5jaGFyQXQoMikgPT09IFwiWFwiIHx8IHN0ci5jaGFyQXQoMikgPT09IFwieFwiKXtcblx0XHRcdFx0cmV0dXJuIGRlY29kZUNvZGVQb2ludChwYXJzZUludChzdHIuc3Vic3RyKDMpLCAxNikpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGRlY29kZUNvZGVQb2ludChwYXJzZUludChzdHIuc3Vic3RyKDIpLCAxMCkpO1xuXHRcdH1cblx0XHRyZXR1cm4gbWFwW3N0ci5zbGljZSgxLCAtMSldO1xuXHR9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0WE1MOiBkZWNvZGVYTUxTdHJpY3QsXG5cdEhUTUw6IGRlY29kZUhUTUwsXG5cdEhUTUxTdHJpY3Q6IGRlY29kZUhUTUxTdHJpY3Rcbn07XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9saWIvZGVjb2RlX2NvZGVwb2ludC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG52YXIgZGVjb2RlTWFwID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi4vbWFwcy9kZWNvZGUuanNvbiAqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9tYXBzL2RlY29kZS5qc29uXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlY29kZUNvZGVQb2ludDtcblxuLy8gbW9kaWZpZWQgdmVyc2lvbiBvZiBodHRwczovL2dpdGh1Yi5jb20vbWF0aGlhc2J5bmVucy9oZS9ibG9iL21hc3Rlci9zcmMvaGUuanMjTDk0LUwxMTlcbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludChjb2RlUG9pbnQpe1xuXG5cdGlmKChjb2RlUG9pbnQgPj0gMHhEODAwICYmIGNvZGVQb2ludCA8PSAweERGRkYpIHx8IGNvZGVQb2ludCA+IDB4MTBGRkZGKXtcblx0XHRyZXR1cm4gXCJcXHVGRkZEXCI7XG5cdH1cblxuXHRpZihjb2RlUG9pbnQgaW4gZGVjb2RlTWFwKXtcblx0XHRjb2RlUG9pbnQgPSBkZWNvZGVNYXBbY29kZVBvaW50XTtcblx0fVxuXG5cdHZhciBvdXRwdXQgPSBcIlwiO1xuXG5cdGlmKGNvZGVQb2ludCA+IDB4RkZGRil7XG5cdFx0Y29kZVBvaW50IC09IDB4MTAwMDA7XG5cdFx0b3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKTtcblx0XHRjb2RlUG9pbnQgPSAweERDMDAgfCBjb2RlUG9pbnQgJiAweDNGRjtcblx0fVxuXG5cdG91dHB1dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVQb2ludCk7XG5cdHJldHVybiBvdXRwdXQ7XG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL2xpYi9lbmNvZGUuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL2xpYi9lbmNvZGUuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxudmFyIGludmVyc2VYTUwgPSBnZXRJbnZlcnNlT2JqKF9fd2VicGFja19yZXF1aXJlX18oLyohIC4uL21hcHMveG1sLmpzb24gKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZW50aXRpZXMvbWFwcy94bWwuanNvblwiKSksXG4gICAgeG1sUmVwbGFjZXIgPSBnZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZVhNTCk7XG5cbmV4cG9ydHMuWE1MID0gZ2V0SW52ZXJzZShpbnZlcnNlWE1MLCB4bWxSZXBsYWNlcik7XG5cbnZhciBpbnZlcnNlSFRNTCA9IGdldEludmVyc2VPYmooX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi4vbWFwcy9lbnRpdGllcy5qc29uICovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL21hcHMvZW50aXRpZXMuanNvblwiKSksXG4gICAgaHRtbFJlcGxhY2VyID0gZ2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2VIVE1MKTtcblxuZXhwb3J0cy5IVE1MID0gZ2V0SW52ZXJzZShpbnZlcnNlSFRNTCwgaHRtbFJlcGxhY2VyKTtcblxuZnVuY3Rpb24gZ2V0SW52ZXJzZU9iaihvYmope1xuXHRyZXR1cm4gT2JqZWN0LmtleXMob2JqKS5zb3J0KCkucmVkdWNlKGZ1bmN0aW9uKGludmVyc2UsIG5hbWUpe1xuXHRcdGludmVyc2Vbb2JqW25hbWVdXSA9IFwiJlwiICsgbmFtZSArIFwiO1wiO1xuXHRcdHJldHVybiBpbnZlcnNlO1xuXHR9LCB7fSk7XG59XG5cbmZ1bmN0aW9uIGdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlKXtcblx0dmFyIHNpbmdsZSA9IFtdLFxuXHQgICAgbXVsdGlwbGUgPSBbXTtcblxuXHRPYmplY3Qua2V5cyhpbnZlcnNlKS5mb3JFYWNoKGZ1bmN0aW9uKGspe1xuXHRcdGlmKGsubGVuZ3RoID09PSAxKXtcblx0XHRcdHNpbmdsZS5wdXNoKFwiXFxcXFwiICsgayk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG11bHRpcGxlLnB1c2goayk7XG5cdFx0fVxuXHR9KTtcblxuXHQvL1RPRE8gYWRkIHJhbmdlc1xuXHRtdWx0aXBsZS51bnNoaWZ0KFwiW1wiICsgc2luZ2xlLmpvaW4oXCJcIikgKyBcIl1cIik7XG5cblx0cmV0dXJuIG5ldyBSZWdFeHAobXVsdGlwbGUuam9pbihcInxcIiksIFwiZ1wiKTtcbn1cblxudmFyIHJlX25vbkFTQ0lJID0gL1teXFwwLVxceDdGXS9nLFxuICAgIHJlX2FzdHJhbFN5bWJvbHMgPSAvW1xcdUQ4MDAtXFx1REJGRl1bXFx1REMwMC1cXHVERkZGXS9nO1xuXG5mdW5jdGlvbiBzaW5nbGVDaGFyUmVwbGFjZXIoYyl7XG5cdHJldHVybiBcIiYjeFwiICsgYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpICsgXCI7XCI7XG59XG5cbmZ1bmN0aW9uIGFzdHJhbFJlcGxhY2VyKGMpe1xuXHQvLyBodHRwOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LWVuY29kaW5nI3N1cnJvZ2F0ZS1mb3JtdWxhZVxuXHR2YXIgaGlnaCA9IGMuY2hhckNvZGVBdCgwKTtcblx0dmFyIGxvdyAgPSBjLmNoYXJDb2RlQXQoMSk7XG5cdHZhciBjb2RlUG9pbnQgPSAoaGlnaCAtIDB4RDgwMCkgKiAweDQwMCArIGxvdyAtIDB4REMwMCArIDB4MTAwMDA7XG5cdHJldHVybiBcIiYjeFwiICsgY29kZVBvaW50LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpICsgXCI7XCI7XG59XG5cbmZ1bmN0aW9uIGdldEludmVyc2UoaW52ZXJzZSwgcmUpe1xuXHRmdW5jdGlvbiBmdW5jKG5hbWUpe1xuXHRcdHJldHVybiBpbnZlcnNlW25hbWVdO1xuXHR9XG5cblx0cmV0dXJuIGZ1bmN0aW9uKGRhdGEpe1xuXHRcdHJldHVybiBkYXRhXG5cdFx0XHRcdC5yZXBsYWNlKHJlLCBmdW5jKVxuXHRcdFx0XHQucmVwbGFjZShyZV9hc3RyYWxTeW1ib2xzLCBhc3RyYWxSZXBsYWNlcilcblx0XHRcdFx0LnJlcGxhY2UocmVfbm9uQVNDSUksIHNpbmdsZUNoYXJSZXBsYWNlcik7XG5cdH07XG59XG5cbnZhciByZV94bWxDaGFycyA9IGdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlWE1MKTtcblxuZnVuY3Rpb24gZXNjYXBlWE1MKGRhdGEpe1xuXHRyZXR1cm4gZGF0YVxuXHRcdFx0LnJlcGxhY2UocmVfeG1sQ2hhcnMsIHNpbmdsZUNoYXJSZXBsYWNlcilcblx0XHRcdC5yZXBsYWNlKHJlX2FzdHJhbFN5bWJvbHMsIGFzdHJhbFJlcGxhY2VyKVxuXHRcdFx0LnJlcGxhY2UocmVfbm9uQVNDSUksIHNpbmdsZUNoYXJSZXBsYWNlcik7XG59XG5cbmV4cG9ydHMuZXNjYXBlID0gZXNjYXBlWE1MO1xuXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9tYXBzL2RlY29kZS5qc29uXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9tYXBzL2RlY29kZS5qc29uICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IDAsIDEyOCwgMTMwLCAxMzEsIDEzMiwgMTMzLCAxMzQsIDEzNSwgMTM2LCAxMzcsIDEzOCwgMTM5LCAxNDAsIDE0MiwgMTQ1LCAxNDYsIDE0NywgMTQ4LCAxNDksIDE1MCwgMTUxLCAxNTIsIDE1MywgMTU0LCAxNTUsIDE1NiwgMTU4LCAxNTksIGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUpIHtcblxubW9kdWxlLmV4cG9ydHMgPSBKU09OLnBhcnNlKFwie1xcXCIwXFxcIjo2NTUzMyxcXFwiMTI4XFxcIjo4MzY0LFxcXCIxMzBcXFwiOjgyMTgsXFxcIjEzMVxcXCI6NDAyLFxcXCIxMzJcXFwiOjgyMjIsXFxcIjEzM1xcXCI6ODIzMCxcXFwiMTM0XFxcIjo4MjI0LFxcXCIxMzVcXFwiOjgyMjUsXFxcIjEzNlxcXCI6NzEwLFxcXCIxMzdcXFwiOjgyNDAsXFxcIjEzOFxcXCI6MzUyLFxcXCIxMzlcXFwiOjgyNDksXFxcIjE0MFxcXCI6MzM4LFxcXCIxNDJcXFwiOjM4MSxcXFwiMTQ1XFxcIjo4MjE2LFxcXCIxNDZcXFwiOjgyMTcsXFxcIjE0N1xcXCI6ODIyMCxcXFwiMTQ4XFxcIjo4MjIxLFxcXCIxNDlcXFwiOjgyMjYsXFxcIjE1MFxcXCI6ODIxMSxcXFwiMTUxXFxcIjo4MjEyLFxcXCIxNTJcXFwiOjczMixcXFwiMTUzXFxcIjo4NDgyLFxcXCIxNTRcXFwiOjM1MyxcXFwiMTU1XFxcIjo4MjUwLFxcXCIxNTZcXFwiOjMzOSxcXFwiMTU4XFxcIjozODIsXFxcIjE1OVxcXCI6Mzc2fVwiKTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL21hcHMvZW50aXRpZXMuanNvblwiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL2h0bWxwYXJzZXIyL25vZGVfbW9kdWxlcy9lbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb24gKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBleHBvcnRzIHByb3ZpZGVkOiBBYWN1dGUsIGFhY3V0ZSwgQWJyZXZlLCBhYnJldmUsIGFjLCBhY2QsIGFjRSwgQWNpcmMsIGFjaXJjLCBhY3V0ZSwgQWN5LCBhY3ksIEFFbGlnLCBhZWxpZywgYWYsIEFmciwgYWZyLCBBZ3JhdmUsIGFncmF2ZSwgYWxlZnN5bSwgYWxlcGgsIEFscGhhLCBhbHBoYSwgQW1hY3IsIGFtYWNyLCBhbWFsZywgYW1wLCBBTVAsIGFuZGFuZCwgQW5kLCBhbmQsIGFuZGQsIGFuZHNsb3BlLCBhbmR2LCBhbmcsIGFuZ2UsIGFuZ2xlLCBhbmdtc2RhYSwgYW5nbXNkYWIsIGFuZ21zZGFjLCBhbmdtc2RhZCwgYW5nbXNkYWUsIGFuZ21zZGFmLCBhbmdtc2RhZywgYW5nbXNkYWgsIGFuZ21zZCwgYW5ncnQsIGFuZ3J0dmIsIGFuZ3J0dmJkLCBhbmdzcGgsIGFuZ3N0LCBhbmd6YXJyLCBBb2dvbiwgYW9nb24sIEFvcGYsIGFvcGYsIGFwYWNpciwgYXAsIGFwRSwgYXBlLCBhcGlkLCBhcG9zLCBBcHBseUZ1bmN0aW9uLCBhcHByb3gsIGFwcHJveGVxLCBBcmluZywgYXJpbmcsIEFzY3IsIGFzY3IsIEFzc2lnbiwgYXN0LCBhc3ltcCwgYXN5bXBlcSwgQXRpbGRlLCBhdGlsZGUsIEF1bWwsIGF1bWwsIGF3Y29uaW50LCBhd2ludCwgYmFja2NvbmcsIGJhY2tlcHNpbG9uLCBiYWNrcHJpbWUsIGJhY2tzaW0sIGJhY2tzaW1lcSwgQmFja3NsYXNoLCBCYXJ2LCBiYXJ2ZWUsIGJhcndlZCwgQmFyd2VkLCBiYXJ3ZWRnZSwgYmJyaywgYmJya3RicmssIGJjb25nLCBCY3ksIGJjeSwgYmRxdW8sIGJlY2F1cywgYmVjYXVzZSwgQmVjYXVzZSwgYmVtcHR5diwgYmVwc2ksIGJlcm5vdSwgQmVybm91bGxpcywgQmV0YSwgYmV0YSwgYmV0aCwgYmV0d2VlbiwgQmZyLCBiZnIsIGJpZ2NhcCwgYmlnY2lyYywgYmlnY3VwLCBiaWdvZG90LCBiaWdvcGx1cywgYmlnb3RpbWVzLCBiaWdzcWN1cCwgYmlnc3RhciwgYmlndHJpYW5nbGVkb3duLCBiaWd0cmlhbmdsZXVwLCBiaWd1cGx1cywgYmlndmVlLCBiaWd3ZWRnZSwgYmthcm93LCBibGFja2xvemVuZ2UsIGJsYWNrc3F1YXJlLCBibGFja3RyaWFuZ2xlLCBibGFja3RyaWFuZ2xlZG93biwgYmxhY2t0cmlhbmdsZWxlZnQsIGJsYWNrdHJpYW5nbGVyaWdodCwgYmxhbmssIGJsazEyLCBibGsxNCwgYmxrMzQsIGJsb2NrLCBibmUsIGJuZXF1aXYsIGJOb3QsIGJub3QsIEJvcGYsIGJvcGYsIGJvdCwgYm90dG9tLCBib3d0aWUsIGJveGJveCwgYm94ZGwsIGJveGRMLCBib3hEbCwgYm94REwsIGJveGRyLCBib3hkUiwgYm94RHIsIGJveERSLCBib3hoLCBib3hILCBib3hoZCwgYm94SGQsIGJveGhELCBib3hIRCwgYm94aHUsIGJveEh1LCBib3hoVSwgYm94SFUsIGJveG1pbnVzLCBib3hwbHVzLCBib3h0aW1lcywgYm94dWwsIGJveHVMLCBib3hVbCwgYm94VUwsIGJveHVyLCBib3h1UiwgYm94VXIsIGJveFVSLCBib3h2LCBib3hWLCBib3h2aCwgYm94dkgsIGJveFZoLCBib3hWSCwgYm94dmwsIGJveHZMLCBib3hWbCwgYm94VkwsIGJveHZyLCBib3h2UiwgYm94VnIsIGJveFZSLCBicHJpbWUsIGJyZXZlLCBCcmV2ZSwgYnJ2YmFyLCBic2NyLCBCc2NyLCBic2VtaSwgYnNpbSwgYnNpbWUsIGJzb2xiLCBic29sLCBic29saHN1YiwgYnVsbCwgYnVsbGV0LCBidW1wLCBidW1wRSwgYnVtcGUsIEJ1bXBlcSwgYnVtcGVxLCBDYWN1dGUsIGNhY3V0ZSwgY2FwYW5kLCBjYXBicmN1cCwgY2FwY2FwLCBjYXAsIENhcCwgY2FwY3VwLCBjYXBkb3QsIENhcGl0YWxEaWZmZXJlbnRpYWxELCBjYXBzLCBjYXJldCwgY2Fyb24sIENheWxleXMsIGNjYXBzLCBDY2Fyb24sIGNjYXJvbiwgQ2NlZGlsLCBjY2VkaWwsIENjaXJjLCBjY2lyYywgQ2NvbmludCwgY2N1cHMsIGNjdXBzc20sIENkb3QsIGNkb3QsIGNlZGlsLCBDZWRpbGxhLCBjZW1wdHl2LCBjZW50LCBjZW50ZXJkb3QsIENlbnRlckRvdCwgY2ZyLCBDZnIsIENIY3ksIGNoY3ksIGNoZWNrLCBjaGVja21hcmssIENoaSwgY2hpLCBjaXJjLCBjaXJjZXEsIGNpcmNsZWFycm93bGVmdCwgY2lyY2xlYXJyb3dyaWdodCwgY2lyY2xlZGFzdCwgY2lyY2xlZGNpcmMsIGNpcmNsZWRkYXNoLCBDaXJjbGVEb3QsIGNpcmNsZWRSLCBjaXJjbGVkUywgQ2lyY2xlTWludXMsIENpcmNsZVBsdXMsIENpcmNsZVRpbWVzLCBjaXIsIGNpckUsIGNpcmUsIGNpcmZuaW50LCBjaXJtaWQsIGNpcnNjaXIsIENsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbCwgQ2xvc2VDdXJseURvdWJsZVF1b3RlLCBDbG9zZUN1cmx5UXVvdGUsIGNsdWJzLCBjbHVic3VpdCwgY29sb24sIENvbG9uLCBDb2xvbmUsIGNvbG9uZSwgY29sb25lcSwgY29tbWEsIGNvbW1hdCwgY29tcCwgY29tcGZuLCBjb21wbGVtZW50LCBjb21wbGV4ZXMsIGNvbmcsIGNvbmdkb3QsIENvbmdydWVudCwgY29uaW50LCBDb25pbnQsIENvbnRvdXJJbnRlZ3JhbCwgY29wZiwgQ29wZiwgY29wcm9kLCBDb3Byb2R1Y3QsIGNvcHksIENPUFksIGNvcHlzciwgQ291bnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbCwgY3JhcnIsIGNyb3NzLCBDcm9zcywgQ3NjciwgY3NjciwgY3N1YiwgY3N1YmUsIGNzdXAsIGNzdXBlLCBjdGRvdCwgY3VkYXJybCwgY3VkYXJyciwgY3VlcHIsIGN1ZXNjLCBjdWxhcnIsIGN1bGFycnAsIGN1cGJyY2FwLCBjdXBjYXAsIEN1cENhcCwgY3VwLCBDdXAsIGN1cGN1cCwgY3VwZG90LCBjdXBvciwgY3VwcywgY3VyYXJyLCBjdXJhcnJtLCBjdXJseWVxcHJlYywgY3VybHllcXN1Y2MsIGN1cmx5dmVlLCBjdXJseXdlZGdlLCBjdXJyZW4sIGN1cnZlYXJyb3dsZWZ0LCBjdXJ2ZWFycm93cmlnaHQsIGN1dmVlLCBjdXdlZCwgY3djb25pbnQsIGN3aW50LCBjeWxjdHksIGRhZ2dlciwgRGFnZ2VyLCBkYWxldGgsIGRhcnIsIERhcnIsIGRBcnIsIGRhc2gsIERhc2h2LCBkYXNodiwgZGJrYXJvdywgZGJsYWMsIERjYXJvbiwgZGNhcm9uLCBEY3ksIGRjeSwgZGRhZ2dlciwgZGRhcnIsIERELCBkZCwgRERvdHJhaGQsIGRkb3RzZXEsIGRlZywgRGVsLCBEZWx0YSwgZGVsdGEsIGRlbXB0eXYsIGRmaXNodCwgRGZyLCBkZnIsIGRIYXIsIGRoYXJsLCBkaGFyciwgRGlhY3JpdGljYWxBY3V0ZSwgRGlhY3JpdGljYWxEb3QsIERpYWNyaXRpY2FsRG91YmxlQWN1dGUsIERpYWNyaXRpY2FsR3JhdmUsIERpYWNyaXRpY2FsVGlsZGUsIGRpYW0sIGRpYW1vbmQsIERpYW1vbmQsIGRpYW1vbmRzdWl0LCBkaWFtcywgZGllLCBEaWZmZXJlbnRpYWxELCBkaWdhbW1hLCBkaXNpbiwgZGl2LCBkaXZpZGUsIGRpdmlkZW9udGltZXMsIGRpdm9ueCwgREpjeSwgZGpjeSwgZGxjb3JuLCBkbGNyb3AsIGRvbGxhciwgRG9wZiwgZG9wZiwgRG90LCBkb3QsIERvdERvdCwgZG90ZXEsIGRvdGVxZG90LCBEb3RFcXVhbCwgZG90bWludXMsIGRvdHBsdXMsIGRvdHNxdWFyZSwgZG91YmxlYmFyd2VkZ2UsIERvdWJsZUNvbnRvdXJJbnRlZ3JhbCwgRG91YmxlRG90LCBEb3VibGVEb3duQXJyb3csIERvdWJsZUxlZnRBcnJvdywgRG91YmxlTGVmdFJpZ2h0QXJyb3csIERvdWJsZUxlZnRUZWUsIERvdWJsZUxvbmdMZWZ0QXJyb3csIERvdWJsZUxvbmdMZWZ0UmlnaHRBcnJvdywgRG91YmxlTG9uZ1JpZ2h0QXJyb3csIERvdWJsZVJpZ2h0QXJyb3csIERvdWJsZVJpZ2h0VGVlLCBEb3VibGVVcEFycm93LCBEb3VibGVVcERvd25BcnJvdywgRG91YmxlVmVydGljYWxCYXIsIERvd25BcnJvd0JhciwgZG93bmFycm93LCBEb3duQXJyb3csIERvd25hcnJvdywgRG93bkFycm93VXBBcnJvdywgRG93bkJyZXZlLCBkb3duZG93bmFycm93cywgZG93bmhhcnBvb25sZWZ0LCBkb3duaGFycG9vbnJpZ2h0LCBEb3duTGVmdFJpZ2h0VmVjdG9yLCBEb3duTGVmdFRlZVZlY3RvciwgRG93bkxlZnRWZWN0b3JCYXIsIERvd25MZWZ0VmVjdG9yLCBEb3duUmlnaHRUZWVWZWN0b3IsIERvd25SaWdodFZlY3RvckJhciwgRG93blJpZ2h0VmVjdG9yLCBEb3duVGVlQXJyb3csIERvd25UZWUsIGRyYmthcm93LCBkcmNvcm4sIGRyY3JvcCwgRHNjciwgZHNjciwgRFNjeSwgZHNjeSwgZHNvbCwgRHN0cm9rLCBkc3Ryb2ssIGR0ZG90LCBkdHJpLCBkdHJpZiwgZHVhcnIsIGR1aGFyLCBkd2FuZ2xlLCBEWmN5LCBkemN5LCBkemlncmFyciwgRWFjdXRlLCBlYWN1dGUsIGVhc3RlciwgRWNhcm9uLCBlY2Fyb24sIEVjaXJjLCBlY2lyYywgZWNpciwgZWNvbG9uLCBFY3ksIGVjeSwgZUREb3QsIEVkb3QsIGVkb3QsIGVEb3QsIGVlLCBlZkRvdCwgRWZyLCBlZnIsIGVnLCBFZ3JhdmUsIGVncmF2ZSwgZWdzLCBlZ3Nkb3QsIGVsLCBFbGVtZW50LCBlbGludGVycywgZWxsLCBlbHMsIGVsc2RvdCwgRW1hY3IsIGVtYWNyLCBlbXB0eSwgZW1wdHlzZXQsIEVtcHR5U21hbGxTcXVhcmUsIGVtcHR5diwgRW1wdHlWZXJ5U21hbGxTcXVhcmUsIGVtc3AxMywgZW1zcDE0LCBlbXNwLCBFTkcsIGVuZywgZW5zcCwgRW9nb24sIGVvZ29uLCBFb3BmLCBlb3BmLCBlcGFyLCBlcGFyc2wsIGVwbHVzLCBlcHNpLCBFcHNpbG9uLCBlcHNpbG9uLCBlcHNpdiwgZXFjaXJjLCBlcWNvbG9uLCBlcXNpbSwgZXFzbGFudGd0ciwgZXFzbGFudGxlc3MsIEVxdWFsLCBlcXVhbHMsIEVxdWFsVGlsZGUsIGVxdWVzdCwgRXF1aWxpYnJpdW0sIGVxdWl2LCBlcXVpdkRELCBlcXZwYXJzbCwgZXJhcnIsIGVyRG90LCBlc2NyLCBFc2NyLCBlc2RvdCwgRXNpbSwgZXNpbSwgRXRhLCBldGEsIEVUSCwgZXRoLCBFdW1sLCBldW1sLCBldXJvLCBleGNsLCBleGlzdCwgRXhpc3RzLCBleHBlY3RhdGlvbiwgZXhwb25lbnRpYWxlLCBFeHBvbmVudGlhbEUsIGZhbGxpbmdkb3RzZXEsIEZjeSwgZmN5LCBmZW1hbGUsIGZmaWxpZywgZmZsaWcsIGZmbGxpZywgRmZyLCBmZnIsIGZpbGlnLCBGaWxsZWRTbWFsbFNxdWFyZSwgRmlsbGVkVmVyeVNtYWxsU3F1YXJlLCBmamxpZywgZmxhdCwgZmxsaWcsIGZsdG5zLCBmbm9mLCBGb3BmLCBmb3BmLCBmb3JhbGwsIEZvckFsbCwgZm9yaywgZm9ya3YsIEZvdXJpZXJ0cmYsIGZwYXJ0aW50LCBmcmFjMTIsIGZyYWMxMywgZnJhYzE0LCBmcmFjMTUsIGZyYWMxNiwgZnJhYzE4LCBmcmFjMjMsIGZyYWMyNSwgZnJhYzM0LCBmcmFjMzUsIGZyYWMzOCwgZnJhYzQ1LCBmcmFjNTYsIGZyYWM1OCwgZnJhYzc4LCBmcmFzbCwgZnJvd24sIGZzY3IsIEZzY3IsIGdhY3V0ZSwgR2FtbWEsIGdhbW1hLCBHYW1tYWQsIGdhbW1hZCwgZ2FwLCBHYnJldmUsIGdicmV2ZSwgR2NlZGlsLCBHY2lyYywgZ2NpcmMsIEdjeSwgZ2N5LCBHZG90LCBnZG90LCBnZSwgZ0UsIGdFbCwgZ2VsLCBnZXEsIGdlcXEsIGdlcXNsYW50LCBnZXNjYywgZ2VzLCBnZXNkb3QsIGdlc2RvdG8sIGdlc2RvdG9sLCBnZXNsLCBnZXNsZXMsIEdmciwgZ2ZyLCBnZywgR2csIGdnZywgZ2ltZWwsIEdKY3ksIGdqY3ksIGdsYSwgZ2wsIGdsRSwgZ2xqLCBnbmFwLCBnbmFwcHJveCwgZ25lLCBnbkUsIGduZXEsIGduZXFxLCBnbnNpbSwgR29wZiwgZ29wZiwgZ3JhdmUsIEdyZWF0ZXJFcXVhbCwgR3JlYXRlckVxdWFsTGVzcywgR3JlYXRlckZ1bGxFcXVhbCwgR3JlYXRlckdyZWF0ZXIsIEdyZWF0ZXJMZXNzLCBHcmVhdGVyU2xhbnRFcXVhbCwgR3JlYXRlclRpbGRlLCBHc2NyLCBnc2NyLCBnc2ltLCBnc2ltZSwgZ3NpbWwsIGd0Y2MsIGd0Y2lyLCBndCwgR1QsIEd0LCBndGRvdCwgZ3RsUGFyLCBndHF1ZXN0LCBndHJhcHByb3gsIGd0cmFyciwgZ3RyZG90LCBndHJlcWxlc3MsIGd0cmVxcWxlc3MsIGd0cmxlc3MsIGd0cnNpbSwgZ3ZlcnRuZXFxLCBndm5FLCBIYWNlaywgaGFpcnNwLCBoYWxmLCBoYW1pbHQsIEhBUkRjeSwgaGFyZGN5LCBoYXJyY2lyLCBoYXJyLCBoQXJyLCBoYXJydywgSGF0LCBoYmFyLCBIY2lyYywgaGNpcmMsIGhlYXJ0cywgaGVhcnRzdWl0LCBoZWxsaXAsIGhlcmNvbiwgaGZyLCBIZnIsIEhpbGJlcnRTcGFjZSwgaGtzZWFyb3csIGhrc3dhcm93LCBob2FyciwgaG9tdGh0LCBob29rbGVmdGFycm93LCBob29rcmlnaHRhcnJvdywgaG9wZiwgSG9wZiwgaG9yYmFyLCBIb3Jpem9udGFsTGluZSwgaHNjciwgSHNjciwgaHNsYXNoLCBIc3Ryb2ssIGhzdHJvaywgSHVtcERvd25IdW1wLCBIdW1wRXF1YWwsIGh5YnVsbCwgaHlwaGVuLCBJYWN1dGUsIGlhY3V0ZSwgaWMsIEljaXJjLCBpY2lyYywgSWN5LCBpY3ksIElkb3QsIElFY3ksIGllY3ksIGlleGNsLCBpZmYsIGlmciwgSWZyLCBJZ3JhdmUsIGlncmF2ZSwgaWksIGlpaWludCwgaWlpbnQsIGlpbmZpbiwgaWlvdGEsIElKbGlnLCBpamxpZywgSW1hY3IsIGltYWNyLCBpbWFnZSwgSW1hZ2luYXJ5SSwgaW1hZ2xpbmUsIGltYWdwYXJ0LCBpbWF0aCwgSW0sIGltb2YsIGltcGVkLCBJbXBsaWVzLCBpbmNhcmUsIGluLCBpbmZpbiwgaW5maW50aWUsIGlub2RvdCwgaW50Y2FsLCBpbnQsIEludCwgaW50ZWdlcnMsIEludGVncmFsLCBpbnRlcmNhbCwgSW50ZXJzZWN0aW9uLCBpbnRsYXJoaywgaW50cHJvZCwgSW52aXNpYmxlQ29tbWEsIEludmlzaWJsZVRpbWVzLCBJT2N5LCBpb2N5LCBJb2dvbiwgaW9nb24sIElvcGYsIGlvcGYsIElvdGEsIGlvdGEsIGlwcm9kLCBpcXVlc3QsIGlzY3IsIElzY3IsIGlzaW4sIGlzaW5kb3QsIGlzaW5FLCBpc2lucywgaXNpbnN2LCBpc2ludiwgaXQsIEl0aWxkZSwgaXRpbGRlLCBJdWtjeSwgaXVrY3ksIEl1bWwsIGl1bWwsIEpjaXJjLCBqY2lyYywgSmN5LCBqY3ksIEpmciwgamZyLCBqbWF0aCwgSm9wZiwgam9wZiwgSnNjciwganNjciwgSnNlcmN5LCBqc2VyY3ksIEp1a2N5LCBqdWtjeSwgS2FwcGEsIGthcHBhLCBrYXBwYXYsIEtjZWRpbCwga2NlZGlsLCBLY3ksIGtjeSwgS2ZyLCBrZnIsIGtncmVlbiwgS0hjeSwga2hjeSwgS0pjeSwga2pjeSwgS29wZiwga29wZiwgS3Njciwga3NjciwgbEFhcnIsIExhY3V0ZSwgbGFjdXRlLCBsYWVtcHR5diwgbGFncmFuLCBMYW1iZGEsIGxhbWJkYSwgbGFuZywgTGFuZywgbGFuZ2QsIGxhbmdsZSwgbGFwLCBMYXBsYWNldHJmLCBsYXF1bywgbGFycmIsIGxhcnJiZnMsIGxhcnIsIExhcnIsIGxBcnIsIGxhcnJmcywgbGFycmhrLCBsYXJybHAsIGxhcnJwbCwgbGFycnNpbSwgbGFycnRsLCBsYXRhaWwsIGxBdGFpbCwgbGF0LCBsYXRlLCBsYXRlcywgbGJhcnIsIGxCYXJyLCBsYmJyaywgbGJyYWNlLCBsYnJhY2ssIGxicmtlLCBsYnJrc2xkLCBsYnJrc2x1LCBMY2Fyb24sIGxjYXJvbiwgTGNlZGlsLCBsY2VkaWwsIGxjZWlsLCBsY3ViLCBMY3ksIGxjeSwgbGRjYSwgbGRxdW8sIGxkcXVvciwgbGRyZGhhciwgbGRydXNoYXIsIGxkc2gsIGxlLCBsRSwgTGVmdEFuZ2xlQnJhY2tldCwgTGVmdEFycm93QmFyLCBsZWZ0YXJyb3csIExlZnRBcnJvdywgTGVmdGFycm93LCBMZWZ0QXJyb3dSaWdodEFycm93LCBsZWZ0YXJyb3d0YWlsLCBMZWZ0Q2VpbGluZywgTGVmdERvdWJsZUJyYWNrZXQsIExlZnREb3duVGVlVmVjdG9yLCBMZWZ0RG93blZlY3RvckJhciwgTGVmdERvd25WZWN0b3IsIExlZnRGbG9vciwgbGVmdGhhcnBvb25kb3duLCBsZWZ0aGFycG9vbnVwLCBsZWZ0bGVmdGFycm93cywgbGVmdHJpZ2h0YXJyb3csIExlZnRSaWdodEFycm93LCBMZWZ0cmlnaHRhcnJvdywgbGVmdHJpZ2h0YXJyb3dzLCBsZWZ0cmlnaHRoYXJwb29ucywgbGVmdHJpZ2h0c3F1aWdhcnJvdywgTGVmdFJpZ2h0VmVjdG9yLCBMZWZ0VGVlQXJyb3csIExlZnRUZWUsIExlZnRUZWVWZWN0b3IsIGxlZnR0aHJlZXRpbWVzLCBMZWZ0VHJpYW5nbGVCYXIsIExlZnRUcmlhbmdsZSwgTGVmdFRyaWFuZ2xlRXF1YWwsIExlZnRVcERvd25WZWN0b3IsIExlZnRVcFRlZVZlY3RvciwgTGVmdFVwVmVjdG9yQmFyLCBMZWZ0VXBWZWN0b3IsIExlZnRWZWN0b3JCYXIsIExlZnRWZWN0b3IsIGxFZywgbGVnLCBsZXEsIGxlcXEsIGxlcXNsYW50LCBsZXNjYywgbGVzLCBsZXNkb3QsIGxlc2RvdG8sIGxlc2RvdG9yLCBsZXNnLCBsZXNnZXMsIGxlc3NhcHByb3gsIGxlc3Nkb3QsIGxlc3NlcWd0ciwgbGVzc2VxcWd0ciwgTGVzc0VxdWFsR3JlYXRlciwgTGVzc0Z1bGxFcXVhbCwgTGVzc0dyZWF0ZXIsIGxlc3NndHIsIExlc3NMZXNzLCBsZXNzc2ltLCBMZXNzU2xhbnRFcXVhbCwgTGVzc1RpbGRlLCBsZmlzaHQsIGxmbG9vciwgTGZyLCBsZnIsIGxnLCBsZ0UsIGxIYXIsIGxoYXJkLCBsaGFydSwgbGhhcnVsLCBsaGJsaywgTEpjeSwgbGpjeSwgbGxhcnIsIGxsLCBMbCwgbGxjb3JuZXIsIExsZWZ0YXJyb3csIGxsaGFyZCwgbGx0cmksIExtaWRvdCwgbG1pZG90LCBsbW91c3RhY2hlLCBsbW91c3QsIGxuYXAsIGxuYXBwcm94LCBsbmUsIGxuRSwgbG5lcSwgbG5lcXEsIGxuc2ltLCBsb2FuZywgbG9hcnIsIGxvYnJrLCBsb25nbGVmdGFycm93LCBMb25nTGVmdEFycm93LCBMb25nbGVmdGFycm93LCBsb25nbGVmdHJpZ2h0YXJyb3csIExvbmdMZWZ0UmlnaHRBcnJvdywgTG9uZ2xlZnRyaWdodGFycm93LCBsb25nbWFwc3RvLCBsb25ncmlnaHRhcnJvdywgTG9uZ1JpZ2h0QXJyb3csIExvbmdyaWdodGFycm93LCBsb29wYXJyb3dsZWZ0LCBsb29wYXJyb3dyaWdodCwgbG9wYXIsIExvcGYsIGxvcGYsIGxvcGx1cywgbG90aW1lcywgbG93YXN0LCBsb3diYXIsIExvd2VyTGVmdEFycm93LCBMb3dlclJpZ2h0QXJyb3csIGxveiwgbG96ZW5nZSwgbG96ZiwgbHBhciwgbHBhcmx0LCBscmFyciwgbHJjb3JuZXIsIGxyaGFyLCBscmhhcmQsIGxybSwgbHJ0cmksIGxzYXF1bywgbHNjciwgTHNjciwgbHNoLCBMc2gsIGxzaW0sIGxzaW1lLCBsc2ltZywgbHNxYiwgbHNxdW8sIGxzcXVvciwgTHN0cm9rLCBsc3Ryb2ssIGx0Y2MsIGx0Y2lyLCBsdCwgTFQsIEx0LCBsdGRvdCwgbHRocmVlLCBsdGltZXMsIGx0bGFyciwgbHRxdWVzdCwgbHRyaSwgbHRyaWUsIGx0cmlmLCBsdHJQYXIsIGx1cmRzaGFyLCBsdXJ1aGFyLCBsdmVydG5lcXEsIGx2bkUsIG1hY3IsIG1hbGUsIG1hbHQsIG1hbHRlc2UsIE1hcCwgbWFwLCBtYXBzdG8sIG1hcHN0b2Rvd24sIG1hcHN0b2xlZnQsIG1hcHN0b3VwLCBtYXJrZXIsIG1jb21tYSwgTWN5LCBtY3ksIG1kYXNoLCBtRERvdCwgbWVhc3VyZWRhbmdsZSwgTWVkaXVtU3BhY2UsIE1lbGxpbnRyZiwgTWZyLCBtZnIsIG1obywgbWljcm8sIG1pZGFzdCwgbWlkY2lyLCBtaWQsIG1pZGRvdCwgbWludXNiLCBtaW51cywgbWludXNkLCBtaW51c2R1LCBNaW51c1BsdXMsIG1sY3AsIG1sZHIsIG1ucGx1cywgbW9kZWxzLCBNb3BmLCBtb3BmLCBtcCwgbXNjciwgTXNjciwgbXN0cG9zLCBNdSwgbXUsIG11bHRpbWFwLCBtdW1hcCwgbmFibGEsIE5hY3V0ZSwgbmFjdXRlLCBuYW5nLCBuYXAsIG5hcEUsIG5hcGlkLCBuYXBvcywgbmFwcHJveCwgbmF0dXJhbCwgbmF0dXJhbHMsIG5hdHVyLCBuYnNwLCBuYnVtcCwgbmJ1bXBlLCBuY2FwLCBOY2Fyb24sIG5jYXJvbiwgTmNlZGlsLCBuY2VkaWwsIG5jb25nLCBuY29uZ2RvdCwgbmN1cCwgTmN5LCBuY3ksIG5kYXNoLCBuZWFyaGssIG5lYXJyLCBuZUFyciwgbmVhcnJvdywgbmUsIG5lZG90LCBOZWdhdGl2ZU1lZGl1bVNwYWNlLCBOZWdhdGl2ZVRoaWNrU3BhY2UsIE5lZ2F0aXZlVGhpblNwYWNlLCBOZWdhdGl2ZVZlcnlUaGluU3BhY2UsIG5lcXVpdiwgbmVzZWFyLCBuZXNpbSwgTmVzdGVkR3JlYXRlckdyZWF0ZXIsIE5lc3RlZExlc3NMZXNzLCBOZXdMaW5lLCBuZXhpc3QsIG5leGlzdHMsIE5mciwgbmZyLCBuZ0UsIG5nZSwgbmdlcSwgbmdlcXEsIG5nZXFzbGFudCwgbmdlcywgbkdnLCBuZ3NpbSwgbkd0LCBuZ3QsIG5ndHIsIG5HdHYsIG5oYXJyLCBuaEFyciwgbmhwYXIsIG5pLCBuaXMsIG5pc2QsIG5pdiwgTkpjeSwgbmpjeSwgbmxhcnIsIG5sQXJyLCBubGRyLCBubEUsIG5sZSwgbmxlZnRhcnJvdywgbkxlZnRhcnJvdywgbmxlZnRyaWdodGFycm93LCBuTGVmdHJpZ2h0YXJyb3csIG5sZXEsIG5sZXFxLCBubGVxc2xhbnQsIG5sZXMsIG5sZXNzLCBuTGwsIG5sc2ltLCBuTHQsIG5sdCwgbmx0cmksIG5sdHJpZSwgbkx0diwgbm1pZCwgTm9CcmVhaywgTm9uQnJlYWtpbmdTcGFjZSwgbm9wZiwgTm9wZiwgTm90LCBub3QsIE5vdENvbmdydWVudCwgTm90Q3VwQ2FwLCBOb3REb3VibGVWZXJ0aWNhbEJhciwgTm90RWxlbWVudCwgTm90RXF1YWwsIE5vdEVxdWFsVGlsZGUsIE5vdEV4aXN0cywgTm90R3JlYXRlciwgTm90R3JlYXRlckVxdWFsLCBOb3RHcmVhdGVyRnVsbEVxdWFsLCBOb3RHcmVhdGVyR3JlYXRlciwgTm90R3JlYXRlckxlc3MsIE5vdEdyZWF0ZXJTbGFudEVxdWFsLCBOb3RHcmVhdGVyVGlsZGUsIE5vdEh1bXBEb3duSHVtcCwgTm90SHVtcEVxdWFsLCBub3Rpbiwgbm90aW5kb3QsIG5vdGluRSwgbm90aW52YSwgbm90aW52Yiwgbm90aW52YywgTm90TGVmdFRyaWFuZ2xlQmFyLCBOb3RMZWZ0VHJpYW5nbGUsIE5vdExlZnRUcmlhbmdsZUVxdWFsLCBOb3RMZXNzLCBOb3RMZXNzRXF1YWwsIE5vdExlc3NHcmVhdGVyLCBOb3RMZXNzTGVzcywgTm90TGVzc1NsYW50RXF1YWwsIE5vdExlc3NUaWxkZSwgTm90TmVzdGVkR3JlYXRlckdyZWF0ZXIsIE5vdE5lc3RlZExlc3NMZXNzLCBub3RuaSwgbm90bml2YSwgbm90bml2Yiwgbm90bml2YywgTm90UHJlY2VkZXMsIE5vdFByZWNlZGVzRXF1YWwsIE5vdFByZWNlZGVzU2xhbnRFcXVhbCwgTm90UmV2ZXJzZUVsZW1lbnQsIE5vdFJpZ2h0VHJpYW5nbGVCYXIsIE5vdFJpZ2h0VHJpYW5nbGUsIE5vdFJpZ2h0VHJpYW5nbGVFcXVhbCwgTm90U3F1YXJlU3Vic2V0LCBOb3RTcXVhcmVTdWJzZXRFcXVhbCwgTm90U3F1YXJlU3VwZXJzZXQsIE5vdFNxdWFyZVN1cGVyc2V0RXF1YWwsIE5vdFN1YnNldCwgTm90U3Vic2V0RXF1YWwsIE5vdFN1Y2NlZWRzLCBOb3RTdWNjZWVkc0VxdWFsLCBOb3RTdWNjZWVkc1NsYW50RXF1YWwsIE5vdFN1Y2NlZWRzVGlsZGUsIE5vdFN1cGVyc2V0LCBOb3RTdXBlcnNldEVxdWFsLCBOb3RUaWxkZSwgTm90VGlsZGVFcXVhbCwgTm90VGlsZGVGdWxsRXF1YWwsIE5vdFRpbGRlVGlsZGUsIE5vdFZlcnRpY2FsQmFyLCBucGFyYWxsZWwsIG5wYXIsIG5wYXJzbCwgbnBhcnQsIG5wb2xpbnQsIG5wciwgbnByY3VlLCBucHJlYywgbnByZWNlcSwgbnByZSwgbnJhcnJjLCBucmFyciwgbnJBcnIsIG5yYXJydywgbnJpZ2h0YXJyb3csIG5SaWdodGFycm93LCBucnRyaSwgbnJ0cmllLCBuc2MsIG5zY2N1ZSwgbnNjZSwgTnNjciwgbnNjciwgbnNob3J0bWlkLCBuc2hvcnRwYXJhbGxlbCwgbnNpbSwgbnNpbWUsIG5zaW1lcSwgbnNtaWQsIG5zcGFyLCBuc3FzdWJlLCBuc3FzdXBlLCBuc3ViLCBuc3ViRSwgbnN1YmUsIG5zdWJzZXQsIG5zdWJzZXRlcSwgbnN1YnNldGVxcSwgbnN1Y2MsIG5zdWNjZXEsIG5zdXAsIG5zdXBFLCBuc3VwZSwgbnN1cHNldCwgbnN1cHNldGVxLCBuc3Vwc2V0ZXFxLCBudGdsLCBOdGlsZGUsIG50aWxkZSwgbnRsZywgbnRyaWFuZ2xlbGVmdCwgbnRyaWFuZ2xlbGVmdGVxLCBudHJpYW5nbGVyaWdodCwgbnRyaWFuZ2xlcmlnaHRlcSwgTnUsIG51LCBudW0sIG51bWVybywgbnVtc3AsIG52YXAsIG52ZGFzaCwgbnZEYXNoLCBuVmRhc2gsIG5WRGFzaCwgbnZnZSwgbnZndCwgbnZIYXJyLCBudmluZmluLCBudmxBcnIsIG52bGUsIG52bHQsIG52bHRyaWUsIG52ckFyciwgbnZydHJpZSwgbnZzaW0sIG53YXJoaywgbndhcnIsIG53QXJyLCBud2Fycm93LCBud25lYXIsIE9hY3V0ZSwgb2FjdXRlLCBvYXN0LCBPY2lyYywgb2NpcmMsIG9jaXIsIE9jeSwgb2N5LCBvZGFzaCwgT2RibGFjLCBvZGJsYWMsIG9kaXYsIG9kb3QsIG9kc29sZCwgT0VsaWcsIG9lbGlnLCBvZmNpciwgT2ZyLCBvZnIsIG9nb24sIE9ncmF2ZSwgb2dyYXZlLCBvZ3QsIG9oYmFyLCBvaG0sIG9pbnQsIG9sYXJyLCBvbGNpciwgb2xjcm9zcywgb2xpbmUsIG9sdCwgT21hY3IsIG9tYWNyLCBPbWVnYSwgb21lZ2EsIE9taWNyb24sIG9taWNyb24sIG9taWQsIG9taW51cywgT29wZiwgb29wZiwgb3BhciwgT3BlbkN1cmx5RG91YmxlUXVvdGUsIE9wZW5DdXJseVF1b3RlLCBvcGVycCwgb3BsdXMsIG9yYXJyLCBPciwgb3IsIG9yZCwgb3JkZXIsIG9yZGVyb2YsIG9yZGYsIG9yZG0sIG9yaWdvZiwgb3Jvciwgb3JzbG9wZSwgb3J2LCBvUywgT3Njciwgb3NjciwgT3NsYXNoLCBvc2xhc2gsIG9zb2wsIE90aWxkZSwgb3RpbGRlLCBvdGltZXNhcywgT3RpbWVzLCBvdGltZXMsIE91bWwsIG91bWwsIG92YmFyLCBPdmVyQmFyLCBPdmVyQnJhY2UsIE92ZXJCcmFja2V0LCBPdmVyUGFyZW50aGVzaXMsIHBhcmEsIHBhcmFsbGVsLCBwYXIsIHBhcnNpbSwgcGFyc2wsIHBhcnQsIFBhcnRpYWxELCBQY3ksIHBjeSwgcGVyY250LCBwZXJpb2QsIHBlcm1pbCwgcGVycCwgcGVydGVuaywgUGZyLCBwZnIsIFBoaSwgcGhpLCBwaGl2LCBwaG1tYXQsIHBob25lLCBQaSwgcGksIHBpdGNoZm9yaywgcGl2LCBwbGFuY2ssIHBsYW5ja2gsIHBsYW5rdiwgcGx1c2FjaXIsIHBsdXNiLCBwbHVzY2lyLCBwbHVzLCBwbHVzZG8sIHBsdXNkdSwgcGx1c2UsIFBsdXNNaW51cywgcGx1c21uLCBwbHVzc2ltLCBwbHVzdHdvLCBwbSwgUG9pbmNhcmVwbGFuZSwgcG9pbnRpbnQsIHBvcGYsIFBvcGYsIHBvdW5kLCBwcmFwLCBQciwgcHIsIHByY3VlLCBwcmVjYXBwcm94LCBwcmVjLCBwcmVjY3VybHllcSwgUHJlY2VkZXMsIFByZWNlZGVzRXF1YWwsIFByZWNlZGVzU2xhbnRFcXVhbCwgUHJlY2VkZXNUaWxkZSwgcHJlY2VxLCBwcmVjbmFwcHJveCwgcHJlY25lcXEsIHByZWNuc2ltLCBwcmUsIHByRSwgcHJlY3NpbSwgcHJpbWUsIFByaW1lLCBwcmltZXMsIHBybmFwLCBwcm5FLCBwcm5zaW0sIHByb2QsIFByb2R1Y3QsIHByb2ZhbGFyLCBwcm9mbGluZSwgcHJvZnN1cmYsIHByb3AsIFByb3BvcnRpb25hbCwgUHJvcG9ydGlvbiwgcHJvcHRvLCBwcnNpbSwgcHJ1cmVsLCBQc2NyLCBwc2NyLCBQc2ksIHBzaSwgcHVuY3NwLCBRZnIsIHFmciwgcWludCwgcW9wZiwgUW9wZiwgcXByaW1lLCBRc2NyLCBxc2NyLCBxdWF0ZXJuaW9ucywgcXVhdGludCwgcXVlc3QsIHF1ZXN0ZXEsIHF1b3QsIFFVT1QsIHJBYXJyLCByYWNlLCBSYWN1dGUsIHJhY3V0ZSwgcmFkaWMsIHJhZW1wdHl2LCByYW5nLCBSYW5nLCByYW5nZCwgcmFuZ2UsIHJhbmdsZSwgcmFxdW8sIHJhcnJhcCwgcmFycmIsIHJhcnJiZnMsIHJhcnJjLCByYXJyLCBSYXJyLCByQXJyLCByYXJyZnMsIHJhcnJoaywgcmFycmxwLCByYXJycGwsIHJhcnJzaW0sIFJhcnJ0bCwgcmFycnRsLCByYXJydywgcmF0YWlsLCByQXRhaWwsIHJhdGlvLCByYXRpb25hbHMsIHJiYXJyLCByQmFyciwgUkJhcnIsIHJiYnJrLCByYnJhY2UsIHJicmFjaywgcmJya2UsIHJicmtzbGQsIHJicmtzbHUsIFJjYXJvbiwgcmNhcm9uLCBSY2VkaWwsIHJjZWRpbCwgcmNlaWwsIHJjdWIsIFJjeSwgcmN5LCByZGNhLCByZGxkaGFyLCByZHF1bywgcmRxdW9yLCByZHNoLCByZWFsLCByZWFsaW5lLCByZWFscGFydCwgcmVhbHMsIFJlLCByZWN0LCByZWcsIFJFRywgUmV2ZXJzZUVsZW1lbnQsIFJldmVyc2VFcXVpbGlicml1bSwgUmV2ZXJzZVVwRXF1aWxpYnJpdW0sIHJmaXNodCwgcmZsb29yLCByZnIsIFJmciwgckhhciwgcmhhcmQsIHJoYXJ1LCByaGFydWwsIFJobywgcmhvLCByaG92LCBSaWdodEFuZ2xlQnJhY2tldCwgUmlnaHRBcnJvd0JhciwgcmlnaHRhcnJvdywgUmlnaHRBcnJvdywgUmlnaHRhcnJvdywgUmlnaHRBcnJvd0xlZnRBcnJvdywgcmlnaHRhcnJvd3RhaWwsIFJpZ2h0Q2VpbGluZywgUmlnaHREb3VibGVCcmFja2V0LCBSaWdodERvd25UZWVWZWN0b3IsIFJpZ2h0RG93blZlY3RvckJhciwgUmlnaHREb3duVmVjdG9yLCBSaWdodEZsb29yLCByaWdodGhhcnBvb25kb3duLCByaWdodGhhcnBvb251cCwgcmlnaHRsZWZ0YXJyb3dzLCByaWdodGxlZnRoYXJwb29ucywgcmlnaHRyaWdodGFycm93cywgcmlnaHRzcXVpZ2Fycm93LCBSaWdodFRlZUFycm93LCBSaWdodFRlZSwgUmlnaHRUZWVWZWN0b3IsIHJpZ2h0dGhyZWV0aW1lcywgUmlnaHRUcmlhbmdsZUJhciwgUmlnaHRUcmlhbmdsZSwgUmlnaHRUcmlhbmdsZUVxdWFsLCBSaWdodFVwRG93blZlY3RvciwgUmlnaHRVcFRlZVZlY3RvciwgUmlnaHRVcFZlY3RvckJhciwgUmlnaHRVcFZlY3RvciwgUmlnaHRWZWN0b3JCYXIsIFJpZ2h0VmVjdG9yLCByaW5nLCByaXNpbmdkb3RzZXEsIHJsYXJyLCBybGhhciwgcmxtLCBybW91c3RhY2hlLCBybW91c3QsIHJubWlkLCByb2FuZywgcm9hcnIsIHJvYnJrLCByb3Bhciwgcm9wZiwgUm9wZiwgcm9wbHVzLCByb3RpbWVzLCBSb3VuZEltcGxpZXMsIHJwYXIsIHJwYXJndCwgcnBwb2xpbnQsIHJyYXJyLCBScmlnaHRhcnJvdywgcnNhcXVvLCByc2NyLCBSc2NyLCByc2gsIFJzaCwgcnNxYiwgcnNxdW8sIHJzcXVvciwgcnRocmVlLCBydGltZXMsIHJ0cmksIHJ0cmllLCBydHJpZiwgcnRyaWx0cmksIFJ1bGVEZWxheWVkLCBydWx1aGFyLCByeCwgU2FjdXRlLCBzYWN1dGUsIHNicXVvLCBzY2FwLCBTY2Fyb24sIHNjYXJvbiwgU2MsIHNjLCBzY2N1ZSwgc2NlLCBzY0UsIFNjZWRpbCwgc2NlZGlsLCBTY2lyYywgc2NpcmMsIHNjbmFwLCBzY25FLCBzY25zaW0sIHNjcG9saW50LCBzY3NpbSwgU2N5LCBzY3ksIHNkb3RiLCBzZG90LCBzZG90ZSwgc2VhcmhrLCBzZWFyciwgc2VBcnIsIHNlYXJyb3csIHNlY3QsIHNlbWksIHNlc3dhciwgc2V0bWludXMsIHNldG1uLCBzZXh0LCBTZnIsIHNmciwgc2Zyb3duLCBzaGFycCwgU0hDSGN5LCBzaGNoY3ksIFNIY3ksIHNoY3ksIFNob3J0RG93bkFycm93LCBTaG9ydExlZnRBcnJvdywgc2hvcnRtaWQsIHNob3J0cGFyYWxsZWwsIFNob3J0UmlnaHRBcnJvdywgU2hvcnRVcEFycm93LCBzaHksIFNpZ21hLCBzaWdtYSwgc2lnbWFmLCBzaWdtYXYsIHNpbSwgc2ltZG90LCBzaW1lLCBzaW1lcSwgc2ltZywgc2ltZ0UsIHNpbWwsIHNpbWxFLCBzaW1uZSwgc2ltcGx1cywgc2ltcmFyciwgc2xhcnIsIFNtYWxsQ2lyY2xlLCBzbWFsbHNldG1pbnVzLCBzbWFzaHAsIHNtZXBhcnNsLCBzbWlkLCBzbWlsZSwgc210LCBzbXRlLCBzbXRlcywgU09GVGN5LCBzb2Z0Y3ksIHNvbGJhciwgc29sYiwgc29sLCBTb3BmLCBzb3BmLCBzcGFkZXMsIHNwYWRlc3VpdCwgc3Bhciwgc3FjYXAsIHNxY2Fwcywgc3FjdXAsIHNxY3VwcywgU3FydCwgc3FzdWIsIHNxc3ViZSwgc3FzdWJzZXQsIHNxc3Vic2V0ZXEsIHNxc3VwLCBzcXN1cGUsIHNxc3Vwc2V0LCBzcXN1cHNldGVxLCBzcXVhcmUsIFNxdWFyZSwgU3F1YXJlSW50ZXJzZWN0aW9uLCBTcXVhcmVTdWJzZXQsIFNxdWFyZVN1YnNldEVxdWFsLCBTcXVhcmVTdXBlcnNldCwgU3F1YXJlU3VwZXJzZXRFcXVhbCwgU3F1YXJlVW5pb24sIHNxdWFyZiwgc3F1LCBzcXVmLCBzcmFyciwgU3Njciwgc3Njciwgc3NldG1uLCBzc21pbGUsIHNzdGFyZiwgU3Rhciwgc3Rhciwgc3RhcmYsIHN0cmFpZ2h0ZXBzaWxvbiwgc3RyYWlnaHRwaGksIHN0cm5zLCBzdWIsIFN1Yiwgc3ViZG90LCBzdWJFLCBzdWJlLCBzdWJlZG90LCBzdWJtdWx0LCBzdWJuRSwgc3VibmUsIHN1YnBsdXMsIHN1YnJhcnIsIHN1YnNldCwgU3Vic2V0LCBzdWJzZXRlcSwgc3Vic2V0ZXFxLCBTdWJzZXRFcXVhbCwgc3Vic2V0bmVxLCBzdWJzZXRuZXFxLCBzdWJzaW0sIHN1YnN1Yiwgc3Vic3VwLCBzdWNjYXBwcm94LCBzdWNjLCBzdWNjY3VybHllcSwgU3VjY2VlZHMsIFN1Y2NlZWRzRXF1YWwsIFN1Y2NlZWRzU2xhbnRFcXVhbCwgU3VjY2VlZHNUaWxkZSwgc3VjY2VxLCBzdWNjbmFwcHJveCwgc3VjY25lcXEsIHN1Y2Nuc2ltLCBzdWNjc2ltLCBTdWNoVGhhdCwgc3VtLCBTdW0sIHN1bmcsIHN1cDEsIHN1cDIsIHN1cDMsIHN1cCwgU3VwLCBzdXBkb3QsIHN1cGRzdWIsIHN1cEUsIHN1cGUsIHN1cGVkb3QsIFN1cGVyc2V0LCBTdXBlcnNldEVxdWFsLCBzdXBoc29sLCBzdXBoc3ViLCBzdXBsYXJyLCBzdXBtdWx0LCBzdXBuRSwgc3VwbmUsIHN1cHBsdXMsIHN1cHNldCwgU3Vwc2V0LCBzdXBzZXRlcSwgc3Vwc2V0ZXFxLCBzdXBzZXRuZXEsIHN1cHNldG5lcXEsIHN1cHNpbSwgc3Vwc3ViLCBzdXBzdXAsIHN3YXJoaywgc3dhcnIsIHN3QXJyLCBzd2Fycm93LCBzd253YXIsIHN6bGlnLCBUYWIsIHRhcmdldCwgVGF1LCB0YXUsIHRicmssIFRjYXJvbiwgdGNhcm9uLCBUY2VkaWwsIHRjZWRpbCwgVGN5LCB0Y3ksIHRkb3QsIHRlbHJlYywgVGZyLCB0ZnIsIHRoZXJlNCwgdGhlcmVmb3JlLCBUaGVyZWZvcmUsIFRoZXRhLCB0aGV0YSwgdGhldGFzeW0sIHRoZXRhdiwgdGhpY2thcHByb3gsIHRoaWNrc2ltLCBUaGlja1NwYWNlLCBUaGluU3BhY2UsIHRoaW5zcCwgdGhrYXAsIHRoa3NpbSwgVEhPUk4sIHRob3JuLCB0aWxkZSwgVGlsZGUsIFRpbGRlRXF1YWwsIFRpbGRlRnVsbEVxdWFsLCBUaWxkZVRpbGRlLCB0aW1lc2JhciwgdGltZXNiLCB0aW1lcywgdGltZXNkLCB0aW50LCB0b2VhLCB0b3Bib3QsIHRvcGNpciwgdG9wLCBUb3BmLCB0b3BmLCB0b3Bmb3JrLCB0b3NhLCB0cHJpbWUsIHRyYWRlLCBUUkFERSwgdHJpYW5nbGUsIHRyaWFuZ2xlZG93biwgdHJpYW5nbGVsZWZ0LCB0cmlhbmdsZWxlZnRlcSwgdHJpYW5nbGVxLCB0cmlhbmdsZXJpZ2h0LCB0cmlhbmdsZXJpZ2h0ZXEsIHRyaWRvdCwgdHJpZSwgdHJpbWludXMsIFRyaXBsZURvdCwgdHJpcGx1cywgdHJpc2IsIHRyaXRpbWUsIHRycGV6aXVtLCBUc2NyLCB0c2NyLCBUU2N5LCB0c2N5LCBUU0hjeSwgdHNoY3ksIFRzdHJvaywgdHN0cm9rLCB0d2l4dCwgdHdvaGVhZGxlZnRhcnJvdywgdHdvaGVhZHJpZ2h0YXJyb3csIFVhY3V0ZSwgdWFjdXRlLCB1YXJyLCBVYXJyLCB1QXJyLCBVYXJyb2NpciwgVWJyY3ksIHVicmN5LCBVYnJldmUsIHVicmV2ZSwgVWNpcmMsIHVjaXJjLCBVY3ksIHVjeSwgdWRhcnIsIFVkYmxhYywgdWRibGFjLCB1ZGhhciwgdWZpc2h0LCBVZnIsIHVmciwgVWdyYXZlLCB1Z3JhdmUsIHVIYXIsIHVoYXJsLCB1aGFyciwgdWhibGssIHVsY29ybiwgdWxjb3JuZXIsIHVsY3JvcCwgdWx0cmksIFVtYWNyLCB1bWFjciwgdW1sLCBVbmRlckJhciwgVW5kZXJCcmFjZSwgVW5kZXJCcmFja2V0LCBVbmRlclBhcmVudGhlc2lzLCBVbmlvbiwgVW5pb25QbHVzLCBVb2dvbiwgdW9nb24sIFVvcGYsIHVvcGYsIFVwQXJyb3dCYXIsIHVwYXJyb3csIFVwQXJyb3csIFVwYXJyb3csIFVwQXJyb3dEb3duQXJyb3csIHVwZG93bmFycm93LCBVcERvd25BcnJvdywgVXBkb3duYXJyb3csIFVwRXF1aWxpYnJpdW0sIHVwaGFycG9vbmxlZnQsIHVwaGFycG9vbnJpZ2h0LCB1cGx1cywgVXBwZXJMZWZ0QXJyb3csIFVwcGVyUmlnaHRBcnJvdywgdXBzaSwgVXBzaSwgdXBzaWgsIFVwc2lsb24sIHVwc2lsb24sIFVwVGVlQXJyb3csIFVwVGVlLCB1cHVwYXJyb3dzLCB1cmNvcm4sIHVyY29ybmVyLCB1cmNyb3AsIFVyaW5nLCB1cmluZywgdXJ0cmksIFVzY3IsIHVzY3IsIHV0ZG90LCBVdGlsZGUsIHV0aWxkZSwgdXRyaSwgdXRyaWYsIHV1YXJyLCBVdW1sLCB1dW1sLCB1d2FuZ2xlLCB2YW5ncnQsIHZhcmVwc2lsb24sIHZhcmthcHBhLCB2YXJub3RoaW5nLCB2YXJwaGksIHZhcnBpLCB2YXJwcm9wdG8sIHZhcnIsIHZBcnIsIHZhcnJobywgdmFyc2lnbWEsIHZhcnN1YnNldG5lcSwgdmFyc3Vic2V0bmVxcSwgdmFyc3Vwc2V0bmVxLCB2YXJzdXBzZXRuZXFxLCB2YXJ0aGV0YSwgdmFydHJpYW5nbGVsZWZ0LCB2YXJ0cmlhbmdsZXJpZ2h0LCB2QmFyLCBWYmFyLCB2QmFydiwgVmN5LCB2Y3ksIHZkYXNoLCB2RGFzaCwgVmRhc2gsIFZEYXNoLCBWZGFzaGwsIHZlZWJhciwgdmVlLCBWZWUsIHZlZWVxLCB2ZWxsaXAsIHZlcmJhciwgVmVyYmFyLCB2ZXJ0LCBWZXJ0LCBWZXJ0aWNhbEJhciwgVmVydGljYWxMaW5lLCBWZXJ0aWNhbFNlcGFyYXRvciwgVmVydGljYWxUaWxkZSwgVmVyeVRoaW5TcGFjZSwgVmZyLCB2ZnIsIHZsdHJpLCB2bnN1Yiwgdm5zdXAsIFZvcGYsIHZvcGYsIHZwcm9wLCB2cnRyaSwgVnNjciwgdnNjciwgdnN1Ym5FLCB2c3VibmUsIHZzdXBuRSwgdnN1cG5lLCBWdmRhc2gsIHZ6aWd6YWcsIFdjaXJjLCB3Y2lyYywgd2VkYmFyLCB3ZWRnZSwgV2VkZ2UsIHdlZGdlcSwgd2VpZXJwLCBXZnIsIHdmciwgV29wZiwgd29wZiwgd3AsIHdyLCB3cmVhdGgsIFdzY3IsIHdzY3IsIHhjYXAsIHhjaXJjLCB4Y3VwLCB4ZHRyaSwgWGZyLCB4ZnIsIHhoYXJyLCB4aEFyciwgWGksIHhpLCB4bGFyciwgeGxBcnIsIHhtYXAsIHhuaXMsIHhvZG90LCBYb3BmLCB4b3BmLCB4b3BsdXMsIHhvdGltZSwgeHJhcnIsIHhyQXJyLCBYc2NyLCB4c2NyLCB4c3FjdXAsIHh1cGx1cywgeHV0cmksIHh2ZWUsIHh3ZWRnZSwgWWFjdXRlLCB5YWN1dGUsIFlBY3ksIHlhY3ksIFljaXJjLCB5Y2lyYywgWWN5LCB5Y3ksIHllbiwgWWZyLCB5ZnIsIFlJY3ksIHlpY3ksIFlvcGYsIHlvcGYsIFlzY3IsIHlzY3IsIFlVY3ksIHl1Y3ksIHl1bWwsIFl1bWwsIFphY3V0ZSwgemFjdXRlLCBaY2Fyb24sIHpjYXJvbiwgWmN5LCB6Y3ksIFpkb3QsIHpkb3QsIHplZXRyZiwgWmVyb1dpZHRoU3BhY2UsIFpldGEsIHpldGEsIHpmciwgWmZyLCBaSGN5LCB6aGN5LCB6aWdyYXJyLCB6b3BmLCBab3BmLCBac2NyLCB6c2NyLCB6d2osIHp3bmosIGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUpIHtcblxubW9kdWxlLmV4cG9ydHMgPSBKU09OLnBhcnNlKFwie1xcXCJBYWN1dGVcXFwiOlxcXCLDgVxcXCIsXFxcImFhY3V0ZVxcXCI6XFxcIsOhXFxcIixcXFwiQWJyZXZlXFxcIjpcXFwixIJcXFwiLFxcXCJhYnJldmVcXFwiOlxcXCLEg1xcXCIsXFxcImFjXFxcIjpcXFwi4oi+XFxcIixcXFwiYWNkXFxcIjpcXFwi4oi/XFxcIixcXFwiYWNFXFxcIjpcXFwi4oi+zLNcXFwiLFxcXCJBY2lyY1xcXCI6XFxcIsOCXFxcIixcXFwiYWNpcmNcXFwiOlxcXCLDolxcXCIsXFxcImFjdXRlXFxcIjpcXFwiwrRcXFwiLFxcXCJBY3lcXFwiOlxcXCLQkFxcXCIsXFxcImFjeVxcXCI6XFxcItCwXFxcIixcXFwiQUVsaWdcXFwiOlxcXCLDhlxcXCIsXFxcImFlbGlnXFxcIjpcXFwiw6ZcXFwiLFxcXCJhZlxcXCI6XFxcIuKBoVxcXCIsXFxcIkFmclxcXCI6XFxcIvCdlIRcXFwiLFxcXCJhZnJcXFwiOlxcXCLwnZSeXFxcIixcXFwiQWdyYXZlXFxcIjpcXFwiw4BcXFwiLFxcXCJhZ3JhdmVcXFwiOlxcXCLDoFxcXCIsXFxcImFsZWZzeW1cXFwiOlxcXCLihLVcXFwiLFxcXCJhbGVwaFxcXCI6XFxcIuKEtVxcXCIsXFxcIkFscGhhXFxcIjpcXFwizpFcXFwiLFxcXCJhbHBoYVxcXCI6XFxcIs6xXFxcIixcXFwiQW1hY3JcXFwiOlxcXCLEgFxcXCIsXFxcImFtYWNyXFxcIjpcXFwixIFcXFwiLFxcXCJhbWFsZ1xcXCI6XFxcIuKov1xcXCIsXFxcImFtcFxcXCI6XFxcIiZcXFwiLFxcXCJBTVBcXFwiOlxcXCImXFxcIixcXFwiYW5kYW5kXFxcIjpcXFwi4qmVXFxcIixcXFwiQW5kXFxcIjpcXFwi4qmTXFxcIixcXFwiYW5kXFxcIjpcXFwi4oinXFxcIixcXFwiYW5kZFxcXCI6XFxcIuKpnFxcXCIsXFxcImFuZHNsb3BlXFxcIjpcXFwi4qmYXFxcIixcXFwiYW5kdlxcXCI6XFxcIuKpmlxcXCIsXFxcImFuZ1xcXCI6XFxcIuKIoFxcXCIsXFxcImFuZ2VcXFwiOlxcXCLipqRcXFwiLFxcXCJhbmdsZVxcXCI6XFxcIuKIoFxcXCIsXFxcImFuZ21zZGFhXFxcIjpcXFwi4qaoXFxcIixcXFwiYW5nbXNkYWJcXFwiOlxcXCLipqlcXFwiLFxcXCJhbmdtc2RhY1xcXCI6XFxcIuKmqlxcXCIsXFxcImFuZ21zZGFkXFxcIjpcXFwi4qarXFxcIixcXFwiYW5nbXNkYWVcXFwiOlxcXCLipqxcXFwiLFxcXCJhbmdtc2RhZlxcXCI6XFxcIuKmrVxcXCIsXFxcImFuZ21zZGFnXFxcIjpcXFwi4qauXFxcIixcXFwiYW5nbXNkYWhcXFwiOlxcXCLipq9cXFwiLFxcXCJhbmdtc2RcXFwiOlxcXCLiiKFcXFwiLFxcXCJhbmdydFxcXCI6XFxcIuKIn1xcXCIsXFxcImFuZ3J0dmJcXFwiOlxcXCLiir5cXFwiLFxcXCJhbmdydHZiZFxcXCI6XFxcIuKmnVxcXCIsXFxcImFuZ3NwaFxcXCI6XFxcIuKIolxcXCIsXFxcImFuZ3N0XFxcIjpcXFwiw4VcXFwiLFxcXCJhbmd6YXJyXFxcIjpcXFwi4o28XFxcIixcXFwiQW9nb25cXFwiOlxcXCLEhFxcXCIsXFxcImFvZ29uXFxcIjpcXFwixIVcXFwiLFxcXCJBb3BmXFxcIjpcXFwi8J2UuFxcXCIsXFxcImFvcGZcXFwiOlxcXCLwnZWSXFxcIixcXFwiYXBhY2lyXFxcIjpcXFwi4qmvXFxcIixcXFwiYXBcXFwiOlxcXCLiiYhcXFwiLFxcXCJhcEVcXFwiOlxcXCLiqbBcXFwiLFxcXCJhcGVcXFwiOlxcXCLiiYpcXFwiLFxcXCJhcGlkXFxcIjpcXFwi4omLXFxcIixcXFwiYXBvc1xcXCI6XFxcIidcXFwiLFxcXCJBcHBseUZ1bmN0aW9uXFxcIjpcXFwi4oGhXFxcIixcXFwiYXBwcm94XFxcIjpcXFwi4omIXFxcIixcXFwiYXBwcm94ZXFcXFwiOlxcXCLiiYpcXFwiLFxcXCJBcmluZ1xcXCI6XFxcIsOFXFxcIixcXFwiYXJpbmdcXFwiOlxcXCLDpVxcXCIsXFxcIkFzY3JcXFwiOlxcXCLwnZKcXFxcIixcXFwiYXNjclxcXCI6XFxcIvCdkrZcXFwiLFxcXCJBc3NpZ25cXFwiOlxcXCLiiZRcXFwiLFxcXCJhc3RcXFwiOlxcXCIqXFxcIixcXFwiYXN5bXBcXFwiOlxcXCLiiYhcXFwiLFxcXCJhc3ltcGVxXFxcIjpcXFwi4omNXFxcIixcXFwiQXRpbGRlXFxcIjpcXFwiw4NcXFwiLFxcXCJhdGlsZGVcXFwiOlxcXCLDo1xcXCIsXFxcIkF1bWxcXFwiOlxcXCLDhFxcXCIsXFxcImF1bWxcXFwiOlxcXCLDpFxcXCIsXFxcImF3Y29uaW50XFxcIjpcXFwi4oizXFxcIixcXFwiYXdpbnRcXFwiOlxcXCLiqJFcXFwiLFxcXCJiYWNrY29uZ1xcXCI6XFxcIuKJjFxcXCIsXFxcImJhY2tlcHNpbG9uXFxcIjpcXFwiz7ZcXFwiLFxcXCJiYWNrcHJpbWVcXFwiOlxcXCLigLVcXFwiLFxcXCJiYWNrc2ltXFxcIjpcXFwi4oi9XFxcIixcXFwiYmFja3NpbWVxXFxcIjpcXFwi4ouNXFxcIixcXFwiQmFja3NsYXNoXFxcIjpcXFwi4oiWXFxcIixcXFwiQmFydlxcXCI6XFxcIuKrp1xcXCIsXFxcImJhcnZlZVxcXCI6XFxcIuKKvVxcXCIsXFxcImJhcndlZFxcXCI6XFxcIuKMhVxcXCIsXFxcIkJhcndlZFxcXCI6XFxcIuKMhlxcXCIsXFxcImJhcndlZGdlXFxcIjpcXFwi4oyFXFxcIixcXFwiYmJya1xcXCI6XFxcIuKOtVxcXCIsXFxcImJicmt0YnJrXFxcIjpcXFwi4o62XFxcIixcXFwiYmNvbmdcXFwiOlxcXCLiiYxcXFwiLFxcXCJCY3lcXFwiOlxcXCLQkVxcXCIsXFxcImJjeVxcXCI6XFxcItCxXFxcIixcXFwiYmRxdW9cXFwiOlxcXCLigJ5cXFwiLFxcXCJiZWNhdXNcXFwiOlxcXCLiiLVcXFwiLFxcXCJiZWNhdXNlXFxcIjpcXFwi4oi1XFxcIixcXFwiQmVjYXVzZVxcXCI6XFxcIuKItVxcXCIsXFxcImJlbXB0eXZcXFwiOlxcXCLiprBcXFwiLFxcXCJiZXBzaVxcXCI6XFxcIs+2XFxcIixcXFwiYmVybm91XFxcIjpcXFwi4oSsXFxcIixcXFwiQmVybm91bGxpc1xcXCI6XFxcIuKErFxcXCIsXFxcIkJldGFcXFwiOlxcXCLOklxcXCIsXFxcImJldGFcXFwiOlxcXCLOslxcXCIsXFxcImJldGhcXFwiOlxcXCLihLZcXFwiLFxcXCJiZXR3ZWVuXFxcIjpcXFwi4omsXFxcIixcXFwiQmZyXFxcIjpcXFwi8J2UhVxcXCIsXFxcImJmclxcXCI6XFxcIvCdlJ9cXFwiLFxcXCJiaWdjYXBcXFwiOlxcXCLii4JcXFwiLFxcXCJiaWdjaXJjXFxcIjpcXFwi4pevXFxcIixcXFwiYmlnY3VwXFxcIjpcXFwi4ouDXFxcIixcXFwiYmlnb2RvdFxcXCI6XFxcIuKogFxcXCIsXFxcImJpZ29wbHVzXFxcIjpcXFwi4qiBXFxcIixcXFwiYmlnb3RpbWVzXFxcIjpcXFwi4qiCXFxcIixcXFwiYmlnc3FjdXBcXFwiOlxcXCLiqIZcXFwiLFxcXCJiaWdzdGFyXFxcIjpcXFwi4piFXFxcIixcXFwiYmlndHJpYW5nbGVkb3duXFxcIjpcXFwi4pa9XFxcIixcXFwiYmlndHJpYW5nbGV1cFxcXCI6XFxcIuKWs1xcXCIsXFxcImJpZ3VwbHVzXFxcIjpcXFwi4qiEXFxcIixcXFwiYmlndmVlXFxcIjpcXFwi4ouBXFxcIixcXFwiYmlnd2VkZ2VcXFwiOlxcXCLii4BcXFwiLFxcXCJia2Fyb3dcXFwiOlxcXCLipI1cXFwiLFxcXCJibGFja2xvemVuZ2VcXFwiOlxcXCLip6tcXFwiLFxcXCJibGFja3NxdWFyZVxcXCI6XFxcIuKWqlxcXCIsXFxcImJsYWNrdHJpYW5nbGVcXFwiOlxcXCLilrRcXFwiLFxcXCJibGFja3RyaWFuZ2xlZG93blxcXCI6XFxcIuKWvlxcXCIsXFxcImJsYWNrdHJpYW5nbGVsZWZ0XFxcIjpcXFwi4peCXFxcIixcXFwiYmxhY2t0cmlhbmdsZXJpZ2h0XFxcIjpcXFwi4pa4XFxcIixcXFwiYmxhbmtcXFwiOlxcXCLikKNcXFwiLFxcXCJibGsxMlxcXCI6XFxcIuKWklxcXCIsXFxcImJsazE0XFxcIjpcXFwi4paRXFxcIixcXFwiYmxrMzRcXFwiOlxcXCLilpNcXFwiLFxcXCJibG9ja1xcXCI6XFxcIuKWiFxcXCIsXFxcImJuZVxcXCI6XFxcIj3ig6VcXFwiLFxcXCJibmVxdWl2XFxcIjpcXFwi4omh4oOlXFxcIixcXFwiYk5vdFxcXCI6XFxcIuKrrVxcXCIsXFxcImJub3RcXFwiOlxcXCLijJBcXFwiLFxcXCJCb3BmXFxcIjpcXFwi8J2UuVxcXCIsXFxcImJvcGZcXFwiOlxcXCLwnZWTXFxcIixcXFwiYm90XFxcIjpcXFwi4oqlXFxcIixcXFwiYm90dG9tXFxcIjpcXFwi4oqlXFxcIixcXFwiYm93dGllXFxcIjpcXFwi4ouIXFxcIixcXFwiYm94Ym94XFxcIjpcXFwi4qeJXFxcIixcXFwiYm94ZGxcXFwiOlxcXCLilJBcXFwiLFxcXCJib3hkTFxcXCI6XFxcIuKVlVxcXCIsXFxcImJveERsXFxcIjpcXFwi4pWWXFxcIixcXFwiYm94RExcXFwiOlxcXCLilZdcXFwiLFxcXCJib3hkclxcXCI6XFxcIuKUjFxcXCIsXFxcImJveGRSXFxcIjpcXFwi4pWSXFxcIixcXFwiYm94RHJcXFwiOlxcXCLilZNcXFwiLFxcXCJib3hEUlxcXCI6XFxcIuKVlFxcXCIsXFxcImJveGhcXFwiOlxcXCLilIBcXFwiLFxcXCJib3hIXFxcIjpcXFwi4pWQXFxcIixcXFwiYm94aGRcXFwiOlxcXCLilKxcXFwiLFxcXCJib3hIZFxcXCI6XFxcIuKVpFxcXCIsXFxcImJveGhEXFxcIjpcXFwi4pWlXFxcIixcXFwiYm94SERcXFwiOlxcXCLilaZcXFwiLFxcXCJib3hodVxcXCI6XFxcIuKUtFxcXCIsXFxcImJveEh1XFxcIjpcXFwi4pWnXFxcIixcXFwiYm94aFVcXFwiOlxcXCLilahcXFwiLFxcXCJib3hIVVxcXCI6XFxcIuKVqVxcXCIsXFxcImJveG1pbnVzXFxcIjpcXFwi4oqfXFxcIixcXFwiYm94cGx1c1xcXCI6XFxcIuKKnlxcXCIsXFxcImJveHRpbWVzXFxcIjpcXFwi4oqgXFxcIixcXFwiYm94dWxcXFwiOlxcXCLilJhcXFwiLFxcXCJib3h1TFxcXCI6XFxcIuKVm1xcXCIsXFxcImJveFVsXFxcIjpcXFwi4pWcXFxcIixcXFwiYm94VUxcXFwiOlxcXCLilZ1cXFwiLFxcXCJib3h1clxcXCI6XFxcIuKUlFxcXCIsXFxcImJveHVSXFxcIjpcXFwi4pWYXFxcIixcXFwiYm94VXJcXFwiOlxcXCLilZlcXFwiLFxcXCJib3hVUlxcXCI6XFxcIuKVmlxcXCIsXFxcImJveHZcXFwiOlxcXCLilIJcXFwiLFxcXCJib3hWXFxcIjpcXFwi4pWRXFxcIixcXFwiYm94dmhcXFwiOlxcXCLilLxcXFwiLFxcXCJib3h2SFxcXCI6XFxcIuKVqlxcXCIsXFxcImJveFZoXFxcIjpcXFwi4pWrXFxcIixcXFwiYm94VkhcXFwiOlxcXCLilaxcXFwiLFxcXCJib3h2bFxcXCI6XFxcIuKUpFxcXCIsXFxcImJveHZMXFxcIjpcXFwi4pWhXFxcIixcXFwiYm94VmxcXFwiOlxcXCLilaJcXFwiLFxcXCJib3hWTFxcXCI6XFxcIuKVo1xcXCIsXFxcImJveHZyXFxcIjpcXFwi4pScXFxcIixcXFwiYm94dlJcXFwiOlxcXCLilZ5cXFwiLFxcXCJib3hWclxcXCI6XFxcIuKVn1xcXCIsXFxcImJveFZSXFxcIjpcXFwi4pWgXFxcIixcXFwiYnByaW1lXFxcIjpcXFwi4oC1XFxcIixcXFwiYnJldmVcXFwiOlxcXCLLmFxcXCIsXFxcIkJyZXZlXFxcIjpcXFwiy5hcXFwiLFxcXCJicnZiYXJcXFwiOlxcXCLCplxcXCIsXFxcImJzY3JcXFwiOlxcXCLwnZK3XFxcIixcXFwiQnNjclxcXCI6XFxcIuKErFxcXCIsXFxcImJzZW1pXFxcIjpcXFwi4oGPXFxcIixcXFwiYnNpbVxcXCI6XFxcIuKIvVxcXCIsXFxcImJzaW1lXFxcIjpcXFwi4ouNXFxcIixcXFwiYnNvbGJcXFwiOlxcXCLip4VcXFwiLFxcXCJic29sXFxcIjpcXFwiXFxcXFxcXFxcXFwiLFxcXCJic29saHN1YlxcXCI6XFxcIuKfiFxcXCIsXFxcImJ1bGxcXFwiOlxcXCLigKJcXFwiLFxcXCJidWxsZXRcXFwiOlxcXCLigKJcXFwiLFxcXCJidW1wXFxcIjpcXFwi4omOXFxcIixcXFwiYnVtcEVcXFwiOlxcXCLiqq5cXFwiLFxcXCJidW1wZVxcXCI6XFxcIuKJj1xcXCIsXFxcIkJ1bXBlcVxcXCI6XFxcIuKJjlxcXCIsXFxcImJ1bXBlcVxcXCI6XFxcIuKJj1xcXCIsXFxcIkNhY3V0ZVxcXCI6XFxcIsSGXFxcIixcXFwiY2FjdXRlXFxcIjpcXFwixIdcXFwiLFxcXCJjYXBhbmRcXFwiOlxcXCLiqYRcXFwiLFxcXCJjYXBicmN1cFxcXCI6XFxcIuKpiVxcXCIsXFxcImNhcGNhcFxcXCI6XFxcIuKpi1xcXCIsXFxcImNhcFxcXCI6XFxcIuKIqVxcXCIsXFxcIkNhcFxcXCI6XFxcIuKLklxcXCIsXFxcImNhcGN1cFxcXCI6XFxcIuKph1xcXCIsXFxcImNhcGRvdFxcXCI6XFxcIuKpgFxcXCIsXFxcIkNhcGl0YWxEaWZmZXJlbnRpYWxEXFxcIjpcXFwi4oWFXFxcIixcXFwiY2Fwc1xcXCI6XFxcIuKIqe+4gFxcXCIsXFxcImNhcmV0XFxcIjpcXFwi4oGBXFxcIixcXFwiY2Fyb25cXFwiOlxcXCLLh1xcXCIsXFxcIkNheWxleXNcXFwiOlxcXCLihK1cXFwiLFxcXCJjY2Fwc1xcXCI6XFxcIuKpjVxcXCIsXFxcIkNjYXJvblxcXCI6XFxcIsSMXFxcIixcXFwiY2Nhcm9uXFxcIjpcXFwixI1cXFwiLFxcXCJDY2VkaWxcXFwiOlxcXCLDh1xcXCIsXFxcImNjZWRpbFxcXCI6XFxcIsOnXFxcIixcXFwiQ2NpcmNcXFwiOlxcXCLEiFxcXCIsXFxcImNjaXJjXFxcIjpcXFwixIlcXFwiLFxcXCJDY29uaW50XFxcIjpcXFwi4oiwXFxcIixcXFwiY2N1cHNcXFwiOlxcXCLiqYxcXFwiLFxcXCJjY3Vwc3NtXFxcIjpcXFwi4qmQXFxcIixcXFwiQ2RvdFxcXCI6XFxcIsSKXFxcIixcXFwiY2RvdFxcXCI6XFxcIsSLXFxcIixcXFwiY2VkaWxcXFwiOlxcXCLCuFxcXCIsXFxcIkNlZGlsbGFcXFwiOlxcXCLCuFxcXCIsXFxcImNlbXB0eXZcXFwiOlxcXCLiprJcXFwiLFxcXCJjZW50XFxcIjpcXFwiwqJcXFwiLFxcXCJjZW50ZXJkb3RcXFwiOlxcXCLCt1xcXCIsXFxcIkNlbnRlckRvdFxcXCI6XFxcIsK3XFxcIixcXFwiY2ZyXFxcIjpcXFwi8J2UoFxcXCIsXFxcIkNmclxcXCI6XFxcIuKErVxcXCIsXFxcIkNIY3lcXFwiOlxcXCLQp1xcXCIsXFxcImNoY3lcXFwiOlxcXCLRh1xcXCIsXFxcImNoZWNrXFxcIjpcXFwi4pyTXFxcIixcXFwiY2hlY2ttYXJrXFxcIjpcXFwi4pyTXFxcIixcXFwiQ2hpXFxcIjpcXFwizqdcXFwiLFxcXCJjaGlcXFwiOlxcXCLPh1xcXCIsXFxcImNpcmNcXFwiOlxcXCLLhlxcXCIsXFxcImNpcmNlcVxcXCI6XFxcIuKJl1xcXCIsXFxcImNpcmNsZWFycm93bGVmdFxcXCI6XFxcIuKGulxcXCIsXFxcImNpcmNsZWFycm93cmlnaHRcXFwiOlxcXCLihrtcXFwiLFxcXCJjaXJjbGVkYXN0XFxcIjpcXFwi4oqbXFxcIixcXFwiY2lyY2xlZGNpcmNcXFwiOlxcXCLiippcXFwiLFxcXCJjaXJjbGVkZGFzaFxcXCI6XFxcIuKKnVxcXCIsXFxcIkNpcmNsZURvdFxcXCI6XFxcIuKKmVxcXCIsXFxcImNpcmNsZWRSXFxcIjpcXFwiwq5cXFwiLFxcXCJjaXJjbGVkU1xcXCI6XFxcIuKTiFxcXCIsXFxcIkNpcmNsZU1pbnVzXFxcIjpcXFwi4oqWXFxcIixcXFwiQ2lyY2xlUGx1c1xcXCI6XFxcIuKKlVxcXCIsXFxcIkNpcmNsZVRpbWVzXFxcIjpcXFwi4oqXXFxcIixcXFwiY2lyXFxcIjpcXFwi4peLXFxcIixcXFwiY2lyRVxcXCI6XFxcIuKng1xcXCIsXFxcImNpcmVcXFwiOlxcXCLiiZdcXFwiLFxcXCJjaXJmbmludFxcXCI6XFxcIuKokFxcXCIsXFxcImNpcm1pZFxcXCI6XFxcIuKrr1xcXCIsXFxcImNpcnNjaXJcXFwiOlxcXCLip4JcXFwiLFxcXCJDbG9ja3dpc2VDb250b3VySW50ZWdyYWxcXFwiOlxcXCLiiLJcXFwiLFxcXCJDbG9zZUN1cmx5RG91YmxlUXVvdGVcXFwiOlxcXCLigJ1cXFwiLFxcXCJDbG9zZUN1cmx5UXVvdGVcXFwiOlxcXCLigJlcXFwiLFxcXCJjbHVic1xcXCI6XFxcIuKZo1xcXCIsXFxcImNsdWJzdWl0XFxcIjpcXFwi4pmjXFxcIixcXFwiY29sb25cXFwiOlxcXCI6XFxcIixcXFwiQ29sb25cXFwiOlxcXCLiiLdcXFwiLFxcXCJDb2xvbmVcXFwiOlxcXCLiqbRcXFwiLFxcXCJjb2xvbmVcXFwiOlxcXCLiiZRcXFwiLFxcXCJjb2xvbmVxXFxcIjpcXFwi4omUXFxcIixcXFwiY29tbWFcXFwiOlxcXCIsXFxcIixcXFwiY29tbWF0XFxcIjpcXFwiQFxcXCIsXFxcImNvbXBcXFwiOlxcXCLiiIFcXFwiLFxcXCJjb21wZm5cXFwiOlxcXCLiiJhcXFwiLFxcXCJjb21wbGVtZW50XFxcIjpcXFwi4oiBXFxcIixcXFwiY29tcGxleGVzXFxcIjpcXFwi4oSCXFxcIixcXFwiY29uZ1xcXCI6XFxcIuKJhVxcXCIsXFxcImNvbmdkb3RcXFwiOlxcXCLiqa1cXFwiLFxcXCJDb25ncnVlbnRcXFwiOlxcXCLiiaFcXFwiLFxcXCJjb25pbnRcXFwiOlxcXCLiiK5cXFwiLFxcXCJDb25pbnRcXFwiOlxcXCLiiK9cXFwiLFxcXCJDb250b3VySW50ZWdyYWxcXFwiOlxcXCLiiK5cXFwiLFxcXCJjb3BmXFxcIjpcXFwi8J2VlFxcXCIsXFxcIkNvcGZcXFwiOlxcXCLihIJcXFwiLFxcXCJjb3Byb2RcXFwiOlxcXCLiiJBcXFwiLFxcXCJDb3Byb2R1Y3RcXFwiOlxcXCLiiJBcXFwiLFxcXCJjb3B5XFxcIjpcXFwiwqlcXFwiLFxcXCJDT1BZXFxcIjpcXFwiwqlcXFwiLFxcXCJjb3B5c3JcXFwiOlxcXCLihJdcXFwiLFxcXCJDb3VudGVyQ2xvY2t3aXNlQ29udG91ckludGVncmFsXFxcIjpcXFwi4oizXFxcIixcXFwiY3JhcnJcXFwiOlxcXCLihrVcXFwiLFxcXCJjcm9zc1xcXCI6XFxcIuKcl1xcXCIsXFxcIkNyb3NzXFxcIjpcXFwi4qivXFxcIixcXFwiQ3NjclxcXCI6XFxcIvCdkp5cXFwiLFxcXCJjc2NyXFxcIjpcXFwi8J2SuFxcXCIsXFxcImNzdWJcXFwiOlxcXCLiq49cXFwiLFxcXCJjc3ViZVxcXCI6XFxcIuKrkVxcXCIsXFxcImNzdXBcXFwiOlxcXCLiq5BcXFwiLFxcXCJjc3VwZVxcXCI6XFxcIuKrklxcXCIsXFxcImN0ZG90XFxcIjpcXFwi4ouvXFxcIixcXFwiY3VkYXJybFxcXCI6XFxcIuKkuFxcXCIsXFxcImN1ZGFycnJcXFwiOlxcXCLipLVcXFwiLFxcXCJjdWVwclxcXCI6XFxcIuKLnlxcXCIsXFxcImN1ZXNjXFxcIjpcXFwi4oufXFxcIixcXFwiY3VsYXJyXFxcIjpcXFwi4oa2XFxcIixcXFwiY3VsYXJycFxcXCI6XFxcIuKkvVxcXCIsXFxcImN1cGJyY2FwXFxcIjpcXFwi4qmIXFxcIixcXFwiY3VwY2FwXFxcIjpcXFwi4qmGXFxcIixcXFwiQ3VwQ2FwXFxcIjpcXFwi4omNXFxcIixcXFwiY3VwXFxcIjpcXFwi4oiqXFxcIixcXFwiQ3VwXFxcIjpcXFwi4ouTXFxcIixcXFwiY3VwY3VwXFxcIjpcXFwi4qmKXFxcIixcXFwiY3VwZG90XFxcIjpcXFwi4oqNXFxcIixcXFwiY3Vwb3JcXFwiOlxcXCLiqYVcXFwiLFxcXCJjdXBzXFxcIjpcXFwi4oiq77iAXFxcIixcXFwiY3VyYXJyXFxcIjpcXFwi4oa3XFxcIixcXFwiY3VyYXJybVxcXCI6XFxcIuKkvFxcXCIsXFxcImN1cmx5ZXFwcmVjXFxcIjpcXFwi4oueXFxcIixcXFwiY3VybHllcXN1Y2NcXFwiOlxcXCLii59cXFwiLFxcXCJjdXJseXZlZVxcXCI6XFxcIuKLjlxcXCIsXFxcImN1cmx5d2VkZ2VcXFwiOlxcXCLii49cXFwiLFxcXCJjdXJyZW5cXFwiOlxcXCLCpFxcXCIsXFxcImN1cnZlYXJyb3dsZWZ0XFxcIjpcXFwi4oa2XFxcIixcXFwiY3VydmVhcnJvd3JpZ2h0XFxcIjpcXFwi4oa3XFxcIixcXFwiY3V2ZWVcXFwiOlxcXCLii45cXFwiLFxcXCJjdXdlZFxcXCI6XFxcIuKLj1xcXCIsXFxcImN3Y29uaW50XFxcIjpcXFwi4oiyXFxcIixcXFwiY3dpbnRcXFwiOlxcXCLiiLFcXFwiLFxcXCJjeWxjdHlcXFwiOlxcXCLijK1cXFwiLFxcXCJkYWdnZXJcXFwiOlxcXCLigKBcXFwiLFxcXCJEYWdnZXJcXFwiOlxcXCLigKFcXFwiLFxcXCJkYWxldGhcXFwiOlxcXCLihLhcXFwiLFxcXCJkYXJyXFxcIjpcXFwi4oaTXFxcIixcXFwiRGFyclxcXCI6XFxcIuKGoVxcXCIsXFxcImRBcnJcXFwiOlxcXCLih5NcXFwiLFxcXCJkYXNoXFxcIjpcXFwi4oCQXFxcIixcXFwiRGFzaHZcXFwiOlxcXCLiq6RcXFwiLFxcXCJkYXNodlxcXCI6XFxcIuKKo1xcXCIsXFxcImRia2Fyb3dcXFwiOlxcXCLipI9cXFwiLFxcXCJkYmxhY1xcXCI6XFxcIsudXFxcIixcXFwiRGNhcm9uXFxcIjpcXFwixI5cXFwiLFxcXCJkY2Fyb25cXFwiOlxcXCLEj1xcXCIsXFxcIkRjeVxcXCI6XFxcItCUXFxcIixcXFwiZGN5XFxcIjpcXFwi0LRcXFwiLFxcXCJkZGFnZ2VyXFxcIjpcXFwi4oChXFxcIixcXFwiZGRhcnJcXFwiOlxcXCLih4pcXFwiLFxcXCJERFxcXCI6XFxcIuKFhVxcXCIsXFxcImRkXFxcIjpcXFwi4oWGXFxcIixcXFwiRERvdHJhaGRcXFwiOlxcXCLipJFcXFwiLFxcXCJkZG90c2VxXFxcIjpcXFwi4qm3XFxcIixcXFwiZGVnXFxcIjpcXFwiwrBcXFwiLFxcXCJEZWxcXFwiOlxcXCLiiIdcXFwiLFxcXCJEZWx0YVxcXCI6XFxcIs6UXFxcIixcXFwiZGVsdGFcXFwiOlxcXCLOtFxcXCIsXFxcImRlbXB0eXZcXFwiOlxcXCLiprFcXFwiLFxcXCJkZmlzaHRcXFwiOlxcXCLipb9cXFwiLFxcXCJEZnJcXFwiOlxcXCLwnZSHXFxcIixcXFwiZGZyXFxcIjpcXFwi8J2UoVxcXCIsXFxcImRIYXJcXFwiOlxcXCLipaVcXFwiLFxcXCJkaGFybFxcXCI6XFxcIuKHg1xcXCIsXFxcImRoYXJyXFxcIjpcXFwi4oeCXFxcIixcXFwiRGlhY3JpdGljYWxBY3V0ZVxcXCI6XFxcIsK0XFxcIixcXFwiRGlhY3JpdGljYWxEb3RcXFwiOlxcXCLLmVxcXCIsXFxcIkRpYWNyaXRpY2FsRG91YmxlQWN1dGVcXFwiOlxcXCLLnVxcXCIsXFxcIkRpYWNyaXRpY2FsR3JhdmVcXFwiOlxcXCJgXFxcIixcXFwiRGlhY3JpdGljYWxUaWxkZVxcXCI6XFxcIsucXFxcIixcXFwiZGlhbVxcXCI6XFxcIuKLhFxcXCIsXFxcImRpYW1vbmRcXFwiOlxcXCLii4RcXFwiLFxcXCJEaWFtb25kXFxcIjpcXFwi4ouEXFxcIixcXFwiZGlhbW9uZHN1aXRcXFwiOlxcXCLimaZcXFwiLFxcXCJkaWFtc1xcXCI6XFxcIuKZplxcXCIsXFxcImRpZVxcXCI6XFxcIsKoXFxcIixcXFwiRGlmZmVyZW50aWFsRFxcXCI6XFxcIuKFhlxcXCIsXFxcImRpZ2FtbWFcXFwiOlxcXCLPnVxcXCIsXFxcImRpc2luXFxcIjpcXFwi4ouyXFxcIixcXFwiZGl2XFxcIjpcXFwiw7dcXFwiLFxcXCJkaXZpZGVcXFwiOlxcXCLDt1xcXCIsXFxcImRpdmlkZW9udGltZXNcXFwiOlxcXCLii4dcXFwiLFxcXCJkaXZvbnhcXFwiOlxcXCLii4dcXFwiLFxcXCJESmN5XFxcIjpcXFwi0IJcXFwiLFxcXCJkamN5XFxcIjpcXFwi0ZJcXFwiLFxcXCJkbGNvcm5cXFwiOlxcXCLijJ5cXFwiLFxcXCJkbGNyb3BcXFwiOlxcXCLijI1cXFwiLFxcXCJkb2xsYXJcXFwiOlxcXCIkXFxcIixcXFwiRG9wZlxcXCI6XFxcIvCdlLtcXFwiLFxcXCJkb3BmXFxcIjpcXFwi8J2VlVxcXCIsXFxcIkRvdFxcXCI6XFxcIsKoXFxcIixcXFwiZG90XFxcIjpcXFwiy5lcXFwiLFxcXCJEb3REb3RcXFwiOlxcXCLig5xcXFwiLFxcXCJkb3RlcVxcXCI6XFxcIuKJkFxcXCIsXFxcImRvdGVxZG90XFxcIjpcXFwi4omRXFxcIixcXFwiRG90RXF1YWxcXFwiOlxcXCLiiZBcXFwiLFxcXCJkb3RtaW51c1xcXCI6XFxcIuKIuFxcXCIsXFxcImRvdHBsdXNcXFwiOlxcXCLiiJRcXFwiLFxcXCJkb3RzcXVhcmVcXFwiOlxcXCLiiqFcXFwiLFxcXCJkb3VibGViYXJ3ZWRnZVxcXCI6XFxcIuKMhlxcXCIsXFxcIkRvdWJsZUNvbnRvdXJJbnRlZ3JhbFxcXCI6XFxcIuKIr1xcXCIsXFxcIkRvdWJsZURvdFxcXCI6XFxcIsKoXFxcIixcXFwiRG91YmxlRG93bkFycm93XFxcIjpcXFwi4oeTXFxcIixcXFwiRG91YmxlTGVmdEFycm93XFxcIjpcXFwi4oeQXFxcIixcXFwiRG91YmxlTGVmdFJpZ2h0QXJyb3dcXFwiOlxcXCLih5RcXFwiLFxcXCJEb3VibGVMZWZ0VGVlXFxcIjpcXFwi4qukXFxcIixcXFwiRG91YmxlTG9uZ0xlZnRBcnJvd1xcXCI6XFxcIuKfuFxcXCIsXFxcIkRvdWJsZUxvbmdMZWZ0UmlnaHRBcnJvd1xcXCI6XFxcIuKfulxcXCIsXFxcIkRvdWJsZUxvbmdSaWdodEFycm93XFxcIjpcXFwi4p+5XFxcIixcXFwiRG91YmxlUmlnaHRBcnJvd1xcXCI6XFxcIuKHklxcXCIsXFxcIkRvdWJsZVJpZ2h0VGVlXFxcIjpcXFwi4oqoXFxcIixcXFwiRG91YmxlVXBBcnJvd1xcXCI6XFxcIuKHkVxcXCIsXFxcIkRvdWJsZVVwRG93bkFycm93XFxcIjpcXFwi4oeVXFxcIixcXFwiRG91YmxlVmVydGljYWxCYXJcXFwiOlxcXCLiiKVcXFwiLFxcXCJEb3duQXJyb3dCYXJcXFwiOlxcXCLipJNcXFwiLFxcXCJkb3duYXJyb3dcXFwiOlxcXCLihpNcXFwiLFxcXCJEb3duQXJyb3dcXFwiOlxcXCLihpNcXFwiLFxcXCJEb3duYXJyb3dcXFwiOlxcXCLih5NcXFwiLFxcXCJEb3duQXJyb3dVcEFycm93XFxcIjpcXFwi4oe1XFxcIixcXFwiRG93bkJyZXZlXFxcIjpcXFwizJFcXFwiLFxcXCJkb3duZG93bmFycm93c1xcXCI6XFxcIuKHilxcXCIsXFxcImRvd25oYXJwb29ubGVmdFxcXCI6XFxcIuKHg1xcXCIsXFxcImRvd25oYXJwb29ucmlnaHRcXFwiOlxcXCLih4JcXFwiLFxcXCJEb3duTGVmdFJpZ2h0VmVjdG9yXFxcIjpcXFwi4qWQXFxcIixcXFwiRG93bkxlZnRUZWVWZWN0b3JcXFwiOlxcXCLipZ5cXFwiLFxcXCJEb3duTGVmdFZlY3RvckJhclxcXCI6XFxcIuKlllxcXCIsXFxcIkRvd25MZWZ0VmVjdG9yXFxcIjpcXFwi4oa9XFxcIixcXFwiRG93blJpZ2h0VGVlVmVjdG9yXFxcIjpcXFwi4qWfXFxcIixcXFwiRG93blJpZ2h0VmVjdG9yQmFyXFxcIjpcXFwi4qWXXFxcIixcXFwiRG93blJpZ2h0VmVjdG9yXFxcIjpcXFwi4oeBXFxcIixcXFwiRG93blRlZUFycm93XFxcIjpcXFwi4oanXFxcIixcXFwiRG93blRlZVxcXCI6XFxcIuKKpFxcXCIsXFxcImRyYmthcm93XFxcIjpcXFwi4qSQXFxcIixcXFwiZHJjb3JuXFxcIjpcXFwi4oyfXFxcIixcXFwiZHJjcm9wXFxcIjpcXFwi4oyMXFxcIixcXFwiRHNjclxcXCI6XFxcIvCdkp9cXFwiLFxcXCJkc2NyXFxcIjpcXFwi8J2SuVxcXCIsXFxcIkRTY3lcXFwiOlxcXCLQhVxcXCIsXFxcImRzY3lcXFwiOlxcXCLRlVxcXCIsXFxcImRzb2xcXFwiOlxcXCLip7ZcXFwiLFxcXCJEc3Ryb2tcXFwiOlxcXCLEkFxcXCIsXFxcImRzdHJva1xcXCI6XFxcIsSRXFxcIixcXFwiZHRkb3RcXFwiOlxcXCLii7FcXFwiLFxcXCJkdHJpXFxcIjpcXFwi4pa/XFxcIixcXFwiZHRyaWZcXFwiOlxcXCLilr5cXFwiLFxcXCJkdWFyclxcXCI6XFxcIuKHtVxcXCIsXFxcImR1aGFyXFxcIjpcXFwi4qWvXFxcIixcXFwiZHdhbmdsZVxcXCI6XFxcIuKmplxcXCIsXFxcIkRaY3lcXFwiOlxcXCLQj1xcXCIsXFxcImR6Y3lcXFwiOlxcXCLRn1xcXCIsXFxcImR6aWdyYXJyXFxcIjpcXFwi4p+/XFxcIixcXFwiRWFjdXRlXFxcIjpcXFwiw4lcXFwiLFxcXCJlYWN1dGVcXFwiOlxcXCLDqVxcXCIsXFxcImVhc3RlclxcXCI6XFxcIuKprlxcXCIsXFxcIkVjYXJvblxcXCI6XFxcIsSaXFxcIixcXFwiZWNhcm9uXFxcIjpcXFwixJtcXFwiLFxcXCJFY2lyY1xcXCI6XFxcIsOKXFxcIixcXFwiZWNpcmNcXFwiOlxcXCLDqlxcXCIsXFxcImVjaXJcXFwiOlxcXCLiiZZcXFwiLFxcXCJlY29sb25cXFwiOlxcXCLiiZVcXFwiLFxcXCJFY3lcXFwiOlxcXCLQrVxcXCIsXFxcImVjeVxcXCI6XFxcItGNXFxcIixcXFwiZUREb3RcXFwiOlxcXCLiqbdcXFwiLFxcXCJFZG90XFxcIjpcXFwixJZcXFwiLFxcXCJlZG90XFxcIjpcXFwixJdcXFwiLFxcXCJlRG90XFxcIjpcXFwi4omRXFxcIixcXFwiZWVcXFwiOlxcXCLihYdcXFwiLFxcXCJlZkRvdFxcXCI6XFxcIuKJklxcXCIsXFxcIkVmclxcXCI6XFxcIvCdlIhcXFwiLFxcXCJlZnJcXFwiOlxcXCLwnZSiXFxcIixcXFwiZWdcXFwiOlxcXCLiqppcXFwiLFxcXCJFZ3JhdmVcXFwiOlxcXCLDiFxcXCIsXFxcImVncmF2ZVxcXCI6XFxcIsOoXFxcIixcXFwiZWdzXFxcIjpcXFwi4qqWXFxcIixcXFwiZWdzZG90XFxcIjpcXFwi4qqYXFxcIixcXFwiZWxcXFwiOlxcXCLiqplcXFwiLFxcXCJFbGVtZW50XFxcIjpcXFwi4oiIXFxcIixcXFwiZWxpbnRlcnNcXFwiOlxcXCLij6dcXFwiLFxcXCJlbGxcXFwiOlxcXCLihJNcXFwiLFxcXCJlbHNcXFwiOlxcXCLiqpVcXFwiLFxcXCJlbHNkb3RcXFwiOlxcXCLiqpdcXFwiLFxcXCJFbWFjclxcXCI6XFxcIsSSXFxcIixcXFwiZW1hY3JcXFwiOlxcXCLEk1xcXCIsXFxcImVtcHR5XFxcIjpcXFwi4oiFXFxcIixcXFwiZW1wdHlzZXRcXFwiOlxcXCLiiIVcXFwiLFxcXCJFbXB0eVNtYWxsU3F1YXJlXFxcIjpcXFwi4pe7XFxcIixcXFwiZW1wdHl2XFxcIjpcXFwi4oiFXFxcIixcXFwiRW1wdHlWZXJ5U21hbGxTcXVhcmVcXFwiOlxcXCLilqtcXFwiLFxcXCJlbXNwMTNcXFwiOlxcXCLigIRcXFwiLFxcXCJlbXNwMTRcXFwiOlxcXCLigIVcXFwiLFxcXCJlbXNwXFxcIjpcXFwi4oCDXFxcIixcXFwiRU5HXFxcIjpcXFwixYpcXFwiLFxcXCJlbmdcXFwiOlxcXCLFi1xcXCIsXFxcImVuc3BcXFwiOlxcXCLigIJcXFwiLFxcXCJFb2dvblxcXCI6XFxcIsSYXFxcIixcXFwiZW9nb25cXFwiOlxcXCLEmVxcXCIsXFxcIkVvcGZcXFwiOlxcXCLwnZS8XFxcIixcXFwiZW9wZlxcXCI6XFxcIvCdlZZcXFwiLFxcXCJlcGFyXFxcIjpcXFwi4ouVXFxcIixcXFwiZXBhcnNsXFxcIjpcXFwi4qejXFxcIixcXFwiZXBsdXNcXFwiOlxcXCLiqbFcXFwiLFxcXCJlcHNpXFxcIjpcXFwizrVcXFwiLFxcXCJFcHNpbG9uXFxcIjpcXFwizpVcXFwiLFxcXCJlcHNpbG9uXFxcIjpcXFwizrVcXFwiLFxcXCJlcHNpdlxcXCI6XFxcIs+1XFxcIixcXFwiZXFjaXJjXFxcIjpcXFwi4omWXFxcIixcXFwiZXFjb2xvblxcXCI6XFxcIuKJlVxcXCIsXFxcImVxc2ltXFxcIjpcXFwi4omCXFxcIixcXFwiZXFzbGFudGd0clxcXCI6XFxcIuKqllxcXCIsXFxcImVxc2xhbnRsZXNzXFxcIjpcXFwi4qqVXFxcIixcXFwiRXF1YWxcXFwiOlxcXCLiqbVcXFwiLFxcXCJlcXVhbHNcXFwiOlxcXCI9XFxcIixcXFwiRXF1YWxUaWxkZVxcXCI6XFxcIuKJglxcXCIsXFxcImVxdWVzdFxcXCI6XFxcIuKJn1xcXCIsXFxcIkVxdWlsaWJyaXVtXFxcIjpcXFwi4oeMXFxcIixcXFwiZXF1aXZcXFwiOlxcXCLiiaFcXFwiLFxcXCJlcXVpdkREXFxcIjpcXFwi4qm4XFxcIixcXFwiZXF2cGFyc2xcXFwiOlxcXCLip6VcXFwiLFxcXCJlcmFyclxcXCI6XFxcIuKlsVxcXCIsXFxcImVyRG90XFxcIjpcXFwi4omTXFxcIixcXFwiZXNjclxcXCI6XFxcIuKEr1xcXCIsXFxcIkVzY3JcXFwiOlxcXCLihLBcXFwiLFxcXCJlc2RvdFxcXCI6XFxcIuKJkFxcXCIsXFxcIkVzaW1cXFwiOlxcXCLiqbNcXFwiLFxcXCJlc2ltXFxcIjpcXFwi4omCXFxcIixcXFwiRXRhXFxcIjpcXFwizpdcXFwiLFxcXCJldGFcXFwiOlxcXCLOt1xcXCIsXFxcIkVUSFxcXCI6XFxcIsOQXFxcIixcXFwiZXRoXFxcIjpcXFwiw7BcXFwiLFxcXCJFdW1sXFxcIjpcXFwiw4tcXFwiLFxcXCJldW1sXFxcIjpcXFwiw6tcXFwiLFxcXCJldXJvXFxcIjpcXFwi4oKsXFxcIixcXFwiZXhjbFxcXCI6XFxcIiFcXFwiLFxcXCJleGlzdFxcXCI6XFxcIuKIg1xcXCIsXFxcIkV4aXN0c1xcXCI6XFxcIuKIg1xcXCIsXFxcImV4cGVjdGF0aW9uXFxcIjpcXFwi4oSwXFxcIixcXFwiZXhwb25lbnRpYWxlXFxcIjpcXFwi4oWHXFxcIixcXFwiRXhwb25lbnRpYWxFXFxcIjpcXFwi4oWHXFxcIixcXFwiZmFsbGluZ2RvdHNlcVxcXCI6XFxcIuKJklxcXCIsXFxcIkZjeVxcXCI6XFxcItCkXFxcIixcXFwiZmN5XFxcIjpcXFwi0YRcXFwiLFxcXCJmZW1hbGVcXFwiOlxcXCLimYBcXFwiLFxcXCJmZmlsaWdcXFwiOlxcXCLvrINcXFwiLFxcXCJmZmxpZ1xcXCI6XFxcIu+sgFxcXCIsXFxcImZmbGxpZ1xcXCI6XFxcIu+shFxcXCIsXFxcIkZmclxcXCI6XFxcIvCdlIlcXFwiLFxcXCJmZnJcXFwiOlxcXCLwnZSjXFxcIixcXFwiZmlsaWdcXFwiOlxcXCLvrIFcXFwiLFxcXCJGaWxsZWRTbWFsbFNxdWFyZVxcXCI6XFxcIuKXvFxcXCIsXFxcIkZpbGxlZFZlcnlTbWFsbFNxdWFyZVxcXCI6XFxcIuKWqlxcXCIsXFxcImZqbGlnXFxcIjpcXFwiZmpcXFwiLFxcXCJmbGF0XFxcIjpcXFwi4pmtXFxcIixcXFwiZmxsaWdcXFwiOlxcXCLvrIJcXFwiLFxcXCJmbHRuc1xcXCI6XFxcIuKWsVxcXCIsXFxcImZub2ZcXFwiOlxcXCLGklxcXCIsXFxcIkZvcGZcXFwiOlxcXCLwnZS9XFxcIixcXFwiZm9wZlxcXCI6XFxcIvCdlZdcXFwiLFxcXCJmb3JhbGxcXFwiOlxcXCLiiIBcXFwiLFxcXCJGb3JBbGxcXFwiOlxcXCLiiIBcXFwiLFxcXCJmb3JrXFxcIjpcXFwi4ouUXFxcIixcXFwiZm9ya3ZcXFwiOlxcXCLiq5lcXFwiLFxcXCJGb3VyaWVydHJmXFxcIjpcXFwi4oSxXFxcIixcXFwiZnBhcnRpbnRcXFwiOlxcXCLiqI1cXFwiLFxcXCJmcmFjMTJcXFwiOlxcXCLCvVxcXCIsXFxcImZyYWMxM1xcXCI6XFxcIuKFk1xcXCIsXFxcImZyYWMxNFxcXCI6XFxcIsK8XFxcIixcXFwiZnJhYzE1XFxcIjpcXFwi4oWVXFxcIixcXFwiZnJhYzE2XFxcIjpcXFwi4oWZXFxcIixcXFwiZnJhYzE4XFxcIjpcXFwi4oWbXFxcIixcXFwiZnJhYzIzXFxcIjpcXFwi4oWUXFxcIixcXFwiZnJhYzI1XFxcIjpcXFwi4oWWXFxcIixcXFwiZnJhYzM0XFxcIjpcXFwiwr5cXFwiLFxcXCJmcmFjMzVcXFwiOlxcXCLihZdcXFwiLFxcXCJmcmFjMzhcXFwiOlxcXCLihZxcXFwiLFxcXCJmcmFjNDVcXFwiOlxcXCLihZhcXFwiLFxcXCJmcmFjNTZcXFwiOlxcXCLihZpcXFwiLFxcXCJmcmFjNThcXFwiOlxcXCLihZ1cXFwiLFxcXCJmcmFjNzhcXFwiOlxcXCLihZ5cXFwiLFxcXCJmcmFzbFxcXCI6XFxcIuKBhFxcXCIsXFxcImZyb3duXFxcIjpcXFwi4oyiXFxcIixcXFwiZnNjclxcXCI6XFxcIvCdkrtcXFwiLFxcXCJGc2NyXFxcIjpcXFwi4oSxXFxcIixcXFwiZ2FjdXRlXFxcIjpcXFwix7VcXFwiLFxcXCJHYW1tYVxcXCI6XFxcIs6TXFxcIixcXFwiZ2FtbWFcXFwiOlxcXCLOs1xcXCIsXFxcIkdhbW1hZFxcXCI6XFxcIs+cXFxcIixcXFwiZ2FtbWFkXFxcIjpcXFwiz51cXFwiLFxcXCJnYXBcXFwiOlxcXCLiqoZcXFwiLFxcXCJHYnJldmVcXFwiOlxcXCLEnlxcXCIsXFxcImdicmV2ZVxcXCI6XFxcIsSfXFxcIixcXFwiR2NlZGlsXFxcIjpcXFwixKJcXFwiLFxcXCJHY2lyY1xcXCI6XFxcIsScXFxcIixcXFwiZ2NpcmNcXFwiOlxcXCLEnVxcXCIsXFxcIkdjeVxcXCI6XFxcItCTXFxcIixcXFwiZ2N5XFxcIjpcXFwi0LNcXFwiLFxcXCJHZG90XFxcIjpcXFwixKBcXFwiLFxcXCJnZG90XFxcIjpcXFwixKFcXFwiLFxcXCJnZVxcXCI6XFxcIuKJpVxcXCIsXFxcImdFXFxcIjpcXFwi4omnXFxcIixcXFwiZ0VsXFxcIjpcXFwi4qqMXFxcIixcXFwiZ2VsXFxcIjpcXFwi4oubXFxcIixcXFwiZ2VxXFxcIjpcXFwi4omlXFxcIixcXFwiZ2VxcVxcXCI6XFxcIuKJp1xcXCIsXFxcImdlcXNsYW50XFxcIjpcXFwi4qm+XFxcIixcXFwiZ2VzY2NcXFwiOlxcXCLiqqlcXFwiLFxcXCJnZXNcXFwiOlxcXCLiqb5cXFwiLFxcXCJnZXNkb3RcXFwiOlxcXCLiqoBcXFwiLFxcXCJnZXNkb3RvXFxcIjpcXFwi4qqCXFxcIixcXFwiZ2VzZG90b2xcXFwiOlxcXCLiqoRcXFwiLFxcXCJnZXNsXFxcIjpcXFwi4oub77iAXFxcIixcXFwiZ2VzbGVzXFxcIjpcXFwi4qqUXFxcIixcXFwiR2ZyXFxcIjpcXFwi8J2UilxcXCIsXFxcImdmclxcXCI6XFxcIvCdlKRcXFwiLFxcXCJnZ1xcXCI6XFxcIuKJq1xcXCIsXFxcIkdnXFxcIjpcXFwi4ouZXFxcIixcXFwiZ2dnXFxcIjpcXFwi4ouZXFxcIixcXFwiZ2ltZWxcXFwiOlxcXCLihLdcXFwiLFxcXCJHSmN5XFxcIjpcXFwi0INcXFwiLFxcXCJnamN5XFxcIjpcXFwi0ZNcXFwiLFxcXCJnbGFcXFwiOlxcXCLiqqVcXFwiLFxcXCJnbFxcXCI6XFxcIuKJt1xcXCIsXFxcImdsRVxcXCI6XFxcIuKqklxcXCIsXFxcImdsalxcXCI6XFxcIuKqpFxcXCIsXFxcImduYXBcXFwiOlxcXCLiqopcXFwiLFxcXCJnbmFwcHJveFxcXCI6XFxcIuKqilxcXCIsXFxcImduZVxcXCI6XFxcIuKqiFxcXCIsXFxcImduRVxcXCI6XFxcIuKJqVxcXCIsXFxcImduZXFcXFwiOlxcXCLiqohcXFwiLFxcXCJnbmVxcVxcXCI6XFxcIuKJqVxcXCIsXFxcImduc2ltXFxcIjpcXFwi4ounXFxcIixcXFwiR29wZlxcXCI6XFxcIvCdlL5cXFwiLFxcXCJnb3BmXFxcIjpcXFwi8J2VmFxcXCIsXFxcImdyYXZlXFxcIjpcXFwiYFxcXCIsXFxcIkdyZWF0ZXJFcXVhbFxcXCI6XFxcIuKJpVxcXCIsXFxcIkdyZWF0ZXJFcXVhbExlc3NcXFwiOlxcXCLii5tcXFwiLFxcXCJHcmVhdGVyRnVsbEVxdWFsXFxcIjpcXFwi4omnXFxcIixcXFwiR3JlYXRlckdyZWF0ZXJcXFwiOlxcXCLiqqJcXFwiLFxcXCJHcmVhdGVyTGVzc1xcXCI6XFxcIuKJt1xcXCIsXFxcIkdyZWF0ZXJTbGFudEVxdWFsXFxcIjpcXFwi4qm+XFxcIixcXFwiR3JlYXRlclRpbGRlXFxcIjpcXFwi4omzXFxcIixcXFwiR3NjclxcXCI6XFxcIvCdkqJcXFwiLFxcXCJnc2NyXFxcIjpcXFwi4oSKXFxcIixcXFwiZ3NpbVxcXCI6XFxcIuKJs1xcXCIsXFxcImdzaW1lXFxcIjpcXFwi4qqOXFxcIixcXFwiZ3NpbWxcXFwiOlxcXCLiqpBcXFwiLFxcXCJndGNjXFxcIjpcXFwi4qqnXFxcIixcXFwiZ3RjaXJcXFwiOlxcXCLiqbpcXFwiLFxcXCJndFxcXCI6XFxcIj5cXFwiLFxcXCJHVFxcXCI6XFxcIj5cXFwiLFxcXCJHdFxcXCI6XFxcIuKJq1xcXCIsXFxcImd0ZG90XFxcIjpcXFwi4ouXXFxcIixcXFwiZ3RsUGFyXFxcIjpcXFwi4qaVXFxcIixcXFwiZ3RxdWVzdFxcXCI6XFxcIuKpvFxcXCIsXFxcImd0cmFwcHJveFxcXCI6XFxcIuKqhlxcXCIsXFxcImd0cmFyclxcXCI6XFxcIuKluFxcXCIsXFxcImd0cmRvdFxcXCI6XFxcIuKLl1xcXCIsXFxcImd0cmVxbGVzc1xcXCI6XFxcIuKLm1xcXCIsXFxcImd0cmVxcWxlc3NcXFwiOlxcXCLiqoxcXFwiLFxcXCJndHJsZXNzXFxcIjpcXFwi4om3XFxcIixcXFwiZ3Ryc2ltXFxcIjpcXFwi4omzXFxcIixcXFwiZ3ZlcnRuZXFxXFxcIjpcXFwi4omp77iAXFxcIixcXFwiZ3ZuRVxcXCI6XFxcIuKJqe+4gFxcXCIsXFxcIkhhY2VrXFxcIjpcXFwiy4dcXFwiLFxcXCJoYWlyc3BcXFwiOlxcXCLigIpcXFwiLFxcXCJoYWxmXFxcIjpcXFwiwr1cXFwiLFxcXCJoYW1pbHRcXFwiOlxcXCLihItcXFwiLFxcXCJIQVJEY3lcXFwiOlxcXCLQqlxcXCIsXFxcImhhcmRjeVxcXCI6XFxcItGKXFxcIixcXFwiaGFycmNpclxcXCI6XFxcIuKliFxcXCIsXFxcImhhcnJcXFwiOlxcXCLihpRcXFwiLFxcXCJoQXJyXFxcIjpcXFwi4oeUXFxcIixcXFwiaGFycndcXFwiOlxcXCLihq1cXFwiLFxcXCJIYXRcXFwiOlxcXCJeXFxcIixcXFwiaGJhclxcXCI6XFxcIuKEj1xcXCIsXFxcIkhjaXJjXFxcIjpcXFwixKRcXFwiLFxcXCJoY2lyY1xcXCI6XFxcIsSlXFxcIixcXFwiaGVhcnRzXFxcIjpcXFwi4pmlXFxcIixcXFwiaGVhcnRzdWl0XFxcIjpcXFwi4pmlXFxcIixcXFwiaGVsbGlwXFxcIjpcXFwi4oCmXFxcIixcXFwiaGVyY29uXFxcIjpcXFwi4oq5XFxcIixcXFwiaGZyXFxcIjpcXFwi8J2UpVxcXCIsXFxcIkhmclxcXCI6XFxcIuKEjFxcXCIsXFxcIkhpbGJlcnRTcGFjZVxcXCI6XFxcIuKEi1xcXCIsXFxcImhrc2Vhcm93XFxcIjpcXFwi4qSlXFxcIixcXFwiaGtzd2Fyb3dcXFwiOlxcXCLipKZcXFwiLFxcXCJob2FyclxcXCI6XFxcIuKHv1xcXCIsXFxcImhvbXRodFxcXCI6XFxcIuKIu1xcXCIsXFxcImhvb2tsZWZ0YXJyb3dcXFwiOlxcXCLihqlcXFwiLFxcXCJob29rcmlnaHRhcnJvd1xcXCI6XFxcIuKGqlxcXCIsXFxcImhvcGZcXFwiOlxcXCLwnZWZXFxcIixcXFwiSG9wZlxcXCI6XFxcIuKEjVxcXCIsXFxcImhvcmJhclxcXCI6XFxcIuKAlVxcXCIsXFxcIkhvcml6b250YWxMaW5lXFxcIjpcXFwi4pSAXFxcIixcXFwiaHNjclxcXCI6XFxcIvCdkr1cXFwiLFxcXCJIc2NyXFxcIjpcXFwi4oSLXFxcIixcXFwiaHNsYXNoXFxcIjpcXFwi4oSPXFxcIixcXFwiSHN0cm9rXFxcIjpcXFwixKZcXFwiLFxcXCJoc3Ryb2tcXFwiOlxcXCLEp1xcXCIsXFxcIkh1bXBEb3duSHVtcFxcXCI6XFxcIuKJjlxcXCIsXFxcIkh1bXBFcXVhbFxcXCI6XFxcIuKJj1xcXCIsXFxcImh5YnVsbFxcXCI6XFxcIuKBg1xcXCIsXFxcImh5cGhlblxcXCI6XFxcIuKAkFxcXCIsXFxcIklhY3V0ZVxcXCI6XFxcIsONXFxcIixcXFwiaWFjdXRlXFxcIjpcXFwiw61cXFwiLFxcXCJpY1xcXCI6XFxcIuKBo1xcXCIsXFxcIkljaXJjXFxcIjpcXFwiw45cXFwiLFxcXCJpY2lyY1xcXCI6XFxcIsOuXFxcIixcXFwiSWN5XFxcIjpcXFwi0JhcXFwiLFxcXCJpY3lcXFwiOlxcXCLQuFxcXCIsXFxcIklkb3RcXFwiOlxcXCLEsFxcXCIsXFxcIklFY3lcXFwiOlxcXCLQlVxcXCIsXFxcImllY3lcXFwiOlxcXCLQtVxcXCIsXFxcImlleGNsXFxcIjpcXFwiwqFcXFwiLFxcXCJpZmZcXFwiOlxcXCLih5RcXFwiLFxcXCJpZnJcXFwiOlxcXCLwnZSmXFxcIixcXFwiSWZyXFxcIjpcXFwi4oSRXFxcIixcXFwiSWdyYXZlXFxcIjpcXFwiw4xcXFwiLFxcXCJpZ3JhdmVcXFwiOlxcXCLDrFxcXCIsXFxcImlpXFxcIjpcXFwi4oWIXFxcIixcXFwiaWlpaW50XFxcIjpcXFwi4qiMXFxcIixcXFwiaWlpbnRcXFwiOlxcXCLiiK1cXFwiLFxcXCJpaW5maW5cXFwiOlxcXCLip5xcXFwiLFxcXCJpaW90YVxcXCI6XFxcIuKEqVxcXCIsXFxcIklKbGlnXFxcIjpcXFwixLJcXFwiLFxcXCJpamxpZ1xcXCI6XFxcIsSzXFxcIixcXFwiSW1hY3JcXFwiOlxcXCLEqlxcXCIsXFxcImltYWNyXFxcIjpcXFwixKtcXFwiLFxcXCJpbWFnZVxcXCI6XFxcIuKEkVxcXCIsXFxcIkltYWdpbmFyeUlcXFwiOlxcXCLihYhcXFwiLFxcXCJpbWFnbGluZVxcXCI6XFxcIuKEkFxcXCIsXFxcImltYWdwYXJ0XFxcIjpcXFwi4oSRXFxcIixcXFwiaW1hdGhcXFwiOlxcXCLEsVxcXCIsXFxcIkltXFxcIjpcXFwi4oSRXFxcIixcXFwiaW1vZlxcXCI6XFxcIuKKt1xcXCIsXFxcImltcGVkXFxcIjpcXFwixrVcXFwiLFxcXCJJbXBsaWVzXFxcIjpcXFwi4oeSXFxcIixcXFwiaW5jYXJlXFxcIjpcXFwi4oSFXFxcIixcXFwiaW5cXFwiOlxcXCLiiIhcXFwiLFxcXCJpbmZpblxcXCI6XFxcIuKInlxcXCIsXFxcImluZmludGllXFxcIjpcXFwi4qedXFxcIixcXFwiaW5vZG90XFxcIjpcXFwixLFcXFwiLFxcXCJpbnRjYWxcXFwiOlxcXCLiirpcXFwiLFxcXCJpbnRcXFwiOlxcXCLiiKtcXFwiLFxcXCJJbnRcXFwiOlxcXCLiiKxcXFwiLFxcXCJpbnRlZ2Vyc1xcXCI6XFxcIuKEpFxcXCIsXFxcIkludGVncmFsXFxcIjpcXFwi4oirXFxcIixcXFwiaW50ZXJjYWxcXFwiOlxcXCLiirpcXFwiLFxcXCJJbnRlcnNlY3Rpb25cXFwiOlxcXCLii4JcXFwiLFxcXCJpbnRsYXJoa1xcXCI6XFxcIuKol1xcXCIsXFxcImludHByb2RcXFwiOlxcXCLiqLxcXFwiLFxcXCJJbnZpc2libGVDb21tYVxcXCI6XFxcIuKBo1xcXCIsXFxcIkludmlzaWJsZVRpbWVzXFxcIjpcXFwi4oGiXFxcIixcXFwiSU9jeVxcXCI6XFxcItCBXFxcIixcXFwiaW9jeVxcXCI6XFxcItGRXFxcIixcXFwiSW9nb25cXFwiOlxcXCLErlxcXCIsXFxcImlvZ29uXFxcIjpcXFwixK9cXFwiLFxcXCJJb3BmXFxcIjpcXFwi8J2VgFxcXCIsXFxcImlvcGZcXFwiOlxcXCLwnZWaXFxcIixcXFwiSW90YVxcXCI6XFxcIs6ZXFxcIixcXFwiaW90YVxcXCI6XFxcIs65XFxcIixcXFwiaXByb2RcXFwiOlxcXCLiqLxcXFwiLFxcXCJpcXVlc3RcXFwiOlxcXCLCv1xcXCIsXFxcImlzY3JcXFwiOlxcXCLwnZK+XFxcIixcXFwiSXNjclxcXCI6XFxcIuKEkFxcXCIsXFxcImlzaW5cXFwiOlxcXCLiiIhcXFwiLFxcXCJpc2luZG90XFxcIjpcXFwi4ou1XFxcIixcXFwiaXNpbkVcXFwiOlxcXCLii7lcXFwiLFxcXCJpc2luc1xcXCI6XFxcIuKLtFxcXCIsXFxcImlzaW5zdlxcXCI6XFxcIuKLs1xcXCIsXFxcImlzaW52XFxcIjpcXFwi4oiIXFxcIixcXFwiaXRcXFwiOlxcXCLigaJcXFwiLFxcXCJJdGlsZGVcXFwiOlxcXCLEqFxcXCIsXFxcIml0aWxkZVxcXCI6XFxcIsSpXFxcIixcXFwiSXVrY3lcXFwiOlxcXCLQhlxcXCIsXFxcIml1a2N5XFxcIjpcXFwi0ZZcXFwiLFxcXCJJdW1sXFxcIjpcXFwiw49cXFwiLFxcXCJpdW1sXFxcIjpcXFwiw69cXFwiLFxcXCJKY2lyY1xcXCI6XFxcIsS0XFxcIixcXFwiamNpcmNcXFwiOlxcXCLEtVxcXCIsXFxcIkpjeVxcXCI6XFxcItCZXFxcIixcXFwiamN5XFxcIjpcXFwi0LlcXFwiLFxcXCJKZnJcXFwiOlxcXCLwnZSNXFxcIixcXFwiamZyXFxcIjpcXFwi8J2Up1xcXCIsXFxcImptYXRoXFxcIjpcXFwiyLdcXFwiLFxcXCJKb3BmXFxcIjpcXFwi8J2VgVxcXCIsXFxcImpvcGZcXFwiOlxcXCLwnZWbXFxcIixcXFwiSnNjclxcXCI6XFxcIvCdkqVcXFwiLFxcXCJqc2NyXFxcIjpcXFwi8J2Sv1xcXCIsXFxcIkpzZXJjeVxcXCI6XFxcItCIXFxcIixcXFwianNlcmN5XFxcIjpcXFwi0ZhcXFwiLFxcXCJKdWtjeVxcXCI6XFxcItCEXFxcIixcXFwianVrY3lcXFwiOlxcXCLRlFxcXCIsXFxcIkthcHBhXFxcIjpcXFwizppcXFwiLFxcXCJrYXBwYVxcXCI6XFxcIs66XFxcIixcXFwia2FwcGF2XFxcIjpcXFwiz7BcXFwiLFxcXCJLY2VkaWxcXFwiOlxcXCLEtlxcXCIsXFxcImtjZWRpbFxcXCI6XFxcIsS3XFxcIixcXFwiS2N5XFxcIjpcXFwi0JpcXFwiLFxcXCJrY3lcXFwiOlxcXCLQulxcXCIsXFxcIktmclxcXCI6XFxcIvCdlI5cXFwiLFxcXCJrZnJcXFwiOlxcXCLwnZSoXFxcIixcXFwia2dyZWVuXFxcIjpcXFwixLhcXFwiLFxcXCJLSGN5XFxcIjpcXFwi0KVcXFwiLFxcXCJraGN5XFxcIjpcXFwi0YVcXFwiLFxcXCJLSmN5XFxcIjpcXFwi0IxcXFwiLFxcXCJramN5XFxcIjpcXFwi0ZxcXFwiLFxcXCJLb3BmXFxcIjpcXFwi8J2VglxcXCIsXFxcImtvcGZcXFwiOlxcXCLwnZWcXFxcIixcXFwiS3NjclxcXCI6XFxcIvCdkqZcXFwiLFxcXCJrc2NyXFxcIjpcXFwi8J2TgFxcXCIsXFxcImxBYXJyXFxcIjpcXFwi4oeaXFxcIixcXFwiTGFjdXRlXFxcIjpcXFwixLlcXFwiLFxcXCJsYWN1dGVcXFwiOlxcXCLEulxcXCIsXFxcImxhZW1wdHl2XFxcIjpcXFwi4qa0XFxcIixcXFwibGFncmFuXFxcIjpcXFwi4oSSXFxcIixcXFwiTGFtYmRhXFxcIjpcXFwizptcXFwiLFxcXCJsYW1iZGFcXFwiOlxcXCLOu1xcXCIsXFxcImxhbmdcXFwiOlxcXCLin6hcXFwiLFxcXCJMYW5nXFxcIjpcXFwi4p+qXFxcIixcXFwibGFuZ2RcXFwiOlxcXCLippFcXFwiLFxcXCJsYW5nbGVcXFwiOlxcXCLin6hcXFwiLFxcXCJsYXBcXFwiOlxcXCLiqoVcXFwiLFxcXCJMYXBsYWNldHJmXFxcIjpcXFwi4oSSXFxcIixcXFwibGFxdW9cXFwiOlxcXCLCq1xcXCIsXFxcImxhcnJiXFxcIjpcXFwi4oekXFxcIixcXFwibGFycmJmc1xcXCI6XFxcIuKkn1xcXCIsXFxcImxhcnJcXFwiOlxcXCLihpBcXFwiLFxcXCJMYXJyXFxcIjpcXFwi4oaeXFxcIixcXFwibEFyclxcXCI6XFxcIuKHkFxcXCIsXFxcImxhcnJmc1xcXCI6XFxcIuKknVxcXCIsXFxcImxhcnJoa1xcXCI6XFxcIuKGqVxcXCIsXFxcImxhcnJscFxcXCI6XFxcIuKGq1xcXCIsXFxcImxhcnJwbFxcXCI6XFxcIuKkuVxcXCIsXFxcImxhcnJzaW1cXFwiOlxcXCLipbNcXFwiLFxcXCJsYXJydGxcXFwiOlxcXCLihqJcXFwiLFxcXCJsYXRhaWxcXFwiOlxcXCLipJlcXFwiLFxcXCJsQXRhaWxcXFwiOlxcXCLipJtcXFwiLFxcXCJsYXRcXFwiOlxcXCLiqqtcXFwiLFxcXCJsYXRlXFxcIjpcXFwi4qqtXFxcIixcXFwibGF0ZXNcXFwiOlxcXCLiqq3vuIBcXFwiLFxcXCJsYmFyclxcXCI6XFxcIuKkjFxcXCIsXFxcImxCYXJyXFxcIjpcXFwi4qSOXFxcIixcXFwibGJicmtcXFwiOlxcXCLinbJcXFwiLFxcXCJsYnJhY2VcXFwiOlxcXCJ7XFxcIixcXFwibGJyYWNrXFxcIjpcXFwiW1xcXCIsXFxcImxicmtlXFxcIjpcXFwi4qaLXFxcIixcXFwibGJya3NsZFxcXCI6XFxcIuKmj1xcXCIsXFxcImxicmtzbHVcXFwiOlxcXCLipo1cXFwiLFxcXCJMY2Fyb25cXFwiOlxcXCLEvVxcXCIsXFxcImxjYXJvblxcXCI6XFxcIsS+XFxcIixcXFwiTGNlZGlsXFxcIjpcXFwixLtcXFwiLFxcXCJsY2VkaWxcXFwiOlxcXCLEvFxcXCIsXFxcImxjZWlsXFxcIjpcXFwi4oyIXFxcIixcXFwibGN1YlxcXCI6XFxcIntcXFwiLFxcXCJMY3lcXFwiOlxcXCLQm1xcXCIsXFxcImxjeVxcXCI6XFxcItC7XFxcIixcXFwibGRjYVxcXCI6XFxcIuKktlxcXCIsXFxcImxkcXVvXFxcIjpcXFwi4oCcXFxcIixcXFwibGRxdW9yXFxcIjpcXFwi4oCeXFxcIixcXFwibGRyZGhhclxcXCI6XFxcIuKlp1xcXCIsXFxcImxkcnVzaGFyXFxcIjpcXFwi4qWLXFxcIixcXFwibGRzaFxcXCI6XFxcIuKGslxcXCIsXFxcImxlXFxcIjpcXFwi4omkXFxcIixcXFwibEVcXFwiOlxcXCLiiaZcXFwiLFxcXCJMZWZ0QW5nbGVCcmFja2V0XFxcIjpcXFwi4p+oXFxcIixcXFwiTGVmdEFycm93QmFyXFxcIjpcXFwi4oekXFxcIixcXFwibGVmdGFycm93XFxcIjpcXFwi4oaQXFxcIixcXFwiTGVmdEFycm93XFxcIjpcXFwi4oaQXFxcIixcXFwiTGVmdGFycm93XFxcIjpcXFwi4oeQXFxcIixcXFwiTGVmdEFycm93UmlnaHRBcnJvd1xcXCI6XFxcIuKHhlxcXCIsXFxcImxlZnRhcnJvd3RhaWxcXFwiOlxcXCLihqJcXFwiLFxcXCJMZWZ0Q2VpbGluZ1xcXCI6XFxcIuKMiFxcXCIsXFxcIkxlZnREb3VibGVCcmFja2V0XFxcIjpcXFwi4p+mXFxcIixcXFwiTGVmdERvd25UZWVWZWN0b3JcXFwiOlxcXCLipaFcXFwiLFxcXCJMZWZ0RG93blZlY3RvckJhclxcXCI6XFxcIuKlmVxcXCIsXFxcIkxlZnREb3duVmVjdG9yXFxcIjpcXFwi4oeDXFxcIixcXFwiTGVmdEZsb29yXFxcIjpcXFwi4oyKXFxcIixcXFwibGVmdGhhcnBvb25kb3duXFxcIjpcXFwi4oa9XFxcIixcXFwibGVmdGhhcnBvb251cFxcXCI6XFxcIuKGvFxcXCIsXFxcImxlZnRsZWZ0YXJyb3dzXFxcIjpcXFwi4oeHXFxcIixcXFwibGVmdHJpZ2h0YXJyb3dcXFwiOlxcXCLihpRcXFwiLFxcXCJMZWZ0UmlnaHRBcnJvd1xcXCI6XFxcIuKGlFxcXCIsXFxcIkxlZnRyaWdodGFycm93XFxcIjpcXFwi4oeUXFxcIixcXFwibGVmdHJpZ2h0YXJyb3dzXFxcIjpcXFwi4oeGXFxcIixcXFwibGVmdHJpZ2h0aGFycG9vbnNcXFwiOlxcXCLih4tcXFwiLFxcXCJsZWZ0cmlnaHRzcXVpZ2Fycm93XFxcIjpcXFwi4oatXFxcIixcXFwiTGVmdFJpZ2h0VmVjdG9yXFxcIjpcXFwi4qWOXFxcIixcXFwiTGVmdFRlZUFycm93XFxcIjpcXFwi4oakXFxcIixcXFwiTGVmdFRlZVxcXCI6XFxcIuKKo1xcXCIsXFxcIkxlZnRUZWVWZWN0b3JcXFwiOlxcXCLipZpcXFwiLFxcXCJsZWZ0dGhyZWV0aW1lc1xcXCI6XFxcIuKLi1xcXCIsXFxcIkxlZnRUcmlhbmdsZUJhclxcXCI6XFxcIuKnj1xcXCIsXFxcIkxlZnRUcmlhbmdsZVxcXCI6XFxcIuKKslxcXCIsXFxcIkxlZnRUcmlhbmdsZUVxdWFsXFxcIjpcXFwi4oq0XFxcIixcXFwiTGVmdFVwRG93blZlY3RvclxcXCI6XFxcIuKlkVxcXCIsXFxcIkxlZnRVcFRlZVZlY3RvclxcXCI6XFxcIuKloFxcXCIsXFxcIkxlZnRVcFZlY3RvckJhclxcXCI6XFxcIuKlmFxcXCIsXFxcIkxlZnRVcFZlY3RvclxcXCI6XFxcIuKGv1xcXCIsXFxcIkxlZnRWZWN0b3JCYXJcXFwiOlxcXCLipZJcXFwiLFxcXCJMZWZ0VmVjdG9yXFxcIjpcXFwi4oa8XFxcIixcXFwibEVnXFxcIjpcXFwi4qqLXFxcIixcXFwibGVnXFxcIjpcXFwi4ouaXFxcIixcXFwibGVxXFxcIjpcXFwi4omkXFxcIixcXFwibGVxcVxcXCI6XFxcIuKJplxcXCIsXFxcImxlcXNsYW50XFxcIjpcXFwi4qm9XFxcIixcXFwibGVzY2NcXFwiOlxcXCLiqqhcXFwiLFxcXCJsZXNcXFwiOlxcXCLiqb1cXFwiLFxcXCJsZXNkb3RcXFwiOlxcXCLiqb9cXFwiLFxcXCJsZXNkb3RvXFxcIjpcXFwi4qqBXFxcIixcXFwibGVzZG90b3JcXFwiOlxcXCLiqoNcXFwiLFxcXCJsZXNnXFxcIjpcXFwi4oua77iAXFxcIixcXFwibGVzZ2VzXFxcIjpcXFwi4qqTXFxcIixcXFwibGVzc2FwcHJveFxcXCI6XFxcIuKqhVxcXCIsXFxcImxlc3Nkb3RcXFwiOlxcXCLii5ZcXFwiLFxcXCJsZXNzZXFndHJcXFwiOlxcXCLii5pcXFwiLFxcXCJsZXNzZXFxZ3RyXFxcIjpcXFwi4qqLXFxcIixcXFwiTGVzc0VxdWFsR3JlYXRlclxcXCI6XFxcIuKLmlxcXCIsXFxcIkxlc3NGdWxsRXF1YWxcXFwiOlxcXCLiiaZcXFwiLFxcXCJMZXNzR3JlYXRlclxcXCI6XFxcIuKJtlxcXCIsXFxcImxlc3NndHJcXFwiOlxcXCLiibZcXFwiLFxcXCJMZXNzTGVzc1xcXCI6XFxcIuKqoVxcXCIsXFxcImxlc3NzaW1cXFwiOlxcXCLiibJcXFwiLFxcXCJMZXNzU2xhbnRFcXVhbFxcXCI6XFxcIuKpvVxcXCIsXFxcIkxlc3NUaWxkZVxcXCI6XFxcIuKJslxcXCIsXFxcImxmaXNodFxcXCI6XFxcIuKlvFxcXCIsXFxcImxmbG9vclxcXCI6XFxcIuKMilxcXCIsXFxcIkxmclxcXCI6XFxcIvCdlI9cXFwiLFxcXCJsZnJcXFwiOlxcXCLwnZSpXFxcIixcXFwibGdcXFwiOlxcXCLiibZcXFwiLFxcXCJsZ0VcXFwiOlxcXCLiqpFcXFwiLFxcXCJsSGFyXFxcIjpcXFwi4qWiXFxcIixcXFwibGhhcmRcXFwiOlxcXCLihr1cXFwiLFxcXCJsaGFydVxcXCI6XFxcIuKGvFxcXCIsXFxcImxoYXJ1bFxcXCI6XFxcIuKlqlxcXCIsXFxcImxoYmxrXFxcIjpcXFwi4paEXFxcIixcXFwiTEpjeVxcXCI6XFxcItCJXFxcIixcXFwibGpjeVxcXCI6XFxcItGZXFxcIixcXFwibGxhcnJcXFwiOlxcXCLih4dcXFwiLFxcXCJsbFxcXCI6XFxcIuKJqlxcXCIsXFxcIkxsXFxcIjpcXFwi4ouYXFxcIixcXFwibGxjb3JuZXJcXFwiOlxcXCLijJ5cXFwiLFxcXCJMbGVmdGFycm93XFxcIjpcXFwi4oeaXFxcIixcXFwibGxoYXJkXFxcIjpcXFwi4qWrXFxcIixcXFwibGx0cmlcXFwiOlxcXCLil7pcXFwiLFxcXCJMbWlkb3RcXFwiOlxcXCLEv1xcXCIsXFxcImxtaWRvdFxcXCI6XFxcIsWAXFxcIixcXFwibG1vdXN0YWNoZVxcXCI6XFxcIuKOsFxcXCIsXFxcImxtb3VzdFxcXCI6XFxcIuKOsFxcXCIsXFxcImxuYXBcXFwiOlxcXCLiqolcXFwiLFxcXCJsbmFwcHJveFxcXCI6XFxcIuKqiVxcXCIsXFxcImxuZVxcXCI6XFxcIuKqh1xcXCIsXFxcImxuRVxcXCI6XFxcIuKJqFxcXCIsXFxcImxuZXFcXFwiOlxcXCLiqodcXFwiLFxcXCJsbmVxcVxcXCI6XFxcIuKJqFxcXCIsXFxcImxuc2ltXFxcIjpcXFwi4oumXFxcIixcXFwibG9hbmdcXFwiOlxcXCLin6xcXFwiLFxcXCJsb2FyclxcXCI6XFxcIuKHvVxcXCIsXFxcImxvYnJrXFxcIjpcXFwi4p+mXFxcIixcXFwibG9uZ2xlZnRhcnJvd1xcXCI6XFxcIuKftVxcXCIsXFxcIkxvbmdMZWZ0QXJyb3dcXFwiOlxcXCLin7VcXFwiLFxcXCJMb25nbGVmdGFycm93XFxcIjpcXFwi4p+4XFxcIixcXFwibG9uZ2xlZnRyaWdodGFycm93XFxcIjpcXFwi4p+3XFxcIixcXFwiTG9uZ0xlZnRSaWdodEFycm93XFxcIjpcXFwi4p+3XFxcIixcXFwiTG9uZ2xlZnRyaWdodGFycm93XFxcIjpcXFwi4p+6XFxcIixcXFwibG9uZ21hcHN0b1xcXCI6XFxcIuKfvFxcXCIsXFxcImxvbmdyaWdodGFycm93XFxcIjpcXFwi4p+2XFxcIixcXFwiTG9uZ1JpZ2h0QXJyb3dcXFwiOlxcXCLin7ZcXFwiLFxcXCJMb25ncmlnaHRhcnJvd1xcXCI6XFxcIuKfuVxcXCIsXFxcImxvb3BhcnJvd2xlZnRcXFwiOlxcXCLihqtcXFwiLFxcXCJsb29wYXJyb3dyaWdodFxcXCI6XFxcIuKGrFxcXCIsXFxcImxvcGFyXFxcIjpcXFwi4qaFXFxcIixcXFwiTG9wZlxcXCI6XFxcIvCdlYNcXFwiLFxcXCJsb3BmXFxcIjpcXFwi8J2VnVxcXCIsXFxcImxvcGx1c1xcXCI6XFxcIuKorVxcXCIsXFxcImxvdGltZXNcXFwiOlxcXCLiqLRcXFwiLFxcXCJsb3dhc3RcXFwiOlxcXCLiiJdcXFwiLFxcXCJsb3diYXJcXFwiOlxcXCJfXFxcIixcXFwiTG93ZXJMZWZ0QXJyb3dcXFwiOlxcXCLihplcXFwiLFxcXCJMb3dlclJpZ2h0QXJyb3dcXFwiOlxcXCLihphcXFwiLFxcXCJsb3pcXFwiOlxcXCLil4pcXFwiLFxcXCJsb3plbmdlXFxcIjpcXFwi4peKXFxcIixcXFwibG96ZlxcXCI6XFxcIuKnq1xcXCIsXFxcImxwYXJcXFwiOlxcXCIoXFxcIixcXFwibHBhcmx0XFxcIjpcXFwi4qaTXFxcIixcXFwibHJhcnJcXFwiOlxcXCLih4ZcXFwiLFxcXCJscmNvcm5lclxcXCI6XFxcIuKMn1xcXCIsXFxcImxyaGFyXFxcIjpcXFwi4oeLXFxcIixcXFwibHJoYXJkXFxcIjpcXFwi4qWtXFxcIixcXFwibHJtXFxcIjpcXFwi4oCOXFxcIixcXFwibHJ0cmlcXFwiOlxcXCLiir9cXFwiLFxcXCJsc2FxdW9cXFwiOlxcXCLigLlcXFwiLFxcXCJsc2NyXFxcIjpcXFwi8J2TgVxcXCIsXFxcIkxzY3JcXFwiOlxcXCLihJJcXFwiLFxcXCJsc2hcXFwiOlxcXCLihrBcXFwiLFxcXCJMc2hcXFwiOlxcXCLihrBcXFwiLFxcXCJsc2ltXFxcIjpcXFwi4omyXFxcIixcXFwibHNpbWVcXFwiOlxcXCLiqo1cXFwiLFxcXCJsc2ltZ1xcXCI6XFxcIuKqj1xcXCIsXFxcImxzcWJcXFwiOlxcXCJbXFxcIixcXFwibHNxdW9cXFwiOlxcXCLigJhcXFwiLFxcXCJsc3F1b3JcXFwiOlxcXCLigJpcXFwiLFxcXCJMc3Ryb2tcXFwiOlxcXCLFgVxcXCIsXFxcImxzdHJva1xcXCI6XFxcIsWCXFxcIixcXFwibHRjY1xcXCI6XFxcIuKqplxcXCIsXFxcImx0Y2lyXFxcIjpcXFwi4qm5XFxcIixcXFwibHRcXFwiOlxcXCI8XFxcIixcXFwiTFRcXFwiOlxcXCI8XFxcIixcXFwiTHRcXFwiOlxcXCLiiapcXFwiLFxcXCJsdGRvdFxcXCI6XFxcIuKLllxcXCIsXFxcImx0aHJlZVxcXCI6XFxcIuKLi1xcXCIsXFxcImx0aW1lc1xcXCI6XFxcIuKLiVxcXCIsXFxcImx0bGFyclxcXCI6XFxcIuKltlxcXCIsXFxcImx0cXVlc3RcXFwiOlxcXCLiqbtcXFwiLFxcXCJsdHJpXFxcIjpcXFwi4peDXFxcIixcXFwibHRyaWVcXFwiOlxcXCLiirRcXFwiLFxcXCJsdHJpZlxcXCI6XFxcIuKXglxcXCIsXFxcImx0clBhclxcXCI6XFxcIuKmllxcXCIsXFxcImx1cmRzaGFyXFxcIjpcXFwi4qWKXFxcIixcXFwibHVydWhhclxcXCI6XFxcIuKlplxcXCIsXFxcImx2ZXJ0bmVxcVxcXCI6XFxcIuKJqO+4gFxcXCIsXFxcImx2bkVcXFwiOlxcXCLiiajvuIBcXFwiLFxcXCJtYWNyXFxcIjpcXFwiwq9cXFwiLFxcXCJtYWxlXFxcIjpcXFwi4pmCXFxcIixcXFwibWFsdFxcXCI6XFxcIuKcoFxcXCIsXFxcIm1hbHRlc2VcXFwiOlxcXCLinKBcXFwiLFxcXCJNYXBcXFwiOlxcXCLipIVcXFwiLFxcXCJtYXBcXFwiOlxcXCLihqZcXFwiLFxcXCJtYXBzdG9cXFwiOlxcXCLihqZcXFwiLFxcXCJtYXBzdG9kb3duXFxcIjpcXFwi4oanXFxcIixcXFwibWFwc3RvbGVmdFxcXCI6XFxcIuKGpFxcXCIsXFxcIm1hcHN0b3VwXFxcIjpcXFwi4oalXFxcIixcXFwibWFya2VyXFxcIjpcXFwi4pauXFxcIixcXFwibWNvbW1hXFxcIjpcXFwi4qipXFxcIixcXFwiTWN5XFxcIjpcXFwi0JxcXFwiLFxcXCJtY3lcXFwiOlxcXCLQvFxcXCIsXFxcIm1kYXNoXFxcIjpcXFwi4oCUXFxcIixcXFwibUREb3RcXFwiOlxcXCLiiLpcXFwiLFxcXCJtZWFzdXJlZGFuZ2xlXFxcIjpcXFwi4oihXFxcIixcXFwiTWVkaXVtU3BhY2VcXFwiOlxcXCLigZ9cXFwiLFxcXCJNZWxsaW50cmZcXFwiOlxcXCLihLNcXFwiLFxcXCJNZnJcXFwiOlxcXCLwnZSQXFxcIixcXFwibWZyXFxcIjpcXFwi8J2UqlxcXCIsXFxcIm1ob1xcXCI6XFxcIuKEp1xcXCIsXFxcIm1pY3JvXFxcIjpcXFwiwrVcXFwiLFxcXCJtaWRhc3RcXFwiOlxcXCIqXFxcIixcXFwibWlkY2lyXFxcIjpcXFwi4quwXFxcIixcXFwibWlkXFxcIjpcXFwi4oijXFxcIixcXFwibWlkZG90XFxcIjpcXFwiwrdcXFwiLFxcXCJtaW51c2JcXFwiOlxcXCLiip9cXFwiLFxcXCJtaW51c1xcXCI6XFxcIuKIklxcXCIsXFxcIm1pbnVzZFxcXCI6XFxcIuKIuFxcXCIsXFxcIm1pbnVzZHVcXFwiOlxcXCLiqKpcXFwiLFxcXCJNaW51c1BsdXNcXFwiOlxcXCLiiJNcXFwiLFxcXCJtbGNwXFxcIjpcXFwi4qubXFxcIixcXFwibWxkclxcXCI6XFxcIuKAplxcXCIsXFxcIm1ucGx1c1xcXCI6XFxcIuKIk1xcXCIsXFxcIm1vZGVsc1xcXCI6XFxcIuKKp1xcXCIsXFxcIk1vcGZcXFwiOlxcXCLwnZWEXFxcIixcXFwibW9wZlxcXCI6XFxcIvCdlZ5cXFwiLFxcXCJtcFxcXCI6XFxcIuKIk1xcXCIsXFxcIm1zY3JcXFwiOlxcXCLwnZOCXFxcIixcXFwiTXNjclxcXCI6XFxcIuKEs1xcXCIsXFxcIm1zdHBvc1xcXCI6XFxcIuKIvlxcXCIsXFxcIk11XFxcIjpcXFwizpxcXFwiLFxcXCJtdVxcXCI6XFxcIs68XFxcIixcXFwibXVsdGltYXBcXFwiOlxcXCLiirhcXFwiLFxcXCJtdW1hcFxcXCI6XFxcIuKKuFxcXCIsXFxcIm5hYmxhXFxcIjpcXFwi4oiHXFxcIixcXFwiTmFjdXRlXFxcIjpcXFwixYNcXFwiLFxcXCJuYWN1dGVcXFwiOlxcXCLFhFxcXCIsXFxcIm5hbmdcXFwiOlxcXCLiiKDig5JcXFwiLFxcXCJuYXBcXFwiOlxcXCLiiYlcXFwiLFxcXCJuYXBFXFxcIjpcXFwi4qmwzLhcXFwiLFxcXCJuYXBpZFxcXCI6XFxcIuKJi8y4XFxcIixcXFwibmFwb3NcXFwiOlxcXCLFiVxcXCIsXFxcIm5hcHByb3hcXFwiOlxcXCLiiYlcXFwiLFxcXCJuYXR1cmFsXFxcIjpcXFwi4pmuXFxcIixcXFwibmF0dXJhbHNcXFwiOlxcXCLihJVcXFwiLFxcXCJuYXR1clxcXCI6XFxcIuKZrlxcXCIsXFxcIm5ic3BcXFwiOlxcXCLCoFxcXCIsXFxcIm5idW1wXFxcIjpcXFwi4omOzLhcXFwiLFxcXCJuYnVtcGVcXFwiOlxcXCLiiY/MuFxcXCIsXFxcIm5jYXBcXFwiOlxcXCLiqYNcXFwiLFxcXCJOY2Fyb25cXFwiOlxcXCLFh1xcXCIsXFxcIm5jYXJvblxcXCI6XFxcIsWIXFxcIixcXFwiTmNlZGlsXFxcIjpcXFwixYVcXFwiLFxcXCJuY2VkaWxcXFwiOlxcXCLFhlxcXCIsXFxcIm5jb25nXFxcIjpcXFwi4omHXFxcIixcXFwibmNvbmdkb3RcXFwiOlxcXCLiqa3MuFxcXCIsXFxcIm5jdXBcXFwiOlxcXCLiqYJcXFwiLFxcXCJOY3lcXFwiOlxcXCLQnVxcXCIsXFxcIm5jeVxcXCI6XFxcItC9XFxcIixcXFwibmRhc2hcXFwiOlxcXCLigJNcXFwiLFxcXCJuZWFyaGtcXFwiOlxcXCLipKRcXFwiLFxcXCJuZWFyclxcXCI6XFxcIuKGl1xcXCIsXFxcIm5lQXJyXFxcIjpcXFwi4oeXXFxcIixcXFwibmVhcnJvd1xcXCI6XFxcIuKGl1xcXCIsXFxcIm5lXFxcIjpcXFwi4omgXFxcIixcXFwibmVkb3RcXFwiOlxcXCLiiZDMuFxcXCIsXFxcIk5lZ2F0aXZlTWVkaXVtU3BhY2VcXFwiOlxcXCLigItcXFwiLFxcXCJOZWdhdGl2ZVRoaWNrU3BhY2VcXFwiOlxcXCLigItcXFwiLFxcXCJOZWdhdGl2ZVRoaW5TcGFjZVxcXCI6XFxcIuKAi1xcXCIsXFxcIk5lZ2F0aXZlVmVyeVRoaW5TcGFjZVxcXCI6XFxcIuKAi1xcXCIsXFxcIm5lcXVpdlxcXCI6XFxcIuKJolxcXCIsXFxcIm5lc2VhclxcXCI6XFxcIuKkqFxcXCIsXFxcIm5lc2ltXFxcIjpcXFwi4omCzLhcXFwiLFxcXCJOZXN0ZWRHcmVhdGVyR3JlYXRlclxcXCI6XFxcIuKJq1xcXCIsXFxcIk5lc3RlZExlc3NMZXNzXFxcIjpcXFwi4omqXFxcIixcXFwiTmV3TGluZVxcXCI6XFxcIlxcXFxuXFxcIixcXFwibmV4aXN0XFxcIjpcXFwi4oiEXFxcIixcXFwibmV4aXN0c1xcXCI6XFxcIuKIhFxcXCIsXFxcIk5mclxcXCI6XFxcIvCdlJFcXFwiLFxcXCJuZnJcXFwiOlxcXCLwnZSrXFxcIixcXFwibmdFXFxcIjpcXFwi4omnzLhcXFwiLFxcXCJuZ2VcXFwiOlxcXCLiibFcXFwiLFxcXCJuZ2VxXFxcIjpcXFwi4omxXFxcIixcXFwibmdlcXFcXFwiOlxcXCLiiafMuFxcXCIsXFxcIm5nZXFzbGFudFxcXCI6XFxcIuKpvsy4XFxcIixcXFwibmdlc1xcXCI6XFxcIuKpvsy4XFxcIixcXFwibkdnXFxcIjpcXFwi4ouZzLhcXFwiLFxcXCJuZ3NpbVxcXCI6XFxcIuKJtVxcXCIsXFxcIm5HdFxcXCI6XFxcIuKJq+KDklxcXCIsXFxcIm5ndFxcXCI6XFxcIuKJr1xcXCIsXFxcIm5ndHJcXFwiOlxcXCLiia9cXFwiLFxcXCJuR3R2XFxcIjpcXFwi4omrzLhcXFwiLFxcXCJuaGFyclxcXCI6XFxcIuKGrlxcXCIsXFxcIm5oQXJyXFxcIjpcXFwi4oeOXFxcIixcXFwibmhwYXJcXFwiOlxcXCLiq7JcXFwiLFxcXCJuaVxcXCI6XFxcIuKIi1xcXCIsXFxcIm5pc1xcXCI6XFxcIuKLvFxcXCIsXFxcIm5pc2RcXFwiOlxcXCLii7pcXFwiLFxcXCJuaXZcXFwiOlxcXCLiiItcXFwiLFxcXCJOSmN5XFxcIjpcXFwi0IpcXFwiLFxcXCJuamN5XFxcIjpcXFwi0ZpcXFwiLFxcXCJubGFyclxcXCI6XFxcIuKGmlxcXCIsXFxcIm5sQXJyXFxcIjpcXFwi4oeNXFxcIixcXFwibmxkclxcXCI6XFxcIuKApVxcXCIsXFxcIm5sRVxcXCI6XFxcIuKJpsy4XFxcIixcXFwibmxlXFxcIjpcXFwi4omwXFxcIixcXFwibmxlZnRhcnJvd1xcXCI6XFxcIuKGmlxcXCIsXFxcIm5MZWZ0YXJyb3dcXFwiOlxcXCLih41cXFwiLFxcXCJubGVmdHJpZ2h0YXJyb3dcXFwiOlxcXCLihq5cXFwiLFxcXCJuTGVmdHJpZ2h0YXJyb3dcXFwiOlxcXCLih45cXFwiLFxcXCJubGVxXFxcIjpcXFwi4omwXFxcIixcXFwibmxlcXFcXFwiOlxcXCLiiabMuFxcXCIsXFxcIm5sZXFzbGFudFxcXCI6XFxcIuKpvcy4XFxcIixcXFwibmxlc1xcXCI6XFxcIuKpvcy4XFxcIixcXFwibmxlc3NcXFwiOlxcXCLiia5cXFwiLFxcXCJuTGxcXFwiOlxcXCLii5jMuFxcXCIsXFxcIm5sc2ltXFxcIjpcXFwi4om0XFxcIixcXFwibkx0XFxcIjpcXFwi4omq4oOSXFxcIixcXFwibmx0XFxcIjpcXFwi4omuXFxcIixcXFwibmx0cmlcXFwiOlxcXCLii6pcXFwiLFxcXCJubHRyaWVcXFwiOlxcXCLii6xcXFwiLFxcXCJuTHR2XFxcIjpcXFwi4omqzLhcXFwiLFxcXCJubWlkXFxcIjpcXFwi4oikXFxcIixcXFwiTm9CcmVha1xcXCI6XFxcIuKBoFxcXCIsXFxcIk5vbkJyZWFraW5nU3BhY2VcXFwiOlxcXCLCoFxcXCIsXFxcIm5vcGZcXFwiOlxcXCLwnZWfXFxcIixcXFwiTm9wZlxcXCI6XFxcIuKElVxcXCIsXFxcIk5vdFxcXCI6XFxcIuKrrFxcXCIsXFxcIm5vdFxcXCI6XFxcIsKsXFxcIixcXFwiTm90Q29uZ3J1ZW50XFxcIjpcXFwi4omiXFxcIixcXFwiTm90Q3VwQ2FwXFxcIjpcXFwi4omtXFxcIixcXFwiTm90RG91YmxlVmVydGljYWxCYXJcXFwiOlxcXCLiiKZcXFwiLFxcXCJOb3RFbGVtZW50XFxcIjpcXFwi4oiJXFxcIixcXFwiTm90RXF1YWxcXFwiOlxcXCLiiaBcXFwiLFxcXCJOb3RFcXVhbFRpbGRlXFxcIjpcXFwi4omCzLhcXFwiLFxcXCJOb3RFeGlzdHNcXFwiOlxcXCLiiIRcXFwiLFxcXCJOb3RHcmVhdGVyXFxcIjpcXFwi4omvXFxcIixcXFwiTm90R3JlYXRlckVxdWFsXFxcIjpcXFwi4omxXFxcIixcXFwiTm90R3JlYXRlckZ1bGxFcXVhbFxcXCI6XFxcIuKJp8y4XFxcIixcXFwiTm90R3JlYXRlckdyZWF0ZXJcXFwiOlxcXCLiiavMuFxcXCIsXFxcIk5vdEdyZWF0ZXJMZXNzXFxcIjpcXFwi4om5XFxcIixcXFwiTm90R3JlYXRlclNsYW50RXF1YWxcXFwiOlxcXCLiqb7MuFxcXCIsXFxcIk5vdEdyZWF0ZXJUaWxkZVxcXCI6XFxcIuKJtVxcXCIsXFxcIk5vdEh1bXBEb3duSHVtcFxcXCI6XFxcIuKJjsy4XFxcIixcXFwiTm90SHVtcEVxdWFsXFxcIjpcXFwi4omPzLhcXFwiLFxcXCJub3RpblxcXCI6XFxcIuKIiVxcXCIsXFxcIm5vdGluZG90XFxcIjpcXFwi4ou1zLhcXFwiLFxcXCJub3RpbkVcXFwiOlxcXCLii7nMuFxcXCIsXFxcIm5vdGludmFcXFwiOlxcXCLiiIlcXFwiLFxcXCJub3RpbnZiXFxcIjpcXFwi4ou3XFxcIixcXFwibm90aW52Y1xcXCI6XFxcIuKLtlxcXCIsXFxcIk5vdExlZnRUcmlhbmdsZUJhclxcXCI6XFxcIuKnj8y4XFxcIixcXFwiTm90TGVmdFRyaWFuZ2xlXFxcIjpcXFwi4ouqXFxcIixcXFwiTm90TGVmdFRyaWFuZ2xlRXF1YWxcXFwiOlxcXCLii6xcXFwiLFxcXCJOb3RMZXNzXFxcIjpcXFwi4omuXFxcIixcXFwiTm90TGVzc0VxdWFsXFxcIjpcXFwi4omwXFxcIixcXFwiTm90TGVzc0dyZWF0ZXJcXFwiOlxcXCLiibhcXFwiLFxcXCJOb3RMZXNzTGVzc1xcXCI6XFxcIuKJqsy4XFxcIixcXFwiTm90TGVzc1NsYW50RXF1YWxcXFwiOlxcXCLiqb3MuFxcXCIsXFxcIk5vdExlc3NUaWxkZVxcXCI6XFxcIuKJtFxcXCIsXFxcIk5vdE5lc3RlZEdyZWF0ZXJHcmVhdGVyXFxcIjpcXFwi4qqizLhcXFwiLFxcXCJOb3ROZXN0ZWRMZXNzTGVzc1xcXCI6XFxcIuKqocy4XFxcIixcXFwibm90bmlcXFwiOlxcXCLiiIxcXFwiLFxcXCJub3RuaXZhXFxcIjpcXFwi4oiMXFxcIixcXFwibm90bml2YlxcXCI6XFxcIuKLvlxcXCIsXFxcIm5vdG5pdmNcXFwiOlxcXCLii71cXFwiLFxcXCJOb3RQcmVjZWRlc1xcXCI6XFxcIuKKgFxcXCIsXFxcIk5vdFByZWNlZGVzRXF1YWxcXFwiOlxcXCLiqq/MuFxcXCIsXFxcIk5vdFByZWNlZGVzU2xhbnRFcXVhbFxcXCI6XFxcIuKLoFxcXCIsXFxcIk5vdFJldmVyc2VFbGVtZW50XFxcIjpcXFwi4oiMXFxcIixcXFwiTm90UmlnaHRUcmlhbmdsZUJhclxcXCI6XFxcIuKnkMy4XFxcIixcXFwiTm90UmlnaHRUcmlhbmdsZVxcXCI6XFxcIuKLq1xcXCIsXFxcIk5vdFJpZ2h0VHJpYW5nbGVFcXVhbFxcXCI6XFxcIuKLrVxcXCIsXFxcIk5vdFNxdWFyZVN1YnNldFxcXCI6XFxcIuKKj8y4XFxcIixcXFwiTm90U3F1YXJlU3Vic2V0RXF1YWxcXFwiOlxcXCLii6JcXFwiLFxcXCJOb3RTcXVhcmVTdXBlcnNldFxcXCI6XFxcIuKKkMy4XFxcIixcXFwiTm90U3F1YXJlU3VwZXJzZXRFcXVhbFxcXCI6XFxcIuKLo1xcXCIsXFxcIk5vdFN1YnNldFxcXCI6XFxcIuKKguKDklxcXCIsXFxcIk5vdFN1YnNldEVxdWFsXFxcIjpcXFwi4oqIXFxcIixcXFwiTm90U3VjY2VlZHNcXFwiOlxcXCLiioFcXFwiLFxcXCJOb3RTdWNjZWVkc0VxdWFsXFxcIjpcXFwi4qqwzLhcXFwiLFxcXCJOb3RTdWNjZWVkc1NsYW50RXF1YWxcXFwiOlxcXCLii6FcXFwiLFxcXCJOb3RTdWNjZWVkc1RpbGRlXFxcIjpcXFwi4om/zLhcXFwiLFxcXCJOb3RTdXBlcnNldFxcXCI6XFxcIuKKg+KDklxcXCIsXFxcIk5vdFN1cGVyc2V0RXF1YWxcXFwiOlxcXCLiiolcXFwiLFxcXCJOb3RUaWxkZVxcXCI6XFxcIuKJgVxcXCIsXFxcIk5vdFRpbGRlRXF1YWxcXFwiOlxcXCLiiYRcXFwiLFxcXCJOb3RUaWxkZUZ1bGxFcXVhbFxcXCI6XFxcIuKJh1xcXCIsXFxcIk5vdFRpbGRlVGlsZGVcXFwiOlxcXCLiiYlcXFwiLFxcXCJOb3RWZXJ0aWNhbEJhclxcXCI6XFxcIuKIpFxcXCIsXFxcIm5wYXJhbGxlbFxcXCI6XFxcIuKIplxcXCIsXFxcIm5wYXJcXFwiOlxcXCLiiKZcXFwiLFxcXCJucGFyc2xcXFwiOlxcXCLiq73ig6VcXFwiLFxcXCJucGFydFxcXCI6XFxcIuKIgsy4XFxcIixcXFwibnBvbGludFxcXCI6XFxcIuKolFxcXCIsXFxcIm5wclxcXCI6XFxcIuKKgFxcXCIsXFxcIm5wcmN1ZVxcXCI6XFxcIuKLoFxcXCIsXFxcIm5wcmVjXFxcIjpcXFwi4oqAXFxcIixcXFwibnByZWNlcVxcXCI6XFxcIuKqr8y4XFxcIixcXFwibnByZVxcXCI6XFxcIuKqr8y4XFxcIixcXFwibnJhcnJjXFxcIjpcXFwi4qSzzLhcXFwiLFxcXCJucmFyclxcXCI6XFxcIuKGm1xcXCIsXFxcIm5yQXJyXFxcIjpcXFwi4oePXFxcIixcXFwibnJhcnJ3XFxcIjpcXFwi4oadzLhcXFwiLFxcXCJucmlnaHRhcnJvd1xcXCI6XFxcIuKGm1xcXCIsXFxcIm5SaWdodGFycm93XFxcIjpcXFwi4oePXFxcIixcXFwibnJ0cmlcXFwiOlxcXCLii6tcXFwiLFxcXCJucnRyaWVcXFwiOlxcXCLii61cXFwiLFxcXCJuc2NcXFwiOlxcXCLiioFcXFwiLFxcXCJuc2NjdWVcXFwiOlxcXCLii6FcXFwiLFxcXCJuc2NlXFxcIjpcXFwi4qqwzLhcXFwiLFxcXCJOc2NyXFxcIjpcXFwi8J2SqVxcXCIsXFxcIm5zY3JcXFwiOlxcXCLwnZODXFxcIixcXFwibnNob3J0bWlkXFxcIjpcXFwi4oikXFxcIixcXFwibnNob3J0cGFyYWxsZWxcXFwiOlxcXCLiiKZcXFwiLFxcXCJuc2ltXFxcIjpcXFwi4omBXFxcIixcXFwibnNpbWVcXFwiOlxcXCLiiYRcXFwiLFxcXCJuc2ltZXFcXFwiOlxcXCLiiYRcXFwiLFxcXCJuc21pZFxcXCI6XFxcIuKIpFxcXCIsXFxcIm5zcGFyXFxcIjpcXFwi4oimXFxcIixcXFwibnNxc3ViZVxcXCI6XFxcIuKLolxcXCIsXFxcIm5zcXN1cGVcXFwiOlxcXCLii6NcXFwiLFxcXCJuc3ViXFxcIjpcXFwi4oqEXFxcIixcXFwibnN1YkVcXFwiOlxcXCLiq4XMuFxcXCIsXFxcIm5zdWJlXFxcIjpcXFwi4oqIXFxcIixcXFwibnN1YnNldFxcXCI6XFxcIuKKguKDklxcXCIsXFxcIm5zdWJzZXRlcVxcXCI6XFxcIuKKiFxcXCIsXFxcIm5zdWJzZXRlcXFcXFwiOlxcXCLiq4XMuFxcXCIsXFxcIm5zdWNjXFxcIjpcXFwi4oqBXFxcIixcXFwibnN1Y2NlcVxcXCI6XFxcIuKqsMy4XFxcIixcXFwibnN1cFxcXCI6XFxcIuKKhVxcXCIsXFxcIm5zdXBFXFxcIjpcXFwi4quGzLhcXFwiLFxcXCJuc3VwZVxcXCI6XFxcIuKKiVxcXCIsXFxcIm5zdXBzZXRcXFwiOlxcXCLiioPig5JcXFwiLFxcXCJuc3Vwc2V0ZXFcXFwiOlxcXCLiiolcXFwiLFxcXCJuc3Vwc2V0ZXFxXFxcIjpcXFwi4quGzLhcXFwiLFxcXCJudGdsXFxcIjpcXFwi4om5XFxcIixcXFwiTnRpbGRlXFxcIjpcXFwiw5FcXFwiLFxcXCJudGlsZGVcXFwiOlxcXCLDsVxcXCIsXFxcIm50bGdcXFwiOlxcXCLiibhcXFwiLFxcXCJudHJpYW5nbGVsZWZ0XFxcIjpcXFwi4ouqXFxcIixcXFwibnRyaWFuZ2xlbGVmdGVxXFxcIjpcXFwi4ousXFxcIixcXFwibnRyaWFuZ2xlcmlnaHRcXFwiOlxcXCLii6tcXFwiLFxcXCJudHJpYW5nbGVyaWdodGVxXFxcIjpcXFwi4outXFxcIixcXFwiTnVcXFwiOlxcXCLOnVxcXCIsXFxcIm51XFxcIjpcXFwizr1cXFwiLFxcXCJudW1cXFwiOlxcXCIjXFxcIixcXFwibnVtZXJvXFxcIjpcXFwi4oSWXFxcIixcXFwibnVtc3BcXFwiOlxcXCLigIdcXFwiLFxcXCJudmFwXFxcIjpcXFwi4omN4oOSXFxcIixcXFwibnZkYXNoXFxcIjpcXFwi4oqsXFxcIixcXFwibnZEYXNoXFxcIjpcXFwi4oqtXFxcIixcXFwiblZkYXNoXFxcIjpcXFwi4oquXFxcIixcXFwiblZEYXNoXFxcIjpcXFwi4oqvXFxcIixcXFwibnZnZVxcXCI6XFxcIuKJpeKDklxcXCIsXFxcIm52Z3RcXFwiOlxcXCI+4oOSXFxcIixcXFwibnZIYXJyXFxcIjpcXFwi4qSEXFxcIixcXFwibnZpbmZpblxcXCI6XFxcIuKnnlxcXCIsXFxcIm52bEFyclxcXCI6XFxcIuKkglxcXCIsXFxcIm52bGVcXFwiOlxcXCLiiaTig5JcXFwiLFxcXCJudmx0XFxcIjpcXFwiPOKDklxcXCIsXFxcIm52bHRyaWVcXFwiOlxcXCLiirTig5JcXFwiLFxcXCJudnJBcnJcXFwiOlxcXCLipINcXFwiLFxcXCJudnJ0cmllXFxcIjpcXFwi4oq14oOSXFxcIixcXFwibnZzaW1cXFwiOlxcXCLiiLzig5JcXFwiLFxcXCJud2FyaGtcXFwiOlxcXCLipKNcXFwiLFxcXCJud2FyclxcXCI6XFxcIuKGllxcXCIsXFxcIm53QXJyXFxcIjpcXFwi4oeWXFxcIixcXFwibndhcnJvd1xcXCI6XFxcIuKGllxcXCIsXFxcIm53bmVhclxcXCI6XFxcIuKkp1xcXCIsXFxcIk9hY3V0ZVxcXCI6XFxcIsOTXFxcIixcXFwib2FjdXRlXFxcIjpcXFwiw7NcXFwiLFxcXCJvYXN0XFxcIjpcXFwi4oqbXFxcIixcXFwiT2NpcmNcXFwiOlxcXCLDlFxcXCIsXFxcIm9jaXJjXFxcIjpcXFwiw7RcXFwiLFxcXCJvY2lyXFxcIjpcXFwi4oqaXFxcIixcXFwiT2N5XFxcIjpcXFwi0J5cXFwiLFxcXCJvY3lcXFwiOlxcXCLQvlxcXCIsXFxcIm9kYXNoXFxcIjpcXFwi4oqdXFxcIixcXFwiT2RibGFjXFxcIjpcXFwixZBcXFwiLFxcXCJvZGJsYWNcXFwiOlxcXCLFkVxcXCIsXFxcIm9kaXZcXFwiOlxcXCLiqLhcXFwiLFxcXCJvZG90XFxcIjpcXFwi4oqZXFxcIixcXFwib2Rzb2xkXFxcIjpcXFwi4qa8XFxcIixcXFwiT0VsaWdcXFwiOlxcXCLFklxcXCIsXFxcIm9lbGlnXFxcIjpcXFwixZNcXFwiLFxcXCJvZmNpclxcXCI6XFxcIuKmv1xcXCIsXFxcIk9mclxcXCI6XFxcIvCdlJJcXFwiLFxcXCJvZnJcXFwiOlxcXCLwnZSsXFxcIixcXFwib2dvblxcXCI6XFxcIsubXFxcIixcXFwiT2dyYXZlXFxcIjpcXFwiw5JcXFwiLFxcXCJvZ3JhdmVcXFwiOlxcXCLDslxcXCIsXFxcIm9ndFxcXCI6XFxcIuKngVxcXCIsXFxcIm9oYmFyXFxcIjpcXFwi4qa1XFxcIixcXFwib2htXFxcIjpcXFwizqlcXFwiLFxcXCJvaW50XFxcIjpcXFwi4oiuXFxcIixcXFwib2xhcnJcXFwiOlxcXCLihrpcXFwiLFxcXCJvbGNpclxcXCI6XFxcIuKmvlxcXCIsXFxcIm9sY3Jvc3NcXFwiOlxcXCLiprtcXFwiLFxcXCJvbGluZVxcXCI6XFxcIuKAvlxcXCIsXFxcIm9sdFxcXCI6XFxcIuKngFxcXCIsXFxcIk9tYWNyXFxcIjpcXFwixYxcXFwiLFxcXCJvbWFjclxcXCI6XFxcIsWNXFxcIixcXFwiT21lZ2FcXFwiOlxcXCLOqVxcXCIsXFxcIm9tZWdhXFxcIjpcXFwiz4lcXFwiLFxcXCJPbWljcm9uXFxcIjpcXFwizp9cXFwiLFxcXCJvbWljcm9uXFxcIjpcXFwizr9cXFwiLFxcXCJvbWlkXFxcIjpcXFwi4qa2XFxcIixcXFwib21pbnVzXFxcIjpcXFwi4oqWXFxcIixcXFwiT29wZlxcXCI6XFxcIvCdlYZcXFwiLFxcXCJvb3BmXFxcIjpcXFwi8J2VoFxcXCIsXFxcIm9wYXJcXFwiOlxcXCLiprdcXFwiLFxcXCJPcGVuQ3VybHlEb3VibGVRdW90ZVxcXCI6XFxcIuKAnFxcXCIsXFxcIk9wZW5DdXJseVF1b3RlXFxcIjpcXFwi4oCYXFxcIixcXFwib3BlcnBcXFwiOlxcXCLiprlcXFwiLFxcXCJvcGx1c1xcXCI6XFxcIuKKlVxcXCIsXFxcIm9yYXJyXFxcIjpcXFwi4oa7XFxcIixcXFwiT3JcXFwiOlxcXCLiqZRcXFwiLFxcXCJvclxcXCI6XFxcIuKIqFxcXCIsXFxcIm9yZFxcXCI6XFxcIuKpnVxcXCIsXFxcIm9yZGVyXFxcIjpcXFwi4oS0XFxcIixcXFwib3JkZXJvZlxcXCI6XFxcIuKEtFxcXCIsXFxcIm9yZGZcXFwiOlxcXCLCqlxcXCIsXFxcIm9yZG1cXFwiOlxcXCLCulxcXCIsXFxcIm9yaWdvZlxcXCI6XFxcIuKKtlxcXCIsXFxcIm9yb3JcXFwiOlxcXCLiqZZcXFwiLFxcXCJvcnNsb3BlXFxcIjpcXFwi4qmXXFxcIixcXFwib3J2XFxcIjpcXFwi4qmbXFxcIixcXFwib1NcXFwiOlxcXCLik4hcXFwiLFxcXCJPc2NyXFxcIjpcXFwi8J2SqlxcXCIsXFxcIm9zY3JcXFwiOlxcXCLihLRcXFwiLFxcXCJPc2xhc2hcXFwiOlxcXCLDmFxcXCIsXFxcIm9zbGFzaFxcXCI6XFxcIsO4XFxcIixcXFwib3NvbFxcXCI6XFxcIuKKmFxcXCIsXFxcIk90aWxkZVxcXCI6XFxcIsOVXFxcIixcXFwib3RpbGRlXFxcIjpcXFwiw7VcXFwiLFxcXCJvdGltZXNhc1xcXCI6XFxcIuKotlxcXCIsXFxcIk90aW1lc1xcXCI6XFxcIuKot1xcXCIsXFxcIm90aW1lc1xcXCI6XFxcIuKKl1xcXCIsXFxcIk91bWxcXFwiOlxcXCLDllxcXCIsXFxcIm91bWxcXFwiOlxcXCLDtlxcXCIsXFxcIm92YmFyXFxcIjpcXFwi4oy9XFxcIixcXFwiT3ZlckJhclxcXCI6XFxcIuKAvlxcXCIsXFxcIk92ZXJCcmFjZVxcXCI6XFxcIuKPnlxcXCIsXFxcIk92ZXJCcmFja2V0XFxcIjpcXFwi4o60XFxcIixcXFwiT3ZlclBhcmVudGhlc2lzXFxcIjpcXFwi4o+cXFxcIixcXFwicGFyYVxcXCI6XFxcIsK2XFxcIixcXFwicGFyYWxsZWxcXFwiOlxcXCLiiKVcXFwiLFxcXCJwYXJcXFwiOlxcXCLiiKVcXFwiLFxcXCJwYXJzaW1cXFwiOlxcXCLiq7NcXFwiLFxcXCJwYXJzbFxcXCI6XFxcIuKrvVxcXCIsXFxcInBhcnRcXFwiOlxcXCLiiIJcXFwiLFxcXCJQYXJ0aWFsRFxcXCI6XFxcIuKIglxcXCIsXFxcIlBjeVxcXCI6XFxcItCfXFxcIixcXFwicGN5XFxcIjpcXFwi0L9cXFwiLFxcXCJwZXJjbnRcXFwiOlxcXCIlXFxcIixcXFwicGVyaW9kXFxcIjpcXFwiLlxcXCIsXFxcInBlcm1pbFxcXCI6XFxcIuKAsFxcXCIsXFxcInBlcnBcXFwiOlxcXCLiiqVcXFwiLFxcXCJwZXJ0ZW5rXFxcIjpcXFwi4oCxXFxcIixcXFwiUGZyXFxcIjpcXFwi8J2Uk1xcXCIsXFxcInBmclxcXCI6XFxcIvCdlK1cXFwiLFxcXCJQaGlcXFwiOlxcXCLOplxcXCIsXFxcInBoaVxcXCI6XFxcIs+GXFxcIixcXFwicGhpdlxcXCI6XFxcIs+VXFxcIixcXFwicGhtbWF0XFxcIjpcXFwi4oSzXFxcIixcXFwicGhvbmVcXFwiOlxcXCLimI5cXFwiLFxcXCJQaVxcXCI6XFxcIs6gXFxcIixcXFwicGlcXFwiOlxcXCLPgFxcXCIsXFxcInBpdGNoZm9ya1xcXCI6XFxcIuKLlFxcXCIsXFxcInBpdlxcXCI6XFxcIs+WXFxcIixcXFwicGxhbmNrXFxcIjpcXFwi4oSPXFxcIixcXFwicGxhbmNraFxcXCI6XFxcIuKEjlxcXCIsXFxcInBsYW5rdlxcXCI6XFxcIuKEj1xcXCIsXFxcInBsdXNhY2lyXFxcIjpcXFwi4qijXFxcIixcXFwicGx1c2JcXFwiOlxcXCLiip5cXFwiLFxcXCJwbHVzY2lyXFxcIjpcXFwi4qiiXFxcIixcXFwicGx1c1xcXCI6XFxcIitcXFwiLFxcXCJwbHVzZG9cXFwiOlxcXCLiiJRcXFwiLFxcXCJwbHVzZHVcXFwiOlxcXCLiqKVcXFwiLFxcXCJwbHVzZVxcXCI6XFxcIuKpslxcXCIsXFxcIlBsdXNNaW51c1xcXCI6XFxcIsKxXFxcIixcXFwicGx1c21uXFxcIjpcXFwiwrFcXFwiLFxcXCJwbHVzc2ltXFxcIjpcXFwi4qimXFxcIixcXFwicGx1c3R3b1xcXCI6XFxcIuKop1xcXCIsXFxcInBtXFxcIjpcXFwiwrFcXFwiLFxcXCJQb2luY2FyZXBsYW5lXFxcIjpcXFwi4oSMXFxcIixcXFwicG9pbnRpbnRcXFwiOlxcXCLiqJVcXFwiLFxcXCJwb3BmXFxcIjpcXFwi8J2VoVxcXCIsXFxcIlBvcGZcXFwiOlxcXCLihJlcXFwiLFxcXCJwb3VuZFxcXCI6XFxcIsKjXFxcIixcXFwicHJhcFxcXCI6XFxcIuKqt1xcXCIsXFxcIlByXFxcIjpcXFwi4qq7XFxcIixcXFwicHJcXFwiOlxcXCLiibpcXFwiLFxcXCJwcmN1ZVxcXCI6XFxcIuKJvFxcXCIsXFxcInByZWNhcHByb3hcXFwiOlxcXCLiqrdcXFwiLFxcXCJwcmVjXFxcIjpcXFwi4om6XFxcIixcXFwicHJlY2N1cmx5ZXFcXFwiOlxcXCLiibxcXFwiLFxcXCJQcmVjZWRlc1xcXCI6XFxcIuKJulxcXCIsXFxcIlByZWNlZGVzRXF1YWxcXFwiOlxcXCLiqq9cXFwiLFxcXCJQcmVjZWRlc1NsYW50RXF1YWxcXFwiOlxcXCLiibxcXFwiLFxcXCJQcmVjZWRlc1RpbGRlXFxcIjpcXFwi4om+XFxcIixcXFwicHJlY2VxXFxcIjpcXFwi4qqvXFxcIixcXFwicHJlY25hcHByb3hcXFwiOlxcXCLiqrlcXFwiLFxcXCJwcmVjbmVxcVxcXCI6XFxcIuKqtVxcXCIsXFxcInByZWNuc2ltXFxcIjpcXFwi4ouoXFxcIixcXFwicHJlXFxcIjpcXFwi4qqvXFxcIixcXFwicHJFXFxcIjpcXFwi4qqzXFxcIixcXFwicHJlY3NpbVxcXCI6XFxcIuKJvlxcXCIsXFxcInByaW1lXFxcIjpcXFwi4oCyXFxcIixcXFwiUHJpbWVcXFwiOlxcXCLigLNcXFwiLFxcXCJwcmltZXNcXFwiOlxcXCLihJlcXFwiLFxcXCJwcm5hcFxcXCI6XFxcIuKquVxcXCIsXFxcInBybkVcXFwiOlxcXCLiqrVcXFwiLFxcXCJwcm5zaW1cXFwiOlxcXCLii6hcXFwiLFxcXCJwcm9kXFxcIjpcXFwi4oiPXFxcIixcXFwiUHJvZHVjdFxcXCI6XFxcIuKIj1xcXCIsXFxcInByb2ZhbGFyXFxcIjpcXFwi4oyuXFxcIixcXFwicHJvZmxpbmVcXFwiOlxcXCLijJJcXFwiLFxcXCJwcm9mc3VyZlxcXCI6XFxcIuKMk1xcXCIsXFxcInByb3BcXFwiOlxcXCLiiJ1cXFwiLFxcXCJQcm9wb3J0aW9uYWxcXFwiOlxcXCLiiJ1cXFwiLFxcXCJQcm9wb3J0aW9uXFxcIjpcXFwi4oi3XFxcIixcXFwicHJvcHRvXFxcIjpcXFwi4oidXFxcIixcXFwicHJzaW1cXFwiOlxcXCLiib5cXFwiLFxcXCJwcnVyZWxcXFwiOlxcXCLiirBcXFwiLFxcXCJQc2NyXFxcIjpcXFwi8J2Sq1xcXCIsXFxcInBzY3JcXFwiOlxcXCLwnZOFXFxcIixcXFwiUHNpXFxcIjpcXFwizqhcXFwiLFxcXCJwc2lcXFwiOlxcXCLPiFxcXCIsXFxcInB1bmNzcFxcXCI6XFxcIuKAiFxcXCIsXFxcIlFmclxcXCI6XFxcIvCdlJRcXFwiLFxcXCJxZnJcXFwiOlxcXCLwnZSuXFxcIixcXFwicWludFxcXCI6XFxcIuKojFxcXCIsXFxcInFvcGZcXFwiOlxcXCLwnZWiXFxcIixcXFwiUW9wZlxcXCI6XFxcIuKEmlxcXCIsXFxcInFwcmltZVxcXCI6XFxcIuKBl1xcXCIsXFxcIlFzY3JcXFwiOlxcXCLwnZKsXFxcIixcXFwicXNjclxcXCI6XFxcIvCdk4ZcXFwiLFxcXCJxdWF0ZXJuaW9uc1xcXCI6XFxcIuKEjVxcXCIsXFxcInF1YXRpbnRcXFwiOlxcXCLiqJZcXFwiLFxcXCJxdWVzdFxcXCI6XFxcIj9cXFwiLFxcXCJxdWVzdGVxXFxcIjpcXFwi4omfXFxcIixcXFwicXVvdFxcXCI6XFxcIlxcXFxcXFwiXFxcIixcXFwiUVVPVFxcXCI6XFxcIlxcXFxcXFwiXFxcIixcXFwickFhcnJcXFwiOlxcXCLih5tcXFwiLFxcXCJyYWNlXFxcIjpcXFwi4oi9zLFcXFwiLFxcXCJSYWN1dGVcXFwiOlxcXCLFlFxcXCIsXFxcInJhY3V0ZVxcXCI6XFxcIsWVXFxcIixcXFwicmFkaWNcXFwiOlxcXCLiiJpcXFwiLFxcXCJyYWVtcHR5dlxcXCI6XFxcIuKms1xcXCIsXFxcInJhbmdcXFwiOlxcXCLin6lcXFwiLFxcXCJSYW5nXFxcIjpcXFwi4p+rXFxcIixcXFwicmFuZ2RcXFwiOlxcXCLippJcXFwiLFxcXCJyYW5nZVxcXCI6XFxcIuKmpVxcXCIsXFxcInJhbmdsZVxcXCI6XFxcIuKfqVxcXCIsXFxcInJhcXVvXFxcIjpcXFwiwrtcXFwiLFxcXCJyYXJyYXBcXFwiOlxcXCLipbVcXFwiLFxcXCJyYXJyYlxcXCI6XFxcIuKHpVxcXCIsXFxcInJhcnJiZnNcXFwiOlxcXCLipKBcXFwiLFxcXCJyYXJyY1xcXCI6XFxcIuKks1xcXCIsXFxcInJhcnJcXFwiOlxcXCLihpJcXFwiLFxcXCJSYXJyXFxcIjpcXFwi4oagXFxcIixcXFwickFyclxcXCI6XFxcIuKHklxcXCIsXFxcInJhcnJmc1xcXCI6XFxcIuKknlxcXCIsXFxcInJhcnJoa1xcXCI6XFxcIuKGqlxcXCIsXFxcInJhcnJscFxcXCI6XFxcIuKGrFxcXCIsXFxcInJhcnJwbFxcXCI6XFxcIuKlhVxcXCIsXFxcInJhcnJzaW1cXFwiOlxcXCLipbRcXFwiLFxcXCJSYXJydGxcXFwiOlxcXCLipJZcXFwiLFxcXCJyYXJydGxcXFwiOlxcXCLihqNcXFwiLFxcXCJyYXJyd1xcXCI6XFxcIuKGnVxcXCIsXFxcInJhdGFpbFxcXCI6XFxcIuKkmlxcXCIsXFxcInJBdGFpbFxcXCI6XFxcIuKknFxcXCIsXFxcInJhdGlvXFxcIjpcXFwi4oi2XFxcIixcXFwicmF0aW9uYWxzXFxcIjpcXFwi4oSaXFxcIixcXFwicmJhcnJcXFwiOlxcXCLipI1cXFwiLFxcXCJyQmFyclxcXCI6XFxcIuKkj1xcXCIsXFxcIlJCYXJyXFxcIjpcXFwi4qSQXFxcIixcXFwicmJicmtcXFwiOlxcXCLinbNcXFwiLFxcXCJyYnJhY2VcXFwiOlxcXCJ9XFxcIixcXFwicmJyYWNrXFxcIjpcXFwiXVxcXCIsXFxcInJicmtlXFxcIjpcXFwi4qaMXFxcIixcXFwicmJya3NsZFxcXCI6XFxcIuKmjlxcXCIsXFxcInJicmtzbHVcXFwiOlxcXCLippBcXFwiLFxcXCJSY2Fyb25cXFwiOlxcXCLFmFxcXCIsXFxcInJjYXJvblxcXCI6XFxcIsWZXFxcIixcXFwiUmNlZGlsXFxcIjpcXFwixZZcXFwiLFxcXCJyY2VkaWxcXFwiOlxcXCLFl1xcXCIsXFxcInJjZWlsXFxcIjpcXFwi4oyJXFxcIixcXFwicmN1YlxcXCI6XFxcIn1cXFwiLFxcXCJSY3lcXFwiOlxcXCLQoFxcXCIsXFxcInJjeVxcXCI6XFxcItGAXFxcIixcXFwicmRjYVxcXCI6XFxcIuKkt1xcXCIsXFxcInJkbGRoYXJcXFwiOlxcXCLipalcXFwiLFxcXCJyZHF1b1xcXCI6XFxcIuKAnVxcXCIsXFxcInJkcXVvclxcXCI6XFxcIuKAnVxcXCIsXFxcInJkc2hcXFwiOlxcXCLihrNcXFwiLFxcXCJyZWFsXFxcIjpcXFwi4oScXFxcIixcXFwicmVhbGluZVxcXCI6XFxcIuKEm1xcXCIsXFxcInJlYWxwYXJ0XFxcIjpcXFwi4oScXFxcIixcXFwicmVhbHNcXFwiOlxcXCLihJ1cXFwiLFxcXCJSZVxcXCI6XFxcIuKEnFxcXCIsXFxcInJlY3RcXFwiOlxcXCLilq1cXFwiLFxcXCJyZWdcXFwiOlxcXCLCrlxcXCIsXFxcIlJFR1xcXCI6XFxcIsKuXFxcIixcXFwiUmV2ZXJzZUVsZW1lbnRcXFwiOlxcXCLiiItcXFwiLFxcXCJSZXZlcnNlRXF1aWxpYnJpdW1cXFwiOlxcXCLih4tcXFwiLFxcXCJSZXZlcnNlVXBFcXVpbGlicml1bVxcXCI6XFxcIuKlr1xcXCIsXFxcInJmaXNodFxcXCI6XFxcIuKlvVxcXCIsXFxcInJmbG9vclxcXCI6XFxcIuKMi1xcXCIsXFxcInJmclxcXCI6XFxcIvCdlK9cXFwiLFxcXCJSZnJcXFwiOlxcXCLihJxcXFwiLFxcXCJySGFyXFxcIjpcXFwi4qWkXFxcIixcXFwicmhhcmRcXFwiOlxcXCLih4FcXFwiLFxcXCJyaGFydVxcXCI6XFxcIuKHgFxcXCIsXFxcInJoYXJ1bFxcXCI6XFxcIuKlrFxcXCIsXFxcIlJob1xcXCI6XFxcIs6hXFxcIixcXFwicmhvXFxcIjpcXFwiz4FcXFwiLFxcXCJyaG92XFxcIjpcXFwiz7FcXFwiLFxcXCJSaWdodEFuZ2xlQnJhY2tldFxcXCI6XFxcIuKfqVxcXCIsXFxcIlJpZ2h0QXJyb3dCYXJcXFwiOlxcXCLih6VcXFwiLFxcXCJyaWdodGFycm93XFxcIjpcXFwi4oaSXFxcIixcXFwiUmlnaHRBcnJvd1xcXCI6XFxcIuKGklxcXCIsXFxcIlJpZ2h0YXJyb3dcXFwiOlxcXCLih5JcXFwiLFxcXCJSaWdodEFycm93TGVmdEFycm93XFxcIjpcXFwi4oeEXFxcIixcXFwicmlnaHRhcnJvd3RhaWxcXFwiOlxcXCLihqNcXFwiLFxcXCJSaWdodENlaWxpbmdcXFwiOlxcXCLijIlcXFwiLFxcXCJSaWdodERvdWJsZUJyYWNrZXRcXFwiOlxcXCLin6dcXFwiLFxcXCJSaWdodERvd25UZWVWZWN0b3JcXFwiOlxcXCLipZ1cXFwiLFxcXCJSaWdodERvd25WZWN0b3JCYXJcXFwiOlxcXCLipZVcXFwiLFxcXCJSaWdodERvd25WZWN0b3JcXFwiOlxcXCLih4JcXFwiLFxcXCJSaWdodEZsb29yXFxcIjpcXFwi4oyLXFxcIixcXFwicmlnaHRoYXJwb29uZG93blxcXCI6XFxcIuKHgVxcXCIsXFxcInJpZ2h0aGFycG9vbnVwXFxcIjpcXFwi4oeAXFxcIixcXFwicmlnaHRsZWZ0YXJyb3dzXFxcIjpcXFwi4oeEXFxcIixcXFwicmlnaHRsZWZ0aGFycG9vbnNcXFwiOlxcXCLih4xcXFwiLFxcXCJyaWdodHJpZ2h0YXJyb3dzXFxcIjpcXFwi4oeJXFxcIixcXFwicmlnaHRzcXVpZ2Fycm93XFxcIjpcXFwi4oadXFxcIixcXFwiUmlnaHRUZWVBcnJvd1xcXCI6XFxcIuKGplxcXCIsXFxcIlJpZ2h0VGVlXFxcIjpcXFwi4oqiXFxcIixcXFwiUmlnaHRUZWVWZWN0b3JcXFwiOlxcXCLipZtcXFwiLFxcXCJyaWdodHRocmVldGltZXNcXFwiOlxcXCLii4xcXFwiLFxcXCJSaWdodFRyaWFuZ2xlQmFyXFxcIjpcXFwi4qeQXFxcIixcXFwiUmlnaHRUcmlhbmdsZVxcXCI6XFxcIuKKs1xcXCIsXFxcIlJpZ2h0VHJpYW5nbGVFcXVhbFxcXCI6XFxcIuKKtVxcXCIsXFxcIlJpZ2h0VXBEb3duVmVjdG9yXFxcIjpcXFwi4qWPXFxcIixcXFwiUmlnaHRVcFRlZVZlY3RvclxcXCI6XFxcIuKlnFxcXCIsXFxcIlJpZ2h0VXBWZWN0b3JCYXJcXFwiOlxcXCLipZRcXFwiLFxcXCJSaWdodFVwVmVjdG9yXFxcIjpcXFwi4oa+XFxcIixcXFwiUmlnaHRWZWN0b3JCYXJcXFwiOlxcXCLipZNcXFwiLFxcXCJSaWdodFZlY3RvclxcXCI6XFxcIuKHgFxcXCIsXFxcInJpbmdcXFwiOlxcXCLLmlxcXCIsXFxcInJpc2luZ2RvdHNlcVxcXCI6XFxcIuKJk1xcXCIsXFxcInJsYXJyXFxcIjpcXFwi4oeEXFxcIixcXFwicmxoYXJcXFwiOlxcXCLih4xcXFwiLFxcXCJybG1cXFwiOlxcXCLigI9cXFwiLFxcXCJybW91c3RhY2hlXFxcIjpcXFwi4o6xXFxcIixcXFwicm1vdXN0XFxcIjpcXFwi4o6xXFxcIixcXFwicm5taWRcXFwiOlxcXCLiq65cXFwiLFxcXCJyb2FuZ1xcXCI6XFxcIuKfrVxcXCIsXFxcInJvYXJyXFxcIjpcXFwi4oe+XFxcIixcXFwicm9icmtcXFwiOlxcXCLin6dcXFwiLFxcXCJyb3BhclxcXCI6XFxcIuKmhlxcXCIsXFxcInJvcGZcXFwiOlxcXCLwnZWjXFxcIixcXFwiUm9wZlxcXCI6XFxcIuKEnVxcXCIsXFxcInJvcGx1c1xcXCI6XFxcIuKorlxcXCIsXFxcInJvdGltZXNcXFwiOlxcXCLiqLVcXFwiLFxcXCJSb3VuZEltcGxpZXNcXFwiOlxcXCLipbBcXFwiLFxcXCJycGFyXFxcIjpcXFwiKVxcXCIsXFxcInJwYXJndFxcXCI6XFxcIuKmlFxcXCIsXFxcInJwcG9saW50XFxcIjpcXFwi4qiSXFxcIixcXFwicnJhcnJcXFwiOlxcXCLih4lcXFwiLFxcXCJScmlnaHRhcnJvd1xcXCI6XFxcIuKHm1xcXCIsXFxcInJzYXF1b1xcXCI6XFxcIuKAulxcXCIsXFxcInJzY3JcXFwiOlxcXCLwnZOHXFxcIixcXFwiUnNjclxcXCI6XFxcIuKEm1xcXCIsXFxcInJzaFxcXCI6XFxcIuKGsVxcXCIsXFxcIlJzaFxcXCI6XFxcIuKGsVxcXCIsXFxcInJzcWJcXFwiOlxcXCJdXFxcIixcXFwicnNxdW9cXFwiOlxcXCLigJlcXFwiLFxcXCJyc3F1b3JcXFwiOlxcXCLigJlcXFwiLFxcXCJydGhyZWVcXFwiOlxcXCLii4xcXFwiLFxcXCJydGltZXNcXFwiOlxcXCLii4pcXFwiLFxcXCJydHJpXFxcIjpcXFwi4pa5XFxcIixcXFwicnRyaWVcXFwiOlxcXCLiirVcXFwiLFxcXCJydHJpZlxcXCI6XFxcIuKWuFxcXCIsXFxcInJ0cmlsdHJpXFxcIjpcXFwi4qeOXFxcIixcXFwiUnVsZURlbGF5ZWRcXFwiOlxcXCLip7RcXFwiLFxcXCJydWx1aGFyXFxcIjpcXFwi4qWoXFxcIixcXFwicnhcXFwiOlxcXCLihJ5cXFwiLFxcXCJTYWN1dGVcXFwiOlxcXCLFmlxcXCIsXFxcInNhY3V0ZVxcXCI6XFxcIsWbXFxcIixcXFwic2JxdW9cXFwiOlxcXCLigJpcXFwiLFxcXCJzY2FwXFxcIjpcXFwi4qq4XFxcIixcXFwiU2Nhcm9uXFxcIjpcXFwixaBcXFwiLFxcXCJzY2Fyb25cXFwiOlxcXCLFoVxcXCIsXFxcIlNjXFxcIjpcXFwi4qq8XFxcIixcXFwic2NcXFwiOlxcXCLiibtcXFwiLFxcXCJzY2N1ZVxcXCI6XFxcIuKJvVxcXCIsXFxcInNjZVxcXCI6XFxcIuKqsFxcXCIsXFxcInNjRVxcXCI6XFxcIuKqtFxcXCIsXFxcIlNjZWRpbFxcXCI6XFxcIsWeXFxcIixcXFwic2NlZGlsXFxcIjpcXFwixZ9cXFwiLFxcXCJTY2lyY1xcXCI6XFxcIsWcXFxcIixcXFwic2NpcmNcXFwiOlxcXCLFnVxcXCIsXFxcInNjbmFwXFxcIjpcXFwi4qq6XFxcIixcXFwic2NuRVxcXCI6XFxcIuKqtlxcXCIsXFxcInNjbnNpbVxcXCI6XFxcIuKLqVxcXCIsXFxcInNjcG9saW50XFxcIjpcXFwi4qiTXFxcIixcXFwic2NzaW1cXFwiOlxcXCLiib9cXFwiLFxcXCJTY3lcXFwiOlxcXCLQoVxcXCIsXFxcInNjeVxcXCI6XFxcItGBXFxcIixcXFwic2RvdGJcXFwiOlxcXCLiiqFcXFwiLFxcXCJzZG90XFxcIjpcXFwi4ouFXFxcIixcXFwic2RvdGVcXFwiOlxcXCLiqaZcXFwiLFxcXCJzZWFyaGtcXFwiOlxcXCLipKVcXFwiLFxcXCJzZWFyclxcXCI6XFxcIuKGmFxcXCIsXFxcInNlQXJyXFxcIjpcXFwi4oeYXFxcIixcXFwic2VhcnJvd1xcXCI6XFxcIuKGmFxcXCIsXFxcInNlY3RcXFwiOlxcXCLCp1xcXCIsXFxcInNlbWlcXFwiOlxcXCI7XFxcIixcXFwic2Vzd2FyXFxcIjpcXFwi4qSpXFxcIixcXFwic2V0bWludXNcXFwiOlxcXCLiiJZcXFwiLFxcXCJzZXRtblxcXCI6XFxcIuKIllxcXCIsXFxcInNleHRcXFwiOlxcXCLinLZcXFwiLFxcXCJTZnJcXFwiOlxcXCLwnZSWXFxcIixcXFwic2ZyXFxcIjpcXFwi8J2UsFxcXCIsXFxcInNmcm93blxcXCI6XFxcIuKMolxcXCIsXFxcInNoYXJwXFxcIjpcXFwi4pmvXFxcIixcXFwiU0hDSGN5XFxcIjpcXFwi0KlcXFwiLFxcXCJzaGNoY3lcXFwiOlxcXCLRiVxcXCIsXFxcIlNIY3lcXFwiOlxcXCLQqFxcXCIsXFxcInNoY3lcXFwiOlxcXCLRiFxcXCIsXFxcIlNob3J0RG93bkFycm93XFxcIjpcXFwi4oaTXFxcIixcXFwiU2hvcnRMZWZ0QXJyb3dcXFwiOlxcXCLihpBcXFwiLFxcXCJzaG9ydG1pZFxcXCI6XFxcIuKIo1xcXCIsXFxcInNob3J0cGFyYWxsZWxcXFwiOlxcXCLiiKVcXFwiLFxcXCJTaG9ydFJpZ2h0QXJyb3dcXFwiOlxcXCLihpJcXFwiLFxcXCJTaG9ydFVwQXJyb3dcXFwiOlxcXCLihpFcXFwiLFxcXCJzaHlcXFwiOlxcXCLCrVxcXCIsXFxcIlNpZ21hXFxcIjpcXFwizqNcXFwiLFxcXCJzaWdtYVxcXCI6XFxcIs+DXFxcIixcXFwic2lnbWFmXFxcIjpcXFwiz4JcXFwiLFxcXCJzaWdtYXZcXFwiOlxcXCLPglxcXCIsXFxcInNpbVxcXCI6XFxcIuKIvFxcXCIsXFxcInNpbWRvdFxcXCI6XFxcIuKpqlxcXCIsXFxcInNpbWVcXFwiOlxcXCLiiYNcXFwiLFxcXCJzaW1lcVxcXCI6XFxcIuKJg1xcXCIsXFxcInNpbWdcXFwiOlxcXCLiqp5cXFwiLFxcXCJzaW1nRVxcXCI6XFxcIuKqoFxcXCIsXFxcInNpbWxcXFwiOlxcXCLiqp1cXFwiLFxcXCJzaW1sRVxcXCI6XFxcIuKqn1xcXCIsXFxcInNpbW5lXFxcIjpcXFwi4omGXFxcIixcXFwic2ltcGx1c1xcXCI6XFxcIuKopFxcXCIsXFxcInNpbXJhcnJcXFwiOlxcXCLipbJcXFwiLFxcXCJzbGFyclxcXCI6XFxcIuKGkFxcXCIsXFxcIlNtYWxsQ2lyY2xlXFxcIjpcXFwi4oiYXFxcIixcXFwic21hbGxzZXRtaW51c1xcXCI6XFxcIuKIllxcXCIsXFxcInNtYXNocFxcXCI6XFxcIuKos1xcXCIsXFxcInNtZXBhcnNsXFxcIjpcXFwi4qekXFxcIixcXFwic21pZFxcXCI6XFxcIuKIo1xcXCIsXFxcInNtaWxlXFxcIjpcXFwi4oyjXFxcIixcXFwic210XFxcIjpcXFwi4qqqXFxcIixcXFwic210ZVxcXCI6XFxcIuKqrFxcXCIsXFxcInNtdGVzXFxcIjpcXFwi4qqs77iAXFxcIixcXFwiU09GVGN5XFxcIjpcXFwi0KxcXFwiLFxcXCJzb2Z0Y3lcXFwiOlxcXCLRjFxcXCIsXFxcInNvbGJhclxcXCI6XFxcIuKMv1xcXCIsXFxcInNvbGJcXFwiOlxcXCLip4RcXFwiLFxcXCJzb2xcXFwiOlxcXCIvXFxcIixcXFwiU29wZlxcXCI6XFxcIvCdlYpcXFwiLFxcXCJzb3BmXFxcIjpcXFwi8J2VpFxcXCIsXFxcInNwYWRlc1xcXCI6XFxcIuKZoFxcXCIsXFxcInNwYWRlc3VpdFxcXCI6XFxcIuKZoFxcXCIsXFxcInNwYXJcXFwiOlxcXCLiiKVcXFwiLFxcXCJzcWNhcFxcXCI6XFxcIuKKk1xcXCIsXFxcInNxY2Fwc1xcXCI6XFxcIuKKk++4gFxcXCIsXFxcInNxY3VwXFxcIjpcXFwi4oqUXFxcIixcXFwic3FjdXBzXFxcIjpcXFwi4oqU77iAXFxcIixcXFwiU3FydFxcXCI6XFxcIuKImlxcXCIsXFxcInNxc3ViXFxcIjpcXFwi4oqPXFxcIixcXFwic3FzdWJlXFxcIjpcXFwi4oqRXFxcIixcXFwic3FzdWJzZXRcXFwiOlxcXCLiio9cXFwiLFxcXCJzcXN1YnNldGVxXFxcIjpcXFwi4oqRXFxcIixcXFwic3FzdXBcXFwiOlxcXCLiipBcXFwiLFxcXCJzcXN1cGVcXFwiOlxcXCLiipJcXFwiLFxcXCJzcXN1cHNldFxcXCI6XFxcIuKKkFxcXCIsXFxcInNxc3Vwc2V0ZXFcXFwiOlxcXCLiipJcXFwiLFxcXCJzcXVhcmVcXFwiOlxcXCLilqFcXFwiLFxcXCJTcXVhcmVcXFwiOlxcXCLilqFcXFwiLFxcXCJTcXVhcmVJbnRlcnNlY3Rpb25cXFwiOlxcXCLiipNcXFwiLFxcXCJTcXVhcmVTdWJzZXRcXFwiOlxcXCLiio9cXFwiLFxcXCJTcXVhcmVTdWJzZXRFcXVhbFxcXCI6XFxcIuKKkVxcXCIsXFxcIlNxdWFyZVN1cGVyc2V0XFxcIjpcXFwi4oqQXFxcIixcXFwiU3F1YXJlU3VwZXJzZXRFcXVhbFxcXCI6XFxcIuKKklxcXCIsXFxcIlNxdWFyZVVuaW9uXFxcIjpcXFwi4oqUXFxcIixcXFwic3F1YXJmXFxcIjpcXFwi4paqXFxcIixcXFwic3F1XFxcIjpcXFwi4pahXFxcIixcXFwic3F1ZlxcXCI6XFxcIuKWqlxcXCIsXFxcInNyYXJyXFxcIjpcXFwi4oaSXFxcIixcXFwiU3NjclxcXCI6XFxcIvCdkq5cXFwiLFxcXCJzc2NyXFxcIjpcXFwi8J2TiFxcXCIsXFxcInNzZXRtblxcXCI6XFxcIuKIllxcXCIsXFxcInNzbWlsZVxcXCI6XFxcIuKMo1xcXCIsXFxcInNzdGFyZlxcXCI6XFxcIuKLhlxcXCIsXFxcIlN0YXJcXFwiOlxcXCLii4ZcXFwiLFxcXCJzdGFyXFxcIjpcXFwi4piGXFxcIixcXFwic3RhcmZcXFwiOlxcXCLimIVcXFwiLFxcXCJzdHJhaWdodGVwc2lsb25cXFwiOlxcXCLPtVxcXCIsXFxcInN0cmFpZ2h0cGhpXFxcIjpcXFwiz5VcXFwiLFxcXCJzdHJuc1xcXCI6XFxcIsKvXFxcIixcXFwic3ViXFxcIjpcXFwi4oqCXFxcIixcXFwiU3ViXFxcIjpcXFwi4ouQXFxcIixcXFwic3ViZG90XFxcIjpcXFwi4qq9XFxcIixcXFwic3ViRVxcXCI6XFxcIuKrhVxcXCIsXFxcInN1YmVcXFwiOlxcXCLiioZcXFwiLFxcXCJzdWJlZG90XFxcIjpcXFwi4quDXFxcIixcXFwic3VibXVsdFxcXCI6XFxcIuKrgVxcXCIsXFxcInN1Ym5FXFxcIjpcXFwi4quLXFxcIixcXFwic3VibmVcXFwiOlxcXCLiiopcXFwiLFxcXCJzdWJwbHVzXFxcIjpcXFwi4qq/XFxcIixcXFwic3VicmFyclxcXCI6XFxcIuKluVxcXCIsXFxcInN1YnNldFxcXCI6XFxcIuKKglxcXCIsXFxcIlN1YnNldFxcXCI6XFxcIuKLkFxcXCIsXFxcInN1YnNldGVxXFxcIjpcXFwi4oqGXFxcIixcXFwic3Vic2V0ZXFxXFxcIjpcXFwi4quFXFxcIixcXFwiU3Vic2V0RXF1YWxcXFwiOlxcXCLiioZcXFwiLFxcXCJzdWJzZXRuZXFcXFwiOlxcXCLiiopcXFwiLFxcXCJzdWJzZXRuZXFxXFxcIjpcXFwi4quLXFxcIixcXFwic3Vic2ltXFxcIjpcXFwi4quHXFxcIixcXFwic3Vic3ViXFxcIjpcXFwi4quVXFxcIixcXFwic3Vic3VwXFxcIjpcXFwi4quTXFxcIixcXFwic3VjY2FwcHJveFxcXCI6XFxcIuKquFxcXCIsXFxcInN1Y2NcXFwiOlxcXCLiibtcXFwiLFxcXCJzdWNjY3VybHllcVxcXCI6XFxcIuKJvVxcXCIsXFxcIlN1Y2NlZWRzXFxcIjpcXFwi4om7XFxcIixcXFwiU3VjY2VlZHNFcXVhbFxcXCI6XFxcIuKqsFxcXCIsXFxcIlN1Y2NlZWRzU2xhbnRFcXVhbFxcXCI6XFxcIuKJvVxcXCIsXFxcIlN1Y2NlZWRzVGlsZGVcXFwiOlxcXCLiib9cXFwiLFxcXCJzdWNjZXFcXFwiOlxcXCLiqrBcXFwiLFxcXCJzdWNjbmFwcHJveFxcXCI6XFxcIuKqulxcXCIsXFxcInN1Y2NuZXFxXFxcIjpcXFwi4qq2XFxcIixcXFwic3VjY25zaW1cXFwiOlxcXCLii6lcXFwiLFxcXCJzdWNjc2ltXFxcIjpcXFwi4om/XFxcIixcXFwiU3VjaFRoYXRcXFwiOlxcXCLiiItcXFwiLFxcXCJzdW1cXFwiOlxcXCLiiJFcXFwiLFxcXCJTdW1cXFwiOlxcXCLiiJFcXFwiLFxcXCJzdW5nXFxcIjpcXFwi4pmqXFxcIixcXFwic3VwMVxcXCI6XFxcIsK5XFxcIixcXFwic3VwMlxcXCI6XFxcIsKyXFxcIixcXFwic3VwM1xcXCI6XFxcIsKzXFxcIixcXFwic3VwXFxcIjpcXFwi4oqDXFxcIixcXFwiU3VwXFxcIjpcXFwi4ouRXFxcIixcXFwic3VwZG90XFxcIjpcXFwi4qq+XFxcIixcXFwic3VwZHN1YlxcXCI6XFxcIuKrmFxcXCIsXFxcInN1cEVcXFwiOlxcXCLiq4ZcXFwiLFxcXCJzdXBlXFxcIjpcXFwi4oqHXFxcIixcXFwic3VwZWRvdFxcXCI6XFxcIuKrhFxcXCIsXFxcIlN1cGVyc2V0XFxcIjpcXFwi4oqDXFxcIixcXFwiU3VwZXJzZXRFcXVhbFxcXCI6XFxcIuKKh1xcXCIsXFxcInN1cGhzb2xcXFwiOlxcXCLin4lcXFwiLFxcXCJzdXBoc3ViXFxcIjpcXFwi4quXXFxcIixcXFwic3VwbGFyclxcXCI6XFxcIuKlu1xcXCIsXFxcInN1cG11bHRcXFwiOlxcXCLiq4JcXFwiLFxcXCJzdXBuRVxcXCI6XFxcIuKrjFxcXCIsXFxcInN1cG5lXFxcIjpcXFwi4oqLXFxcIixcXFwic3VwcGx1c1xcXCI6XFxcIuKrgFxcXCIsXFxcInN1cHNldFxcXCI6XFxcIuKKg1xcXCIsXFxcIlN1cHNldFxcXCI6XFxcIuKLkVxcXCIsXFxcInN1cHNldGVxXFxcIjpcXFwi4oqHXFxcIixcXFwic3Vwc2V0ZXFxXFxcIjpcXFwi4quGXFxcIixcXFwic3Vwc2V0bmVxXFxcIjpcXFwi4oqLXFxcIixcXFwic3Vwc2V0bmVxcVxcXCI6XFxcIuKrjFxcXCIsXFxcInN1cHNpbVxcXCI6XFxcIuKriFxcXCIsXFxcInN1cHN1YlxcXCI6XFxcIuKrlFxcXCIsXFxcInN1cHN1cFxcXCI6XFxcIuKrllxcXCIsXFxcInN3YXJoa1xcXCI6XFxcIuKkplxcXCIsXFxcInN3YXJyXFxcIjpcXFwi4oaZXFxcIixcXFwic3dBcnJcXFwiOlxcXCLih5lcXFwiLFxcXCJzd2Fycm93XFxcIjpcXFwi4oaZXFxcIixcXFwic3dud2FyXFxcIjpcXFwi4qSqXFxcIixcXFwic3psaWdcXFwiOlxcXCLDn1xcXCIsXFxcIlRhYlxcXCI6XFxcIlxcXFx0XFxcIixcXFwidGFyZ2V0XFxcIjpcXFwi4oyWXFxcIixcXFwiVGF1XFxcIjpcXFwizqRcXFwiLFxcXCJ0YXVcXFwiOlxcXCLPhFxcXCIsXFxcInRicmtcXFwiOlxcXCLijrRcXFwiLFxcXCJUY2Fyb25cXFwiOlxcXCLFpFxcXCIsXFxcInRjYXJvblxcXCI6XFxcIsWlXFxcIixcXFwiVGNlZGlsXFxcIjpcXFwixaJcXFwiLFxcXCJ0Y2VkaWxcXFwiOlxcXCLFo1xcXCIsXFxcIlRjeVxcXCI6XFxcItCiXFxcIixcXFwidGN5XFxcIjpcXFwi0YJcXFwiLFxcXCJ0ZG90XFxcIjpcXFwi4oObXFxcIixcXFwidGVscmVjXFxcIjpcXFwi4oyVXFxcIixcXFwiVGZyXFxcIjpcXFwi8J2Ul1xcXCIsXFxcInRmclxcXCI6XFxcIvCdlLFcXFwiLFxcXCJ0aGVyZTRcXFwiOlxcXCLiiLRcXFwiLFxcXCJ0aGVyZWZvcmVcXFwiOlxcXCLiiLRcXFwiLFxcXCJUaGVyZWZvcmVcXFwiOlxcXCLiiLRcXFwiLFxcXCJUaGV0YVxcXCI6XFxcIs6YXFxcIixcXFwidGhldGFcXFwiOlxcXCLOuFxcXCIsXFxcInRoZXRhc3ltXFxcIjpcXFwiz5FcXFwiLFxcXCJ0aGV0YXZcXFwiOlxcXCLPkVxcXCIsXFxcInRoaWNrYXBwcm94XFxcIjpcXFwi4omIXFxcIixcXFwidGhpY2tzaW1cXFwiOlxcXCLiiLxcXFwiLFxcXCJUaGlja1NwYWNlXFxcIjpcXFwi4oGf4oCKXFxcIixcXFwiVGhpblNwYWNlXFxcIjpcXFwi4oCJXFxcIixcXFwidGhpbnNwXFxcIjpcXFwi4oCJXFxcIixcXFwidGhrYXBcXFwiOlxcXCLiiYhcXFwiLFxcXCJ0aGtzaW1cXFwiOlxcXCLiiLxcXFwiLFxcXCJUSE9STlxcXCI6XFxcIsOeXFxcIixcXFwidGhvcm5cXFwiOlxcXCLDvlxcXCIsXFxcInRpbGRlXFxcIjpcXFwiy5xcXFwiLFxcXCJUaWxkZVxcXCI6XFxcIuKIvFxcXCIsXFxcIlRpbGRlRXF1YWxcXFwiOlxcXCLiiYNcXFwiLFxcXCJUaWxkZUZ1bGxFcXVhbFxcXCI6XFxcIuKJhVxcXCIsXFxcIlRpbGRlVGlsZGVcXFwiOlxcXCLiiYhcXFwiLFxcXCJ0aW1lc2JhclxcXCI6XFxcIuKosVxcXCIsXFxcInRpbWVzYlxcXCI6XFxcIuKKoFxcXCIsXFxcInRpbWVzXFxcIjpcXFwiw5dcXFwiLFxcXCJ0aW1lc2RcXFwiOlxcXCLiqLBcXFwiLFxcXCJ0aW50XFxcIjpcXFwi4oitXFxcIixcXFwidG9lYVxcXCI6XFxcIuKkqFxcXCIsXFxcInRvcGJvdFxcXCI6XFxcIuKMtlxcXCIsXFxcInRvcGNpclxcXCI6XFxcIuKrsVxcXCIsXFxcInRvcFxcXCI6XFxcIuKKpFxcXCIsXFxcIlRvcGZcXFwiOlxcXCLwnZWLXFxcIixcXFwidG9wZlxcXCI6XFxcIvCdlaVcXFwiLFxcXCJ0b3Bmb3JrXFxcIjpcXFwi4quaXFxcIixcXFwidG9zYVxcXCI6XFxcIuKkqVxcXCIsXFxcInRwcmltZVxcXCI6XFxcIuKAtFxcXCIsXFxcInRyYWRlXFxcIjpcXFwi4oSiXFxcIixcXFwiVFJBREVcXFwiOlxcXCLihKJcXFwiLFxcXCJ0cmlhbmdsZVxcXCI6XFxcIuKWtVxcXCIsXFxcInRyaWFuZ2xlZG93blxcXCI6XFxcIuKWv1xcXCIsXFxcInRyaWFuZ2xlbGVmdFxcXCI6XFxcIuKXg1xcXCIsXFxcInRyaWFuZ2xlbGVmdGVxXFxcIjpcXFwi4oq0XFxcIixcXFwidHJpYW5nbGVxXFxcIjpcXFwi4omcXFxcIixcXFwidHJpYW5nbGVyaWdodFxcXCI6XFxcIuKWuVxcXCIsXFxcInRyaWFuZ2xlcmlnaHRlcVxcXCI6XFxcIuKKtVxcXCIsXFxcInRyaWRvdFxcXCI6XFxcIuKXrFxcXCIsXFxcInRyaWVcXFwiOlxcXCLiiZxcXFwiLFxcXCJ0cmltaW51c1xcXCI6XFxcIuKoulxcXCIsXFxcIlRyaXBsZURvdFxcXCI6XFxcIuKDm1xcXCIsXFxcInRyaXBsdXNcXFwiOlxcXCLiqLlcXFwiLFxcXCJ0cmlzYlxcXCI6XFxcIuKnjVxcXCIsXFxcInRyaXRpbWVcXFwiOlxcXCLiqLtcXFwiLFxcXCJ0cnBleml1bVxcXCI6XFxcIuKPolxcXCIsXFxcIlRzY3JcXFwiOlxcXCLwnZKvXFxcIixcXFwidHNjclxcXCI6XFxcIvCdk4lcXFwiLFxcXCJUU2N5XFxcIjpcXFwi0KZcXFwiLFxcXCJ0c2N5XFxcIjpcXFwi0YZcXFwiLFxcXCJUU0hjeVxcXCI6XFxcItCLXFxcIixcXFwidHNoY3lcXFwiOlxcXCLRm1xcXCIsXFxcIlRzdHJva1xcXCI6XFxcIsWmXFxcIixcXFwidHN0cm9rXFxcIjpcXFwixadcXFwiLFxcXCJ0d2l4dFxcXCI6XFxcIuKJrFxcXCIsXFxcInR3b2hlYWRsZWZ0YXJyb3dcXFwiOlxcXCLihp5cXFwiLFxcXCJ0d29oZWFkcmlnaHRhcnJvd1xcXCI6XFxcIuKGoFxcXCIsXFxcIlVhY3V0ZVxcXCI6XFxcIsOaXFxcIixcXFwidWFjdXRlXFxcIjpcXFwiw7pcXFwiLFxcXCJ1YXJyXFxcIjpcXFwi4oaRXFxcIixcXFwiVWFyclxcXCI6XFxcIuKGn1xcXCIsXFxcInVBcnJcXFwiOlxcXCLih5FcXFwiLFxcXCJVYXJyb2NpclxcXCI6XFxcIuKliVxcXCIsXFxcIlVicmN5XFxcIjpcXFwi0I5cXFwiLFxcXCJ1YnJjeVxcXCI6XFxcItGeXFxcIixcXFwiVWJyZXZlXFxcIjpcXFwixaxcXFwiLFxcXCJ1YnJldmVcXFwiOlxcXCLFrVxcXCIsXFxcIlVjaXJjXFxcIjpcXFwiw5tcXFwiLFxcXCJ1Y2lyY1xcXCI6XFxcIsO7XFxcIixcXFwiVWN5XFxcIjpcXFwi0KNcXFwiLFxcXCJ1Y3lcXFwiOlxcXCLRg1xcXCIsXFxcInVkYXJyXFxcIjpcXFwi4oeFXFxcIixcXFwiVWRibGFjXFxcIjpcXFwixbBcXFwiLFxcXCJ1ZGJsYWNcXFwiOlxcXCLFsVxcXCIsXFxcInVkaGFyXFxcIjpcXFwi4qWuXFxcIixcXFwidWZpc2h0XFxcIjpcXFwi4qW+XFxcIixcXFwiVWZyXFxcIjpcXFwi8J2UmFxcXCIsXFxcInVmclxcXCI6XFxcIvCdlLJcXFwiLFxcXCJVZ3JhdmVcXFwiOlxcXCLDmVxcXCIsXFxcInVncmF2ZVxcXCI6XFxcIsO5XFxcIixcXFwidUhhclxcXCI6XFxcIuKlo1xcXCIsXFxcInVoYXJsXFxcIjpcXFwi4oa/XFxcIixcXFwidWhhcnJcXFwiOlxcXCLihr5cXFwiLFxcXCJ1aGJsa1xcXCI6XFxcIuKWgFxcXCIsXFxcInVsY29yblxcXCI6XFxcIuKMnFxcXCIsXFxcInVsY29ybmVyXFxcIjpcXFwi4oycXFxcIixcXFwidWxjcm9wXFxcIjpcXFwi4oyPXFxcIixcXFwidWx0cmlcXFwiOlxcXCLil7hcXFwiLFxcXCJVbWFjclxcXCI6XFxcIsWqXFxcIixcXFwidW1hY3JcXFwiOlxcXCLFq1xcXCIsXFxcInVtbFxcXCI6XFxcIsKoXFxcIixcXFwiVW5kZXJCYXJcXFwiOlxcXCJfXFxcIixcXFwiVW5kZXJCcmFjZVxcXCI6XFxcIuKPn1xcXCIsXFxcIlVuZGVyQnJhY2tldFxcXCI6XFxcIuKOtVxcXCIsXFxcIlVuZGVyUGFyZW50aGVzaXNcXFwiOlxcXCLij51cXFwiLFxcXCJVbmlvblxcXCI6XFxcIuKLg1xcXCIsXFxcIlVuaW9uUGx1c1xcXCI6XFxcIuKKjlxcXCIsXFxcIlVvZ29uXFxcIjpcXFwixbJcXFwiLFxcXCJ1b2dvblxcXCI6XFxcIsWzXFxcIixcXFwiVW9wZlxcXCI6XFxcIvCdlYxcXFwiLFxcXCJ1b3BmXFxcIjpcXFwi8J2VplxcXCIsXFxcIlVwQXJyb3dCYXJcXFwiOlxcXCLipJJcXFwiLFxcXCJ1cGFycm93XFxcIjpcXFwi4oaRXFxcIixcXFwiVXBBcnJvd1xcXCI6XFxcIuKGkVxcXCIsXFxcIlVwYXJyb3dcXFwiOlxcXCLih5FcXFwiLFxcXCJVcEFycm93RG93bkFycm93XFxcIjpcXFwi4oeFXFxcIixcXFwidXBkb3duYXJyb3dcXFwiOlxcXCLihpVcXFwiLFxcXCJVcERvd25BcnJvd1xcXCI6XFxcIuKGlVxcXCIsXFxcIlVwZG93bmFycm93XFxcIjpcXFwi4oeVXFxcIixcXFwiVXBFcXVpbGlicml1bVxcXCI6XFxcIuKlrlxcXCIsXFxcInVwaGFycG9vbmxlZnRcXFwiOlxcXCLihr9cXFwiLFxcXCJ1cGhhcnBvb25yaWdodFxcXCI6XFxcIuKGvlxcXCIsXFxcInVwbHVzXFxcIjpcXFwi4oqOXFxcIixcXFwiVXBwZXJMZWZ0QXJyb3dcXFwiOlxcXCLihpZcXFwiLFxcXCJVcHBlclJpZ2h0QXJyb3dcXFwiOlxcXCLihpdcXFwiLFxcXCJ1cHNpXFxcIjpcXFwiz4VcXFwiLFxcXCJVcHNpXFxcIjpcXFwiz5JcXFwiLFxcXCJ1cHNpaFxcXCI6XFxcIs+SXFxcIixcXFwiVXBzaWxvblxcXCI6XFxcIs6lXFxcIixcXFwidXBzaWxvblxcXCI6XFxcIs+FXFxcIixcXFwiVXBUZWVBcnJvd1xcXCI6XFxcIuKGpVxcXCIsXFxcIlVwVGVlXFxcIjpcXFwi4oqlXFxcIixcXFwidXB1cGFycm93c1xcXCI6XFxcIuKHiFxcXCIsXFxcInVyY29yblxcXCI6XFxcIuKMnVxcXCIsXFxcInVyY29ybmVyXFxcIjpcXFwi4oydXFxcIixcXFwidXJjcm9wXFxcIjpcXFwi4oyOXFxcIixcXFwiVXJpbmdcXFwiOlxcXCLFrlxcXCIsXFxcInVyaW5nXFxcIjpcXFwixa9cXFwiLFxcXCJ1cnRyaVxcXCI6XFxcIuKXuVxcXCIsXFxcIlVzY3JcXFwiOlxcXCLwnZKwXFxcIixcXFwidXNjclxcXCI6XFxcIvCdk4pcXFwiLFxcXCJ1dGRvdFxcXCI6XFxcIuKLsFxcXCIsXFxcIlV0aWxkZVxcXCI6XFxcIsWoXFxcIixcXFwidXRpbGRlXFxcIjpcXFwixalcXFwiLFxcXCJ1dHJpXFxcIjpcXFwi4pa1XFxcIixcXFwidXRyaWZcXFwiOlxcXCLilrRcXFwiLFxcXCJ1dWFyclxcXCI6XFxcIuKHiFxcXCIsXFxcIlV1bWxcXFwiOlxcXCLDnFxcXCIsXFxcInV1bWxcXFwiOlxcXCLDvFxcXCIsXFxcInV3YW5nbGVcXFwiOlxcXCLipqdcXFwiLFxcXCJ2YW5ncnRcXFwiOlxcXCLippxcXFwiLFxcXCJ2YXJlcHNpbG9uXFxcIjpcXFwiz7VcXFwiLFxcXCJ2YXJrYXBwYVxcXCI6XFxcIs+wXFxcIixcXFwidmFybm90aGluZ1xcXCI6XFxcIuKIhVxcXCIsXFxcInZhcnBoaVxcXCI6XFxcIs+VXFxcIixcXFwidmFycGlcXFwiOlxcXCLPllxcXCIsXFxcInZhcnByb3B0b1xcXCI6XFxcIuKInVxcXCIsXFxcInZhcnJcXFwiOlxcXCLihpVcXFwiLFxcXCJ2QXJyXFxcIjpcXFwi4oeVXFxcIixcXFwidmFycmhvXFxcIjpcXFwiz7FcXFwiLFxcXCJ2YXJzaWdtYVxcXCI6XFxcIs+CXFxcIixcXFwidmFyc3Vic2V0bmVxXFxcIjpcXFwi4oqK77iAXFxcIixcXFwidmFyc3Vic2V0bmVxcVxcXCI6XFxcIuKri++4gFxcXCIsXFxcInZhcnN1cHNldG5lcVxcXCI6XFxcIuKKi++4gFxcXCIsXFxcInZhcnN1cHNldG5lcXFcXFwiOlxcXCLiq4zvuIBcXFwiLFxcXCJ2YXJ0aGV0YVxcXCI6XFxcIs+RXFxcIixcXFwidmFydHJpYW5nbGVsZWZ0XFxcIjpcXFwi4oqyXFxcIixcXFwidmFydHJpYW5nbGVyaWdodFxcXCI6XFxcIuKKs1xcXCIsXFxcInZCYXJcXFwiOlxcXCLiq6hcXFwiLFxcXCJWYmFyXFxcIjpcXFwi4qurXFxcIixcXFwidkJhcnZcXFwiOlxcXCLiq6lcXFwiLFxcXCJWY3lcXFwiOlxcXCLQklxcXCIsXFxcInZjeVxcXCI6XFxcItCyXFxcIixcXFwidmRhc2hcXFwiOlxcXCLiiqJcXFwiLFxcXCJ2RGFzaFxcXCI6XFxcIuKKqFxcXCIsXFxcIlZkYXNoXFxcIjpcXFwi4oqpXFxcIixcXFwiVkRhc2hcXFwiOlxcXCLiiqtcXFwiLFxcXCJWZGFzaGxcXFwiOlxcXCLiq6ZcXFwiLFxcXCJ2ZWViYXJcXFwiOlxcXCLiirtcXFwiLFxcXCJ2ZWVcXFwiOlxcXCLiiKhcXFwiLFxcXCJWZWVcXFwiOlxcXCLii4FcXFwiLFxcXCJ2ZWVlcVxcXCI6XFxcIuKJmlxcXCIsXFxcInZlbGxpcFxcXCI6XFxcIuKLrlxcXCIsXFxcInZlcmJhclxcXCI6XFxcInxcXFwiLFxcXCJWZXJiYXJcXFwiOlxcXCLigJZcXFwiLFxcXCJ2ZXJ0XFxcIjpcXFwifFxcXCIsXFxcIlZlcnRcXFwiOlxcXCLigJZcXFwiLFxcXCJWZXJ0aWNhbEJhclxcXCI6XFxcIuKIo1xcXCIsXFxcIlZlcnRpY2FsTGluZVxcXCI6XFxcInxcXFwiLFxcXCJWZXJ0aWNhbFNlcGFyYXRvclxcXCI6XFxcIuKdmFxcXCIsXFxcIlZlcnRpY2FsVGlsZGVcXFwiOlxcXCLiiYBcXFwiLFxcXCJWZXJ5VGhpblNwYWNlXFxcIjpcXFwi4oCKXFxcIixcXFwiVmZyXFxcIjpcXFwi8J2UmVxcXCIsXFxcInZmclxcXCI6XFxcIvCdlLNcXFwiLFxcXCJ2bHRyaVxcXCI6XFxcIuKKslxcXCIsXFxcInZuc3ViXFxcIjpcXFwi4oqC4oOSXFxcIixcXFwidm5zdXBcXFwiOlxcXCLiioPig5JcXFwiLFxcXCJWb3BmXFxcIjpcXFwi8J2VjVxcXCIsXFxcInZvcGZcXFwiOlxcXCLwnZWnXFxcIixcXFwidnByb3BcXFwiOlxcXCLiiJ1cXFwiLFxcXCJ2cnRyaVxcXCI6XFxcIuKKs1xcXCIsXFxcIlZzY3JcXFwiOlxcXCLwnZKxXFxcIixcXFwidnNjclxcXCI6XFxcIvCdk4tcXFwiLFxcXCJ2c3VibkVcXFwiOlxcXCLiq4vvuIBcXFwiLFxcXCJ2c3VibmVcXFwiOlxcXCLiiorvuIBcXFwiLFxcXCJ2c3VwbkVcXFwiOlxcXCLiq4zvuIBcXFwiLFxcXCJ2c3VwbmVcXFwiOlxcXCLiiovvuIBcXFwiLFxcXCJWdmRhc2hcXFwiOlxcXCLiiqpcXFwiLFxcXCJ2emlnemFnXFxcIjpcXFwi4qaaXFxcIixcXFwiV2NpcmNcXFwiOlxcXCLFtFxcXCIsXFxcIndjaXJjXFxcIjpcXFwixbVcXFwiLFxcXCJ3ZWRiYXJcXFwiOlxcXCLiqZ9cXFwiLFxcXCJ3ZWRnZVxcXCI6XFxcIuKIp1xcXCIsXFxcIldlZGdlXFxcIjpcXFwi4ouAXFxcIixcXFwid2VkZ2VxXFxcIjpcXFwi4omZXFxcIixcXFwid2VpZXJwXFxcIjpcXFwi4oSYXFxcIixcXFwiV2ZyXFxcIjpcXFwi8J2UmlxcXCIsXFxcIndmclxcXCI6XFxcIvCdlLRcXFwiLFxcXCJXb3BmXFxcIjpcXFwi8J2VjlxcXCIsXFxcIndvcGZcXFwiOlxcXCLwnZWoXFxcIixcXFwid3BcXFwiOlxcXCLihJhcXFwiLFxcXCJ3clxcXCI6XFxcIuKJgFxcXCIsXFxcIndyZWF0aFxcXCI6XFxcIuKJgFxcXCIsXFxcIldzY3JcXFwiOlxcXCLwnZKyXFxcIixcXFwid3NjclxcXCI6XFxcIvCdk4xcXFwiLFxcXCJ4Y2FwXFxcIjpcXFwi4ouCXFxcIixcXFwieGNpcmNcXFwiOlxcXCLil69cXFwiLFxcXCJ4Y3VwXFxcIjpcXFwi4ouDXFxcIixcXFwieGR0cmlcXFwiOlxcXCLilr1cXFwiLFxcXCJYZnJcXFwiOlxcXCLwnZSbXFxcIixcXFwieGZyXFxcIjpcXFwi8J2UtVxcXCIsXFxcInhoYXJyXFxcIjpcXFwi4p+3XFxcIixcXFwieGhBcnJcXFwiOlxcXCLin7pcXFwiLFxcXCJYaVxcXCI6XFxcIs6eXFxcIixcXFwieGlcXFwiOlxcXCLOvlxcXCIsXFxcInhsYXJyXFxcIjpcXFwi4p+1XFxcIixcXFwieGxBcnJcXFwiOlxcXCLin7hcXFwiLFxcXCJ4bWFwXFxcIjpcXFwi4p+8XFxcIixcXFwieG5pc1xcXCI6XFxcIuKLu1xcXCIsXFxcInhvZG90XFxcIjpcXFwi4qiAXFxcIixcXFwiWG9wZlxcXCI6XFxcIvCdlY9cXFwiLFxcXCJ4b3BmXFxcIjpcXFwi8J2VqVxcXCIsXFxcInhvcGx1c1xcXCI6XFxcIuKogVxcXCIsXFxcInhvdGltZVxcXCI6XFxcIuKoglxcXCIsXFxcInhyYXJyXFxcIjpcXFwi4p+2XFxcIixcXFwieHJBcnJcXFwiOlxcXCLin7lcXFwiLFxcXCJYc2NyXFxcIjpcXFwi8J2Ss1xcXCIsXFxcInhzY3JcXFwiOlxcXCLwnZONXFxcIixcXFwieHNxY3VwXFxcIjpcXFwi4qiGXFxcIixcXFwieHVwbHVzXFxcIjpcXFwi4qiEXFxcIixcXFwieHV0cmlcXFwiOlxcXCLilrNcXFwiLFxcXCJ4dmVlXFxcIjpcXFwi4ouBXFxcIixcXFwieHdlZGdlXFxcIjpcXFwi4ouAXFxcIixcXFwiWWFjdXRlXFxcIjpcXFwiw51cXFwiLFxcXCJ5YWN1dGVcXFwiOlxcXCLDvVxcXCIsXFxcIllBY3lcXFwiOlxcXCLQr1xcXCIsXFxcInlhY3lcXFwiOlxcXCLRj1xcXCIsXFxcIlljaXJjXFxcIjpcXFwixbZcXFwiLFxcXCJ5Y2lyY1xcXCI6XFxcIsW3XFxcIixcXFwiWWN5XFxcIjpcXFwi0KtcXFwiLFxcXCJ5Y3lcXFwiOlxcXCLRi1xcXCIsXFxcInllblxcXCI6XFxcIsKlXFxcIixcXFwiWWZyXFxcIjpcXFwi8J2UnFxcXCIsXFxcInlmclxcXCI6XFxcIvCdlLZcXFwiLFxcXCJZSWN5XFxcIjpcXFwi0IdcXFwiLFxcXCJ5aWN5XFxcIjpcXFwi0ZdcXFwiLFxcXCJZb3BmXFxcIjpcXFwi8J2VkFxcXCIsXFxcInlvcGZcXFwiOlxcXCLwnZWqXFxcIixcXFwiWXNjclxcXCI6XFxcIvCdkrRcXFwiLFxcXCJ5c2NyXFxcIjpcXFwi8J2TjlxcXCIsXFxcIllVY3lcXFwiOlxcXCLQrlxcXCIsXFxcInl1Y3lcXFwiOlxcXCLRjlxcXCIsXFxcInl1bWxcXFwiOlxcXCLDv1xcXCIsXFxcIll1bWxcXFwiOlxcXCLFuFxcXCIsXFxcIlphY3V0ZVxcXCI6XFxcIsW5XFxcIixcXFwiemFjdXRlXFxcIjpcXFwixbpcXFwiLFxcXCJaY2Fyb25cXFwiOlxcXCLFvVxcXCIsXFxcInpjYXJvblxcXCI6XFxcIsW+XFxcIixcXFwiWmN5XFxcIjpcXFwi0JdcXFwiLFxcXCJ6Y3lcXFwiOlxcXCLQt1xcXCIsXFxcIlpkb3RcXFwiOlxcXCLFu1xcXCIsXFxcInpkb3RcXFwiOlxcXCLFvFxcXCIsXFxcInplZXRyZlxcXCI6XFxcIuKEqFxcXCIsXFxcIlplcm9XaWR0aFNwYWNlXFxcIjpcXFwi4oCLXFxcIixcXFwiWmV0YVxcXCI6XFxcIs6WXFxcIixcXFwiemV0YVxcXCI6XFxcIs62XFxcIixcXFwiemZyXFxcIjpcXFwi8J2Ut1xcXCIsXFxcIlpmclxcXCI6XFxcIuKEqFxcXCIsXFxcIlpIY3lcXFwiOlxcXCLQllxcXCIsXFxcInpoY3lcXFwiOlxcXCLQtlxcXCIsXFxcInppZ3JhcnJcXFwiOlxcXCLih51cXFwiLFxcXCJ6b3BmXFxcIjpcXFwi8J2Vq1xcXCIsXFxcIlpvcGZcXFwiOlxcXCLihKRcXFwiLFxcXCJac2NyXFxcIjpcXFwi8J2StVxcXCIsXFxcInpzY3JcXFwiOlxcXCLwnZOPXFxcIixcXFwiendqXFxcIjpcXFwi4oCNXFxcIixcXFwiendualxcXCI6XFxcIuKAjFxcXCJ9XCIpO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZW50aXRpZXMvbWFwcy9sZWdhY3kuanNvblwiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL25vZGVfbW9kdWxlcy9odG1scGFyc2VyMi9ub2RlX21vZHVsZXMvZW50aXRpZXMvbWFwcy9sZWdhY3kuanNvbiAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBleHBvcnRzIHByb3ZpZGVkOiBBYWN1dGUsIGFhY3V0ZSwgQWNpcmMsIGFjaXJjLCBhY3V0ZSwgQUVsaWcsIGFlbGlnLCBBZ3JhdmUsIGFncmF2ZSwgYW1wLCBBTVAsIEFyaW5nLCBhcmluZywgQXRpbGRlLCBhdGlsZGUsIEF1bWwsIGF1bWwsIGJydmJhciwgQ2NlZGlsLCBjY2VkaWwsIGNlZGlsLCBjZW50LCBjb3B5LCBDT1BZLCBjdXJyZW4sIGRlZywgZGl2aWRlLCBFYWN1dGUsIGVhY3V0ZSwgRWNpcmMsIGVjaXJjLCBFZ3JhdmUsIGVncmF2ZSwgRVRILCBldGgsIEV1bWwsIGV1bWwsIGZyYWMxMiwgZnJhYzE0LCBmcmFjMzQsIGd0LCBHVCwgSWFjdXRlLCBpYWN1dGUsIEljaXJjLCBpY2lyYywgaWV4Y2wsIElncmF2ZSwgaWdyYXZlLCBpcXVlc3QsIEl1bWwsIGl1bWwsIGxhcXVvLCBsdCwgTFQsIG1hY3IsIG1pY3JvLCBtaWRkb3QsIG5ic3AsIG5vdCwgTnRpbGRlLCBudGlsZGUsIE9hY3V0ZSwgb2FjdXRlLCBPY2lyYywgb2NpcmMsIE9ncmF2ZSwgb2dyYXZlLCBvcmRmLCBvcmRtLCBPc2xhc2gsIG9zbGFzaCwgT3RpbGRlLCBvdGlsZGUsIE91bWwsIG91bWwsIHBhcmEsIHBsdXNtbiwgcG91bmQsIHF1b3QsIFFVT1QsIHJhcXVvLCByZWcsIFJFRywgc2VjdCwgc2h5LCBzdXAxLCBzdXAyLCBzdXAzLCBzemxpZywgVEhPUk4sIHRob3JuLCB0aW1lcywgVWFjdXRlLCB1YWN1dGUsIFVjaXJjLCB1Y2lyYywgVWdyYXZlLCB1Z3JhdmUsIHVtbCwgVXVtbCwgdXVtbCwgWWFjdXRlLCB5YWN1dGUsIHllbiwgeXVtbCwgZGVmYXVsdCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSkge1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpTT04ucGFyc2UoXCJ7XFxcIkFhY3V0ZVxcXCI6XFxcIsOBXFxcIixcXFwiYWFjdXRlXFxcIjpcXFwiw6FcXFwiLFxcXCJBY2lyY1xcXCI6XFxcIsOCXFxcIixcXFwiYWNpcmNcXFwiOlxcXCLDolxcXCIsXFxcImFjdXRlXFxcIjpcXFwiwrRcXFwiLFxcXCJBRWxpZ1xcXCI6XFxcIsOGXFxcIixcXFwiYWVsaWdcXFwiOlxcXCLDplxcXCIsXFxcIkFncmF2ZVxcXCI6XFxcIsOAXFxcIixcXFwiYWdyYXZlXFxcIjpcXFwiw6BcXFwiLFxcXCJhbXBcXFwiOlxcXCImXFxcIixcXFwiQU1QXFxcIjpcXFwiJlxcXCIsXFxcIkFyaW5nXFxcIjpcXFwiw4VcXFwiLFxcXCJhcmluZ1xcXCI6XFxcIsOlXFxcIixcXFwiQXRpbGRlXFxcIjpcXFwiw4NcXFwiLFxcXCJhdGlsZGVcXFwiOlxcXCLDo1xcXCIsXFxcIkF1bWxcXFwiOlxcXCLDhFxcXCIsXFxcImF1bWxcXFwiOlxcXCLDpFxcXCIsXFxcImJydmJhclxcXCI6XFxcIsKmXFxcIixcXFwiQ2NlZGlsXFxcIjpcXFwiw4dcXFwiLFxcXCJjY2VkaWxcXFwiOlxcXCLDp1xcXCIsXFxcImNlZGlsXFxcIjpcXFwiwrhcXFwiLFxcXCJjZW50XFxcIjpcXFwiwqJcXFwiLFxcXCJjb3B5XFxcIjpcXFwiwqlcXFwiLFxcXCJDT1BZXFxcIjpcXFwiwqlcXFwiLFxcXCJjdXJyZW5cXFwiOlxcXCLCpFxcXCIsXFxcImRlZ1xcXCI6XFxcIsKwXFxcIixcXFwiZGl2aWRlXFxcIjpcXFwiw7dcXFwiLFxcXCJFYWN1dGVcXFwiOlxcXCLDiVxcXCIsXFxcImVhY3V0ZVxcXCI6XFxcIsOpXFxcIixcXFwiRWNpcmNcXFwiOlxcXCLDilxcXCIsXFxcImVjaXJjXFxcIjpcXFwiw6pcXFwiLFxcXCJFZ3JhdmVcXFwiOlxcXCLDiFxcXCIsXFxcImVncmF2ZVxcXCI6XFxcIsOoXFxcIixcXFwiRVRIXFxcIjpcXFwiw5BcXFwiLFxcXCJldGhcXFwiOlxcXCLDsFxcXCIsXFxcIkV1bWxcXFwiOlxcXCLDi1xcXCIsXFxcImV1bWxcXFwiOlxcXCLDq1xcXCIsXFxcImZyYWMxMlxcXCI6XFxcIsK9XFxcIixcXFwiZnJhYzE0XFxcIjpcXFwiwrxcXFwiLFxcXCJmcmFjMzRcXFwiOlxcXCLCvlxcXCIsXFxcImd0XFxcIjpcXFwiPlxcXCIsXFxcIkdUXFxcIjpcXFwiPlxcXCIsXFxcIklhY3V0ZVxcXCI6XFxcIsONXFxcIixcXFwiaWFjdXRlXFxcIjpcXFwiw61cXFwiLFxcXCJJY2lyY1xcXCI6XFxcIsOOXFxcIixcXFwiaWNpcmNcXFwiOlxcXCLDrlxcXCIsXFxcImlleGNsXFxcIjpcXFwiwqFcXFwiLFxcXCJJZ3JhdmVcXFwiOlxcXCLDjFxcXCIsXFxcImlncmF2ZVxcXCI6XFxcIsOsXFxcIixcXFwiaXF1ZXN0XFxcIjpcXFwiwr9cXFwiLFxcXCJJdW1sXFxcIjpcXFwiw49cXFwiLFxcXCJpdW1sXFxcIjpcXFwiw69cXFwiLFxcXCJsYXF1b1xcXCI6XFxcIsKrXFxcIixcXFwibHRcXFwiOlxcXCI8XFxcIixcXFwiTFRcXFwiOlxcXCI8XFxcIixcXFwibWFjclxcXCI6XFxcIsKvXFxcIixcXFwibWljcm9cXFwiOlxcXCLCtVxcXCIsXFxcIm1pZGRvdFxcXCI6XFxcIsK3XFxcIixcXFwibmJzcFxcXCI6XFxcIsKgXFxcIixcXFwibm90XFxcIjpcXFwiwqxcXFwiLFxcXCJOdGlsZGVcXFwiOlxcXCLDkVxcXCIsXFxcIm50aWxkZVxcXCI6XFxcIsOxXFxcIixcXFwiT2FjdXRlXFxcIjpcXFwiw5NcXFwiLFxcXCJvYWN1dGVcXFwiOlxcXCLDs1xcXCIsXFxcIk9jaXJjXFxcIjpcXFwiw5RcXFwiLFxcXCJvY2lyY1xcXCI6XFxcIsO0XFxcIixcXFwiT2dyYXZlXFxcIjpcXFwiw5JcXFwiLFxcXCJvZ3JhdmVcXFwiOlxcXCLDslxcXCIsXFxcIm9yZGZcXFwiOlxcXCLCqlxcXCIsXFxcIm9yZG1cXFwiOlxcXCLCulxcXCIsXFxcIk9zbGFzaFxcXCI6XFxcIsOYXFxcIixcXFwib3NsYXNoXFxcIjpcXFwiw7hcXFwiLFxcXCJPdGlsZGVcXFwiOlxcXCLDlVxcXCIsXFxcIm90aWxkZVxcXCI6XFxcIsO1XFxcIixcXFwiT3VtbFxcXCI6XFxcIsOWXFxcIixcXFwib3VtbFxcXCI6XFxcIsO2XFxcIixcXFwicGFyYVxcXCI6XFxcIsK2XFxcIixcXFwicGx1c21uXFxcIjpcXFwiwrFcXFwiLFxcXCJwb3VuZFxcXCI6XFxcIsKjXFxcIixcXFwicXVvdFxcXCI6XFxcIlxcXFxcXFwiXFxcIixcXFwiUVVPVFxcXCI6XFxcIlxcXFxcXFwiXFxcIixcXFwicmFxdW9cXFwiOlxcXCLCu1xcXCIsXFxcInJlZ1xcXCI6XFxcIsKuXFxcIixcXFwiUkVHXFxcIjpcXFwiwq5cXFwiLFxcXCJzZWN0XFxcIjpcXFwiwqdcXFwiLFxcXCJzaHlcXFwiOlxcXCLCrVxcXCIsXFxcInN1cDFcXFwiOlxcXCLCuVxcXCIsXFxcInN1cDJcXFwiOlxcXCLCslxcXCIsXFxcInN1cDNcXFwiOlxcXCLCs1xcXCIsXFxcInN6bGlnXFxcIjpcXFwiw59cXFwiLFxcXCJUSE9STlxcXCI6XFxcIsOeXFxcIixcXFwidGhvcm5cXFwiOlxcXCLDvlxcXCIsXFxcInRpbWVzXFxcIjpcXFwiw5dcXFwiLFxcXCJVYWN1dGVcXFwiOlxcXCLDmlxcXCIsXFxcInVhY3V0ZVxcXCI6XFxcIsO6XFxcIixcXFwiVWNpcmNcXFwiOlxcXCLDm1xcXCIsXFxcInVjaXJjXFxcIjpcXFwiw7tcXFwiLFxcXCJVZ3JhdmVcXFwiOlxcXCLDmVxcXCIsXFxcInVncmF2ZVxcXCI6XFxcIsO5XFxcIixcXFwidW1sXFxcIjpcXFwiwqhcXFwiLFxcXCJVdW1sXFxcIjpcXFwiw5xcXFwiLFxcXCJ1dW1sXFxcIjpcXFwiw7xcXFwiLFxcXCJZYWN1dGVcXFwiOlxcXCLDnVxcXCIsXFxcInlhY3V0ZVxcXCI6XFxcIsO9XFxcIixcXFwieWVuXFxcIjpcXFwiwqVcXFwiLFxcXCJ5dW1sXFxcIjpcXFwiw79cXFwifVwiKTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL21hcHMveG1sLmpzb25cIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvaHRtbHBhcnNlcjIvbm9kZV9tb2R1bGVzL2VudGl0aWVzL21hcHMveG1sLmpzb24gKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgZXhwb3J0cyBwcm92aWRlZDogYW1wLCBhcG9zLCBndCwgbHQsIHF1b3QsIGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUpIHtcblxubW9kdWxlLmV4cG9ydHMgPSBKU09OLnBhcnNlKFwie1xcXCJhbXBcXFwiOlxcXCImXFxcIixcXFwiYXBvc1xcXCI6XFxcIidcXFwiLFxcXCJndFxcXCI6XFxcIj5cXFwiLFxcXCJsdFxcXCI6XFxcIjxcXFwiLFxcXCJxdW90XFxcIjpcXFwiXFxcXFxcXCJcXFwifVwiKTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2FuaXRpemUtaHRtbC9ub2RlX21vZHVsZXMvcmVnZXhwLXF1b3RlL3JlZ2V4cC1xdW90ZS5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3Nhbml0aXplLWh0bWwvbm9kZV9tb2R1bGVzL3JlZ2V4cC1xdW90ZS9yZWdleHAtcXVvdGUuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLVxcXFxeJCorPy4oKXxbXFxde31dL2csIFwiXFxcXCQmXCIpXG59XG5cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9ub2RlX21vZHVsZXMvc2V0aW1tZWRpYXRlL3NldEltbWVkaWF0ZS5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3NldGltbWVkaWF0ZS9zZXRJbW1lZGlhdGUuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24oZ2xvYmFsLCBwcm9jZXNzKSB7KGZ1bmN0aW9uIChnbG9iYWwsIHVuZGVmaW5lZCkge1xuICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgaWYgKGdsb2JhbC5zZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBuZXh0SGFuZGxlID0gMTsgLy8gU3BlYyBzYXlzIGdyZWF0ZXIgdGhhbiB6ZXJvXG4gICAgdmFyIHRhc2tzQnlIYW5kbGUgPSB7fTtcbiAgICB2YXIgY3VycmVudGx5UnVubmluZ0FUYXNrID0gZmFsc2U7XG4gICAgdmFyIGRvYyA9IGdsb2JhbC5kb2N1bWVudDtcbiAgICB2YXIgcmVnaXN0ZXJJbW1lZGlhdGU7XG5cbiAgICBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoY2FsbGJhY2spIHtcbiAgICAgIC8vIENhbGxiYWNrIGNhbiBlaXRoZXIgYmUgYSBmdW5jdGlvbiBvciBhIHN0cmluZ1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNhbGxiYWNrID0gbmV3IEZ1bmN0aW9uKFwiXCIgKyBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgICAvLyBDb3B5IGZ1bmN0aW9uIGFyZ3VtZW50c1xuICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpICsgMV07XG4gICAgICB9XG4gICAgICAvLyBTdG9yZSBhbmQgcmVnaXN0ZXIgdGhlIHRhc2tcbiAgICAgIHZhciB0YXNrID0geyBjYWxsYmFjazogY2FsbGJhY2ssIGFyZ3M6IGFyZ3MgfTtcbiAgICAgIHRhc2tzQnlIYW5kbGVbbmV4dEhhbmRsZV0gPSB0YXNrO1xuICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUobmV4dEhhbmRsZSk7XG4gICAgICByZXR1cm4gbmV4dEhhbmRsZSsrO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGhhbmRsZSkge1xuICAgICAgICBkZWxldGUgdGFza3NCeUhhbmRsZVtoYW5kbGVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bih0YXNrKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IHRhc2suY2FsbGJhY2s7XG4gICAgICAgIHZhciBhcmdzID0gdGFzay5hcmdzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bklmUHJlc2VudChoYW5kbGUpIHtcbiAgICAgICAgLy8gRnJvbSB0aGUgc3BlYzogXCJXYWl0IHVudGlsIGFueSBpbnZvY2F0aW9ucyBvZiB0aGlzIGFsZ29yaXRobSBzdGFydGVkIGJlZm9yZSB0aGlzIG9uZSBoYXZlIGNvbXBsZXRlZC5cIlxuICAgICAgICAvLyBTbyBpZiB3ZSdyZSBjdXJyZW50bHkgcnVubmluZyBhIHRhc2ssIHdlJ2xsIG5lZWQgdG8gZGVsYXkgdGhpcyBpbnZvY2F0aW9uLlxuICAgICAgICBpZiAoY3VycmVudGx5UnVubmluZ0FUYXNrKSB7XG4gICAgICAgICAgICAvLyBEZWxheSBieSBkb2luZyBhIHNldFRpbWVvdXQuIHNldEltbWVkaWF0ZSB3YXMgdHJpZWQgaW5zdGVhZCwgYnV0IGluIEZpcmVmb3ggNyBpdCBnZW5lcmF0ZWQgYVxuICAgICAgICAgICAgLy8gXCJ0b28gbXVjaCByZWN1cnNpb25cIiBlcnJvci5cbiAgICAgICAgICAgIHNldFRpbWVvdXQocnVuSWZQcmVzZW50LCAwLCBoYW5kbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHRhc2sgPSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgICAgICAgICBpZiAodGFzaykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IHRydWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcnVuKHRhc2spO1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW1tZWRpYXRlKGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7IHJ1bklmUHJlc2VudChoYW5kbGUpOyB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYW5Vc2VQb3N0TWVzc2FnZSgpIHtcbiAgICAgICAgLy8gVGhlIHRlc3QgYWdhaW5zdCBgaW1wb3J0U2NyaXB0c2AgcHJldmVudHMgdGhpcyBpbXBsZW1lbnRhdGlvbiBmcm9tIGJlaW5nIGluc3RhbGxlZCBpbnNpZGUgYSB3ZWIgd29ya2VyLFxuICAgICAgICAvLyB3aGVyZSBgZ2xvYmFsLnBvc3RNZXNzYWdlYCBtZWFucyBzb21ldGhpbmcgY29tcGxldGVseSBkaWZmZXJlbnQgYW5kIGNhbid0IGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZS5cbiAgICAgICAgaWYgKGdsb2JhbC5wb3N0TWVzc2FnZSAmJiAhZ2xvYmFsLmltcG9ydFNjcmlwdHMpIHtcbiAgICAgICAgICAgIHZhciBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBvbGRPbk1lc3NhZ2UgPSBnbG9iYWwub25tZXNzYWdlO1xuICAgICAgICAgICAgZ2xvYmFsLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlSXNBc3luY2hyb25vdXMgPSBmYWxzZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBnbG9iYWwucG9zdE1lc3NhZ2UoXCJcIiwgXCIqXCIpO1xuICAgICAgICAgICAgZ2xvYmFsLm9ubWVzc2FnZSA9IG9sZE9uTWVzc2FnZTtcbiAgICAgICAgICAgIHJldHVybiBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFBvc3RNZXNzYWdlSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIC8vIEluc3RhbGxzIGFuIGV2ZW50IGhhbmRsZXIgb24gYGdsb2JhbGAgZm9yIHRoZSBgbWVzc2FnZWAgZXZlbnQ6IHNlZVxuICAgICAgICAvLyAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0RPTS93aW5kb3cucG9zdE1lc3NhZ2VcbiAgICAgICAgLy8gKiBodHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS9jb21tcy5odG1sI2Nyb3NzRG9jdW1lbnRNZXNzYWdlc1xuXG4gICAgICAgIHZhciBtZXNzYWdlUHJlZml4ID0gXCJzZXRJbW1lZGlhdGUkXCIgKyBNYXRoLnJhbmRvbSgpICsgXCIkXCI7XG4gICAgICAgIHZhciBvbkdsb2JhbE1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnNvdXJjZSA9PT0gZ2xvYmFsICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGV2ZW50LmRhdGEgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgICAgICBldmVudC5kYXRhLmluZGV4T2YobWVzc2FnZVByZWZpeCkgPT09IDApIHtcbiAgICAgICAgICAgICAgICBydW5JZlByZXNlbnQoK2V2ZW50LmRhdGEuc2xpY2UobWVzc2FnZVByZWZpeC5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCBvbkdsb2JhbE1lc3NhZ2UsIGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsb2JhbC5hdHRhY2hFdmVudChcIm9ubWVzc2FnZVwiLCBvbkdsb2JhbE1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShtZXNzYWdlUHJlZml4ICsgaGFuZGxlLCBcIipcIik7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbE1lc3NhZ2VDaGFubmVsSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBldmVudC5kYXRhO1xuICAgICAgICAgICAgcnVuSWZQcmVzZW50KGhhbmRsZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoaGFuZGxlKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsUmVhZHlTdGF0ZUNoYW5nZUltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICB2YXIgaHRtbCA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgICAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICAgICAgICB2YXIgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgICAgICAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBudWxsO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsU2V0VGltZW91dEltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgc2V0VGltZW91dChydW5JZlByZXNlbnQsIDAsIGhhbmRsZSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSWYgc3VwcG9ydGVkLCB3ZSBzaG91bGQgYXR0YWNoIHRvIHRoZSBwcm90b3R5cGUgb2YgZ2xvYmFsLCBzaW5jZSB0aGF0IGlzIHdoZXJlIHNldFRpbWVvdXQgZXQgYWwuIGxpdmUuXG4gICAgdmFyIGF0dGFjaFRvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihnbG9iYWwpO1xuICAgIGF0dGFjaFRvID0gYXR0YWNoVG8gJiYgYXR0YWNoVG8uc2V0VGltZW91dCA/IGF0dGFjaFRvIDogZ2xvYmFsO1xuXG4gICAgLy8gRG9uJ3QgZ2V0IGZvb2xlZCBieSBlLmcuIGJyb3dzZXJpZnkgZW52aXJvbm1lbnRzLlxuICAgIGlmICh7fS50b1N0cmluZy5jYWxsKGdsb2JhbC5wcm9jZXNzKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIpIHtcbiAgICAgICAgLy8gRm9yIE5vZGUuanMgYmVmb3JlIDAuOVxuICAgICAgICBpbnN0YWxsTmV4dFRpY2tJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChjYW5Vc2VQb3N0TWVzc2FnZSgpKSB7XG4gICAgICAgIC8vIEZvciBub24tSUUxMCBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgaW5zdGFsbFBvc3RNZXNzYWdlSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoZ2xvYmFsLk1lc3NhZ2VDaGFubmVsKSB7XG4gICAgICAgIC8vIEZvciB3ZWIgd29ya2Vycywgd2hlcmUgc3VwcG9ydGVkXG4gICAgICAgIGluc3RhbGxNZXNzYWdlQ2hhbm5lbEltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGRvYyAmJiBcIm9ucmVhZHlzdGF0ZWNoYW5nZVwiIGluIGRvYy5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpKSB7XG4gICAgICAgIC8vIEZvciBJRSA24oCTOFxuICAgICAgICBpbnN0YWxsUmVhZHlTdGF0ZUNoYW5nZUltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGb3Igb2xkZXIgYnJvd3NlcnNcbiAgICAgICAgaW5zdGFsbFNldFRpbWVvdXRJbXBsZW1lbnRhdGlvbigpO1xuICAgIH1cblxuICAgIGF0dGFjaFRvLnNldEltbWVkaWF0ZSA9IHNldEltbWVkaWF0ZTtcbiAgICBhdHRhY2hUby5jbGVhckltbWVkaWF0ZSA9IGNsZWFySW1tZWRpYXRlO1xufSh0eXBlb2Ygc2VsZiA9PT0gXCJ1bmRlZmluZWRcIiA/IHR5cGVvZiBnbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgPyB0aGlzIDogZ2xvYmFsIDogc2VsZikpO1xuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwodGhpcywgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8uLi93ZWJwYWNrL2J1aWxkaW4vZ2xvYmFsLmpzICovIFwiLi9ub2RlX21vZHVsZXMvd2VicGFjay9idWlsZGluL2dsb2JhbC5qc1wiKSwgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8uLi9wcm9jZXNzL2Jyb3dzZXIuanMgKi8gXCIuL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanNcIikpKVxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy9zdHJlYW0tYnJvd3NlcmlmeS9pbmRleC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGV2ZW50cyAqLyBcIi4vbm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanNcIikuRXZlbnRFbWl0dGVyO1xudmFyIGluaGVyaXRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgaW5oZXJpdHMgKi8gXCIuL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzXCIpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHJlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qc1wiKTtcblN0cmVhbS5Xcml0YWJsZSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHJlYWRhYmxlLXN0cmVhbS93cml0YWJsZS5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS93cml0YWJsZS5qc1wiKTtcblN0cmVhbS5EdXBsZXggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISByZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2R1cGxleC5qc1wiKTtcblN0cmVhbS5UcmFuc2Zvcm0gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISByZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzICovIFwiLi9ub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qc1wiKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHJlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qc1wiKTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC40LnhcblN0cmVhbS5TdHJlYW0gPSBTdHJlYW07XG5cblxuXG4vLyBvbGQtc3R5bGUgc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGUgcGlwZSBtZXRob2QgKHRoZSBvbmx5IHJlbGV2YW50XG4vLyBwYXJ0IG9mIHRoaXMgY2xhc3MpIGlzIG92ZXJyaWRkZW4gaW4gdGhlIFJlYWRhYmxlIGNsYXNzLlxuXG5mdW5jdGlvbiBTdHJlYW0oKSB7XG4gIEVFLmNhbGwodGhpcyk7XG59XG5cblN0cmVhbS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIG9wdGlvbnMpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgaWYgKGRlc3Qud3JpdGFibGUpIHtcbiAgICAgIGlmIChmYWxzZSA9PT0gZGVzdC53cml0ZShjaHVuaykgJiYgc291cmNlLnBhdXNlKSB7XG4gICAgICAgIHNvdXJjZS5wYXVzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZGF0YScsIG9uZGF0YSk7XG5cbiAgZnVuY3Rpb24gb25kcmFpbigpIHtcbiAgICBpZiAoc291cmNlLnJlYWRhYmxlICYmIHNvdXJjZS5yZXN1bWUpIHtcbiAgICAgIHNvdXJjZS5yZXN1bWUoKTtcbiAgICB9XG4gIH1cblxuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIC8vIElmIHRoZSAnZW5kJyBvcHRpb24gaXMgbm90IHN1cHBsaWVkLCBkZXN0LmVuZCgpIHdpbGwgYmUgY2FsbGVkIHdoZW5cbiAgLy8gc291cmNlIGdldHMgdGhlICdlbmQnIG9yICdjbG9zZScgZXZlbnRzLiAgT25seSBkZXN0LmVuZCgpIG9uY2UuXG4gIGlmICghZGVzdC5faXNTdGRpbyAmJiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5lbmQgIT09IGZhbHNlKSkge1xuICAgIHNvdXJjZS5vbignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5vbignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfVxuXG4gIHZhciBkaWRPbkVuZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgZGVzdC5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSBkZXN0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8vIGRvbid0IGxlYXZlIGRhbmdsaW5nIHBpcGVzIHdoZW4gdGhlcmUgYXJlIGVycm9ycy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGNsZWFudXAoKTtcbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudCh0aGlzLCAnZXJyb3InKSA9PT0gMCkge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCBzdHJlYW0gZXJyb3IgaW4gcGlwZS5cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gcmVtb3ZlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZC5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcbiAgfVxuXG4gIHNvdXJjZS5vbignZW5kJywgY2xlYW51cCk7XG4gIHNvdXJjZS5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0Lm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3QuZW1pdCgncGlwZScsIHNvdXJjZSk7XG5cbiAgLy8gQWxsb3cgZm9yIHVuaXgtbGlrZSB1c2FnZTogQS5waXBlKEIpLnBpcGUoQylcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy90aW1lcnMtYnJvd3NlcmlmeS9tYWluLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovKGZ1bmN0aW9uKGdsb2JhbCkge3ZhciBzY29wZSA9ICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiICYmIGdsb2JhbCkgfHxcbiAgICAgICAgICAgICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZWxmKSB8fFxuICAgICAgICAgICAgd2luZG93O1xudmFyIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xuXG4vLyBET00gQVBJcywgZm9yIGNvbXBsZXRlbmVzc1xuXG5leHBvcnRzLnNldFRpbWVvdXQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBUaW1lb3V0KGFwcGx5LmNhbGwoc2V0VGltZW91dCwgc2NvcGUsIGFyZ3VtZW50cyksIGNsZWFyVGltZW91dCk7XG59O1xuZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRJbnRlcnZhbCwgc2NvcGUsIGFyZ3VtZW50cyksIGNsZWFySW50ZXJ2YWwpO1xufTtcbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID1cbmV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGZ1bmN0aW9uKHRpbWVvdXQpIHtcbiAgaWYgKHRpbWVvdXQpIHtcbiAgICB0aW1lb3V0LmNsb3NlKCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIFRpbWVvdXQoaWQsIGNsZWFyRm4pIHtcbiAgdGhpcy5faWQgPSBpZDtcbiAgdGhpcy5fY2xlYXJGbiA9IGNsZWFyRm47XG59XG5UaW1lb3V0LnByb3RvdHlwZS51bnJlZiA9IFRpbWVvdXQucHJvdG90eXBlLnJlZiA9IGZ1bmN0aW9uKCkge307XG5UaW1lb3V0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9jbGVhckZuLmNhbGwoc2NvcGUsIHRoaXMuX2lkKTtcbn07XG5cbi8vIERvZXMgbm90IHN0YXJ0IHRoZSB0aW1lLCBqdXN0IHNldHMgdXAgdGhlIG1lbWJlcnMgbmVlZGVkLlxuZXhwb3J0cy5lbnJvbGwgPSBmdW5jdGlvbihpdGVtLCBtc2Vjcykge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gbXNlY3M7XG59O1xuXG5leHBvcnRzLnVuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gLTE7XG59O1xuXG5leHBvcnRzLl91bnJlZkFjdGl2ZSA9IGV4cG9ydHMuYWN0aXZlID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG5cbiAgdmFyIG1zZWNzID0gaXRlbS5faWRsZVRpbWVvdXQ7XG4gIGlmIChtc2VjcyA+PSAwKSB7XG4gICAgaXRlbS5faWRsZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgaWYgKGl0ZW0uX29uVGltZW91dClcbiAgICAgICAgaXRlbS5fb25UaW1lb3V0KCk7XG4gICAgfSwgbXNlY3MpO1xuICB9XG59O1xuXG4vLyBzZXRpbW1lZGlhdGUgYXR0YWNoZXMgaXRzZWxmIHRvIHRoZSBnbG9iYWwgb2JqZWN0XG5fX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBzZXRpbW1lZGlhdGUgKi8gXCIuL25vZGVfbW9kdWxlcy9zZXRpbW1lZGlhdGUvc2V0SW1tZWRpYXRlLmpzXCIpO1xuLy8gT24gc29tZSBleG90aWMgZW52aXJvbm1lbnRzLCBpdCdzIG5vdCBjbGVhciB3aGljaCBvYmplY3QgYHNldGltbWVkaWF0ZWAgd2FzXG4vLyBhYmxlIHRvIGluc3RhbGwgb250by4gIFNlYXJjaCBlYWNoIHBvc3NpYmlsaXR5IGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZVxuLy8gYHNldGltbWVkaWF0ZWAgbGlicmFyeS5cbmV4cG9ydHMuc2V0SW1tZWRpYXRlID0gKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGYuc2V0SW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBnbG9iYWwuc2V0SW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAodGhpcyAmJiB0aGlzLnNldEltbWVkaWF0ZSk7XG5leHBvcnRzLmNsZWFySW1tZWRpYXRlID0gKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGYuY2xlYXJJbW1lZGlhdGUpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgKHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgJiYgZ2xvYmFsLmNsZWFySW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzICYmIHRoaXMuY2xlYXJJbW1lZGlhdGUpO1xuXG4vKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi99LmNhbGwodGhpcywgX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi8uLi93ZWJwYWNrL2J1aWxkaW4vZ2xvYmFsLmpzICovIFwiLi9ub2RlX21vZHVsZXMvd2VicGFjay9idWlsZGluL2dsb2JhbC5qc1wiKSkpXG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vbm9kZV9tb2R1bGVzL3V0aWwtZGVwcmVjYXRlL2Jyb3dzZXIuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL25vZGVfbW9kdWxlcy91dGlsLWRlcHJlY2F0ZS9icm93c2VyLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovKGZ1bmN0aW9uKGdsb2JhbCkge1xuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cblxuLyogV0VCUEFDSyBWQVIgSU5KRUNUSU9OICovfS5jYWxsKHRoaXMsIF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vLi4vd2VicGFjay9idWlsZGluL2dsb2JhbC5qcyAqLyBcIi4vbm9kZV9tb2R1bGVzL3dlYnBhY2svYnVpbGRpbi9nbG9iYWwuanNcIikpKVxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy93ZWJwYWNrL2J1aWxkaW4vZ2xvYmFsLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAod2VicGFjaykvYnVpbGRpbi9nbG9iYWwuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIG5vIHN0YXRpYyBleHBvcnRzIGZvdW5kICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbnZhciBnO1xuXG4vLyBUaGlzIHdvcmtzIGluIG5vbi1zdHJpY3QgbW9kZVxuZyA9IChmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXM7XG59KSgpO1xuXG50cnkge1xuXHQvLyBUaGlzIHdvcmtzIGlmIGV2YWwgaXMgYWxsb3dlZCAoc2VlIENTUClcblx0ZyA9IGcgfHwgbmV3IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKTtcbn0gY2F0Y2ggKGUpIHtcblx0Ly8gVGhpcyB3b3JrcyBpZiB0aGUgd2luZG93IHJlZmVyZW5jZSBpcyBhdmFpbGFibGVcblx0aWYgKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIpIGcgPSB3aW5kb3c7XG59XG5cbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cbi8vIFdlIHJldHVybiB1bmRlZmluZWQsIGluc3RlYWQgb2Ygbm90aGluZyBoZXJlLCBzbyBpdCdzXG4vLyBlYXNpZXIgdG8gaGFuZGxlIHRoaXMgY2FzZS4gaWYoIWdsb2JhbCkgeyAuLi59XG5cbm1vZHVsZS5leHBvcnRzID0gZztcblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL25vZGVfbW9kdWxlcy94dGVuZC9pbW11dGFibGUuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3h0ZW5kL2ltbXV0YWJsZS5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubW9kdWxlLmV4cG9ydHMgPSBleHRlbmRcblxudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gZXh0ZW5kKCkge1xuICAgIHZhciB0YXJnZXQgPSB7fVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXRcbn1cblxuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL3NyYy9Db21tb24vTGlicmFyaWVzL2NvbW1vbi5saWJyYXJpZXMucHJvcG9nYXRlSWZyYW1lRXZlbnRzLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9zcmMvQ29tbW9uL0xpYnJhcmllcy9jb21tb24ubGlicmFyaWVzLnByb3BvZ2F0ZUlmcmFtZUV2ZW50cy5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGV4cG9ydCAoYmluZGluZykgKi8gX193ZWJwYWNrX3JlcXVpcmVfXy5kKF9fd2VicGFja19leHBvcnRzX18sIFwiZGVmYXVsdFwiLCBmdW5jdGlvbigpIHsgcmV0dXJuIHByb3BvZ2F0ZUlmcmFtZUV2ZW50czsgfSk7XG4vLyBJRnJhbWUgZWxlbWVudHMgc3dhbGxvdyBtb3VzZSBldmVudHMuIFRoaXMgaW50ZXJmZXJlIHdpdGhcbi8vIGNvZGUgaW4gdGhlIHBhcmVudCBmcmFtZSB0aGF0IHJlbHkgb24gY2F0Y2hpbmcgbW91c2UgXG4vLyBldmVudHMgc3VjaCBhcyB0aGUgRnVsbHNjcmVlbiBtZW51IGRpcmVjdGl2ZSwgc3BlY2lmaWNhbGx5XG4vLyBkcmFnZ2luZyB0aGUgbWVudSBvdmVyIHRoZSBpZnJhbWUsIGFuZCB0aGUgdmlld2VyJ3MgdXNlciBcbi8vIGFjdGl2aXR5IGRldGVjdGlvbiBvdmVyIHRoZSBpZnJhbWVcbmZ1bmN0aW9uIHByb3BvZ2F0ZUlmcmFtZUV2ZW50cyhpZnJhbWUpIHtcbiAgaWZyYW1lLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIGZ1bmN0aW9uICgpIHtcbiAgICBbXCJtb3VzZW1vdmVcIiwgXCJtb3VzZWRvd25cIiwgXCJtb3VzZXVwXCIsIFwiY2xpY2tcIl0uZm9yRWFjaChmdW5jdGlvbiAobW91c2VFdmVudFR5cGUpIHtcbiAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LmFkZEV2ZW50TGlzdGVuZXIobW91c2VFdmVudFR5cGUsIGZ1bmN0aW9uIChtb3VzZUV2ZW50KSB7XG4gICAgICAgIGJ1YmJsZVVwTW91c2VFdmVudChpZnJhbWUsIG1vdXNlRXZlbnQpO1xuICAgICAgfSwgdHJ1ZSk7XG4gICAgfSk7XG4gICAgW1wia2V5ZG93blwiLCBcImtleXVwXCIsIFwia2V5cHJlc3NcIl0uZm9yRWFjaChmdW5jdGlvbiAoa2V5Ym9hcmRFdmVudFR5cGUpIHtcbiAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LmFkZEV2ZW50TGlzdGVuZXIoa2V5Ym9hcmRFdmVudFR5cGUsIGZ1bmN0aW9uIChrZXlib2FyZEV2ZW50KSB7XG4gICAgICAgIGJ1YmJsZVVwS2V5Ym9hcmRFdmVudChpZnJhbWUsIGtleWJvYXJkRXZlbnQpO1xuICAgICAgfSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBidWJibGVVcEtleWJvYXJkRXZlbnQoaWZyYW1lLCBrZXlib2FyZEV2ZW50KSB7XG4gIHRyeSB7XG4gICAgdmFyIGN1c3RvbUV2ZW50ID0gbmV3IEtleWJvYXJkRXZlbnQoa2V5Ym9hcmRFdmVudC50eXBlLCB7XG4gICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICBrZXk6IGtleWJvYXJkRXZlbnQua2V5LFxuICAgICAgY29kZToga2V5Ym9hcmRFdmVudC5jb2RlLFxuICAgICAgbG9jYXRpb246IGtleWJvYXJkRXZlbnQubG9jYXRpb24sXG4gICAgICBjdHJsS2V5OiBrZXlib2FyZEV2ZW50LmN0cmxLZXksXG4gICAgICBzaGlmdEtleToga2V5Ym9hcmRFdmVudC5zaGlmdEtleSxcbiAgICAgIGFsdEtleToga2V5Ym9hcmRFdmVudC5hbHRLZXksXG4gICAgICBtZXRhS2V5OiBrZXlib2FyZEV2ZW50Lm1ldGFLZXksXG4gICAgICByZXBlYXQ6IGtleWJvYXJkRXZlbnQucmVwZWF0LFxuICAgICAgaXNDb21wb3Npbmc6IGtleWJvYXJkRXZlbnQuaXNDb21wb3NpbmcsXG4gICAgICBjaGFyQ29kZToga2V5Ym9hcmRFdmVudC5jaGFyQ29kZSxcbiAgICAgIGtleUNvZGU6IGtleWJvYXJkRXZlbnQua2V5Q29kZSxcbiAgICAgIHdoaWNoOiBrZXlib2FyZEV2ZW50LndoaWNoXG4gICAgfSk7XG4gICAgaWZyYW1lLmRpc3BhdGNoRXZlbnQoY3VzdG9tRXZlbnQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdmFyIF9jdXN0b21FdmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KFwiS2V5Ym9hcmRFdmVudFwiKTtcblxuICAgIHZhciBtb2RpZmllckxpc3QgPSBba2V5Ym9hcmRFdmVudC5hbHRLZXkgPyBcIkFsdFwiIDogXCJcIiwga2V5Ym9hcmRFdmVudC5jdHJsS2V5ID8gXCJDb250cm9sXCIgOiBcIlwiLCBrZXlib2FyZEV2ZW50Lm1ldGFLZXkgPyBcIk1ldGFcIiA6IFwiXCIsIGtleWJvYXJkRXZlbnQuc2hpZnRLZXkgPyBcIlNoaWZ0XCIgOiBcIlwiXS5maWx0ZXIoZnVuY3Rpb24gKGEpIHtcbiAgICAgIHJldHVybiBhO1xuICAgIH0pLmpvaW4oXCIgXCIpO1xuXG4gICAgX2N1c3RvbUV2ZW50LmluaXRLZXlib2FyZEV2ZW50KGtleWJvYXJkRXZlbnQudHlwZSwgdHJ1ZSxcbiAgICAvKiBjYW5CdWJibGUgKi9cbiAgICBmYWxzZSxcbiAgICAvKiBjYW5jZWxhYmxlICovXG4gICAgbnVsbCxcbiAgICAvKiB2aWV3IChXaW5kb3dQcm94eSkgKi9cbiAgICBrZXlib2FyZEV2ZW50LmNoYXIsIGtleWJvYXJkRXZlbnQua2V5LCBrZXlib2FyZEV2ZW50LmxvY2F0aW9uLCBtb2RpZmllckxpc3QsIGtleWJvYXJkRXZlbnQucmVwZWF0KTtcblxuICAgIGlmcmFtZS5kaXNwYXRjaEV2ZW50KF9jdXN0b21FdmVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYnViYmxlVXBNb3VzZUV2ZW50KGlmcmFtZSwgbW91c2VFdmVudCkge1xuICB2YXIgYm91bmRpbmdDbGllbnRSZWN0ID0gaWZyYW1lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gIHRyeSB7XG4gICAgdmFyIGN1c3RvbUV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KG1vdXNlRXZlbnQudHlwZSwge1xuICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgIGNhbmNlbGFibGU6IGZhbHNlXG4gICAgfSk7XG4gICAgY3VzdG9tRXZlbnQuZGV0YWlsID0gbW91c2VFdmVudC5kZXRhaWw7XG4gICAgY3VzdG9tRXZlbnQuc2NyZWVuWCA9IG1vdXNlRXZlbnQuc2NyZWVuWDtcbiAgICBjdXN0b21FdmVudC5zY3JlZW5ZID0gbW91c2VFdmVudC5zY3JlZW5ZO1xuICAgIGN1c3RvbUV2ZW50LmNsaWVudFggPSBtb3VzZUV2ZW50LmNsaWVudFggKyBib3VuZGluZ0NsaWVudFJlY3QubGVmdDtcbiAgICBjdXN0b21FdmVudC5jbGllbnRZID0gbW91c2VFdmVudC5jbGllbnRZICsgYm91bmRpbmdDbGllbnRSZWN0LnRvcDtcbiAgICBjdXN0b21FdmVudC5jdHJsS2V5ID0gbW91c2VFdmVudC5jdHJsS2V5O1xuICAgIGN1c3RvbUV2ZW50LmFsdEtleSA9IG1vdXNlRXZlbnQuYWx0S2V5O1xuICAgIGN1c3RvbUV2ZW50LnNoaWZ0S2V5ID0gbW91c2VFdmVudC5zaGlmdEtleTtcbiAgICBjdXN0b21FdmVudC5tZXRhS2V5ID0gbW91c2VFdmVudC5tZXRhS2V5O1xuICAgIGN1c3RvbUV2ZW50LmJ1dHRvbiA9IG1vdXNlRXZlbnQuYnV0dG9uO1xuICAgIGlmcmFtZS5kaXNwYXRjaEV2ZW50KGN1c3RvbUV2ZW50KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIElFIDExIHdheTpcbiAgICB2YXIgX2N1c3RvbUV2ZW50MiA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KFwiTW91c2VFdmVudHNcIik7XG5cbiAgICBfY3VzdG9tRXZlbnQyLmluaXRNb3VzZUV2ZW50KG1vdXNlRXZlbnQudHlwZSwgdHJ1ZSwgLy8gYnViYmxlc1xuICAgIGZhbHNlLCAvLyBub3QgY2FuY2VsYWJsZVxuICAgIHdpbmRvdywgbW91c2VFdmVudC5kZXRhaWwsIG1vdXNlRXZlbnQuc2NyZWVuWCwgbW91c2VFdmVudC5zY3JlZW5ZLCBtb3VzZUV2ZW50LmNsaWVudFggKyBib3VuZGluZ0NsaWVudFJlY3QubGVmdCwgbW91c2VFdmVudC5jbGllbnRZICsgYm91bmRpbmdDbGllbnRSZWN0LnRvcCwgbW91c2VFdmVudC5jdHJsS2V5LCBtb3VzZUV2ZW50LmFsdEtleSwgbW91c2VFdmVudC5zaGlmdEtleSwgbW91c2VFdmVudC5tZXRhS2V5LCBtb3VzZUV2ZW50LmJ1dHRvbiwgbnVsbCAvLyBubyByZWxhdGVkIGVsZW1lbnRcbiAgICApO1xuXG4gICAgaWZyYW1lLmRpc3BhdGNoRXZlbnQoX2N1c3RvbUV2ZW50Mik7XG4gIH1cbn1cblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQuY29uc3RhbnRzLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5jb25zdGFudHMuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2tleWJvYXJkc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9jb250cm9scy5zcGFya0NsaWVudC5rZXlib2FyZHMgKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5rZXlib2FyZHMuanNcIik7XG5cbi8qIGhhcm1vbnkgZGVmYXVsdCBleHBvcnQgKi8gX193ZWJwYWNrX2V4cG9ydHNfX1tcImRlZmF1bHRcIl0gPSAoe1xuICBsb2NhbFN0b3JhZ2VLZXk6ICdTZWxlY3RlZEtleWJvYXJkRm9yU21hcnRBY2Nlc3NSZHAnLFxuICBEZWZhdWx0S2V5Ym9hcmRWYWx1ZTogX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2tleWJvYXJkc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fW1wiZGVmYXVsdFwiXVtcIkVuZ2xpc2ggKFVuaXRlZCBTdGF0ZXMpXCJdLFxuICBEZWZhdWx0Vm5jS2V5Ym9hcmQ6IFwidXNcIixcbiAgVGltZW91dFRpbWU6IDUwMDBcbn0pO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBleHBvcnRzIHByb3ZpZGVkOiBkZWZhdWx0ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBfX3dlYnBhY2tfZXhwb3J0c19fLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yKF9fd2VicGFja19leHBvcnRzX18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIHNhbml0aXplX2h0bWxfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzBfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIHNhbml0aXplLWh0bWwgKi8gXCIuL25vZGVfbW9kdWxlcy9zYW5pdGl6ZS1odG1sL2luZGV4LmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIHNhbml0aXplX2h0bWxfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzBfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihzYW5pdGl6ZV9odG1sX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9pZnJhbWVfc3BhcmtDbGllbnRfaWZyYW1lX2ZpbGVzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2lmcmFtZS9zcGFya0NsaWVudC5pZnJhbWUuZmlsZXMgKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9pZnJhbWUvc3BhcmtDbGllbnQuaWZyYW1lLmZpbGVzLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb250cm9sc19zcGFya0NsaWVudF9zdGF0ZXNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzJfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29udHJvbHMuc3BhcmtDbGllbnQuc3RhdGVzICovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQuc3RhdGVzLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb250cm9sc19zcGFya0NsaWVudF9wcm90b2NvbHNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29udHJvbHMuc3BhcmtDbGllbnQucHJvdG9jb2xzICovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQucHJvdG9jb2xzLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb250cm9sc19zcGFya0NsaWVudF9jb25zdGFudHNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzRfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29udHJvbHMuc3BhcmtDbGllbnQuY29uc3RhbnRzICovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQuY29uc3RhbnRzLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb250cm9sc19zcGFya0Vycm9yX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV81X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvbnRyb2xzLnNwYXJrRXJyb3IgKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0Vycm9yLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb250cm9sc19zcGFya0NsaWVudF9zb3VuZENvbmZpZ19lbnVtX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV82X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvbnRyb2xzLnNwYXJrQ2xpZW50LnNvdW5kQ29uZmlnLmVudW0gKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5zb3VuZENvbmZpZy5lbnVtLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb250cm9sc19zcGFya1RleHRTZW5kZXJfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzdfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29udHJvbHMuc3BhcmtUZXh0U2VuZGVyICovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtUZXh0U2VuZGVyLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIENvbW1vbl9MaWJyYXJpZXNfY29tbW9uX2xpYnJhcmllc19wcm9wb2dhdGVJZnJhbWVFdmVudHNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzhfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIENvbW1vbi9MaWJyYXJpZXMvY29tbW9uLmxpYnJhcmllcy5wcm9wb2dhdGVJZnJhbWVFdmVudHMgKi8gXCIuL3NyYy9Db21tb24vTGlicmFyaWVzL2NvbW1vbi5saWJyYXJpZXMucHJvcG9nYXRlSWZyYW1lRXZlbnRzLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIF9jb250cm9sc19zcGFya0NsaWVudF9uYXZpZ2F0aW9uQWN0aW9uX2VudW1fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzlfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29udHJvbHMuc3BhcmtDbGllbnQubmF2aWdhdGlvbkFjdGlvbi5lbnVtICovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQubmF2aWdhdGlvbkFjdGlvbi5lbnVtLmpzXCIpO1xuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG5cblxuXG5cblxuXG5cblxuXG5cblxudmFyIFNwYXJrQ2xpZW50ID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gU3BhcmtDbGllbnQob3B0aW9ucykge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTcGFya0NsaWVudCk7XG5cbiAgICB0aGlzLl9jaGVja09wdGlvbnMob3B0aW9ucyk7IC8vIHVwZGF0ZVxuICAgIC8vIEludGVybmFsIGRhdGFcblxuXG4gICAgdGhpcy5fY2xpZW50QWRhcHRlciA9IG51bGw7XG4gICAgdGhpcy5fc3BhcmtUZXh0U2VuZGVyID0gbnVsbDtcbiAgICB0aGlzLl9pZnJhbWVXcmFwcGVyRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5faW5wdXREaXNhYmxlZCA9ICEhb3B0aW9ucy5kaXNhYmxlSW5wdXQ7XG4gICAgdGhpcy5fc2VuZFRleHRQcm9taXNlID0gbnVsbDsgLy8gRXZlbnRzXG5cbiAgICB0aGlzLl9vbnN0YXRlY2hhbmdlID0gb3B0aW9ucy5vbnN0YXRlY2hhbmdlIHx8IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgdGhpcy5fb25jbGlwYm9hcmQgPSBvcHRpb25zLm9uY2xpcGJvYXJkIHx8IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgdGhpcy5fb25lcnJvciA9IG9wdGlvbnMub25lcnJvciB8fCBmdW5jdGlvbiAoKSB7fTtcblxuICAgIHRoaXMuX29ucmVzaXplID0gb3B0aW9ucy5vbnJlc2l6ZSB8fCBmdW5jdGlvbiAoKSB7fTtcblxuICAgIHRoaXMuX29uc3luYyA9IG9wdGlvbnMub25zeW5jIHx8IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgdGhpcy5fb25sb2dzeW5jID0gb3B0aW9ucy5vbmxvZ3N5bmMgfHwgZnVuY3Rpb24gKCkge307XG5cbiAgICB0aGlzLl9vbnRpbWVvdXQgPSBvcHRpb25zLm9udGltZW91dCB8fCBmdW5jdGlvbiAoKSB7fTsgLy8gU2VydmVyIERhdGFcblxuXG4gICAgdGhpcy5fc2Vzc2lvbk51bWVyaWNJZCA9IG9wdGlvbnMuY29ubmVjdGlvbklkIHx8IG51bGw7XG4gICAgdGhpcy5fZ2F0ZXdheSA9IG9wdGlvbnMuaG9zdG5hbWU7XG4gICAgdGhpcy5fcHJvdG9jb2wgPSBvcHRpb25zLnByb3RvY29sO1xuICAgIHRoaXMuX3NlcnZlciA9IG9wdGlvbnMuc2VydmVyO1xuICAgIHRoaXMuX3BvcnQgPSBvcHRpb25zLnBvcnQgfHwgdGhpcy5fZ2V0RGVmYXVsdFByb3RvY29sUG9ydChvcHRpb25zLnByb3RvY29sKTtcbiAgICB0aGlzLl91c2VyID0gb3B0aW9ucy51c2VyO1xuICAgIHRoaXMuX2RvbWFpbiA9IG9wdGlvbnMuZG9tYWluO1xuICAgIHRoaXMuX3Bhc3N3b3JkID0gb3B0aW9ucy5wYXNzd29yZDtcbiAgICB0aGlzLl9jdXJzb3JMYWJlbCA9IG9wdGlvbnMuY3Vyc29yTGFiZWwgfHwgXCJcIjtcbiAgICB0aGlzLl9tYWNoaW5lSWQgPSBvcHRpb25zLm1hY2hpbmVJZCB8fCBudWxsO1xuICAgIHRoaXMuX2VudklkID0gb3B0aW9ucy5lbnZJZCB8fCBudWxsO1xuICAgIHRoaXMuX3VzZXJFbWFpbCA9IG9wdGlvbnMudXNlckVtYWlsIHx8IG51bGw7XG4gICAgdGhpcy5fY2xhc3NJZCA9IG9wdGlvbnMuY2xhc3NJZCB8fCBudWxsO1xuICAgIHRoaXMuX3N0dWRlbnRJZCA9IG9wdGlvbnMuc3R1ZGVudElkIHx8IG51bGw7XG4gICAgdGhpcy5fbm9kZSA9IG9wdGlvbnMubm9kZSB8fCBudWxsO1xuICAgIHRoaXMuX3JkcFdhbGxwYXBlciA9IG9wdGlvbnMucmRwV2FsbHBhcGVyIHx8IG51bGw7XG4gICAgdGhpcy5fcmRwVGhlbWVzID0gb3B0aW9ucy5yZHBUaGVtZXMgfHwgbnVsbDtcbiAgICB0aGlzLl9yZHBGb250U21vb3RoaW5nID0gb3B0aW9ucy5yZHBGb250U21vb3RoaW5nIHx8IG51bGw7XG4gICAgdGhpcy5fcmRwU291bmRDb25maWcgPSBvcHRpb25zLnJkcFNvdW5kQ29uZmlnIHx8IG51bGw7XG4gICAgdGhpcy5fdXNlS2V5ZmlsZSA9IG9wdGlvbnMudXNlS2V5ZmlsZSB8fCBmYWxzZTtcbiAgICB0aGlzLl9leHRlcm5hbENsb3VkVHlwZSA9IG9wdGlvbnMuZXh0ZXJuYWxDbG91ZFR5cGUgfHwgbnVsbDtcbiAgICB0aGlzLl9yZW1vdGVBY2Nlc3NTZXNzaW9uSWQgPSBvcHRpb25zLnJlbW90ZUFjY2Vzc1Nlc3Npb25JZCB8fCBudWxsOyAvLyBDbGllbnQgRGF0YVxuXG4gICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBvcHRpb25zLnJvb3RFbGVtZW50O1xuICAgIHRoaXMuX3JlY29ubmVjdE9uUmVzaXplID0gISFvcHRpb25zLnJlY29ubmVjdE9uUmVzaXplO1xuICAgIHRoaXMuX2hlaWdodCA9IG9wdGlvbnMuZml0U2NyZWVuID8gbnVsbCA6IG9wdGlvbnMuaGVpZ2h0O1xuICAgIHRoaXMuX3dpZHRoID0gb3B0aW9ucy5maXRTY3JlZW4gPyBudWxsIDogb3B0aW9ucy53aWR0aDtcbiAgICB0aGlzLl9maXRTY3JlZW4gPSBvcHRpb25zLmZpdFNjcmVlbjtcbiAgICB0aGlzLl9ub3RTZWN1cmUgPSBvcHRpb25zLm5vdFNlY3VyZTtcbiAgICB0aGlzLl9jb2xvckRlcHRoID0gb3B0aW9ucy5jb2xvckRlcHRoO1xuICAgIHRoaXMuX2tleWJvYXJkSWQgPSBvcHRpb25zLmtleWJvYXJkSWQgfHwgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2NvbnN0YW50c19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNF9fW1wiZGVmYXVsdFwiXS5EZWZhdWx0S2V5Ym9hcmRWYWx1ZTtcbiAgICB0aGlzLl92bmNLZXlib2FyZCA9IG9wdGlvbnMudm5jS2V5Ym9hcmQgfHwgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2NvbnN0YW50c19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNF9fW1wiZGVmYXVsdFwiXS5EZWZhdWx0Vm5jS2V5Ym9hcmQ7XG4gICAgdGhpcy5fY3VycmVudFNjYWxlID0gMTtcbiAgICB0aGlzLl9hbGxvd1Rsc1YxID0gISFvcHRpb25zLmFsbG93VGxzVjE7XG4gICAgdGhpcy5fc2VuZFRleHRPblBhc3RlID0gISFvcHRpb25zLnNlbmRUZXh0T25QYXN0ZTtcbiAgICB0aGlzLl9jcmVkU1NQID0gb3B0aW9ucy5jcmVkU1NQICE9PSBmYWxzZTtcbiAgICB0aGlzLl9zc2hGb250U2l6ZSA9IG9wdGlvbnMuc3NoRm9udFNpemU7XG4gICAgdGhpcy5fc3NoTGluZUhlaWdodCA9IG9wdGlvbnMuc3NoTGluZUhlaWdodDtcbiAgICB0aGlzLl9rZXlPdmVycmlkZXMgPSBvcHRpb25zLmtleU92ZXJyaWRlcyB8fCBudWxsO1xuICAgIHRoaXMuX2Nvbm5lY3RpbmdUaW1lb3V0SWQgPSBudWxsO1xuICAgIHRoaXMuX2Nvbm5lY3RpbmdUaW1lb3V0U2Vjb25kcyA9IG9wdGlvbnMuY29ubmVjdGluZ1RpbWVvdXRTZWNvbmRzIHx8IG51bGw7IC8vIFRCRFxuXG4gICAgdGhpcy5fbW91c2UgPSBudWxsO1xuICAgIHRoaXMuX3Jlc29sdmVEaXNjb25uZWN0ID0gbnVsbDtcbiAgICB0aGlzLl9yZXNvbHZlQ29ubmVjdCA9IG51bGw7XG4gICAgdGhpcy5fcmVqZWN0Q29ubmVjdCA9IG51bGw7XG4gICAgdGhpcy5fY29ubmVjdGVkID0gZmFsc2U7XG4gICAgdGhpcy5fbGFzdEVycm9yID0gbnVsbDtcbiAgICB0aGlzLlNUQVRFUyA9IF9jb250cm9sc19zcGFya0NsaWVudF9zdGF0ZXNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzJfX1tcImRlZmF1bHRcIl07XG5cbiAgICB0aGlzLl9zZXRDdXJyZW50U3RhdGUoX2NvbnRyb2xzX3NwYXJrQ2xpZW50X3N0YXRlc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMl9fW1wiZGVmYXVsdFwiXS5JRExFKTtcblxuICAgIHRoaXMuX3Nhbml0aXplSHRtbCA9IHRoaXMuX2NyZWF0ZUh0bWxTYW5pdGl6ZUZ1bmN0aW9uKCk7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3MoU3BhcmtDbGllbnQsIFt7XG4gICAga2V5OiBcInNldHVwQW5kQ29ubmVjdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXR1cEFuZENvbm5lY3QoKSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcblxuICAgICAgdGhpcy5fc2V0Q3VycmVudFN0YXRlKF9jb250cm9sc19zcGFya0NsaWVudF9zdGF0ZXNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzJfX1tcImRlZmF1bHRcIl0uQ09OTkVDVElORyk7XG5cbiAgICAgIGlmICh0aGlzLl9jb25uZWN0aW5nVGltZW91dFNlY29uZHMpIHtcbiAgICAgICAgdGhpcy5fcmVzZXRDb25uZWN0aW5nVGltZW91dElkKCk7XG5cbiAgICAgICAgdGhpcy5fY29ubmVjdGluZ1RpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIF90aGlzLl9vbnRpbWVvdXQoKTtcblxuICAgICAgICAgIF90aGlzLnNldHVwQW5kQ29ubmVjdCgpO1xuICAgICAgICB9LCB0aGlzLl9jb25uZWN0aW5nVGltZW91dFNlY29uZHMgKiAxMDAwKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX2luamVjdElmcmFtZUFuZEdldENsaWVudEFkYXB0ZXIoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3RoaXMuX3JlZ2lzdGVyVG9FdmVudHMoKTtcblxuICAgICAgICBfdGhpcy5fY2xpZW50QWRhcHRlci5jb25uZWN0KHtcbiAgICAgICAgICBzZXNzaW9uTnVtZXJpY0lkOiBfdGhpcy5fc2Vzc2lvbk51bWVyaWNJZCxcbiAgICAgICAgICBwcm90b2NvbDogX3RoaXMuZ2V0UHJvdG9jb2xOYW1lKF90aGlzLl9wcm90b2NvbCksXG4gICAgICAgICAgZ2F0ZXdheTogX3RoaXMuX2dhdGV3YXksXG4gICAgICAgICAgc2VydmVyOiBfdGhpcy5fc2VydmVyLFxuICAgICAgICAgIHBvcnQ6IF90aGlzLl9wb3J0LFxuICAgICAgICAgIHVzZXI6IF90aGlzLl91c2VyLFxuICAgICAgICAgIGRvbWFpbjogX3RoaXMuX2RvbWFpbixcbiAgICAgICAgICBwYXNzd29yZDogX3RoaXMuX3Bhc3N3b3JkLFxuICAgICAgICAgIG5vdFNlY3VyZTogX3RoaXMuX25vdFNlY3VyZSxcbiAgICAgICAgICByZWNvbm5lY3RPblJlc2l6ZTogX3RoaXMuX3JlY29ubmVjdE9uUmVzaXplLFxuICAgICAgICAgIGNvbG9yRGVwdGg6IF90aGlzLl9jb2xvckRlcHRoLFxuICAgICAgICAgIHVzZVdvcmtlcjogZmFsc2UsXG4gICAgICAgICAga2V5Ym9hcmQ6IF90aGlzLl9rZXlib2FyZElkLFxuICAgICAgICAgIG1hY2hpbmVJZDogX3RoaXMuX21hY2hpbmVJZCxcbiAgICAgICAgICBjdXJzb3JMYWJlbDogX3RoaXMuX2N1cnNvckxhYmVsLFxuICAgICAgICAgIHVzZXJFbWFpbDogX3RoaXMuX3VzZXJFbWFpbCxcbiAgICAgICAgICBlbnZJZDogX3RoaXMuX2VudklkLFxuICAgICAgICAgIGNsYXNzSWQ6IF90aGlzLl9jbGFzc0lkLFxuICAgICAgICAgIHN0dWRlbnRJZDogX3RoaXMuX3N0dWRlbnRJZCxcbiAgICAgICAgICBub2RlOiBfdGhpcy5fbm9kZSxcbiAgICAgICAgICByZHBXYWxscGFwZXI6IF90aGlzLl9yZHBXYWxscGFwZXIsXG4gICAgICAgICAgcmRwVGhlbWVzOiBfdGhpcy5fcmRwVGhlbWVzLFxuICAgICAgICAgIHJkcEZvbnRTbW9vdGhpbmc6IF90aGlzLl9yZHBGb250U21vb3RoaW5nLFxuICAgICAgICAgIHBsYXlTb3VuZDogX3RoaXMuX3JkcFNvdW5kQ29uZmlnVG9QbGF5U291bmQoX3RoaXMuX3JkcFNvdW5kQ29uZmlnKSxcbiAgICAgICAgICBzb3VuZFByZWY6IF90aGlzLl9yZHBTb3VuZENvbmZpZ1RvU291bmRQZXJmKF90aGlzLl9yZHBTb3VuZENvbmZpZyksXG4gICAgICAgICAgYWxsb3dUbHNWMTogX3RoaXMuX2FsbG93VGxzVjEsXG4gICAgICAgICAga2V5T3ZlcnJpZGVzOiBfdGhpcy5fa2V5T3ZlcnJpZGVzLFxuICAgICAgICAgIHVzZUtleWZpbGU6IF90aGlzLl91c2VLZXlmaWxlLFxuICAgICAgICAgIGV4dGVybmFsQ2xvdWRUeXBlOiBfdGhpcy5fZXh0ZXJuYWxDbG91ZFR5cGUsXG4gICAgICAgICAgY3JlZFNTUDogX3RoaXMuX2NyZWRTU1AsXG4gICAgICAgICAgc3NoRm9udFNpemU6IF90aGlzLl9zc2hGb250U2l6ZSxcbiAgICAgICAgICBzc2hMaW5lSGVpZ2h0OiBfdGhpcy5fc3NoTGluZUhlaWdodCxcbiAgICAgICAgICByZW1vdGVBY2Nlc3NTZXNzaW9uSWQ6IF90aGlzLl9yZW1vdGVBY2Nlc3NTZXNzaW9uSWRcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZGlzY29ubmVjdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBkaXNjb25uZWN0KCkge1xuICAgICAgaWYgKHRoaXMuX2N1cnJlbnRTdGF0ZSAhPT0gX2NvbnRyb2xzX3NwYXJrQ2xpZW50X3N0YXRlc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMl9fW1wiZGVmYXVsdFwiXS5JRExFKSB7XG4gICAgICAgIHRoaXMuX3NldEN1cnJlbnRTdGF0ZShfY29udHJvbHNfc3BhcmtDbGllbnRfc3RhdGVzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yX19bXCJkZWZhdWx0XCJdLkRJU0NPTk5FQ1RFRCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9jbGllbnRBZGFwdGVyKSB7XG4gICAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIuY2xvc2UoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2VuZFRleHRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2VuZFRleHQodGV4dCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIGlmICh0aGlzLl9zcGFya1RleHRTZW5kZXIuaXNSdW5uaW5nKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fcHJvdG9jb2wgPT09IF9jb250cm9sc19zcGFya0NsaWVudF9wcm90b2NvbHNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzNfX1tcImRlZmF1bHRcIl0uVm5jKSB7XG4gICAgICAgIHZhciBwcmV2aW91c0lucHV0RGlzYWJsZWRWYWx1ZSA9IHRoaXMuaW5wdXREaXNhYmxlZDtcbiAgICAgICAgdGhpcy5pbnB1dERpc2FibGVkID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5zZXRTdXJmYWNlUmVhZE9ubHkodHJ1ZSk7XG5cbiAgICAgICAgdGhpcy5fc2VuZFRleHRQcm9taXNlID0gdGhpcy5fc3BhcmtUZXh0U2VuZGVyLnNlbmRUZXh0KHRleHQsIHRoaXMuX3ZuY0tleWJvYXJkKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBfdGhpczIuX2NsaWVudEFkYXB0ZXIuc2V0U3VyZmFjZVJlYWRPbmx5KGZhbHNlKTtcblxuICAgICAgICAgIF90aGlzMi5pbnB1dERpc2FibGVkID0gcHJldmlvdXNJbnB1dERpc2FibGVkVmFsdWU7XG4gICAgICAgICAgX3RoaXMyLl9zZW5kVGV4dFByb21pc2UgPSBudWxsO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIud3JpdGVUZXh0KHRleHQpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZW5kS2V5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNlbmRLZXkoa2V5LCBkb3duKSB7XG4gICAgICBpZiAodGhpcy5fc3BhcmtUZXh0U2VuZGVyLmlzUnVubmluZygpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci53cml0ZUtleUNvZGUoZG93biwga2V5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2VuZEN0cmxBbHREZWxldGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2VuZEN0cmxBbHREZWxldGUoKSB7XG4gICAgICBpZiAodGhpcy5fc3BhcmtUZXh0U2VuZGVyLmlzUnVubmluZygpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci53cml0ZUtleUNvbWIoXCJDdHJsK0FsdCtEZWxcIiwgMCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNlbmRDdHJsV1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZW5kQ3RybFcoKSB7XG4gICAgICBpZiAodGhpcy5fc3BhcmtUZXh0U2VuZGVyLmlzUnVubmluZygpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci53cml0ZUtleUNvbWIoXCJDdHJsK3dcIiwgMCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNlbmROYXZpZ2F0aW9uQWN0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNlbmROYXZpZ2F0aW9uQWN0aW9uKG5hdmlnYXRpb25BY3Rpb24pIHtcbiAgICAgIGlmICghbmF2aWdhdGlvbkFjdGlvbiB8fCB0aGlzLl9zcGFya1RleHRTZW5kZXIuaXNSdW5uaW5nKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKG5hdmlnYXRpb25BY3Rpb24pIHtcbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfbmF2aWdhdGlvbkFjdGlvbl9lbnVtX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV85X19bXCJkZWZhdWx0XCJdLmhvbWU6XG4gICAgICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci53cml0ZUtleUNvbWIoXCJBbHQraG9tZVwiLCAwKTtcblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X25hdmlnYXRpb25BY3Rpb25fZW51bV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfOV9fW1wiZGVmYXVsdFwiXS5iYWNrOlxuICAgICAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIud3JpdGVLZXlDb21iKFwiQWx0K2xlZnRcIiwgMCk7XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIF9jb250cm9sc19zcGFya0NsaWVudF9uYXZpZ2F0aW9uQWN0aW9uX2VudW1fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzlfX1tcImRlZmF1bHRcIl0uZm9yd2FyZDpcbiAgICAgICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLndyaXRlS2V5Q29tYihcIkFsdCtyaWdodFwiLCAwKTtcblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlzc2luZyBuYXZpZ2F0aW9uIHR5cGUgbWFwcGluZ1wiKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2VuZFdpbmRvd3NLZXlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2VuZFdpbmRvd3NLZXkoKSB7XG4gICAgICBpZiAodGhpcy5fc3BhcmtUZXh0U2VuZGVyLmlzUnVubmluZygpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci53cml0ZUtleUNvbWIoXCJ3aW5kb3dzXCIsIDApO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRUaHVtYm5haWxcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VGh1bWJuYWlsKHdpZHRoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2xpZW50QWRhcHRlci5nZXRUaHVtYm5haWwod2lkdGgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRDbGlwYm9hcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0Q2xpcGJvYXJkKHRleHQpIHtcbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIuY29weVRvQ2xpcCh0ZXh0KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic2NhbGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2NhbGUodmFsdWUpIHtcbiAgICAgIHRoaXMuX2N1cnJlbnRTY2FsZSA9IHZhbHVlO1xuXG4gICAgICB0aGlzLl9zY2FsZUJ5TWF4V2lkdGhBbmRIZWlnaHQodGhpcy5faWZyYW1lV3JhcHBlckVsZW1lbnQsIHZhbHVlKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0U2NhbGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0U2NhbGUoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY3VycmVudFNjYWxlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRQcm90b2NvbE5hbWVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UHJvdG9jb2xOYW1lKCkge1xuICAgICAgc3dpdGNoICh0aGlzLl9wcm90b2NvbCkge1xuICAgICAgICBjYXNlIF9jb250cm9sc19zcGFya0NsaWVudF9wcm90b2NvbHNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzNfX1tcImRlZmF1bHRcIl0uUmRwOlxuICAgICAgICAgIHJldHVybiBcInJkcFwiO1xuXG4gICAgICAgIGNhc2UgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X3Byb3RvY29sc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfM19fW1wiZGVmYXVsdFwiXS5WbmM6XG4gICAgICAgICAgcmV0dXJuIFwidm5jXCI7XG5cbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfcHJvdG9jb2xzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8zX19bXCJkZWZhdWx0XCJdLlNzaDpcbiAgICAgICAgICByZXR1cm4gXCJzc2hcIjtcblxuICAgICAgICBjYXNlIF9jb250cm9sc19zcGFya0NsaWVudF9wcm90b2NvbHNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzNfX1tcImRlZmF1bHRcIl0uV2ViQ29uc29sZTpcbiAgICAgICAgICByZXR1cm4gXCJ3ZWJjb25zb2xlXCI7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0RWxlbWVudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRFbGVtZW50KCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRTZW5kVGV4dE9uUGFzdGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0U2VuZFRleHRPblBhc3RlKHZhbHVlKSB7XG4gICAgICB0aGlzLl9zZW5kVGV4dE9uUGFzdGUgPSB2YWx1ZTtcblxuICAgICAgaWYgKHRoaXMuX2NsaWVudEFkYXB0ZXIpIHtcbiAgICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5zZXRTZW5kVGV4dE9uUGFzdGUodmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRSZW1vdGVBY2Nlc3NTZXNzaW9uSWRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UmVtb3RlQWNjZXNzU2Vzc2lvbklkKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbW90ZUFjY2Vzc1Nlc3Npb25JZDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2NoZWNrT3B0aW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfY2hlY2tPcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgIC8vIFRCRFxuICAgICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBvcHRpb25zIG9iamVjdCBwYXJhbWV0ZXInKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFvcHRpb25zLmhvc3RuYW1lICYmICFvcHRpb25zLnNlc3Npb25OdW1lcmljSWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGhvc3RuYW1lIHBhcmFtZXRlcicpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfcmVnaXN0ZXJUb0V2ZW50c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfcmVnaXN0ZXJUb0V2ZW50cygpIHtcbiAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICBpZiAoIXRoaXMuX2NsaWVudEFkYXB0ZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLm9uY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbmNsb3NlJyk7XG5cbiAgICAgICAgX3RoaXMzLl9zZXRDdXJyZW50U3RhdGUoX2NvbnRyb2xzX3NwYXJrQ2xpZW50X3N0YXRlc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMl9fW1wiZGVmYXVsdFwiXS5ESVNDT05ORUNURUQpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbmVycm9yJywgZXJyb3IpO1xuXG4gICAgICAgIF90aGlzMy5fb25lcnJvcihuZXcgX2NvbnRyb2xzX3NwYXJrRXJyb3JfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzVfX1tcImRlZmF1bHRcIl0oZXJyb3IpLCBfdGhpczMpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5vbmxvZ2dlZGluID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zb2xlLmxvZygnb25sb2dnZWRpbicpO1xuXG4gICAgICAgIF90aGlzMy5fc2V0Q3VycmVudFN0YXRlKF9jb250cm9sc19zcGFya0NsaWVudF9zdGF0ZXNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzJfX1tcImRlZmF1bHRcIl0uQ09OTkVDVEVEQU5ETE9HR0VESU4pO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5iZWZvcmV1cGxvYWQgPSBmdW5jdGlvbiAoZmlsZSwgcGF0aCkge1xuICAgICAgICBjb25zb2xlLmxvZygnYmVmb3JldXBsb2FkJywgZmlsZSwgcGF0aCk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLm9uZmlsZXVwbG9hZGVkID0gZnVuY3Rpb24gKGZpbGVOYW1lKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbmZpbGV1cGxvYWRlZCcsIGZpbGVOYW1lKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub251cGxvYWRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ29udXBsb2FkZWQnKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub25zZXNzaW9uam9pbiA9IGZ1bmN0aW9uIChhcHBJbmZvKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbnNlc3Npb25qb2luJywgYXBwSW5mbyk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLm9uc2Vzc2lvbmV4aXQgPSBmdW5jdGlvbiAoYXBwSW5mbykge1xuICAgICAgICBjb25zb2xlLmxvZygnb25zZXNzaW9uZXhpdCcsIGFwcEluZm8pO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5vbmdpdmVjb250cm9sID0gZnVuY3Rpb24gKGFwcEluZm8pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ29uZ2l2ZWNvbnRyb2wnLCBhcHBJbmZvKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub250YWtlYmFja2NvbnRyb2wgPSBmdW5jdGlvbiAoYXBwSW5mbykge1xuICAgICAgICBjb25zb2xlLmxvZygnb250YWtlYmFja2NvbnRyb2wnLCBhcHBJbmZvKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub25yZXF1aXJlY29udHJvbCA9IGZ1bmN0aW9uIChhcHBJbmZvKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbnJlcXVpcmVjb250cm9sJywgYXBwSW5mbyk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLm9ucmVtb3RlYXBwc3RhcnQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICBjb25zb2xlLmxvZygnb25yZW1vdGVhcHBzdGFydCcsIGUpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5vbmFjdGl2aXR5ID0gZnVuY3Rpb24gKCkgey8vY29uc29sZS5sb2coJ29uYWN0aXZpdHknLCBpbnB1dCk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLm9udXJscmVkaXJlY3Rpb24gPSBmdW5jdGlvbiAoVVJMKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbnVybHJlZGlyZWN0aW9uJywgVVJMKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub250aXRsZWNoYW5nZSA9IGZ1bmN0aW9uICh0aXRsZSkge1xuICAgICAgICBjb25zb2xlLmxvZygnb250aXRsZWNoYW5nZScsIHRpdGxlKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub25zZXNzaW9uc3RhcnQgPSBmdW5jdGlvbiAoc2Vzc2lvbkluZm8pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ29uc2Vzc2lvbnN0YXJ0Jywgc2Vzc2lvbkluZm8pO1xuXG4gICAgICAgIF90aGlzMy5fc2V0Q3VycmVudFN0YXRlKF9jb250cm9sc19zcGFya0NsaWVudF9zdGF0ZXNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzJfX1tcImRlZmF1bHRcIl0uQ09OTkVDVEVEKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub25yZXF1ZXN0Y3JlZGVudGlhbCA9IGZ1bmN0aW9uIChpbmZvKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbnJlcXVlc3RjcmVkZW50aWFsJywgaW5mbyk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLm9ucmVzb2x1dGlvbmNoYW5nZSA9IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdvbnJlc29sdXRpb25jaGFuZ2UnLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgICAgICBpZiAoIV90aGlzMy5fZml0U2NyZWVuKSB7XG4gICAgICAgICAgX3RoaXMzLl9pZnJhbWVXcmFwcGVyRWxlbWVudC5zdHlsZS53aWR0aCA9IHdpZHRoICsgXCJweFwiO1xuICAgICAgICAgIF90aGlzMy5faWZyYW1lV3JhcHBlckVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0ICsgXCJweFwiO1xuICAgICAgICB9XG5cbiAgICAgICAgX3RoaXMzLl9vbnJlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub25ub3Jlc3BvbnNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zb2xlLmxvZygnb25ub3Jlc3BvbnNlJyk7XG5cbiAgICAgICAgX3RoaXMzLl9vbmVycm9yKG5ldyBfY29udHJvbHNfc3BhcmtFcnJvcl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNV9fW1wiZGVmYXVsdFwiXShcIk5vIHJlc3BvbnNlXCIpLCBfdGhpczMpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5vbnNlcnZlcmNvcHkgPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICBjb25zb2xlLmxvZygnb25zZXJ2ZXJjb3B5Jyk7XG5cbiAgICAgICAgdmFyIGNsaXBib2FyZENvbnRlbnQgPSBfdGhpczMuX3BhcnNlT25zZXJ2ZXJjb3B5RGF0YSh0ZXh0KTtcblxuICAgICAgICBfdGhpczMuX29uY2xpcGJvYXJkKGNsaXBib2FyZENvbnRlbnQpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5vbmF1dGhlcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZyhcIm9uYXV0aGVycm9yXCIsIGVycm9yKTtcblxuICAgICAgICBfdGhpczMuX29uZXJyb3IobmV3IF9jb250cm9sc19zcGFya0Vycm9yX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV81X19bXCJkZWZhdWx0XCJdKFwiQXV0aCBlcnJvclwiKSwgX3RoaXMzKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIub25zZW5kdGV4dHJlcXVlc3QgPSBmdW5jdGlvbiAobG9jYWxDbGlwYm9hcmRUZXh0KSB7XG4gICAgICAgIF90aGlzMy5zZW5kVGV4dChsb2NhbENsaXBib2FyZFRleHQsIF90aGlzMy5fdm5jS2V5Ym9hcmQpO1xuICAgICAgfTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX3NldEN1cnJlbnRTdGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfc2V0Q3VycmVudFN0YXRlKHN0YXRlKSB7XG4gICAgICBpZiAodGhpcy5fY3VycmVudFN0YXRlICE9PSBzdGF0ZSkge1xuICAgICAgICB0aGlzLl9jdXJyZW50U3RhdGUgPSBzdGF0ZTtcblxuICAgICAgICB0aGlzLl9vbnN0YXRlY2hhbmdlKHN0YXRlLCB0aGlzKTtcblxuICAgICAgICBjb25zb2xlLmxvZygnc3RhdGUgY2hhbmdlZCAnICsgc3RhdGUpO1xuXG4gICAgICAgIHRoaXMuX3Jlc2V0Q29ubmVjdGluZ1RpbWVvdXRJZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfcmVzZXRDb25uZWN0aW5nVGltZW91dElkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9yZXNldENvbm5lY3RpbmdUaW1lb3V0SWQoKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5fY29ubmVjdGluZ1RpbWVvdXRJZCk7XG4gICAgICB0aGlzLl9jb25uZWN0aW5nVGltZW91dElkID0gbnVsbDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX3BhcnNlT25zZXJ2ZXJjb3B5RGF0YVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfcGFyc2VPbnNlcnZlcmNvcHlEYXRhKHRleHQpIHtcbiAgICAgIGlmICghdGV4dCkge1xuICAgICAgICByZXR1cm4gdGV4dDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRleHQuaW5kZXhPZigndGV4dC9wbGFpbjsnKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGV4dC5zdWJzdHJpbmcoJ3RleHQvcGxhaW47Jy5sZW5ndGgpO1xuICAgICAgfSBlbHNlIGlmICh0ZXh0LmluZGV4T2YoJ3RleHQvaHRtbDsnKSA9PT0gMCkge1xuICAgICAgICB2YXIgaHRtbCA9IHRleHQuc3Vic3RyaW5nKCd0ZXh0L2h0bWw7Jy5sZW5ndGgpO1xuICAgICAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICBlbC5pbm5lckhUTUwgPSB0aGlzLl9zYW5pdGl6ZUh0bWwoaHRtbCk7XG4gICAgICAgIHJldHVybiBlbC50ZXh0Q29udGVudDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9jcmVhdGVIdG1sU2FuaXRpemVGdW5jdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfY3JlYXRlSHRtbFNhbml0aXplRnVuY3Rpb24oKSB7XG4gICAgICB2YXIgY29uZmlnID0ge1xuICAgICAgICBhbGxvd2VkVGFnczogW1wiaW1nXCIsIFwiaDFcIiwgXCJoMlwiLCBcInNwYW5cIiwgXCJ1XCIsIFwiZm9udFwiLCBcImgzXCIsIFwiaDRcIiwgXCJoNVwiLCBcImg2XCIsIFwiYmxvY2txdW90ZVwiLCBcInBcIiwgXCJhXCIsIFwidWxcIiwgXCJvbFwiLCBcIm5sXCIsIFwibGlcIiwgXCJiXCIsIFwiaVwiLCBcInN0cm9uZ1wiLCBcImVtXCIsIFwic3RyaWtlXCIsIFwiY29kZVwiLCBcImhyXCIsIFwiYnJcIiwgXCJkaXZcIiwgXCJ0YWJsZVwiLCBcInRoZWFkXCIsIFwiY2FwdGlvblwiLCBcInRib2R5XCIsIFwidHJcIiwgXCJ0aFwiLCBcInRkXCIsIFwicHJlXCJdLFxuICAgICAgICBhbGxvd2VkQXR0cmlidXRlczoge1xuICAgICAgICAgIGE6IFtcImhyZWZcIiwgXCJuYW1lXCIsIFwidGFyZ2V0XCJdLFxuICAgICAgICAgIGltZzogW1wic3JjXCJdLFxuICAgICAgICAgIFwiKlwiOiBbXCJhbHRcIiwgXCJkaXJcIiwgXCJzcmNcIiwgXCJzdHlsZVwiLCBcImhyZWZcIiwgXCJ0YXJnZXRcIiwgXCJjZWxscGFkZGluZ1wiLCBcImNlbGxzcGFjaW5nXCIsIFwiaWRcIiwgXCJjb2xzcGFuXCIsIFwiY2xhc3NcIiwgXCJmYWNlXCIsIFwiY29sb3JcIiwgXCJyZWZcIiwgXCJhbGlnblwiLCBcImxhbmdcIiwgXCJib3JkZXJcIiwgXCJzY29wZVwiLCBcImhlaWdodFwiLCBcInRpdGxlXCIsIFwid2lkdGhcIl1cbiAgICAgICAgfSxcbiAgICAgICAgc2VsZkNsb3Npbmc6IFtcImltZ1wiLCBcImJyXCIsIFwiaHJcIiwgXCJhcmVhXCIsIFwiYmFzZVwiLCBcImJhc2Vmb250XCIsIFwiaW5wdXRcIiwgXCJsaW5rXCIsIFwibWV0YVwiXSxcbiAgICAgICAgYWxsb3dlZFNjaGVtZXM6IFtcImh0dHBcIiwgXCJodHRwc1wiLCBcImZ0cFwiLCBcIm1haWx0b1wiXSxcbiAgICAgICAgYWxsb3dlZFNjaGVtZXNCeVRhZzoge31cbiAgICAgIH07XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGh0bWwpIHtcbiAgICAgICAgcmV0dXJuIHNhbml0aXplX2h0bWxfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzBfX19kZWZhdWx0KCkoaHRtbCwgY29uZmlnKTtcbiAgICAgIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9pbmplY3RJZnJhbWVBbmRHZXRDbGllbnRBZGFwdGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9pbmplY3RJZnJhbWVBbmRHZXRDbGllbnRBZGFwdGVyKCkge1xuICAgICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICBfdGhpczQuX2lmcmFtZVdyYXBwZXJFbGVtZW50ID0gX3RoaXM0Ll9jcmVhdGVJZnJhbWVXcmFwcGVyKCk7XG5cbiAgICAgICAgdmFyIHZlcnRpY2FsQWxpZ25lckVsZW1lbnQgPSBfdGhpczQuX2NyZWF0ZVZlcnRpY2FsQWxpZ25lcigpO1xuXG4gICAgICAgIHZhciBpZnJhbWVFbGVtZW50ID0gX3RoaXM0Ll9jcmVhdGVJZnJhbWUocmVzb2x2ZSk7XG5cbiAgICAgICAgX3RoaXM0Ll9pZnJhbWVXcmFwcGVyRWxlbWVudC5hcHBlbmRDaGlsZChpZnJhbWVFbGVtZW50KTtcblxuICAgICAgICBfdGhpczQuX3Jvb3RFbGVtZW50LmlubmVySFRNTCA9IFwiXCI7XG5cbiAgICAgICAgX3RoaXM0Ll9yb290RWxlbWVudC5hcHBlbmRDaGlsZChfdGhpczQuX2lmcmFtZVdyYXBwZXJFbGVtZW50KTtcblxuICAgICAgICBfdGhpczQuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHZlcnRpY2FsQWxpZ25lckVsZW1lbnQpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9jcmVhdGVJZnJhbWVXcmFwcGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9jcmVhdGVJZnJhbWVXcmFwcGVyKCkge1xuICAgICAgdmFyIGlmcmFtZVdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgaWZyYW1lV3JhcHBlci5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBcImNlbnRlciAwXCI7XG4gICAgICBpZnJhbWVXcmFwcGVyLnN0eWxlLldlYmtpdFRyYW5zZm9ybU9yaWdpbiA9IFwiY2VudGVyIDBcIjtcbiAgICAgIGlmcmFtZVdyYXBwZXIuc3R5bGUuTW96VHJhbnNmb3JtT3JpZ2luID0gXCJjZW50ZXIgMFwiO1xuICAgICAgaWZyYW1lV3JhcHBlci5zdHlsZS5Nc1RyYW5zZm9ybU9yaWdpbiA9IFwiY2VudGVyIDBcIjtcbiAgICAgIGlmcmFtZVdyYXBwZXIuc3R5bGUubWluV2lkdGggPSBcIjgwcHhcIjtcbiAgICAgIGlmcmFtZVdyYXBwZXIuc3R5bGUubWluSGVpZ2h0ID0gXCI4MHB4XCI7XG5cbiAgICAgIGlmICh0aGlzLl9maXRTY3JlZW4pIHtcbiAgICAgICAgaWZyYW1lV3JhcHBlci5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuICAgICAgICBpZnJhbWVXcmFwcGVyLnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLl93aWR0aCAmJiB0aGlzLl9oZWlnaHQpIHtcbiAgICAgICAgaWZyYW1lV3JhcHBlci5zdHlsZS53aWR0aCA9IHRoaXMuX3dpZHRoICsgXCJweFwiO1xuICAgICAgICBpZnJhbWVXcmFwcGVyLnN0eWxlLmhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmcmFtZVdyYXBwZXIuc3R5bGUud2lkdGggPSBcIjcwMHB4XCI7XG4gICAgICAgIGlmcmFtZVdyYXBwZXIuc3R5bGUuaGVpZ2h0ID0gXCI1MDBweFwiO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fc2Vzc2lvbk51bWVyaWNJZCAhPSBudWxsKSB7XG4gICAgICAgIGlmcmFtZVdyYXBwZXIuc3R5bGUubWF4V2lkdGggPSBcIjEwMCVcIjtcbiAgICAgICAgaWZyYW1lV3JhcHBlci5zdHlsZS5tYXhIZWlnaHQgPSBcIjEwMCVcIjtcbiAgICAgIH1cblxuICAgICAgaWZyYW1lV3JhcHBlci5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIjtcbiAgICAgIGlmcmFtZVdyYXBwZXIuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG4gICAgICBpZnJhbWVXcmFwcGVyLnN0eWxlLnZlcnRpY2FsQWxpZ24gPSBcIm1pZGRsZVwiO1xuICAgICAgcmV0dXJuIGlmcmFtZVdyYXBwZXI7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9jcmVhdGVJZnJhbWVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2NyZWF0ZUlmcmFtZShyZXNvbHZlKSB7XG4gICAgICB2YXIgX3RoaXM1ID0gdGhpcztcblxuICAgICAgdmFyIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpZnJhbWVcIik7XG4gICAgICBpZnJhbWUuc2V0QXR0cmlidXRlKFwidGVsZW1ldHJ5LWlucHV0XCIsIFwic3BhcmstY2xpZW50LWlmcmFtZVwiKTtcbiAgICAgIGlmcmFtZS5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuICAgICAgaWZyYW1lLnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuICAgICAgaWZyYW1lLnN0eWxlLmJvcmRlciA9IFwibm9uZVwiO1xuICAgICAgaWZyYW1lLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgICAgaWZyYW1lLnN0eWxlLnRvcCA9IFwiMFwiO1xuICAgICAgaWZyYW1lLnN0eWxlLmxlZnQgPSBcIjBcIjtcbiAgICAgIGlmcmFtZS5zcmMgPSBfaWZyYW1lX3NwYXJrQ2xpZW50X2lmcmFtZV9maWxlc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMV9fW1wiZGVmYXVsdFwiXTtcbiAgICAgIGlmcmFtZS5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpZnJhbWVXaW5kb3cgPSBpZnJhbWUuY29udGVudFdpbmRvdztcbiAgICAgICAgX3RoaXM1Ll9jbGllbnRBZGFwdGVyID0gbmV3IGlmcmFtZVdpbmRvdy5TcGFya0NsaWVudEFkYXB0ZXIoX3RoaXM1Ll9pbnB1dERpc2FibGVkLCBfdGhpczUuX3NlbmRUZXh0T25QYXN0ZSwgX3RoaXM1Ll9rZXlPdmVycmlkZXMpO1xuICAgICAgICBfdGhpczUuX3NwYXJrVGV4dFNlbmRlciA9IG5ldyBfY29udHJvbHNfc3BhcmtUZXh0U2VuZGVyX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV83X19bXCJkZWZhdWx0XCJdKF90aGlzNS5fY2xpZW50QWRhcHRlcik7XG5cbiAgICAgICAgX3RoaXM1Ll9jbGllbnRBZGFwdGVyLmxpc3Rlbk9uUmVhZHkoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJlc29sdmUoX3RoaXM1Ll9jbGllbnRBZGFwdGVyKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIE9iamVjdChDb21tb25fTGlicmFyaWVzX2NvbW1vbl9saWJyYXJpZXNfcHJvcG9nYXRlSWZyYW1lRXZlbnRzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV84X19bXCJkZWZhdWx0XCJdKShpZnJhbWUpO1xuICAgICAgcmV0dXJuIGlmcmFtZTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2NyZWF0ZVZlcnRpY2FsQWxpZ25lclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfY3JlYXRlVmVydGljYWxBbGlnbmVyKCkge1xuICAgICAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBkaXYuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCI7XG4gICAgICBkaXYuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG4gICAgICBkaXYuc3R5bGUudmVydGljYWxBbGlnbiA9IFwibWlkZGxlXCI7XG4gICAgICByZXR1cm4gZGl2O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0RGVmYXVsdFByb3RvY29sUG9ydFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0RGVmYXVsdFByb3RvY29sUG9ydChwcm90b2NvbE51bWJlcikge1xuICAgICAgc3dpdGNoIChwcm90b2NvbE51bWJlcikge1xuICAgICAgICBjYXNlIF9jb250cm9sc19zcGFya0NsaWVudF9wcm90b2NvbHNfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzNfX1tcImRlZmF1bHRcIl0uUmRwOlxuICAgICAgICAgIHJldHVybiAzMzg5O1xuXG4gICAgICAgIGNhc2UgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X3Byb3RvY29sc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfM19fW1wiZGVmYXVsdFwiXS5WbmM6XG4gICAgICAgICAgcmV0dXJuIDU5MDE7XG5cbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfcHJvdG9jb2xzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8zX19bXCJkZWZhdWx0XCJdLlNzaDpcbiAgICAgICAgICByZXR1cm4gMjI7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIl9zY2FsZUJ5TWF4V2lkdGhBbmRIZWlnaHRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX3NjYWxlQnlNYXhXaWR0aEFuZEhlaWdodChlbGVtZW50LCBzY2FsZSkge1xuICAgICAgdmFyIGVsZW1lbnRSZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGVsZW1lbnQuc3R5bGUubWF4V2lkdGggPSBcIlwiLmNvbmNhdChlbGVtZW50UmVjdC53aWR0aCAqIHNjYWxlIHwgMCwgXCJweFwiKTtcbiAgICAgIGVsZW1lbnQuc3R5bGUubWF4SGVpZ2h0ID0gXCJcIi5jb25jYXQoZWxlbWVudFJlY3QuaGVpZ2h0ICogc2NhbGUgfCAwLCBcInB4XCIpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfcmRwU291bmRDb25maWdUb1BsYXlTb3VuZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfcmRwU291bmRDb25maWdUb1BsYXlTb3VuZChyZHBTb3VuZENvbmZpZykge1xuICAgICAgc3dpdGNoIChyZHBTb3VuZENvbmZpZykge1xuICAgICAgICBjYXNlIF9jb250cm9sc19zcGFya0NsaWVudF9zb3VuZENvbmZpZ19lbnVtX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV82X19bXCJkZWZhdWx0XCJdLmVuYWJsZWRPblJlbW90ZU9ubHk6XG4gICAgICAgICAgcmV0dXJuIDI7XG5cbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfc291bmRDb25maWdfZW51bV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNl9fW1wiZGVmYXVsdFwiXS5lbmFibGVkTG93UXVhbGl0eTpcbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfc291bmRDb25maWdfZW51bV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNl9fW1wiZGVmYXVsdFwiXS5lbmFibGVkSGlnaFF1YWxpdHk6XG4gICAgICAgICAgcmV0dXJuIDA7XG5cbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfc291bmRDb25maWdfZW51bV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNl9fW1wiZGVmYXVsdFwiXS5kaXNhYmxlZDpcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX3JkcFNvdW5kQ29uZmlnVG9Tb3VuZFBlcmZcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX3JkcFNvdW5kQ29uZmlnVG9Tb3VuZFBlcmYocmRwU291bmRDb25maWcpIHtcbiAgICAgIHN3aXRjaCAocmRwU291bmRDb25maWcpIHtcbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfc291bmRDb25maWdfZW51bV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNl9fW1wiZGVmYXVsdFwiXS5lbmFibGVkSGlnaFF1YWxpdHk6XG4gICAgICAgICAgcmV0dXJuIDE7XG5cbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfc291bmRDb25maWdfZW51bV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNl9fW1wiZGVmYXVsdFwiXS5lbmFibGVkTG93UXVhbGl0eTpcbiAgICAgICAgY2FzZSBfY29udHJvbHNfc3BhcmtDbGllbnRfc291bmRDb25maWdfZW51bV9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNl9fW1wiZGVmYXVsdFwiXS5lbmFibGVkT25SZW1vdGVPbmx5OlxuICAgICAgICBjYXNlIF9jb250cm9sc19zcGFya0NsaWVudF9zb3VuZENvbmZpZ19lbnVtX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV82X19bXCJkZWZhdWx0XCJdLmRpc2FibGVkOlxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZWNvbm5lY3RPblJlc2l6ZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgaWYgKHRoaXMuX2NsaWVudEFkYXB0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudEFkYXB0ZXIuZ2V0UmVjb25uZWN0T25SZXNpemUoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQodmFsKSB7XG4gICAgICB0aGlzLl9yZWNvbm5lY3RPblJlc2l6ZSA9IHZhbDtcblxuICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5zZXRSZWNvbm5lY3RPblJlc2l6ZSh2YWwpO1xuXG4gICAgICB0aGlzLl9jbGllbnRBZGFwdGVyLnBhdXNlKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImhvc3RuYW1lXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2F0ZXdheTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaW5wdXREaXNhYmxlZFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2lucHV0RGlzYWJsZWQ7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uIHNldCh2YWwpIHtcbiAgICAgIHZhciBfdGhpczYgPSB0aGlzO1xuXG4gICAgICBpZiAodGhpcy5fc3BhcmtUZXh0U2VuZGVyICYmIHRoaXMuX3NwYXJrVGV4dFNlbmRlci5pc1J1bm5pbmcoKSkge1xuICAgICAgICB0aGlzLl9zZW5kVGV4dFByb21pc2UudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgX3RoaXM2LmlucHV0RGlzYWJsZWQgPSB2YWw7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5faW5wdXREaXNhYmxlZCA9IHZhbDtcblxuICAgICAgaWYgKHRoaXMuX2NsaWVudEFkYXB0ZXIpIHtcbiAgICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci5zZXRJbnB1dERpc2FibGVkKHZhbCk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImN1cnJlbnRTdGF0ZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRTdGF0ZTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gU3BhcmtDbGllbnQ7XG59KCk7XG5cbi8qIGhhcm1vbnkgZGVmYXVsdCBleHBvcnQgKi8gX193ZWJwYWNrX2V4cG9ydHNfX1tcImRlZmF1bHRcIl0gPSAoU3BhcmtDbGllbnQpO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5rZXlDb21iTWFwLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQua2V5Q29tYk1hcC5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGRlZmF1bHQgZXhwb3J0ICovIF9fd2VicGFja19leHBvcnRzX19bXCJkZWZhdWx0XCJdID0gKHtcbiAgXCJ1c1wiOiB7XG4gICAgXCJ+XCI6IFwiU2hpZnQrYFwiLFxuICAgIFwiIVwiOiBcIlNoaWZ0KzFcIixcbiAgICBcIkBcIjogXCJTaGlmdCsyXCIsXG4gICAgXCIjXCI6IFwiU2hpZnQrM1wiLFxuICAgIFwiJFwiOiBcIlNoaWZ0KzRcIixcbiAgICBcIiVcIjogXCJTaGlmdCs1XCIsXG4gICAgXCJeXCI6IFwiU2hpZnQrNlwiLFxuICAgIFwiJlwiOiBcIlNoaWZ0KzdcIixcbiAgICBcIipcIjogXCJTaGlmdCs4XCIsXG4gICAgXCIoXCI6IFwiU2hpZnQrOVwiLFxuICAgIFwiKVwiOiBcIlNoaWZ0KzBcIixcbiAgICBcIl9cIjogXCJTaGlmdCstXCIsXG4gICAgXCIrXCI6IFwiU2hpZnQrPVwiLFxuICAgIFwie1wiOiBcIlNoaWZ0K1tcIixcbiAgICBcIn1cIjogXCJTaGlmdCtdXCIsXG4gICAgXCJ8XCI6IFwiU2hpZnQrXFxcXFwiLFxuICAgIFwiOlwiOiBcIlNoaWZ0KztcIixcbiAgICBcIlxcXCJcIjogXCJTaGlmdCsnXCIsXG4gICAgXCI8XCI6IFwiU2hpZnQrLFwiLFxuICAgIFwiPlwiOiBcIlNoaWZ0Ky5cIixcbiAgICBcIj9cIjogXCJTaGlmdCsvXCIsXG4gICAgXCJBXCI6IFwiU2hpZnQrYVwiLFxuICAgIFwiQlwiOiBcIlNoaWZ0K2JcIixcbiAgICBcIkNcIjogXCJTaGlmdCtjXCIsXG4gICAgXCJEXCI6IFwiU2hpZnQrZFwiLFxuICAgIFwiRVwiOiBcIlNoaWZ0K2VcIixcbiAgICBcIkZcIjogXCJTaGlmdCtmXCIsXG4gICAgXCJHXCI6IFwiU2hpZnQrZ1wiLFxuICAgIFwiSFwiOiBcIlNoaWZ0K2hcIixcbiAgICBcIklcIjogXCJTaGlmdCtpXCIsXG4gICAgXCJKXCI6IFwiU2hpZnQralwiLFxuICAgIFwiS1wiOiBcIlNoaWZ0K2tcIixcbiAgICBcIkxcIjogXCJTaGlmdCtsXCIsXG4gICAgXCJNXCI6IFwiU2hpZnQrbVwiLFxuICAgIFwiTlwiOiBcIlNoaWZ0K25cIixcbiAgICBcIk9cIjogXCJTaGlmdCtvXCIsXG4gICAgXCJQXCI6IFwiU2hpZnQrcFwiLFxuICAgIFwiUVwiOiBcIlNoaWZ0K3FcIixcbiAgICBcIlJcIjogXCJTaGlmdCtyXCIsXG4gICAgXCJTXCI6IFwiU2hpZnQrc1wiLFxuICAgIFwiVFwiOiBcIlNoaWZ0K3RcIixcbiAgICBcIlVcIjogXCJTaGlmdCt1XCIsXG4gICAgXCJWXCI6IFwiU2hpZnQrdlwiLFxuICAgIFwiV1wiOiBcIlNoaWZ0K3dcIixcbiAgICBcIlhcIjogXCJTaGlmdCt4XCIsXG4gICAgXCJZXCI6IFwiU2hpZnQreVwiLFxuICAgIFwiWlwiOiBcIlNoaWZ0K3pcIlxuICB9LFxuICBcImZyLWJlXCI6IHtcbiAgICBcIjFcIjogXCJTaGlmdCsmXCIsXG4gICAgXCIyXCI6IFwiU2hpZnQrMlwiLFxuICAgIFwiM1wiOiBcIlNoaWZ0K1xcXCJcIixcbiAgICBcIjRcIjogXCJTaGlmdCsnXCIsXG4gICAgXCI1XCI6IFwiU2hpZnQrKFwiLFxuICAgIFwiNlwiOiBcIlNoaWZ0K8KnXCIsXG4gICAgXCI3XCI6IFwiU2hpZnQrN1wiLFxuICAgIFwiOFwiOiBcIlNoaWZ0KyFcIixcbiAgICBcIjlcIjogXCJTaGlmdCs5XCIsXG4gICAgXCIwXCI6IFwiU2hpZnQrMFwiLFxuICAgIFwiwrBcIjogXCJTaGlmdCspXCIsXG4gICAgXCJfXCI6IFwiU2hpZnQrLVwiLFxuICAgIFwiKlwiOiBcIlNoaWZ0KyRcIixcbiAgICBcIsKjXCI6IFwiU2hpZnQrXFxcXFwiLFxuICAgIFwiJVwiOiBcIlNoaWZ0KydcIixcbiAgICBcIsKzXCI6IFwiU2hpZnQrwrJcIixcbiAgICBcIj9cIjogXCJTaGlmdCssXCIsXG4gICAgXCIuXCI6IFwiU2hpZnQrO1wiLFxuICAgIFwiL1wiOiBcIlNoaWZ0KzpcIixcbiAgICBcIitcIjogXCJTaGlmdCs9XCIsXG4gICAgXCI+XCI6IFwiU2hpZnQrPFwiLFxuICAgIFwiQVwiOiBcIlNoaWZ0K2FcIixcbiAgICBcIkJcIjogXCJTaGlmdCtiXCIsXG4gICAgXCJDXCI6IFwiU2hpZnQrY1wiLFxuICAgIFwiRFwiOiBcIlNoaWZ0K2RcIixcbiAgICBcIkVcIjogXCJTaGlmdCtlXCIsXG4gICAgXCJGXCI6IFwiU2hpZnQrZlwiLFxuICAgIFwiR1wiOiBcIlNoaWZ0K2dcIixcbiAgICBcIkhcIjogXCJTaGlmdCtoXCIsXG4gICAgXCJJXCI6IFwiU2hpZnQraVwiLFxuICAgIFwiSlwiOiBcIlNoaWZ0K2pcIixcbiAgICBcIktcIjogXCJTaGlmdCtrXCIsXG4gICAgXCJMXCI6IFwiU2hpZnQrbFwiLFxuICAgIFwiTVwiOiBcIlNoaWZ0K21cIixcbiAgICBcIk5cIjogXCJTaGlmdCtuXCIsXG4gICAgXCJPXCI6IFwiU2hpZnQrb1wiLFxuICAgIFwiUFwiOiBcIlNoaWZ0K3BcIixcbiAgICBcIlFcIjogXCJTaGlmdCtxXCIsXG4gICAgXCJSXCI6IFwiU2hpZnQrclwiLFxuICAgIFwiU1wiOiBcIlNoaWZ0K3NcIixcbiAgICBcIlRcIjogXCJTaGlmdCt0XCIsXG4gICAgXCJVXCI6IFwiU2hpZnQrdVwiLFxuICAgIFwiVlwiOiBcIlNoaWZ0K3ZcIixcbiAgICBcIldcIjogXCJTaGlmdCt3XCIsXG4gICAgXCJYXCI6IFwiU2hpZnQreFwiLFxuICAgIFwiWVwiOiBcIlNoaWZ0K3lcIixcbiAgICBcIlpcIjogXCJTaGlmdCt6XCIsXG4gICAgXCJ8XCI6IFwiQWx0R3IrJlwiLFxuICAgIFwiQFwiOiBcIkFsdEdyKzJcIixcbiAgICBcIiNcIjogXCJBbHRHcitcXFwiXCIsXG4gICAgXCJ7XCI6IFwiQWx0R3IrOVwiLFxuICAgIFwifVwiOiBcIkFsdEdyKzBcIixcbiAgICBcIuKCrFwiOiBcIkFsdEdyK2VcIixcbiAgICBcIltcIjogXCJBbHRHcitbXCIsXG4gICAgLy8gZG9lc24ndCB3b3JrIHdpdGggVk1XYXJlIFZOQ1xuICAgIFwiXVwiOiBcIkFsdEdyK11cIixcbiAgICBcIn5cIjogW1wiQWx0R3IrPVwiLCBcIlNwYWNlXCJdLFxuICAgIFwiYFwiOiBbXCJBbHRHcitcXFxcXCIsIFwiU3BhY2VcIl0sXG4gICAgLy8gZG9lc24ndCB3b3JrIHdpdGggVk1XYXJlIFZOQ1xuICAgIFwiwrRcIjogW1wiQWx0R3IrYFwiLCBcIlNwYWNlXCJdIC8vIGRvZXNuJ3Qgd29yayB3aXRoIFZNV2FyZSBWTkNcblxuICB9XG59KTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQua2V5Ym9hcmRzLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5rZXlib2FyZHMuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGRlZmF1bHQgZXhwb3J0ICovIF9fd2VicGFja19leHBvcnRzX19bXCJkZWZhdWx0XCJdID0gKHtcbiAgXCJVbmljb2RlIChVbml2ZXJzYWwgUVdFUlRZKVwiOiA5OTk5OSxcbiAgXCJVbmljb2RlIChVbml2ZXJzYWwgQVpFUlRZKVwiOiA5OTk5OCxcbiAgXCJVbmljb2RlIChVbml2ZXJzYWwgUVdFUlRaKVwiOiA5OTk5NyxcbiAgXCJFbmdsaXNoIChVbml0ZWQgU3RhdGVzKVwiOiAxMDMzLFxuICBcIkVuZ2xpc2ggKFVuaXRlZCBLaW5nZG9tKVwiOiAyMDU3LFxuICBcIkVuZ2xpc2ggKENhbmFkaWFuIEZyZW5jaClcIjogNDEwNSxcbiAgXCJBcmFiaWMgKFNhdWRpIEFyYWJpYSlcIjogMTAyNSxcbiAgXCJDaGluZXNlIChTaW1wbGlmaWVkKVwiOiAyMDUyLFxuICBcIkNoaW5lc2UgKFRyYWRpdGlvbmFsKVwiOiAxMDI4LFxuICBcIkR1dGNoIChCZWxnaXVtKVwiOiAyMDY3LFxuICBcIkR1dGNoIChOZXRoZXJsYW5kcylcIjogMTA0MyxcbiAgXCJGcmVuY2ggKEJlbGdpdW0pXCI6IDIwNjAsXG4gIFwiRnJlbmNoIChDYW5hZGEgTGVnYWN5KVwiOiAzMDg0LFxuICBcIkZyZW5jaCAoRnJhbmNlKVwiOiAxMDM2LFxuICBcIkZyZW5jaCAoU3dpdHplcmxhbmQpXCI6IDQxMDgsXG4gIFwiR2VybWFuIChHZXJtYW55KVwiOiAxMDMxLFxuICBcIkdlcm1hbiAoU3dpdHplcmxhbmQpXCI6IDIwNTUsXG4gIFwiR2VybWFuIChJQk0pXCI6IDY2NTY3LFxuICBcIkhlYnJld1wiOiAxMDM3LFxuICBcIkljZWxhbmRpY1wiOiAxMDM5LFxuICBcIklyaXNoIChJcmVsYW5kKVwiOiA2MTUzLFxuICBcIkl0YWxpYW4gKEl0YWx5KVwiOiAxMDQwLFxuICBcIkl0YWxpYW4gKDE0MikgKEl0YWx5KVwiOiA2NjU3NixcbiAgXCJKYXBhbmVzZSAoSmFwYW4pXCI6IDM3NTgxNjI5NjEsXG4gIFwiS29yZWFuIChLb3JlYSlcIjogMzc1ODE2Mjk2MixcbiAgXCJOb3J3ZWdpYW4gKEJva21hbClcIjogMTA0NCxcbiAgXCJOb3J3ZWdpYW4gd2l0aCBTYW1pXCI6IDEwODMsXG4gIFwiUG9ydHVndWVzZVwiOiAyMDcwLFxuICBcIlBvcnR1Z3Vlc2UgKEJyYXppbCBBQk5UKVwiOiAxMDQ2LFxuICBcIlBvcnR1Z3Vlc2UgKEJyYXppbCBBQk5UMilcIjogNjY1ODIsXG4gIFwiUnVzc2lhbiAoUnVzc2lhKVwiOiAxMDQ5LFxuICBcIlNwYW5pc2ggKEludGVybmF0aW9uYWwgU29ydClcIjogMTAzNCxcbiAgXCJTcGFuaXNoIChWYXJpYXRpb24pXCI6IDY2NTcwLFxuICBcIlNwYW5pc2ggKE1leGljby9MYXRpbiBBbWVyaWNhbilcIjogMjA1OCxcbiAgXCJTd2VkaXNoIChTd2VkZW4pXCI6IDEwNTMsXG4gIFwiVHVya2lzaFwiOiAxMDU1XG59KTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQubmF2aWdhdGlvbkFjdGlvbi5lbnVtLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5uYXZpZ2F0aW9uQWN0aW9uLmVudW0uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGRlZmF1bHQgZXhwb3J0ICovIF9fd2VicGFja19leHBvcnRzX19bXCJkZWZhdWx0XCJdID0gKHtcbiAgaG9tZTogMSxcbiAgLy8gaSBzdGFydGVkIGF0IDEgYmVjYXVzZSBJIGRvbnQgd2FudCB0aGUgdmFsdWUgb2YgMCB3aGljaCBpcyBmYWxzZXlcbiAgYmFjazogMixcbiAgZm9yd2FyZDogM1xufSk7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2NvbnRyb2xzLnNwYXJrQ2xpZW50LnByb3RvY29scy5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQucHJvdG9jb2xzLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBleHBvcnRzIHByb3ZpZGVkOiBkZWZhdWx0ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBfX3dlYnBhY2tfZXhwb3J0c19fLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yKF9fd2VicGFja19leHBvcnRzX18pO1xudmFyIFNwYXJrUHJvdG9jb2xzID0ge1xuICBSZHA6IDAsXG4gIFZuYzogMSxcbiAgU3NoOiAyLFxuICBUZWxuZXQ6IDMsXG4gIFdlYkNvbnNvbGU6IDRcbn07XG4vKiBoYXJtb255IGRlZmF1bHQgZXhwb3J0ICovIF9fd2VicGFja19leHBvcnRzX19bXCJkZWZhdWx0XCJdID0gKFNwYXJrUHJvdG9jb2xzKTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQuc291bmRDb25maWcuZW51bS5qc1wiOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2NvbnRyb2xzLnNwYXJrQ2xpZW50LnNvdW5kQ29uZmlnLmVudW0uanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBleHBvcnRzIHByb3ZpZGVkOiBkZWZhdWx0ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBfX3dlYnBhY2tfZXhwb3J0c19fLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yKF9fd2VicGFja19leHBvcnRzX18pO1xuLyogaGFybW9ueSBkZWZhdWx0IGV4cG9ydCAqLyBfX3dlYnBhY2tfZXhwb3J0c19fW1wiZGVmYXVsdFwiXSA9ICh7XG4gIGRpc2FibGVkOiBcIkRpc2FibGVkXCIsXG4gIGVuYWJsZWRPblJlbW90ZU9ubHk6IFwiRW5hYmxlZE9uUmVtb3RlT25seVwiLFxuICBlbmFibGVkTG93UXVhbGl0eTogXCJFbmFibGVkTG93UXVhbGl0eVwiLFxuICBlbmFibGVkSGlnaFF1YWxpdHk6IFwiRW5hYmxlZEhpZ2hRdWFsaXR5XCJcbn0pO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5zdGF0ZXMuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIC4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2NvbnRyb2xzLnNwYXJrQ2xpZW50LnN0YXRlcy5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgZXhwb3J0cyBwcm92aWRlZDogZGVmYXVsdCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgX193ZWJwYWNrX2V4cG9ydHNfXywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcbl9fd2VicGFja19yZXF1aXJlX18ucihfX3dlYnBhY2tfZXhwb3J0c19fKTtcbnZhciBTcGFya1N0YXRlcyA9IHtcbiAgSURMRTogMCxcbiAgQ09OTkVDVElORzogMSxcbiAgV0FJVElORzogMixcbiAgQ09OTkVDVEVEOiAzLFxuICBESVNDT05ORUNUSU5HOiA0LFxuICBESVNDT05ORUNURUQ6IDUsXG4gIENPTk5FQ1RFREFORExPR0dFRElOOiA2XG59O1xuLyogaGFybW9ueSBkZWZhdWx0IGV4cG9ydCAqLyBfX3dlYnBhY2tfZXhwb3J0c19fW1wiZGVmYXVsdFwiXSA9IChTcGFya1N0YXRlcyk7XG5cbi8qKiovIH0pLFxuXG4vKioqLyBcIi4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2NvbnRyb2xzLnNwYXJrRXJyb3IuanNcIjpcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0Vycm9yLmpzICoqKiFcbiAgXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgZXhwb3J0cyBwcm92aWRlZDogZGVmYXVsdCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgX193ZWJwYWNrX2V4cG9ydHNfXywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcbl9fd2VicGFja19yZXF1aXJlX18ucihfX3dlYnBhY2tfZXhwb3J0c19fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBleHBvcnRzX2xvYWRlcl93aW5kb3dfZ2V0U3BhcmtJMThuX2ltcG9ydHNfbG9hZGVyX3dpbmRvd3NfdGhpc19leHRlcm5hbHNfU3BhcmtNb2R1bGVfc3RyaW5nc19lbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZXhwb3J0cy1sb2FkZXI/d2luZG93LmdldFNwYXJrSTE4biFpbXBvcnRzLWxvYWRlcj93aW5kb3dzPT50aGlzIS4uLy4uLy4uL2V4dGVybmFscy9TcGFya01vZHVsZS9zdHJpbmdzLWVuICovIFwiLi9ub2RlX21vZHVsZXMvZXhwb3J0cy1sb2FkZXIvaW5kZXguanM/d2luZG93LmdldFNwYXJrSTE4biEuL25vZGVfbW9kdWxlcy9pbXBvcnRzLWxvYWRlci9pbmRleC5qcz93aW5kb3dzPT50aGlzIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3N0cmluZ3MtZW4uanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZXhwb3J0c19sb2FkZXJfd2luZG93X2dldFNwYXJrSTE4bl9pbXBvcnRzX2xvYWRlcl93aW5kb3dzX3RoaXNfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3N0cmluZ3NfZW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzBfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihleHBvcnRzX2xvYWRlcl93aW5kb3dfZ2V0U3BhcmtJMThuX2ltcG9ydHNfbG9hZGVyX3dpbmRvd3NfdGhpc19leHRlcm5hbHNfU3BhcmtNb2R1bGVfc3RyaW5nc19lbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fKTtcbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH1cblxuZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH1cblxuXG5cbnZhciBTcGFya0Vycm9yID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gU3BhcmtFcnJvcihvbkVycm9yQXJnKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNwYXJrRXJyb3IpO1xuXG4gICAgdGhpcy5fb25FcnJvckFyZyA9IG9uRXJyb3JBcmc7XG4gICAgdGhpcy5zcGFya1N0cmluZ3MgPSBleHBvcnRzX2xvYWRlcl93aW5kb3dfZ2V0U3BhcmtJMThuX2ltcG9ydHNfbG9hZGVyX3dpbmRvd3NfdGhpc19leHRlcm5hbHNfU3BhcmtNb2R1bGVfc3RyaW5nc19lbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fX2RlZmF1bHQoKSgpO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFNwYXJrRXJyb3IsIFt7XG4gICAga2V5OiBcInRvTG9nU3RyaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRvTG9nU3RyaW5nKCkge1xuICAgICAgdmFyIGFyZyA9IHRoaXMuX29uRXJyb3JBcmc7XG5cbiAgICAgIGlmIChhcmcgJiYgYXJnLm5hbWUgJiYgYXJnLm1lc3NhZ2UgIT0gbnVsbCkge1xuICAgICAgICB2YXIgdW50cmFuc2xhdGVkTWVzc2FnZSA9IHRoaXMuc3BhcmtTdHJpbmdzLmVycm9yQ29kZVthcmcubmFtZV0gfHwgdGhpcy5zcGFya1N0cmluZ3MuZXJyb3JDb2RlW1wiU1wiICsgYXJnLm5hbWVdO1xuXG4gICAgICAgIGlmICghdW50cmFuc2xhdGVkTWVzc2FnZSB8fCB1bnRyYW5zbGF0ZWRNZXNzYWdlID09PSBhcmcubWVzc2FnZSkge1xuICAgICAgICAgIHJldHVybiBcIlN0YXR1cyhcIi5jb25jYXQoYXJnLm5hbWUsIFwiLCBcIikuY29uY2F0KGFyZy5tZXNzYWdlLCBcIilcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFwiU3RhdHVzKFwiLmNvbmNhdChhcmcubmFtZSwgXCIsIFwiKS5jb25jYXQoYXJnLm1lc3NhZ2UsIFwiLCBcIikuY29uY2F0KHVudHJhbnNsYXRlZE1lc3NhZ2UsIFwiKVwiKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybiBhcmc7XG4gICAgICB9IGVsc2UgaWYgKGFyZykge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzaG91bGRSZWNvbm5lY3RcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2hvdWxkUmVjb25uZWN0KCkge1xuICAgICAgdmFyIGVycm9yQ29kZSA9IHRoaXMuX29uRXJyb3JBcmcgJiYgdGhpcy5fb25FcnJvckFyZy5uYW1lO1xuICAgICAgcmV0dXJuICFlcnJvckNvZGUgfHwgIXByZXZlbnRBdXRvUmVjb25uZWN0RXJyb3JDb2Rlc1tlcnJvckNvZGVdO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ0b0NsaWVudFN0cmluZ1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB0b0NsaWVudFN0cmluZygpIHtcbiAgICAgIHZhciBhcmcgPSB0aGlzLl9vbkVycm9yQXJnO1xuXG4gICAgICBpZiAoYXJnICYmIGFyZy5tZXNzYWdlKSB7XG4gICAgICAgIHJldHVybiBhcmcubWVzc2FnZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgfVxuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBTcGFya0Vycm9yO1xufSgpO1xuXG52YXIgcHJldmVudEF1dG9SZWNvbm5lY3RFcnJvckNvZGVzID0ge1xuICAnNSc6ICdBbm90aGVyIHVzZXIgY29ubmVjdGVkIHRvIHRoZSBzZXJ2ZXIsIGZvcmNpbmcgdGhlIGRpc2Nvbm5lY3Rpb24gb2YgdGhlIGN1cnJlbnQgY29ubmVjdGlvbi4nLFxuICAnOSc6ICdUaGUgdXNlciBjYW5ub3QgY29ubmVjdCB0byB0aGUgc2VydmVyIGR1ZSB0byBpbnN1ZmZpY2llbnQgYWNjZXNzIHByaXZpbGVnZXMuJyxcbiAgJ0MnOiAnVGhlIGRpc2Nvbm5lY3Rpb24gd2FzIGluaXRpYXRlZCBieSB0aGUgdXNlciBsb2dnaW5nIG9mZiBoaXMgb3IgaGVyIHNlc3Npb24gb24gdGhlIHNlcnZlci4nXG59O1xuLyogaGFybW9ueSBkZWZhdWx0IGV4cG9ydCAqLyBfX3dlYnBhY2tfZXhwb3J0c19fW1wiZGVmYXVsdFwiXSA9IChTcGFya0Vycm9yKTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtUZXh0U2VuZGVyLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya1RleHRTZW5kZXIuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2tleUNvbWJNYXBfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzBfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vY29udHJvbHMuc3BhcmtDbGllbnQua2V5Q29tYk1hcCAqLyBcIi4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2NvbnRyb2xzLnNwYXJrQ2xpZW50LmtleUNvbWJNYXAuanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2NvbnN0YW50c19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9jb250cm9scy5zcGFya0NsaWVudC5jb25zdGFudHMgKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9jb250cm9scy5zcGFya0NsaWVudC5jb25zdGFudHMuanNcIik7XG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9XG5cbmZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9XG5cblxuXG52YXIgbWF4VGV4dFNpemUgPSAxMDI0O1xudmFyIGxvbmdUZXh0VGhyZXNob2xkID0gMTAwO1xudmFyIGxvbmdUZXh0V2FpdE1zID0gNTAwO1xudmFyIHNob3J0VGV4dFdhaXRNcyA9IDE7XG5cbnZhciBTcGFya1RleHRTZW5kZXIgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTcGFya1RleHRTZW5kZXIoY2xpZW50QWRhcHRlcikge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTcGFya1RleHRTZW5kZXIpO1xuXG4gICAgdGhpcy5fY2xpZW50QWRhcHRlciA9IGNsaWVudEFkYXB0ZXI7XG4gICAgdGhpcy5fcnVubmluZyA9IGZhbHNlO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFNwYXJrVGV4dFNlbmRlciwgW3tcbiAgICBrZXk6IFwic2VuZFRleHRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2VuZFRleHQodGV4dCwga2V5Ym9hcmQpIHtcbiAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgIHRoaXMuX3J1bm5pbmcgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5ldyBTdGF0ZWZ1bFNwYXJrVGV4dFNlbmRlcih0aGlzLl9jbGllbnRBZGFwdGVyLCB0ZXh0LCBrZXlib2FyZCkuc2VuZFRleHQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3RoaXMuX3J1bm5pbmcgPSBmYWxzZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJpc1J1bm5pbmdcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaXNSdW5uaW5nKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3J1bm5pbmc7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFNwYXJrVGV4dFNlbmRlcjtcbn0oKTtcblxudmFyIFN0YXRlZnVsU3BhcmtUZXh0U2VuZGVyID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gU3RhdGVmdWxTcGFya1RleHRTZW5kZXIoY2xpZW50QWRhcHRlciwgdGV4dCwga2V5Ym9hcmQpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU3RhdGVmdWxTcGFya1RleHRTZW5kZXIpO1xuXG4gICAgdGhpcy5fY2xpZW50QWRhcHRlciA9IGNsaWVudEFkYXB0ZXI7XG4gICAgdGhpcy5fdGV4dCA9IHRleHQ7XG4gICAgdGhpcy5fa2V5Ym9hcmQgPSBrZXlib2FyZCB8fCBfY29udHJvbHNfc3BhcmtDbGllbnRfY29uc3RhbnRzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xX19bXCJkZWZhdWx0XCJdLkRlZmF1bHRWbmNLZXlib2FyZDtcbiAgICB0aGlzLl9vcmRlckluZGV4ID0gMDtcbiAgICB0aGlzLl9vcmRlcnMgPSBbXTtcbiAgICB0aGlzLl90ZXh0QWNjdW0gPSBcIlwiO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKFN0YXRlZnVsU3BhcmtUZXh0U2VuZGVyLCBbe1xuICAgIGtleTogXCJzZW5kVGV4dFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZW5kVGV4dCgpIHtcbiAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgX3RoaXMyLl9maWxsT3JkZXJzQXJyYXkoKTtcblxuICAgICAgICBfdGhpczIuX2V4ZWNPcmRlckluRGVsYXkocmVzb2x2ZSk7XG4gICAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7Ly8gaWdub3JlIGV4Y2VwdGlvbnNcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfZmlsbE9yZGVyc0FycmF5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9maWxsT3JkZXJzQXJyYXkoKSB7XG4gICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl90ZXh0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBjID0gdGhpcy5fdGV4dFtpXTtcblxuICAgICAgICB2YXIga2V5Q29tYiA9IHRoaXMuX3RvS2V5Q29tYihjKTtcblxuICAgICAgICBpZiAoYyA9PT0gXCJcXG5cIikge1xuICAgICAgICAgIHRoaXMuX2ZsdXNoVGV4dEFjY3VtKCk7XG5cbiAgICAgICAgICB0aGlzLl9vcmRlcnMucHVzaCh7XG4gICAgICAgICAgICBrZXlDb21iOiB0cnVlLFxuICAgICAgICAgICAgY29udGVudDogXCJFbnRlclwiXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5Q29tYikge1xuICAgICAgICAgIHRoaXMuX2ZsdXNoVGV4dEFjY3VtKCk7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGtleUNvbWIgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX29yZGVycy5wdXNoKHtcbiAgICAgICAgICAgICAga2V5Q29tYjogdHJ1ZSxcbiAgICAgICAgICAgICAgY29udGVudDoga2V5Q29tYlxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGtleUNvbWIuZm9yRWFjaChmdW5jdGlvbiAoa2MpIHtcbiAgICAgICAgICAgICAgX3RoaXMzLl9vcmRlcnMucHVzaCh7XG4gICAgICAgICAgICAgICAga2V5Q29tYjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjb250ZW50OiBrY1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl90ZXh0QWNjdW0gKz0gYztcblxuICAgICAgICAgIGlmICh0aGlzLl90ZXh0QWNjdW0ubGVuZ3RoID09PSBtYXhUZXh0U2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5fZmx1c2hUZXh0QWNjdW0oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5fZmx1c2hUZXh0QWNjdW0oKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2ZsdXNoVGV4dEFjY3VtXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9mbHVzaFRleHRBY2N1bSgpIHtcbiAgICAgIGlmICh0aGlzLl90ZXh0QWNjdW0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fb3JkZXJzLnB1c2goe1xuICAgICAgICBrZXlDb21iOiBmYWxzZSxcbiAgICAgICAgY29udGVudDogdGhpcy5fdGV4dEFjY3VtXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5fdGV4dEFjY3VtID0gXCJcIjtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2V4ZWNPcmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZXhlY09yZGVyKGNhbGxiYWNrKSB7XG4gICAgICB2YXIgb3JkZXIgPSB0aGlzLl9vcmRlcnNbdGhpcy5fb3JkZXJJbmRleF07XG5cbiAgICAgIGlmIChvcmRlci5rZXlDb21iKSB7XG4gICAgICAgIHRoaXMuX2NsaWVudEFkYXB0ZXIud3JpdGVLZXlDb21iKG9yZGVyLmNvbnRlbnQsIDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fY2xpZW50QWRhcHRlci53cml0ZVRleHQob3JkZXIuY29udGVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9vcmRlckluZGV4IDwgdGhpcy5fb3JkZXJzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgdGhpcy5fb3JkZXJJbmRleCArPSAxO1xuXG4gICAgICAgIGlmIChvcmRlci5jb250ZW50Lmxlbmd0aCA+IGxvbmdUZXh0VGhyZXNob2xkKSB7XG4gICAgICAgICAgdGhpcy5fZXhlY09yZGVySW5EZWxheShjYWxsYmFjaywgbG9uZ1RleHRXYWl0TXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX2V4ZWNPcmRlckluRGVsYXkoY2FsbGJhY2ssIHNob3J0VGV4dFdhaXRNcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiX2V4ZWNPcmRlckluRGVsYXlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2V4ZWNPcmRlckluRGVsYXkoY2FsbGJhY2ssIGRlbGF5TXMpIHtcbiAgICAgIHZhciBfdGhpczQgPSB0aGlzO1xuXG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBfdGhpczQuX2V4ZWNPcmRlcihjYWxsYmFjayk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgZXhjZXB0aW9uc1xuICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIGRlbGF5TXMpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfdG9LZXlDb21iXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF90b0tleUNvbWIoYykge1xuICAgICAgdmFyIG1hcCA9IF9jb250cm9sc19zcGFya0NsaWVudF9rZXlDb21iTWFwX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX19bXCJkZWZhdWx0XCJdW3RoaXMuX2tleWJvYXJkXSB8fCBfY29udHJvbHNfc3BhcmtDbGllbnRfa2V5Q29tYk1hcF9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fW1wiZGVmYXVsdFwiXVtfY29udHJvbHNfc3BhcmtDbGllbnRfY29uc3RhbnRzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xX19bXCJkZWZhdWx0XCJdLkRlZmF1bHRWbmNLZXlib2FyZF07XG4gICAgICByZXR1cm4gbWFwW2NdO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBTdGF0ZWZ1bFNwYXJrVGV4dFNlbmRlcjtcbn0oKTtcblxuLyogaGFybW9ueSBkZWZhdWx0IGV4cG9ydCAqLyBfX3dlYnBhY2tfZXhwb3J0c19fW1wiZGVmYXVsdFwiXSA9IChTcGFya1RleHRTZW5kZXIpO1xuXG4vKioqLyB9KSxcblxuLyoqKi8gXCIuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9pZnJhbWUvc3BhcmtDbGllbnQuaWZyYW1lLmZpbGVzLmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaWZyYW1lL3NwYXJrQ2xpZW50LmlmcmFtZS5maWxlcy5qcyAqKiohXG4gIFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IGRlZmF1bHQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9zcGFya0NsaWVudF9pZnJhbWVfaHRtbF9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9zcGFya0NsaWVudC5pZnJhbWUuaHRtbCAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2lmcmFtZS9zcGFya0NsaWVudC5pZnJhbWUuaHRtbFwiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X3NwYXJrQ2xpZW50X2lmcmFtZV9odG1sX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9zcGFya0NsaWVudF9pZnJhbWVfaHRtbF9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X3NwYXJrQ2xpZW50X2lmcmFtZV9hZGFwdGVyX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL3NwYXJrQ2xpZW50LmlmcmFtZS5hZGFwdGVyICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaWZyYW1lL3NwYXJrQ2xpZW50LmlmcmFtZS5hZGFwdGVyLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfc3BhcmtDbGllbnRfaWZyYW1lX2FkYXB0ZXJfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzFfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X3NwYXJrQ2xpZW50X2lmcmFtZV9hZGFwdGVyX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xX18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfc3BhcmtDbGllbnRfaWZyYW1lX3dta3NLZXlDb2RlTWFwX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL3NwYXJrQ2xpZW50LmlmcmFtZS53bWtzS2V5Q29kZU1hcCAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2lmcmFtZS9zcGFya0NsaWVudC5pZnJhbWUud21rc0tleUNvZGVNYXAuanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9zcGFya0NsaWVudF9pZnJhbWVfd21rc0tleUNvZGVNYXBfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzJfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X3NwYXJrQ2xpZW50X2lmcmFtZV93bWtzS2V5Q29kZU1hcF9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMl9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X3NwYXJrQ2xpZW50X2lmcmFtZV93bWtzVnNjYW5Db2RlTWFwX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8zX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL3NwYXJrQ2xpZW50LmlmcmFtZS53bWtzVnNjYW5Db2RlTWFwICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaWZyYW1lL3NwYXJrQ2xpZW50LmlmcmFtZS53bWtzVnNjYW5Db2RlTWFwLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfc3BhcmtDbGllbnRfaWZyYW1lX3dta3NWc2NhbkNvZGVNYXBfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzNfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X3NwYXJrQ2xpZW50X2lmcmFtZV93bWtzVnNjYW5Db2RlTWFwX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8zX18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2hpNV9jc3NfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzRfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGZpbGUtbG9hZGVyP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4uLy4uLy4uLy4uL2V4dGVybmFscy9TcGFya01vZHVsZS9oaTUuY3NzICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGk1LmNzc1wiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9oaTVfY3NzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV80X19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaGk1X2Nzc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNF9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9yZHBfY3NzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV81X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmRwLmNzcyAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JkcC5jc3NcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfcmRwX2Nzc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNV9fX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX193ZWJwYWNrX3JlcXVpcmVfXy5uKGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3JkcF9jc3NfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzVfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2ZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2tiZF9wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzZfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohICFmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUva2JkLnBuZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2tiZC5wbmdcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2ZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2tiZF9wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzZfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfa2JkX3BuZ19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfNl9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfY2xvdWRfcG5nX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV83X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAhZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi4vLi4vLi4vLi4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2Nsb3VkLnBuZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2Nsb3VkLnBuZ1wiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfY2xvdWRfcG5nX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV83X19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oX2ZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2Nsb3VkX3BuZ19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfN19fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaW5mb19wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzhfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohICFmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaW5mby5wbmcgKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9pbmZvLnBuZ1wiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaW5mb19wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzhfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaW5mb19wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzhfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2ZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2hhbmRsZV9wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzlfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohICFmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGFuZGxlLnBuZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2hhbmRsZS5wbmdcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2ZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2hhbmRsZV9wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzlfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaGFuZGxlX3BuZ19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfOV9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBfZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfZGVsX3BuZ19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMTBfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohICFmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvZGVsLnBuZyAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2RlbC5wbmdcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2ZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2RlbF9wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzEwX19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oX2ZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2RlbF9wbmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzEwX18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3Jlc291cmNlX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xMV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi4vLi4vLi4vLi4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3Jlc291cmNlICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmVzb3VyY2UuanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfcmVzb3VyY2VfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzExX19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfcmVzb3VyY2VfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzExX18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3N0cmluZ3NfZW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzEyX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvc3RyaW5ncy1lbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3N0cmluZ3MtZW4uanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfc3RyaW5nc19lbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMTJfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9zdHJpbmdzX2VuX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xMl9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9hcHBjZmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzEzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvYXBwY2ZnICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvYXBwY2ZnLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2FwcGNmZ19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMTNfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9hcHBjZmdfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzEzX18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2hpNWNvcmVfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xNF9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi4vLi4vLi4vLi4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2hpNWNvcmVfbWluICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGk1Y29yZV9taW4uanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaGk1Y29yZV9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzE0X19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaGk1Y29yZV9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzE0X18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX2hpNV9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzE1X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvaGk1X21pbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL2hpNV9taW4uanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfaGk1X21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMTVfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9oaTVfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xNV9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9zdXJmYWNlX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMTZfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGZpbGUtbG9hZGVyP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4uLy4uLy4uLy4uL2V4dGVybmFscy9TcGFya01vZHVsZS9zdXJmYWNlX21pbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3N1cmZhY2VfbWluLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3N1cmZhY2VfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xNl9fX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX193ZWJwYWNrX3JlcXVpcmVfXy5uKGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3N1cmZhY2VfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xNl9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9yZHBjb3JlX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMTdfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGZpbGUtbG9hZGVyP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4uLy4uLy4uLy4uL2V4dGVybmFscy9TcGFya01vZHVsZS9yZHBjb3JlX21pbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JkcGNvcmVfbWluLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3JkcGNvcmVfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xN19fX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX193ZWJwYWNrX3JlcXVpcmVfXy5uKGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3JkcGNvcmVfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xN19fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9yZHBfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xOF9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi4vLi4vLi4vLi4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JkcF9taW4gKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9yZHBfbWluLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3JkcF9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzE4X19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfcmRwX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMThfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfcmRwd29ya2VyX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMTlfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGZpbGUtbG9hZGVyP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4uLy4uLy4uLy4uL2V4dGVybmFscy9TcGFya01vZHVsZS9yZHB3b3JrZXJfbWluICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmRwd29ya2VyX21pbi5qc1wiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9yZHB3b3JrZXJfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xOV9fX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX193ZWJwYWNrX3JlcXVpcmVfXy5uKGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3JkcHdvcmtlcl9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzE5X18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3NzaF9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzIwX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvc3NoX21pbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3NzaF9taW4uanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfc3NoX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjBfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9zc2hfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yMF9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV92bmNfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yMV9fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi4vLi4vLi4vLi4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3ZuY19taW4gKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS92bmNfbWluLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3ZuY19taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzIxX19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfdm5jX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjFfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfdm5jdXRpbF9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzIyX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm5jdXRpbF9taW4gKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS92bmN1dGlsX21pbi5qc1wiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV92bmN1dGlsX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjJfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV92bmN1dGlsX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjJfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfdm13YXJlX3dta3NfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yM19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi4vLi4vLi4vLi4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3Ztd2FyZS93bWtzLm1pbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3Ztd2FyZS93bWtzLm1pbi5qc1wiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV92bXdhcmVfd21rc19taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzIzX19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfdm13YXJlX3dta3NfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yM19fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV92bXdhcmVfanF1ZXJ5XzNfNF8xX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjRfXyA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIGZpbGUtbG9hZGVyP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4uLy4uLy4uLy4uL2V4dGVybmFscy9TcGFya01vZHVsZS92bXdhcmUvanF1ZXJ5LTMuNC4xLm1pbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3Ztd2FyZS9qcXVlcnktMy40LjEubWluLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3Ztd2FyZV9qcXVlcnlfM180XzFfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yNF9fX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX193ZWJwYWNrX3JlcXVpcmVfXy5uKGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3Ztd2FyZV9qcXVlcnlfM180XzFfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yNF9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV92bXdhcmVfanF1ZXJ5X3VpXzFfMTJfMF9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzI1X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm13YXJlL2pxdWVyeS11aS0xLjEyLjAubWluICovIFwiLi9ub2RlX21vZHVsZXMvZmlsZS1sb2FkZXIvZGlzdC9janMuanM/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvdm13YXJlL2pxdWVyeS11aS0xLjEyLjAubWluLmpzXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3Ztd2FyZV9qcXVlcnlfdWlfMV8xMl8wX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjVfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV92bXdhcmVfanF1ZXJ5X3VpXzFfMTJfMF9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzI1X18pO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3JlY29yZGluZ19taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzI2X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvcmVjb3JkaW5nX21pbiAqLyBcIi4vbm9kZV9tb2R1bGVzL2ZpbGUtbG9hZGVyL2Rpc3QvY2pzLmpzP25hbWU9c3BhcmtJZnJhbWUvW25hbWVdLltleHRdIS4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3JlY29yZGluZ19taW4uanNcIik7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfcmVjb3JkaW5nX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjZfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9yZWNvcmRpbmdfbWluX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yNl9fKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9wbHVnaW5fc3dmX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yN19fID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgZmlsZS1sb2FkZXI/bmFtZT1zcGFya0lmcmFtZS9bbmFtZV0uW2V4dF0hLi4vLi4vLi4vLi4vZXh0ZXJuYWxzL1NwYXJrTW9kdWxlL3BsdWdpbi5zd2YgKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9wbHVnaW4uc3dmXCIpO1xuLyogaGFybW9ueSBpbXBvcnQgKi8gdmFyIGZpbGVfbG9hZGVyX25hbWVfc3BhcmtJZnJhbWVfbmFtZV9leHRfZXh0ZXJuYWxzX1NwYXJrTW9kdWxlX3BsdWdpbl9zd2ZfX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzI3X19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9fX3dlYnBhY2tfcmVxdWlyZV9fLm4oZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfcGx1Z2luX3N3Zl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjdfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgZmlsZV9sb2FkZXJfbmFtZV9zcGFya0lmcmFtZV9uYW1lX2V4dF9leHRlcm5hbHNfU3BhcmtNb2R1bGVfYXVkaW9yZWNvcmRlcl9taW5fX1dFQlBBQ0tfSU1QT1JURURfTU9EVUxFXzI4X18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBmaWxlLWxvYWRlcj9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuLi8uLi8uLi8uLi9leHRlcm5hbHMvU3BhcmtNb2R1bGUvYXVkaW9yZWNvcmRlcl9taW4gKi8gXCIuL25vZGVfbW9kdWxlcy9maWxlLWxvYWRlci9kaXN0L2Nqcy5qcz9uYW1lPXNwYXJrSWZyYW1lL1tuYW1lXS5bZXh0XSEuL2V4dGVybmFscy9TcGFya01vZHVsZS9hdWRpb3JlY29yZGVyX21pbi5qc1wiKTtcbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9hdWRpb3JlY29yZGVyX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjhfX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19fd2VicGFja19yZXF1aXJlX18ubihmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X2V4dGVybmFsc19TcGFya01vZHVsZV9hdWRpb3JlY29yZGVyX21pbl9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMjhfXyk7XG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuLyogaGFybW9ueSBkZWZhdWx0IGV4cG9ydCAqLyBfX3dlYnBhY2tfZXhwb3J0c19fW1wiZGVmYXVsdFwiXSA9IChmaWxlX2xvYWRlcl9uYW1lX3NwYXJrSWZyYW1lX25hbWVfZXh0X3NwYXJrQ2xpZW50X2lmcmFtZV9odG1sX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX19fZGVmYXVsdC5hKTtcblxuLyoqKi8gfSksXG5cbi8qKiovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvaW5kZXguZGVwbG95LmpzXCI6XG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiEqXFxcbiAgISoqKiAuL3NyYy9Db250cm9scy9TcGFya0NsaWVudC9pbmRleC5kZXBsb3kuanMgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyohIGV4cG9ydHMgcHJvdmlkZWQ6IFNwYXJrQ2xpZW50LCBTcGFya0tleWJvYXJkcywgU3BhcmtDb25zdGFudHMgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIF9fd2VicGFja19leHBvcnRzX18sIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIoX193ZWJwYWNrX2V4cG9ydHNfXyk7XG4vKiBoYXJtb255IGltcG9ydCAqLyB2YXIgX2NvbnRyb2xzX3NwYXJrQ2xpZW50X19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvbnRyb2xzLnNwYXJrQ2xpZW50ICovIFwiLi9zcmMvQ29udHJvbHMvU3BhcmtDbGllbnQvY29udHJvbHMuc3BhcmtDbGllbnQuanNcIik7XG4vKiBoYXJtb255IHJlZXhwb3J0IChzYWZlKSAqLyBfX3dlYnBhY2tfcmVxdWlyZV9fLmQoX193ZWJwYWNrX2V4cG9ydHNfXywgXCJTcGFya0NsaWVudFwiLCBmdW5jdGlvbigpIHsgcmV0dXJuIF9jb250cm9sc19zcGFya0NsaWVudF9fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMF9fW1wiZGVmYXVsdFwiXTsgfSk7XG5cbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBfY29udHJvbHNfc3BhcmtDbGllbnRfa2V5Ym9hcmRzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8xX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvbnRyb2xzLnNwYXJrQ2xpZW50LmtleWJvYXJkcyAqLyBcIi4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2NvbnRyb2xzLnNwYXJrQ2xpZW50LmtleWJvYXJkcy5qc1wiKTtcbi8qIGhhcm1vbnkgcmVleHBvcnQgKHNhZmUpICovIF9fd2VicGFja19yZXF1aXJlX18uZChfX3dlYnBhY2tfZXhwb3J0c19fLCBcIlNwYXJrS2V5Ym9hcmRzXCIsIGZ1bmN0aW9uKCkgeyByZXR1cm4gX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2tleWJvYXJkc19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMV9fW1wiZGVmYXVsdFwiXTsgfSk7XG5cbi8qIGhhcm1vbnkgaW1wb3J0ICovIHZhciBfY29udHJvbHNfc3BhcmtDbGllbnRfY29uc3RhbnRzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8yX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2NvbnRyb2xzLnNwYXJrQ2xpZW50LmNvbnN0YW50cyAqLyBcIi4vc3JjL0NvbnRyb2xzL1NwYXJrQ2xpZW50L2NvbnRyb2xzLnNwYXJrQ2xpZW50LmNvbnN0YW50cy5qc1wiKTtcbi8qIGhhcm1vbnkgcmVleHBvcnQgKHNhZmUpICovIF9fd2VicGFja19yZXF1aXJlX18uZChfX3dlYnBhY2tfZXhwb3J0c19fLCBcIlNwYXJrQ29uc3RhbnRzXCIsIGZ1bmN0aW9uKCkgeyByZXR1cm4gX2NvbnRyb2xzX3NwYXJrQ2xpZW50X2NvbnN0YW50c19fV0VCUEFDS19JTVBPUlRFRF9NT0RVTEVfMl9fW1wiZGVmYXVsdFwiXTsgfSk7XG5cblxuXG5cblxuXG4vKioqLyB9KSxcblxuLyoqKi8gMDpcbi8qISoqKioqKioqKioqKioqKioqKioqKiohKlxcXG4gICEqKiogdXRpbCAoaWdub3JlZCkgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKiovXG4vKiEgbm8gc3RhdGljIGV4cG9ydHMgZm91bmQgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuLyogKGlnbm9yZWQpICovXG5cbi8qKiovIH0pLFxuXG4vKioqLyAxOlxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxuICAhKioqIHJlYWRhYmxlLXN0cmVhbSAoaWdub3JlZCkgKioqIVxuICBcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qISBubyBzdGF0aWMgZXhwb3J0cyBmb3VuZCAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG4vKiAoaWdub3JlZCkgKi9cblxuLyoqKi8gfSlcblxuLyoqKioqKi8gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zcGFyay1jbGllbnQuanMubWFwXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvc3BhcmstY2xpZW50LWNvcmUvc3BhcmstY2xpZW50LmpzXG4vLyBtb2R1bGUgaWQgPSAxNDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIEJvdHRsZSA9IHJlcXVpcmUoJ2JvdHRsZWpzJyk7XHJcbnZhciBib3R0bGUgPSBuZXcgQm90dGxlKCk7XHJcblxyXG5ib3R0bGUuZmFjdG9yeSgnQ2xvdWRTaGFyZUNsaWVudCcsIGZ1bmN0aW9uKCkgeyByZXR1cm4gcmVxdWlyZSgnLi4vY3Mtc2RrJyk7IH0pO1xyXG5ib3R0bGUuc2VydmljZSgnU3lta2V5U2VydmljZScsIHJlcXVpcmUoJy4vc3lta2V5LXNlcnZpY2UnKSk7XHJcbmJvdHRsZS5zZXJ2aWNlKCdDbG91ZFNoYXJlU3BhcmsnLCByZXF1aXJlKCcuL2Nsb3Vkc2hhcmUtc3BhcmsnKSwgJ0Nsb3VkU2hhcmVDbGllbnQnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYm90dGxlO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL3NwYXJrLWNsaWVudC9ib3R0bGUuanNcbi8vIG1vZHVsZSBpZCA9IDE0MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJ2YXIgUHJvbWlzZSA9IHJlcXVpcmUoJ2VzNi1wcm9taXNlJykuUHJvbWlzZTtcclxudmFyIFNwYXJrU3RhdGVzID0gcmVxdWlyZSgnLi9zcGFyay1zdGF0ZXMnKTtcclxudmFyIFNwYXJrQ2xpZW50ID0gcmVxdWlyZSgnLi4vc3BhcmstY2xpZW50LWNvcmUvc3BhcmstY2xpZW50LmpzJyk7XHJcblxyXG5mdW5jdGlvbiBDbG91ZFNoYXJlU3BhcmsoY3NjbGllbnQpIHtcclxuXHR0aGlzLmNzY2xpZW50ID0gY3NjbGllbnQ7XHJcblx0dGhpcy5zcGFya0NsaWVudHMgPSB7fTtcclxuXHR0aGlzLlNUQVRFUyA9IFNwYXJrU3RhdGVzO1xyXG5cdHRoaXMuS0VZQk9BUkRTID0gU3BhcmtDbGllbnQuU3BhcmtLZXlib2FyZHM7XHJcblx0dGhpcy5DT05TVEFOVFMgPSBTcGFya0NsaWVudC5TcGFya0NvbnN0YW50cztcclxuXHR0aGlzLl9vcHRpb25zUGVyQ2xpZW50ID0ge307XHJcblx0dGhpcy5jb25uZWN0aW9uQXR0ZW1wdHNDb3VudCA9IDA7XHJcblx0dGhpcy5NQVhfQ09OTkVDVElPTl9BVFRFTVBUU19OVU0gPSAxMjtcclxuXHR0aGlzLklETEVfVElNRV9CRVRXRUVOX0NPTk5FQ1RJT05fQVRURU1QVFNfU0VDID0gNTtcclxufVxyXG5cclxuQ2xvdWRTaGFyZVNwYXJrLnByb3RvdHlwZS5jb25uZWN0ID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG5cdHZhciBzZWxmID0gdGhpcztcclxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xyXG5cdFx0Y2hlY2tPcHRpb25zKG9wdGlvbnMpO1xyXG5cdFx0aWYgKCFpc0NsaWVudENvbm5lY3RlZChzZWxmLCBvcHRpb25zLmlkKSl7XHJcblx0XHQgIHNlbGYuY29ubmVjdGlvbkF0dGVtcHRzQ291bnQgPSAwO1xyXG5cdFx0XHRyZXNvbHZlKHJlcXVlc3RQYXNzd29yZEFuZENvbm5lY3Qoc2VsZiwgb3B0aW9ucykpO1xyXG5cdFx0fSBlbHNlXHJcblx0XHRcdHJlc29sdmUoKTtcclxuXHR9KTtcclxufTtcclxuXHJcbkNsb3VkU2hhcmVTcGFyay5wcm90b3R5cGUuZGlzY29ubmVjdCA9IGZ1bmN0aW9uKGlkKSB7XHJcblx0dmFyIHNlbGYgPSB0aGlzO1xyXG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7XHJcblx0XHR2YXIgY2xpZW50ID0gc2VsZi5zcGFya0NsaWVudHNbaWRdO1xyXG5cdFx0aWYgKGNsaWVudCkge1xyXG5cdFx0XHRjbGllbnQuZGlzY29ubmVjdCgpO1xyXG5cdFx0fVxyXG5cdFx0c2V0VGltZW91dChyZXNvbHZlLCA1MDApO1xyXG5cdH0pO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZVNwYXJrLnByb3RvdHlwZS5zZXRDbGlwYm9hcmQgPSBmdW5jdGlvbihpZCwgdGV4dCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLnNwYXJrQ2xpZW50c1tpZF07XHJcblx0aWYgKGNsaWVudClcclxuXHRcdGNsaWVudC5zZXRDbGlwYm9hcmQodGV4dCk7XHJcbn07XHJcblxyXG5DbG91ZFNoYXJlU3BhcmsucHJvdG90eXBlLnNlbmRUZXh0ID0gZnVuY3Rpb24oaWQsIHRleHQpIHtcclxuXHR2YXIgY2xpZW50ID0gdGhpcy5zcGFya0NsaWVudHNbaWRdO1xyXG5cdGlmICghY2xpZW50KVxyXG5cdFx0cmV0dXJuO1xyXG5cclxuXHRjbGllbnQuc2VuZFRleHQodGV4dCk7XHJcbn07XHJcblxyXG5DbG91ZFNoYXJlU3BhcmsucHJvdG90eXBlLnNlbmRDdHJsQWx0RGVsZXRlID0gZnVuY3Rpb24oaWQpIHtcclxuXHR2YXIgY2xpZW50ID0gdGhpcy5zcGFya0NsaWVudHNbaWRdO1xyXG5cdGlmICghY2xpZW50KVxyXG5cdFx0cmV0dXJuO1xyXG5cdGNsaWVudC5zZW5kQ3RybEFsdERlbGV0ZSgpO1xyXG59XHJcblxyXG5DbG91ZFNoYXJlU3BhcmsucHJvdG90eXBlLnNlbmRDdHJsVyA9IGZ1bmN0aW9uKGlkKSB7XHJcblx0dmFyIGNsaWVudCA9IHRoaXMuc3BhcmtDbGllbnRzW2lkXTtcclxuXHRpZiAoIWNsaWVudClcclxuXHRcdHJldHVybjtcclxuXHRjbGllbnQuc2VuZEN0cmxXKCk7XHJcbn1cclxuXHJcbkNsb3VkU2hhcmVTcGFyay5wcm90b3R5cGUuc2VuZFdpbmRvd3NLZXkgPSBmdW5jdGlvbihpZCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLnNwYXJrQ2xpZW50c1tpZF07XHJcblx0aWYgKCFjbGllbnQpXHJcblx0XHRyZXR1cm47XHJcblx0Y2xpZW50LnNlbmRXaW5kb3dzS2V5KCk7XHJcbn1cclxuXHJcbkNsb3VkU2hhcmVTcGFyay5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24oaWQsIHdpZHRoLCBoZWlnaHQpIHtcclxuXHR2YXIgY2xpZW50ID0gdGhpcy5zcGFya0NsaWVudHNbaWRdO1xyXG5cclxuXHR2YXIgb3B0aW9ucyA9IHRoaXMuX29wdGlvbnNQZXJDbGllbnRbaWRdO1xyXG5cdGlmIChjbGllbnQgJiYgb3B0aW9ucykge1xyXG5cdFx0b3B0aW9ucy53aWR0aCA9IHdpZHRoO1xyXG5cdFx0b3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XHJcblxyXG5cdFx0dGhpcy5jb25uZWN0KG9wdGlvbnMpO1xyXG5cdH1cclxufTtcclxuXHJcbkNsb3VkU2hhcmVTcGFyay5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbihpZCwgc2NhbGUpIHtcclxuXHR2YXIgY2xpZW50ID0gdGhpcy5zcGFya0NsaWVudHNbaWRdO1xyXG5cdGlmIChjbGllbnQpXHJcblx0XHRjbGllbnQuc2NhbGUoc2NhbGUpO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZVNwYXJrLnByb3RvdHlwZS5nZXRTY2FsZSA9IGZ1bmN0aW9uKGlkKSB7XHJcblx0dmFyIGNsaWVudCA9IHRoaXMuc3BhcmtDbGllbnRzW2lkXTtcclxuXHRpZiAoY2xpZW50KVxyXG5cdFx0cmV0dXJuIGNsaWVudC5nZXRTY2FsZSgpO1xyXG5cdGVsc2VcclxuXHRcdHJldHVybiAxO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZVNwYXJrLnByb3RvdHlwZS5nZXRTaGFyZVByb3RvY29sID0gZnVuY3Rpb24oaWQpIHtcclxuXHR2YXIgY2xpZW50ID0gdGhpcy5zcGFya0NsaWVudHNbaWRdO1xyXG5cdGlmIChjbGllbnQpXHJcblx0XHRyZXR1cm4gY2xpZW50LmdldFByb3RvY29sTmFtZSgpO1xyXG5cdGVsc2VcclxuXHRcdHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZVNwYXJrLnByb3RvdHlwZS5nZXRGbGF0dGVuZWRDYW52YXMgPSBmdW5jdGlvbihpZCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLnNwYXJrQ2xpZW50c1tpZF07XHJcblx0aWYgKGNsaWVudClcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHRvRGF0YVVSTDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0cmV0dXJuIGNsaWVudC5nZXRUaHVtYm5haWwoNDAwKTsgLy8gVEJEIC0gdGFrZSB3aWR0aCBmcm9tIGNvbmZpZ3VyYXRpb25cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxufTtcclxuXHJcbkNsb3VkU2hhcmVTcGFyay5wcm90b3R5cGUuZGlzYWJsZUlucHV0cyA9IGZ1bmN0aW9uKGlkKSB7XHJcblx0dmFyIGNsaWVudCA9IHRoaXMuc3BhcmtDbGllbnRzW2lkXTtcclxuXHRpZiAoY2xpZW50KVxyXG5cdFx0Y2xpZW50LmlucHV0RGlzYWJsZWQgPSB0cnVlO1xyXG59O1xyXG5cclxuQ2xvdWRTaGFyZVNwYXJrLnByb3RvdHlwZS5lbmFibGVJbnB1dHMgPSBmdW5jdGlvbihpZCkge1xyXG5cdHZhciBjbGllbnQgPSB0aGlzLnNwYXJrQ2xpZW50c1tpZF07XHJcblx0aWYgKGNsaWVudClcclxuXHRcdGNsaWVudC5pbnB1dERpc2FibGVkID0gZmFsc2U7XHJcbn07XHJcblxyXG5DbG91ZFNoYXJlU3BhcmsucHJvdG90eXBlLmdldENvbm5lY3Rpb25UeXBlID0gZnVuY3Rpb24oaWQpIHtcclxuXHJcblx0aWYgKGlkID09PSBudWxsIHx8IGlkID09PSB1bmRlZmluZWQgfHwgISh0aGlzLnNwYXJrQ2xpZW50c1tpZF0pKVxyXG5cdFx0cmV0dXJuIG51bGw7XHJcblxyXG5cdHJldHVybiAnV2ViU29ja2V0JztcclxufTtcclxuXHJcbkNsb3VkU2hhcmVTcGFyay5wcm90b3R5cGUuc2V0U2VuZFRleHRPblBhc3RlID0gZnVuY3Rpb24oaWQsIHZhbHVlKSB7XHJcblx0dmFyIGNsaWVudCA9IHRoaXMuc3BhcmtDbGllbnRzW2lkXTtcclxuXHRpZiAoY2xpZW50KVxyXG5cdFx0Y2xpZW50LnNldFNlbmRUZXh0T25QYXN0ZSh2YWx1ZSk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiByZXF1ZXN0UGFzc3dvcmRBbmRDb25uZWN0KHNlbGYsIG9wdGlvbnMpIHtcclxuXHRyZXR1cm4gcmVxdWVzdFBhc3N3b3JkKHNlbGYsIG9wdGlvbnMpXHJcblx0XHQudGhlbihmdW5jdGlvbihyZXNwb25zZSkge1xyXG5cclxuXHRcdFx0X21lcmdlQ2xpZW50U2lkZURhdGEob3B0aW9ucywgcmVzcG9uc2UuY29udGVudCk7XHJcblxyXG5cdFx0XHRyZXNwb25zZS5jb250ZW50LmNvbnRhaW5lckVsZW1lbnQgPSBvcHRpb25zLmNvbnRhaW5lckVsZW1lbnQ7XHJcblx0XHRcdHJlc3BvbnNlLmNvbnRlbnQucm9vdEVsZW1lbnQgPSBvcHRpb25zLmNvbnRhaW5lckVsZW1lbnQ7XHJcblx0XHRcdHJlc3BvbnNlLmNvbnRlbnQuaWQgPSBvcHRpb25zLmlkO1xyXG5cdFx0XHRyZXNwb25zZS5jb250ZW50Lm1hY2hpbmVJZCA9IG9wdGlvbnMuY29ubmVjdGlvbkNvbmZpZ3VyYXRpb24ubWFjaGluZVRva2VuO1xyXG5cdFx0XHRyZXNwb25zZS5jb250ZW50LmVudklkID0gb3B0aW9ucy5jb25uZWN0aW9uQ29uZmlndXJhdGlvbi5lbnZJZDtcclxuXHRcdFx0cmVzcG9uc2UuY29udGVudC5jbGFzc0lkID0gb3B0aW9ucy5jb25uZWN0aW9uQ29uZmlndXJhdGlvbi5jbGFzc0lkO1xyXG5cdFx0XHRyZXNwb25zZS5jb250ZW50LnN0dWRlbnRJZCA9IG9wdGlvbnMuY29ubmVjdGlvbkNvbmZpZ3VyYXRpb24uc3R1ZGVudElkO1xyXG5cdFx0XHRyZXNwb25zZS5jb250ZW50LnVzZXJFbWFpbCA9IG9wdGlvbnMuY29ubmVjdGlvbkNvbmZpZ3VyYXRpb24udXNlckVtYWlsO1xyXG5cdFx0XHRyZXNwb25zZS5jb250ZW50LmtleWJvYXJkSWQgPSBvcHRpb25zLmNvbm5lY3Rpb25Db25maWd1cmF0aW9uLmtleWJvYXJkSWQ7XHJcblx0XHRcdHJlc3BvbnNlLmNvbnRlbnQuY3Vyc29yTGFiZWwgPSBvcHRpb25zLmNvbm5lY3Rpb25Db25maWd1cmF0aW9uLmN1cnNvckxhYmVsO1xyXG5cdFx0XHRcclxuXHRcdFx0dmFyIGNsaWVudCA9IGNyZWF0ZU5ld1NwYXJrQ2xpZW50KHNlbGYsXHJcblx0XHRcdFx0cmVzcG9uc2UuY29udGVudCxcclxuXHRcdFx0XHRyZXNwb25zZS5jb250ZW50Lmhvc3QsXHJcblx0XHRcdFx0cmVzcG9uc2UuY29udGVudC5odHRwRmFsbEJhY2tIb3N0LFxyXG5cdFx0XHRcdHJlc3BvbnNlLmNvbnRlbnQucHJvdG9jb2wpO1xyXG5cclxuXHRcdFx0c2VsZi5fb3B0aW9uc1BlckNsaWVudFtvcHRpb25zLmlkXSA9IHJlc3BvbnNlLmNvbnRlbnQ7XHJcblxyXG5cdFx0XHRyZXR1cm4gY2xpZW50LnNldHVwQW5kQ29ubmVjdCgpO1xyXG5cdFx0fSlcclxuXHRcdC5jYXRjaChmdW5jdGlvbiAoKXtcclxuXHRcdFx0Ly8gVGhpcyBjYXRjaCB3aXRoIHJldHJ5IGF0dGVtcHRzIHdhcyBhZGRlZCwgXHJcblx0XHRcdC8vIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSBhIGNvbm5lY3QgYXR0ZW1wdCBmYWlscyBiZWNhdXNlIGl0J3MgbWFkZSBiZWZvcmUgdGhlIHN0dWRlbnQgKHZpZXdlcikgbWFuYWdlZCB0byBjb25uZWN0IHRvIHRoZSBtYWNoaW5lLiBcclxuXHRcdFxyXG5cdFx0XHRpZiAoc2VsZi5jb25uZWN0aW9uQXR0ZW1wdHNDb3VudCA8IHNlbGYuTUFYX0NPTk5FQ1RJT05fQVRURU1QVFNfTlVNKXtcclxuXHRcdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0XHRcdHNlbGYuY29ubmVjdGlvbkF0dGVtcHRzQ291bnQrKztcclxuXHRcdFx0XHRcdHJldHVybiByZXF1ZXN0UGFzc3dvcmRBbmRDb25uZWN0KHNlbGYsIG9wdGlvbnMpO1xyXG5cdFx0XHRcdH0sIHNlbGYuSURMRV9USU1FX0JFVFdFRU5fQ09OTkVDVElPTl9BVFRFTVBUU19TRUMgKiAxMDAwKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIF9tZXJnZUNsaWVudFNpZGVEYXRhKGZyb20sIHRvKSB7XHJcblx0dG8ud2lkdGggPSBmcm9tLmNvbm5lY3Rpb25Db25maWd1cmF0aW9uLnBhcmFtZXRlcnMud2lkdGg7XHJcblx0dG8uaGVpZ2h0ID0gZnJvbS5jb25uZWN0aW9uQ29uZmlndXJhdGlvbi5wYXJhbWV0ZXJzLmhlaWdodDtcclxuXHR0by5jb2xvckRlcHRoID0gZnJvbS5jb25uZWN0aW9uQ29uZmlndXJhdGlvbi5wYXJhbWV0ZXJzW1wiY29sb3ItZGVwdGhcIl07XHJcblx0dG8uZml0U2NyZWVuID0gZnJvbS5jb25uZWN0aW9uQ29uZmlndXJhdGlvbi5wYXJhbWV0ZXJzLmZpdFNjcmVlbjtcclxuXHR0by5yZHBTb3VuZENvbmZpZyA9IGZyb20uY29ubmVjdGlvbkNvbmZpZ3VyYXRpb24ucmRwU291bmRDb25maWc7XHJcblx0dG8uc2VuZFRleHRPblBhc3RlID0gZnJvbS5jb25uZWN0aW9uQ29uZmlndXJhdGlvbi5zZW5kVGV4dE9uUGFzdGU7XHJcblx0dG8uYWxsb3dUbHNWMSA9IGZyb20uY29ubmVjdGlvbkNvbmZpZ3VyYXRpb24ucGFyYW1ldGVycy5hbGxvd1Rsc1YxO1xyXG5cdHRvLnVzZUtleWZpbGUgPSBmcm9tLmNvbm5lY3Rpb25Db25maWd1cmF0aW9uLnBhcmFtZXRlcnMudXNlS2V5ZmlsZTtcclxuXHR0by5kaXNhYmxlSW5wdXQgPSBmcm9tLmRpc2FibGVJbnB1dDtcclxuXHR0by5vbnN0YXRlY2hhbmdlID0gZnJvbS5vbnN0YXRlY2hhbmdlO1xyXG5cdHRvLm9uZXJyb3IgPSBmcm9tLm9uZXJyb3I7XHJcblx0dG8ub25jbGlwYm9hcmQgPSBmcm9tLm9uY2xpcGJvYXJkO1xyXG5cdHRvLm9ucmVzaXplID0gZnJvbS5vbnJlc2l6ZTtcclxuXHR0by5vbnRpbWVvdXQgPSBmcm9tLm9udGltZW91dDtcclxuXHR0by5jcmVkU1NQID0gZnJvbS5jb25uZWN0aW9uQ29uZmlndXJhdGlvbi5wYXJhbWV0ZXJzLmNyZWRTU1A7XHJcblx0dG8uc3NoRm9udFNpemUgPSBmcm9tLmNvbm5lY3Rpb25Db25maWd1cmF0aW9uLnBhcmFtZXRlcnMuc3NoRm9udFNpemU7XHJcblx0dG8uc3NoTGluZUhlaWdodCA9IGZyb20uY29ubmVjdGlvbkNvbmZpZ3VyYXRpb24ucGFyYW1ldGVycy5zc2hMaW5lSGVpZ2h0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0NsaWVudENvbm5lY3RlZChzZWxmLCBpZCkge1xyXG5cdHZhciBjbGllbnQgPSBzZWxmLnNwYXJrQ2xpZW50c1tpZF07XHJcblx0aWYgKCFjbGllbnQpXHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0cmV0dXJuIGNsaWVudC5jdXJyZW50U3RhdGUgPT09IFNwYXJrU3RhdGVzLkNPTk5FQ1RJTkcgfHxcclxuXHRcdGNsaWVudC5jdXJyZW50U3RhdGUgPT09IFNwYXJrU3RhdGVzLldBSVRJTkcgfHxcclxuXHRcdGNsaWVudC5jdXJyZW50U3RhdGUgPT09IFNwYXJrU3RhdGVzLkNPTk5FQ1RFRCB8fFxyXG5cdFx0Y2xpZW50LmN1cnJlbnRTdGF0ZSA9PT0gU3BhcmtTdGF0ZXMuQ09OTkVDVEVEQU5ETE9HR0VESU47XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZU5ld1NwYXJrQ2xpZW50KHNlbGYsIG9wdGlvbnMsIG92ZXJyaWRlSG9zdG5hbWUsIG92ZXJyaWRlSHR0cEhvc3RuYW1lLCBzaGFyZVByb3RvY29sKSB7XHJcblx0aWYgKHNlbGYuc3BhcmtDbGllbnRzW29wdGlvbnMuaWRdKSB7XHJcblx0XHRzZWxmLmRpc2Nvbm5lY3Qob3B0aW9ucy5pZCk7XHJcblx0XHRzZWxmLnNwYXJrQ2xpZW50c1tvcHRpb25zLmlkXSA9IHVuZGVmaW5lZDtcclxuXHR9XHJcblxyXG5cdHZhciBjbGllbnQgPSBjcmVhdGVTcGFya0NsaWVudChzZWxmLCBvcHRpb25zLCBvdmVycmlkZUhvc3RuYW1lLCBvdmVycmlkZUh0dHBIb3N0bmFtZSwgc2hhcmVQcm90b2NvbCk7XHJcblx0c2VsZi5zcGFya0NsaWVudHNbb3B0aW9ucy5pZF0gPSBjbGllbnQ7XHJcblx0c2VsZi5sYXN0VXNlZEhvc3ROYW1lID0gY2xpZW50Lmhvc3RuYW1lO1xyXG5cclxuXHRyZXR1cm4gc2VsZi5zcGFya0NsaWVudHNbb3B0aW9ucy5pZF07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVNwYXJrQ2xpZW50KHNlbGYsIG9wdGlvbnMsIG92ZXJyaWRlSG9zdG5hbWUsIG92ZXJyaWRlSHR0cEhvc3RuYW1lLCBzaGFyZVByb3RvY29sKSB7XHJcblx0cmV0dXJuIG5ldyBTcGFya0NsaWVudC5TcGFya0NsaWVudChvcHRpb25zKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVxdWVzdFBhc3N3b3JkKHNlbGYsIG9wdGlvbnMpIHtcclxuXHRyZXR1cm4gc2VsZi5jc2NsaWVudC5yZXEoe1xyXG5cdFx0aG9zdG5hbWU6IG9wdGlvbnMuY2xvdWRTaGFyZUhvc3RuYW1lLFxyXG5cdFx0bWV0aG9kOiAnUE9TVCcsXHJcblx0XHRwYXRoOiAnUmVtb3RlQWNjZXNzQ29ubmVjdGlvbicsXHJcblx0XHRhcGlJZDogb3B0aW9ucy5hcGlJZCxcclxuXHRcdGFwaUtleTogb3B0aW9ucy5hcGlLZXksXHJcblx0XHRjb250ZW50OiBvcHRpb25zLmNvbm5lY3Rpb25Db25maWd1cmF0aW9uXHJcblx0fSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNoZWNrT3B0aW9ucyhvcHRpb25zKSB7XHJcblx0aWYgKCFvcHRpb25zKVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIG9wdGlvbnMnKTtcclxuXHRlbHNlIGlmIChvcHRpb25zLmlkICE9PSAwICYmICFvcHRpb25zLmlkKVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIElEIHBhcmFtZXRlcicpO1xyXG5cdGVsc2UgaWYgKCFvcHRpb25zLmhvc3RuYW1lKVxyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGhvc3RuYW1lIHBhcmFtZXRlcicpO1xyXG5cdGVsc2UgaWYgKCFvcHRpb25zLmNvbnRhaW5lckVsZW1lbnQpXHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgY29udGFpbmVyRWxlbWVudCBwYXJhbWV0ZXInKTtcclxuXHRlbHNlIGlmICghb3B0aW9ucy5jb25uZWN0aW9uQ29uZmlndXJhdGlvbilcclxuXHRcdHRocm93IG5ldyBFcnJvcignTWlzc2luZyBjb25uZWN0aW9uQ29uZmlndXJhdGlvbiBwYXJhbWV0ZXInKTtcclxuXHRlbHNlIGlmICghb3B0aW9ucy5jbG91ZFNoYXJlSG9zdG5hbWUpXHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgY2xvdWRTaGFyZUhvc3RuYW1lIHBhcmFtZXRlcicpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZW5kS2V5U3Ryb2tlcyhjbGllbnQsIGtleVN0cm9rZXMpIHtcclxuXHRmb3IgKHZhciBpID0gMDsgaSA8IGtleVN0cm9rZXMubGVuZ3RoOyArK2kpIHtcclxuXHRcdHZhciBrID0ga2V5U3Ryb2tlc1tpXTtcclxuXHRcdGlmIChrLmlzRG93bilcclxuXHRcdFx0Y2xpZW50LnNlbmRTeW1rZXlEb3duKGsuc3lta2V5KTtcclxuXHRcdGVsc2VcclxuXHRcdFx0Y2xpZW50LnNlbmRTeW1rZXlVcChrLnN5bWtleSk7XHJcblx0fVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IENsb3VkU2hhcmVTcGFyaztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9zcGFyay1jbGllbnQvY2xvdWRzaGFyZS1zcGFyay5qc1xuLy8gbW9kdWxlIGlkID0gMTQyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0ge1xyXG5cdElETEU6IDAsXHJcblx0Q09OTkVDVElORzogMSxcclxuXHRXQUlUSU5HOiAyLFxyXG5cdENPTk5FQ1RFRDogMyxcclxuXHRESVNDT05ORUNUSU5HOiA0LFxyXG5cdERJU0NPTk5FQ1RFRDogNSxcclxuXHRDT05ORUNURURBTkRMT0dHRURJTjogNlxyXG59O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL3NwYXJrLWNsaWVudC9zcGFyay1zdGF0ZXMuanNcbi8vIG1vZHVsZSBpZCA9IDE0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJmdW5jdGlvbiBTeW1rZXlTZXJ2aWNlKCkge1xyXG5cdFxyXG59XHJcblxyXG5TeW1rZXlTZXJ2aWNlLnByb3RvdHlwZS50b1N5bUtleSA9IGZ1bmN0aW9uKHRleHQpIHtcclxuXHR2YXIgY2hhcmNvZGUgPSB0ZXh0LmNoYXJDb2RlQXQoMCk7XHJcblx0aWYgKGlzQ29udHJvbENoYXJhY3RlcihjaGFyY29kZSkpXHJcblx0XHRyZXR1cm4gMHhGRjAwIHwgY2hhcmNvZGU7XHJcblx0aWYgKGlzQVNDSUkoY2hhcmNvZGUpKVxyXG5cdFx0cmV0dXJuIGNoYXJjb2RlO1xyXG5cdGlmIChpc1VuaWNvZGVDaGFyYWN0ZXIoY2hhcmNvZGUpKVxyXG5cdFx0cmV0dXJuIDB4MDEwMDAwMDAgfCBjaGFyY29kZTtcclxuXHRyZXR1cm4gbnVsbDtcclxufTtcclxuXHJcbmZ1bmN0aW9uIGlzQVNDSUkoY2hhcmNvZGUpIHtcclxuXHRyZXR1cm4gY2hhcmNvZGUgPj0gMHgwMCAmJiBjaGFyY29kZSA8PSAweEZGO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0NvbnRyb2xDaGFyYWN0ZXIoY2hhcmNvZGUpIHtcclxuICAgIHJldHVybiBjaGFyY29kZSA8PSAweDFGIHx8IChjaGFyY29kZSA+PSAweDdGICYmIGNoYXJjb2RlIDw9IDB4OUYpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1VuaWNvZGVDaGFyYWN0ZXIoY2hhcmNvZGUpIHtcclxuXHRyZXR1cm4gY2hhcmNvZGUgPiAweEZGICYmIGNoYXJjb2RlIDwgMHgxMTAwMDA7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gU3lta2V5U2VydmljZTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9zcGFyay1jbGllbnQvc3lta2V5LXNlcnZpY2UuanNcbi8vIG1vZHVsZSBpZCA9IDE0NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAoaWdub3JlZCkgKi9cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyB2ZXJ0eCAoaWdub3JlZClcbi8vIG1vZHVsZSBpZCA9IDE0NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAoaWdub3JlZCkgKi9cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyByZWFkYWJsZS1zdHJlYW0gKGlnbm9yZWQpXG4vLyBtb2R1bGUgaWQgPSAxNDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyogKGlnbm9yZWQpICovXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gdXRpbCAoaWdub3JlZClcbi8vIG1vZHVsZSBpZCA9IDE0N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIgdmFyIEh0bWxTYW5pdGl6ZXIgPSByZXF1aXJlKFwiLi9odG1sLXNhbml0aXplclwiKTtcclxuXHJcbndpbmRvdy5jcyA9IHdpbmRvdy5jcyB8fCB7fTtcclxuXHJcbmlmICghd2luZG93LmNzLnNwYXJrY2xpZW50KVxyXG5cdHdpbmRvdy5jcy5zcGFya2NsaWVudCA9IHJlcXVpcmUoXCIuL3NwYXJrLWNsaWVudFwiKTtcclxuXHJcbmlmICghd2luZG93LmNzLmNzY2xpZW50KVxyXG5cdHdpbmRvdy5jcy5jc2NsaWVudCA9IHJlcXVpcmUoXCIuL2NzLXNka1wiKTtcclxuXHJcbndpbmRvdy5jcy5ndWFjY2xpZW50ID0gcmVxdWlyZShcIi4vZ3VhY2Ftb2xlLWNsaWVudFwiKTtcclxud2luZG93LmNzLmNob2NvbGF0ZXljbGllbnQgPSByZXF1aXJlKFwiLi9jaG9jb2xhdGV5LWNsaWVudFwiKTtcclxud2luZG93LmNzLmhlYXJ0YmVhdHNvdmVyd3MgPSByZXF1aXJlKFwiLi9oZWFydGJlYXQtb3Zlci13c1wiKTtcclxuXHJcbmlmICghd2luZG93LmNzLnRvdXJTZXJ2aWNlKVxyXG5cdHdpbmRvdy5jcy50b3VyU2VydmljZSA9IHJlcXVpcmUoXCIuL2Nsb3Vkc2hhcmUtdG91clwiKTtcclxuXHJcbmlmICghd2luZG93LmNzLmh0bWxTYW5pdGl6ZXIpXHJcblx0d2luZG93LmNzLmh0bWxTYW5pdGl6ZXIgPSBuZXcgSHRtbFNhbml0aXplcigpO1xyXG5cclxuaWYgKCF3aW5kb3cuY3MuY3N3cykge1xyXG5cdHdpbmRvdy5jcy5jc3dzID0gcmVxdWlyZShcIi4vY3N3c1wiKS5jc3dzO1xyXG59XHJcblxyXG5pZiAoIXdpbmRvdy5jcy5jb25uZWN0aXZpdHlUZXN0RmFpbHVyZUluZm9ybWF0aW9uKSB7XHJcblx0d2luZG93LmNzLmNvbm5lY3Rpdml0eVRlc3RGYWlsdXJlSW5mb3JtYXRpb24gPSByZXF1aXJlKFwiLi9jb25uZWN0aXZpdHktdGVzdC1mYWlsdXJlLWluZm9ybWF0aW9uXCIpLmRpcmVjdGl2ZUZ1bmN0aW9uO1xyXG59XHJcblxyXG5pZiAoIXdpbmRvdy5jcy5icm93c2VyU2Vzc2lvblByb3ZpZGVyKSB7XHJcblx0dmFyIEJyb3dzZXJTZXNzaW9uUHJvdmlkZXIgPSByZXF1aXJlKFwiLi9icm93c2VyU2Vzc2lvblByb3ZpZGVyXCIpLkJyb3dzZXJTZXNzaW9uUHJvdmlkZXI7XHJcblx0d2luZG93LmNzLmJyb3dzZXJTZXNzaW9uUHJvdmlkZXIgPSBuZXcgQnJvd3NlclNlc3Npb25Qcm92aWRlcigpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHdpbmRvdy5jcztcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDE0OFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9;
