From 2eef3c2e627f2d6f5d05dd78d22d9c759ac92c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matuzal=C3=A9m=20Teles?= Date: Wed, 10 Apr 2019 10:33:11 -0300 Subject: [PATCH] Bump version 2.7.5 -> 2.7.6 --- build/amd/senna/src/app/version-min.js | 2 +- build/amd/senna/src/app/version.js | 2 +- build/globals/senna-debug.js | 4 +- build/globals/senna-min.js | 4 +- build/globals/senna.js | 4 +- build/globals/senna.js.map | 2 +- package-lock.json | 5312 ++++++++++++------------ package.json | 2 +- 8 files changed, 2666 insertions(+), 2666 deletions(-) diff --git a/build/amd/senna/src/app/version-min.js b/build/amd/senna/src/app/version-min.js index 3054001..6b4946d 100644 --- a/build/amd/senna/src/app/version-min.js +++ b/build/amd/senna/src/app/version-min.js @@ -1 +1 @@ -define(["exports"],function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var t="2.7.5";e["default"]=t}); \ No newline at end of file +define(["exports"],function(e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var t="2.7.6";e["default"]=t}); \ No newline at end of file diff --git a/build/amd/senna/src/app/version.js b/build/amd/senna/src/app/version.js index 5fa7012..bd278b4 100644 --- a/build/amd/senna/src/app/version.js +++ b/build/amd/senna/src/app/version.js @@ -8,7 +8,7 @@ define(['exports'], function (exports) { * @returns String containing the current senna version */ - var version = '2.7.5'; + var version = '2.7.6'; exports.default = version; }); diff --git a/build/globals/senna-debug.js b/build/globals/senna-debug.js index c9f47e5..501fd9f 100644 --- a/build/globals/senna-debug.js +++ b/build/globals/senna-debug.js @@ -1,7 +1,7 @@ /** * Senna.js - A blazing-fast Single Page Application engine * @author Liferay, Inc. - * @version v2.7.5 + * @version v2.7.6 * @link http://sennajs.com * @license BSD-3-Clause */ @@ -9917,7 +9917,7 @@ globals.document.addEventListener('DOMContentLoaded', function () { * @returns String containing the current senna version */ -var version = '2.7.5'; +var version = '2.7.6'; exports['default'] = App$1; exports.dataAttributeHandler = dataAttributeHandler; diff --git a/build/globals/senna-min.js b/build/globals/senna-min.js index 134e6ba..75deb36 100644 --- a/build/globals/senna-min.js +++ b/build/globals/senna-min.js @@ -1,10 +1,10 @@ /** * Senna.js - A blazing-fast Single Page Application engine * @author Liferay, Inc. - * @version v2.7.5 + * @version v2.7.6 * @link http://sennajs.com * @license BSD-3-Clause */ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.senna={})}(this,function(e){"use strict";function t(){throw Error("Unimplemented abstract method")}function n(){Ae=void 0}function r(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};Ae=e}function i(){return"undefined"!=typeof window&&window.__METAL_COMPATIBILITY__&&r(window.__METAL_COMPATIBILITY__),Ae}function a(e,t){return e||t}function o(e){if(!e.name){var t=e.toString();e.name=t.substring(9,t.indexOf("("))}return e.name}function u(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:a,r=t+"_MERGED";if(!e.hasOwnProperty(r)){var i=e.hasOwnProperty(t)?e[t]:null;e.__proto__&&!e.__proto__.isPrototypeOf(Function)&&(i=n(i,u(e.__proto__,t,n))),e[r]=i}return e[r]}function s(e,t){if(e){var n=e[Te];return t&&!e.hasOwnProperty(Te)&&(n=null),n||(e[Te]=Re++)}return Re++}function l(e){return e}function c(e){return"boolean"==typeof e}function h(e){return void 0!==e}function f(e){return h(e)&&!m(e)}function d(e){return e&&"object"===("undefined"==typeof e?"undefined":ke(e))&&9===e.nodeType}function v(e){return e&&"object"===("undefined"==typeof e?"undefined":ke(e))&&11===e.nodeType}function p(e){return e&&"object"===("undefined"==typeof e?"undefined":ke(e))&&1===e.nodeType}function y(e){return"function"==typeof e}function m(e){return null===e}function g(e){return"number"==typeof e}function _(e){return null!==e&&e===e.window}function k(e){var t="undefined"==typeof e?"undefined":ke(e);return"object"===t&&null!==e||"function"===t}function E(e){return e&&"object"===("undefined"==typeof e?"undefined":ke(e))&&"function"==typeof e.then}function S(e){return"string"==typeof e||e instanceof String}function b(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{checkEnv:!0},t="undefined"!=typeof process&&!process.browser;return t&&e.checkEnv&&(t="undefined"!=typeof process.env&&"test"!==process.env.NODE_ENV),t}function P(){}function w(e){return e=e||[],Array.isArray(e)?e:[e]}function C(e,t){if(k(e)&&S(t)){e.length||(e=[e]);for(var n=0;n"+e,t.removeChild(t.firstChild);for(var n=document.createDocumentFragment();t.firstChild;)n.appendChild(t.firstChild);return n}function U(e,t){return d(e)?e.documentElement.contains(t):e.contains(t)}function x(e,t,n,r,i){var a=Ye[t];return a&&a.delegate&&(t=a.originalEvent,r=a.handler.bind(a,r)),i&&(r=r.bind(),r.defaultListener_=!0),O(e,t),S(n)?L(e,t,n,r):T(n,t,r),new Qe(S(n)?e:n,t,r,S(n)?n:null)}function F(e,t,n){if(n&&"click"===t&&2===n.button)return!1;var r=["BUTTON","INPUT","SELECT","TEXTAREA","FIELDSET"];return!("click"===t&&r.indexOf(e.tagName)>-1)||!(e.disabled||Y(e,"fieldset[disabled]"))}function j(e){return f(e)&&"number"==typeof e.length&&"function"==typeof e.item}function M(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function q(e){V(e);var t=!0,n=e.currentTarget,r=[];return t&=re(n,e,r),t&=ne(r,e),e.delegateTarget=null,e[ze]=n,t}function B(e,t){if(!e||1!==e.nodeType)return!1;var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector;return r?r.call(e,t):Q(e,t)}function Q(e,t){var n=e.parentNode;if(n)for(var r=n.querySelectorAll(t),i=0;i>>0),Le=Object.freeze({UID_PROPERTY:Te,abstractMethod:t,disableCompatibilityMode:n,enableCompatibilityMode:r,getCompatibilityModeData:i,getFunctionName:o,getStaticProperty:u,getUid:s,identityFunction:l,isBoolean:c,isDef:h,isDefAndNotNull:f,isDocument:d,isDocumentFragment:v,isElement:p,isFunction:y,isNull:m,isNumber:g,isWindow:_,isObject:k,isPromise:E,isString:S,isServerSide:b,nullFunction:P}),Ne=function(){function e(){Ee(this,e)}return Se(e,null,[{key:"equal",value:function(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:[],r=0;r=0)&&e.removeAt(t,r),i}},{key:"removeAt",value:function(e,t){return 1===Array.prototype.splice.call(e,t,1).length}},{key:"slice",value:function(e,t){for(var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=[],i=t;i1?r-1:0),a=1;a1&&void 0!==arguments[1]?arguments[1]:window,n=e.split(".");return n.reduce(function(e,t){return e[t]},t)}},{key:"map",value:function(e,t){for(var n={},r=Object.keys(e),i=0;i0?n:null}},{key:"removeListener",value:function(){return this.off.apply(this,arguments)}},{key:"runListenerHandlers_",value:function(e){var t=this.listenerHandlers_;if(t){t=w(t);for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:"";Ee(this,e),this.url=e.parse(this.maybeAddProtocolAndHostname_(t))}return Se(e,[{key:"addParametersFromMultiMap",value:function(e){var t=this;return e.names().forEach(function(n){e.getAll(n).forEach(function(e){t.addParameterValue(n,e)})}),this}},{key:"addParameterValue",value:function(e,t){return this.ensureQueryInitialized_(),h(t)&&(t=String(t)),this.query.add(e,t),this}},{key:"addParameterValues",value:function(e,t){var n=this;return t.forEach(function(t){return n.addParameterValue(e,t)}),this}},{key:"ensureQueryInitialized_",value:function(){var t=this;if(!this.query){this.query=new tt;var n=this.url.search;n&&n.substring(1).split("&").forEach(function(n){var r=n.split("="),i=Ce(r,2),a=i[0],o=i[1];h(o)&&(o=e.urlDecode(o)),t.addParameterValue(a,o)})}}},{key:"getHash",value:function(){return this.url.hash||""}},{key:"getHost",value:function(){var e=this.getHostname();if(e){var t=this.getPort();t&&"80"!==t&&(e+=":"+t)}return e}},{key:"getHostname",value:function(){var t=this.url.hostname;return t===e.HOSTNAME_PLACEHOLDER?"":t}},{key:"getOrigin",value:function(){var e=this.getHost();return e?this.getProtocol()+"//"+e:""}},{key:"getParameterValue",value:function(e){return this.ensureQueryInitialized_(),this.query.get(e)}},{key:"getParameterValues",value:function(e){return this.ensureQueryInitialized_(),this.query.getAll(e)}},{key:"getParameterNames",value:function(){return this.ensureQueryInitialized_(),this.query.names()}},{key:"getPathname",value:function(){return this.url.pathname}},{key:"getPort",value:function(){return this.url.port}},{key:"getProtocol",value:function(){return this.url.protocol}},{key:"getSearch",value:function(){var e=this,t="",n="";return this.getParameterNames().forEach(function(t){e.getParameterValues(t).forEach(function(e){n+=t,h(e)&&(n+="="+encodeURIComponent(e)),n+="&"})}),n=n.slice(0,-1),n&&(t+="?"+n),t}},{key:"hasParameter",value:function(e){return this.ensureQueryInitialized_(),this.query.contains(e)}},{key:"makeUnique",value:function(){return this.setParameterValue(e.RANDOM_PARAM,He.getRandomString()),this}},{key:"maybeAddProtocolAndHostname_",value:function(t){var n=t;if(t.indexOf("://")===-1&&0!==t.indexOf("javascript:"))switch(n=e.DEFAULT_PROTOCOL,"/"===t[0]&&"/"===t[1]||(n+="//"),t.charAt(0)){case".":case"?":case"#":n+=e.HOSTNAME_PLACEHOLDER,n+="/",n+=t;break;case"":case"/":"/"!==t[1]&&(n+=e.HOSTNAME_PLACEHOLDER),n+=t;break;default:n+=t}return n}},{key:"removeParameter",value:function(e){return this.ensureQueryInitialized_(),this.query.remove(e),this}},{key:"removeUnique",value:function(){return this.removeParameter(e.RANDOM_PARAM),this}},{key:"setHash",value:function(e){return this.url.hash=e,this}},{key:"setHostname",value:function(e){return this.url.hostname=e,this}},{key:"setParameterValue",value:function(e,t){return this.removeParameter(e),this.addParameterValue(e,t),this}},{key:"setParameterValues",value:function(e,t){var n=this;return this.removeParameter(e),t.forEach(function(t){ return n.addParameterValue(e,t)}),this}},{key:"setPathname",value:function(e){return this.url.pathname=e,this}},{key:"setPort",value:function(e){return this.url.port=e,this}},{key:"setProtocol",value:function(e){return this.url.protocol=e,":"!==this.url.protocol[this.url.protocol.length-1]&&(this.url.protocol+=":"),this}},{key:"toString",value:function(){var e="",t=this.getHost();return t&&(e+=this.getProtocol()+"//"),e+=t+this.getPathname()+this.getSearch()+this.getHash()}}],[{key:"getParseFn",value:function(){return it}},{key:"parse",value:function(e){return it(e)}},{key:"setParseFn",value:function(e){it=e}},{key:"joinPaths",value:function(e){for(var t=arguments.length,n=Array(t>1?t-1:0),r=1;r1&&"/"===e[t-1]&&(e=e.substr(0,t-1)),e}},{key:"setElementWithRandomHref",value:function(e){return e.href=e.href+"?q="+Math.random(),e}},{key:"setReferrer",value:function(e){Object.defineProperty(Ze.document,"referrer",{configurable:!0,get:function(){return e}})}}]),e}(),st={basePath:"data-senna-base-path",linkSelector:"data-senna-link-selector",loadingCssClass:"data-senna-loading-css-class",senna:"data-senna",dispatch:"data-senna-dispatch",surface:"data-senna-surface",updateScrollPosition:"data-senna-update-scroll-position"},lt=function(){};lt.prototype.then=function(){},lt.IMPLEMENTED_BY_PROP="$goog_Thenable",lt.addImplementation=function(e){e.prototype.then=e.prototype.then,e.prototype.$goog_Thenable=!0},lt.isImplementedBy=function(e){if(!e)return!1;try{return!!e.$goog_Thenable}catch(t){return!1}};var ct=function(e){var t=Array.prototype.slice.call(arguments,1);return function(){var n=t.slice();return n.push.apply(n,arguments),e.apply(this,n)}},ht=function Tt(e,t){this.state_=Tt.State_.PENDING,this.result_=void 0,this.parent_=null,this.callbackEntries_=null,this.executing_=!1,Tt.UNHANDLED_REJECTION_DELAY>0?this.unhandledRejectionId_=0:0===Tt.UNHANDLED_REJECTION_DELAY&&(this.hadUnhandledRejection_=!1);try{var n=this;e.call(t,function(e){n.resolve_(Tt.State_.FULFILLED,e)},function(e){n.resolve_(Tt.State_.REJECTED,e)})}catch(r){this.resolve_(Tt.State_.REJECTED,r)}};ht.UNHANDLED_REJECTION_DELAY=0,ht.State_={PENDING:0,BLOCKED:1,FULFILLED:2,REJECTED:3},ht.CallbackEntry_=null,ht.resolve=function(e){return new ht(function(t){t(e)})},ht.reject=function(e){return new ht(function(t,n){n(e)})},ht.race=function(e){return new ht(function(t,n){e.length||t(void 0);for(var r,i=0;r=e[i];i++)r.then(t,n)})},ht.all=function(e){return new ht(function(t,n){var r=e.length,i=[];if(!r)return void t(i);for(var a,o=function(e,n){r--,i[e]=n,0===r&&t(i)},u=function(e){n(e)},s=0;a=e[s];s++)a.then(ct(o,s),u)})},ht.firstFulfilled=function(e){return new ht(function(t,n){var r=e.length,i=[];if(!r)return void t(void 0);for(var a,o=function(e){t(e)},u=function(e,t){r--,i[e]=t,0===r&&n(i)},s=0;a=e[s];s++)a.then(o,ct(u,s))})},ht.prototype.then=function(e,t,n){return this.addChildPromise_(y(e)?e:null,y(t)?t:null,n)},lt.addImplementation(ht),ht.prototype.thenAlways=function(e,t){var n=function(){try{e.call(t)}catch(n){ht.handleRejection_.call(null,n)}};return this.addCallbackEntry_({child:null,onRejected:n,onFulfilled:n}),this},ht.prototype.thenCatch=function(e,t){return this.addChildPromise_(null,e,t)},ht.prototype["catch"]=ht.prototype.thenCatch,ht.prototype.cancel=function(e){this.state_===ht.State_.PENDING&&Oe.run(function(){var t=new ht.CancellationError(e);t.IS_CANCELLATION_ERROR=!0,this.cancelInternal_(t)},this)},ht.prototype.cancelInternal_=function(e){this.state_===ht.State_.PENDING&&(this.parent_?this.parent_.cancelChild_(this,e):this.resolve_(ht.State_.REJECTED,e))},ht.prototype.cancelChild_=function(e,t){if(this.callbackEntries_){for(var n,r=0,i=-1,a=0;n=this.callbackEntries_[a];a++){var o=n.child;if(o&&(r++,o===e&&(i=a),i>=0&&r>1))break}if(i>=0)if(this.state_===ht.State_.PENDING&&1===r)this.cancelInternal_(t);else{var u=this.callbackEntries_.splice(i,1)[0];this.executeCallback_(u,ht.State_.REJECTED,t)}}},ht.prototype.addCallbackEntry_=function(e){this.callbackEntries_&&this.callbackEntries_.length||this.state_!==ht.State_.FULFILLED&&this.state_!==ht.State_.REJECTED||this.scheduleCallbacks_(),this.callbackEntries_||(this.callbackEntries_=[]),this.callbackEntries_.push(e)},ht.prototype.addChildPromise_=function(e,t,n){var r={child:null,onFulfilled:null,onRejected:null};return r.child=new ht(function(i,a){r.onFulfilled=e?function(t){try{var r=e.call(n,t);i(r)}catch(o){a(o)}}:i,r.onRejected=t?function(e){try{var r=t.call(n,e);!h(r)&&e.IS_CANCELLATION_ERROR?a(e):i(r)}catch(o){a(o)}}:a}),r.child.parent_=this,this.addCallbackEntry_(r),r.child},ht.prototype.unblockAndFulfill_=function(e){if(this.state_!==ht.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=ht.State_.PENDING,this.resolve_(ht.State_.FULFILLED,e)},ht.prototype.unblockAndReject_=function(e){if(this.state_!==ht.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=ht.State_.PENDING,this.resolve_(ht.State_.REJECTED,e)},ht.prototype.resolve_=function(e,t){if(this.state_===ht.State_.PENDING){if(this===t)e=ht.State_.REJECTED,t=new TypeError("CancellablePromise cannot resolve to itself");else{if(lt.isImplementedBy(t))return t=t,this.state_=ht.State_.BLOCKED,void t.then(this.unblockAndFulfill_,this.unblockAndReject_,this);if(k(t))try{var n=t.then;if(y(n))return void this.tryThen_(t,n)}catch(r){e=ht.State_.REJECTED,t=r}}this.result_=t,this.state_=e,this.scheduleCallbacks_(),e!==ht.State_.REJECTED||t.IS_CANCELLATION_ERROR||ht.addUnhandledRejection_(this,t)}},ht.prototype.tryThen_=function(e,t){this.state_=ht.State_.BLOCKED;var n=this,r=!1,i=function(e){r||(r=!0,n.unblockAndFulfill_(e))},a=function(e){r||(r=!0,n.unblockAndReject_(e))};try{t.call(e,i,a)}catch(o){a(o)}},ht.prototype.scheduleCallbacks_=function(){this.executing_||(this.executing_=!0,Oe.run(this.executeCallbacks_,this))},ht.prototype.executeCallbacks_=function(){for(;this.callbackEntries_&&this.callbackEntries_.length;){var e=this.callbackEntries_;this.callbackEntries_=[];for(var t=0;t0)for(e=this;e&&e.unhandledRejectionId_;e=e.parent_)clearTimeout(e.unhandledRejectionId_),e.unhandledRejectionId_=0;else if(0===ht.UNHANDLED_REJECTION_DELAY)for(e=this;e&&e.hadUnhandledRejection_;e=e.parent_)e.hadUnhandledRejection_=!1},ht.addUnhandledRejection_=function(e,t){ht.UNHANDLED_REJECTION_DELAY>0?e.unhandledRejectionId_=setTimeout(function(){ht.handleRejection_.call(null,t)},ht.UNHANDLED_REJECTION_DELAY):0===ht.UNHANDLED_REJECTION_DELAY&&(e.hadUnhandledRejection_=!0,Oe.run(function(){e.hadUnhandledRejection_&&ht.handleRejection_.call(null,t)}))},ht.handleRejection_=Oe.throwException,ht.setUnhandledRejectionHandler=function(e){ht.handleRejection_=e},ht.CancellationError=function(e){function t(e){Ee(this,t);var n=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return e&&(n.message=e),n}return Pe(t,e),t}(Error),ht.CancellationError.prototype.name="cancel";var ft=/([\/])?(?:(?:\:(\w+)(?:\(((?:\\.|[^\\()])*)\))?|\(((?:\\.|[^\\()])+)\))([+*?])?)/g,dt=function(){function e(t,n){if(Ee(this,e),!f(t))throw new Error("Route path not specified.");if(!y(n))throw new Error("Route handler is not a function.");this.handler=n,this.path=t}return Se(e,[{key:"buildParsedData_",value:function(){if(!this.parsedData_){var e=me(this.path),t=ge(e);this.parsedData_={regex:t,tokens:e}}return this.parsedData_}},{key:"extractParams",value:function(e){return S(this.path)?_e(this.buildParsedData_().tokens,e):{}}},{key:"getHandler",value:function(){return this.handler}},{key:"getPath",value:function(){return this.path}},{key:"matchesPath",value:function(e){var t=this.path;return y(t)?t(e):(S(t)&&(t=this.buildParsedData_().regex),t instanceof RegExp&&e.search(t)>-1)}}]),e}(),vt=function(e){function t(){Ee(this,t);var e=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.cache=null,e.cacheable=!1,e}return Pe(t,e),Se(t,[{key:"addCache",value:function(e){return this.cacheable&&(this.cache=e),this}},{key:"clearCache",value:function(){return this.cache=null,this}},{key:"disposeInternal",value:function(){this.clearCache()}},{key:"getCache",value:function(){return this.cache}},{key:"isCacheable",value:function(){return this.cacheable}},{key:"setCacheable",value:function(e){e||this.clearCache(),this.cacheable=e}}]),t}(De),pt=function(e){function t(){Ee(this,t);var e=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.id=e.makeId_(s()),e.metas=null,e.title=null,e}return Pe(t,e),Se(t,[{key:"activate",value:function(){}},{key:"beforeActivate",value:function(){}},{key:"beforeDeactivate",value:function(){}},{key:"beforeUpdateHistoryPath",value:function(e){return e}},{key:"beforeUpdateHistoryState",value:function(e){return e}},{key:"deactivate",value:function(){}},{key:"disposeInternal",value:function(){be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"disposeInternal",this).call(this)}},{key:"evaluateScripts",value:function(e){return Object.keys(e).forEach(function(t){e[t].activeChild&&$e.runScriptsInElement(e[t].activeChild)}),ht.resolve()}},{key:"evaluateStyles",value:function(){return ht.resolve()}},{key:"flip",value:function(e){var t=this,n=[];return Object.keys(e).forEach(function(r){var i=e[r],a=i.show(t.id);n.push(a)}),ht.all(n)}},{key:"getId",value:function(){return this.id}},{key:"getMetas",value:function(){return this.metas}},{key:"getSurfaceContent",value:function(){}},{key:"getTitle",value:function(){return this.title}},{key:"load",value:function(){return ht.resolve()}},{key:"makeId_",value:function(e){return"screen_"+e}},{key:"setId",value:function(e){this.id=e}},{key:"setMetas",value:function(e){this.metas=e}},{key:"setTitle",value:function(e){this.title=e}},{key:"toString",value:function(){return this.id}}]),t}(vt);pt.isImplementedBy=function(e){return e instanceof pt};var yt=function(e){function t(e){Ee(this,t);var n=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));if(!e)throw new Error("Surface element id not specified. A surface element requires a valid id.");return n.activeChild=null,n.defaultChild=null,n.element=null,n.id=e,n.transitionFn=null,n.defaultChild=n.getChild(t.DEFAULT),n.maybeWrapContentAsDefault_(),n.activeChild=n.defaultChild,n}return Pe(t,e),Se(t,[{key:"addContent",value:function(e,t){var n=this.defaultChild;f(t)&&(n=this.getChild(e),n?G(n):(n=this.createChild(e),this.transition(n,null)),I(n,t));var r=this.getElement();return r&&n&&I(r,n),n}},{key:"createChild",value:function(e){var t=Ze.document.createElement("div");return t.setAttribute("id",this.makeId_(e)),t}},{key:"getChild",value:function(e){return Ze.document.getElementById(this.makeId_(e))}},{key:"getElement",value:function(){return this.element?this.element:(this.element=Ze.document.getElementById(this.id),this.element)}},{key:"getId",value:function(){return this.id}},{key:"getTransitionFn",value:function(){return this.transitionFn}},{key:"makeId_",value:function(e){return this.id+"-"+e}},{key:"maybeWrapContentAsDefault_",value:function(){var e=this.getElement();if(e&&!this.defaultChild){for(var n=Ze.document.createDocumentFragment();e.firstChild;)n.appendChild(e.firstChild);this.defaultChild=this.addContent(t.DEFAULT,n),this.transition(null,this.defaultChild)}}},{key:"setId",value:function(e){this.id=e}},{key:"setTransitionFn",value:function(e){this.transitionFn=e}},{key:"show",value:function(e){var t=this.activeChild,n=this.getChild(e);return n||(n=this.defaultChild),this.activeChild=n,this.transition(t,n).thenAlways(function(){t&&t!==n&&M(t)})}},{key:"remove",value:function(e){var t=this.getChild(e);t&&M(t)}},{key:"toString",value:function(){return this.id}},{key:"transition",value:function(e,n){var r=this.transitionFn||t.defaultTransition;return ht.resolve(r.call(this,e,n))}}]),t}(De);yt.DEFAULT="default",yt.defaultTransition=function(e,t){e&&(e.style.display="none",e.classList.remove("flipped")),t&&(t.style.display="block",t.classList.add("flipped"))};var mt={IMMEDIATE:"immediate",SCHEDULE_LAST:"scheduleLast"},gt=function(e){function t(){Ee(this,t);var e=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.activeScreen=null,e.activePath=null,e.allowPreventNavigate=!0,e.basePath="",e.browserPathBeforeNavigate=ut.getCurrentBrowserPathWithoutHash(),e.captureScrollPositionFromScrollEvent=!0,e.defaultTitle=Ze.document.title,e.formSelector='form[enctype="multipart/form-data"]:not([data-senna-off])',e.ignoreQueryStringFromRoutePath=!1,e.linkSelector='a:not([data-senna-off]):not([target="_blank"])',e.loadingCssClass="senna-loading",e.nativeScrollRestorationSupported="scrollRestoration"in Ze.window.history,e.navigationStrategy=mt.IMMEDIATE,e.isNavigationPending=!1,e.pendingNavigate=null,e.popstateScrollLeft=0,e.popstateScrollTop=0,e.redirectPath=null,e.routes=[],e.scheduledNavigationQueue=[],e.screens={},e.skipLoadPopstate=!1,e.surfaces={},e.updateScrollPosition=!0,e.appEventHandlers_=new Be,e.appEventHandlers_.add(W(Ze.window,"scroll",ce(e.onScroll_.bind(e),100)),W(Ze.window,"load",e.onLoad_.bind(e)),W(Ze.window,"popstate",e.onPopstate_.bind(e))),e.on("startNavigate",e.onStartNavigate_),e.on("beforeNavigate",e.onBeforeNavigate_),e.on("beforeNavigate",e.onBeforeNavigateDefault_,!0),e.on("beforeUnload",e.onBeforeUnloadDefault_),e.setLinkSelector(e.linkSelector),e.setFormSelector(e.formSelector),e.maybeOverloadBeforeUnload_(),e}return Pe(t,e),Se(t,[{key:"addRoutes",value:function(e){var t=this;return Array.isArray(e)||(e=[e]),e.forEach(function(e){e instanceof dt||(e=new dt(e.path,e.handler)),t.routes.push(e)}),this}},{key:"addSurfaces",value:function(e){var t=this;return Array.isArray(e)||(e=[e]),e.forEach(function(e){S(e)&&(e=new yt(e)),t.surfaces[e.getId()]=e}),this}},{key:"canNavigate",value:function(e){var t=ut.isWebUri(e);if(!t)return!1;var n=ut.getUrlPath(e);return!!this.isLinkSameOrigin_(t.getHost())&&(!!this.isSameBasePath_(n)&&((!t.getHash()||!ut.isCurrentBrowserPath(n))&&!!this.findRoute(n)))}},{key:"clearScreensCache",value:function(){var e=this;Object.keys(this.screens).forEach(function(t){t===e.activePath?e.activeScreen.clearCache():e.isNavigationPending&&e.pendingNavigate.path===t||e.removeScreen(t)})}},{key:"createScreenInstance",value:function(e,t){if(!this.pendingNavigate&&e===this.activePath)return this.activeScreen;var n=this.screens[e];if(!n){var r=t.getHandler();n=r===pt||pt.isImplementedBy(r.prototype)?new r:r(t)||new pt}return n}},{key:"disposeInternal",value:function(){this.activeScreen&&this.removeScreen(this.activePath),this.clearScreensCache(),this.formEventHandler_.removeListener(),this.linkEventHandler_.removeListener(),this.appEventHandlers_.removeAllListeners(),be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"disposeInternal",this).call(this)}},{key:"dispatch",value:function(){return this.navigate(ut.getCurrentBrowserPath(),!0)}},{key:"doNavigate_",value:function(e,t){var n=this,r=this.findRoute(e);if(!r)return this.pendingNavigate=ht.reject(new ht.CancellationError("No route for "+e)),this.pendingNavigate;this.stopPendingNavigate_(),this.isNavigationPending=!0;var i=this.createScreenInstance(e,r);return this.maybePreventDeactivate_().then(function(){return n.maybePreventActivate_(i)}).then(function(){return i.load(e)}).then(function(){n.navigationStrategy=mt.SCHEDULE_LAST,n.activeScreen&&n.activeScreen.deactivate(),n.prepareNavigateHistory_(e,i,t),n.prepareNavigateSurfaces_(i,n.surfaces,n.extractParams(r,e))}).then(function(){return i.evaluateStyles(n.surfaces)}).then(function(){return i.flip(n.surfaces)}).then(function(){return i.evaluateScripts(n.surfaces)}).then(function(){return n.maybeUpdateScrollPositionState_()}).then(function(){return n.syncScrollPositionSyncThenAsync_()}).then(function(){return n.finalizeNavigate_(e,i)}).then(function(){return n.maybeOverloadBeforeUnload_()})["catch"](function(t){throw n.isNavigationPending=!1,n.handleNavigateError_(e,i,t),t}).thenAlways(function(){if(n.navigationStrategy=mt.IMMEDIATE,n.scheduledNavigationQueue.length){var e=n.scheduledNavigationQueue.shift();n.maybeNavigate_(e.href,e)}})}},{key:"extractParams",value:function(e,t){return e.extractParams(this.getRoutePath(t))}},{key:"finalizeNavigate_",value:function(e,t){t.activate(),this.activeScreen&&!this.activeScreen.isCacheable()&&this.activeScreen!==t&&this.removeScreen(this.activePath),this.activePath=e,this.activeScreen=t,this.browserPathBeforeNavigate=ut.getCurrentBrowserPathWithoutHash(),this.screens[e]=t,this.isNavigationPending=!1,this.pendingNavigate=null,Ze.capturedFormElement=null,Ze.capturedFormButtonElement=null}},{key:"findRoute",value:function(e){e=this.getRoutePath(e);for(var t=0;t0}},{key:"isLinkSameOrigin_",value:function(e){var t=new at(e),n=new at(Ze.window.location.host);return t.getPort()===n.getPort()&&t.getHostname()===n.getHostname()}},{key:"isSameBasePath_",value:function(e){return 0===e.indexOf(this.basePath)}},{key:"lockHistoryScrollPosition_",value:function(){var e=Ze.window.history.state;if(e){var t=!1,n=function r(){Ze.document.removeEventListener("scroll",r,!1),t||(Ze.window.scrollTo(e.scrollLeft,e.scrollTop),t=!0)};Oe.nextTick(n),Ze.document.addEventListener("scroll",n,!1)}}},{key:"maybeDisableNativeScrollRestoration",value:function(){this.nativeScrollRestorationSupported&&(this.nativeScrollRestoration_=Ze.window.history.scrollRestoration,Ze.window.history.scrollRestoration="manual")}},{key:"maybeScheduleNavigation_",value:function(e,t){return!(!this.isNavigationPending||this.navigationStrategy!==mt.SCHEDULE_LAST)&&(this.scheduledNavigationQueue=[Ie.mixin({href:e,isScheduledNavigation:!0},t)],!0)}},{key:"maybeNavigate_",value:function(e,t){if(this.canNavigate(e)){var n=this.maybeScheduleNavigation_(e,t);if(n)return void t.preventDefault();var r=!1;try{this.navigate(ut.getUrlPath(e),!1,t)}catch(i){r=!0}r||t.isScheduledNavigation||t.preventDefault()}}},{key:"maybeOverloadBeforeUnload_",value:function(){var e=this;"function"==typeof window.onbeforeunload&&(window._onbeforeunload=window.onbeforeunload,window.onbeforeunload=function(t){if(e.emit("beforeUnload",t),t&&t.defaultPrevented)return!0},window.onbeforeunload._overloaded=!0)}},{key:"maybePreventActivate_",value:function(e){var t=this;return ht.resolve().then(function(){return e.beforeActivate()}).then(function(e){if(e)return t.pendingNavigate=ht.reject(new ht.CancellationError("Cancelled by next screen")),t.pendingNavigate})}},{key:"maybePreventDeactivate_",value:function(){var e=this;return ht.resolve().then(function(){if(e.activeScreen)return e.activeScreen.beforeDeactivate()}).then(function(t){if(t)return e.pendingNavigate=ht.reject(new ht.CancellationError("Cancelled by active screen")),e.pendingNavigate})}},{key:"maybeRepositionScrollToHashedAnchor",value:function(){var e=Ze.window.location.hash;if(e){var t=Ze.document.getElementById(e.substring(1));if(t){var n=ut.getNodeOffset(t),r=n.offsetLeft,i=n.offsetTop;Ze.window.scrollTo(r,i)}}}},{key:"maybeRestoreNativeScrollRestoration",value:function(){this.nativeScrollRestorationSupported&&this.nativeScrollRestoration_&&(Ze.window.history.scrollRestoration=this.nativeScrollRestoration_)}},{key:"maybeRestoreRedirectPathHash_",value:function(e,t,n){return t===ut.getUrlPathWithoutHash(e)?t+n:t}},{key:"maybeUpdateScrollPositionState_",value:function(){var e=Ze.window.location.hash,t=Ze.document.getElementById(e.substring(1));if(t){var n=ut.getNodeOffset(t),r=n.offsetLeft,i=n.offsetTop;this.saveHistoryCurrentPageScrollPosition_(i,r)}}},{key:"navigate",value:function(e,t,n){if(!ut.isHtml5HistorySupported())throw new Error("HTML5 History is not supported. Senna will not intercept navigation.");return n&&(Ze.capturedFormElement=n.capturedFormElement,Ze.capturedFormButtonElement=n.capturedFormButtonElement),e===this.activePath&&(t=!0),this.emit("beforeNavigate",{event:n,path:e,replaceHistory:!!t}),this.pendingNavigate}},{key:"onBeforeNavigate_",value:function(e){Ze.capturedFormElement&&(e.form=Ze.capturedFormElement)}},{key:"onBeforeNavigateDefault_",value:function(e){(!this.pendingNavigate||this.pendingNavigate.path!==e.path&&this.navigationStrategy!==mt.SCHEDULE_LAST)&&(this.emit("beforeUnload",e),this.emit("startNavigate",{form:e.form,path:e.path,replaceHistory:e.replaceHistory}))}},{key:"onBeforeUnloadDefault_",value:function(e){var t=window._onbeforeunload;t&&!t._overloaded&&t()&&e.preventDefault()}},{key:"onDocClickDelegate_",value:function(e){e.altKey||e.ctrlKey||e.metaKey||e.shiftKey||e.button||this.maybeNavigate_(e.delegateTarget.href,e)}},{key:"onDocSubmitDelegate_",value:function(e){var t=e.delegateTarget;if("get"!==t.method){e.capturedFormElement=t;var n="button:not([type]),button[type=submit],input[type=submit]";B(Ze.document.activeElement,n)?e.capturedFormButtonElement=Ze.document.activeElement:e.capturedFormButtonElement=t.querySelector(n),this.maybeNavigate_(t.action,e)}}},{key:"onLoad_",value:function(){var e=this;this.skipLoadPopstate=!0,setTimeout(function(){e.skipLoadPopstate=!1},0),this.maybeRepositionScrollToHashedAnchor()}},{key:"onPopstate_",value:function(e){if(!this.skipLoadPopstate){if(ut.isCurrentBrowserPath(this.browserPathBeforeNavigate))return void this.maybeRepositionScrollToHashedAnchor();var t=e.state;if(!t)return void(Ze.window.location.hash?(this.redirectPath&&!ut.isCurrentBrowserPath(this.redirectPath)&&this.reloadPage(),this.maybeRepositionScrollToHashedAnchor()):this.reloadPage());if(t.senna){this.popstateScrollTop=t.scrollTop,this.popstateScrollLeft=t.scrollLeft,this.nativeScrollRestorationSupported||this.lockHistoryScrollPosition_(),this.once("endNavigate",function(){t.referrer&&ut.setReferrer(t.referrer)});var n=new at(t.path);n.setHostname(Ze.window.location.hostname),n.setPort(Ze.window.location.port);var r=this.maybeScheduleNavigation_(n.toString(),{});if(r)return;this.navigate(t.path,!0)}}}},{key:"onScroll_",value:function(){this.captureScrollPositionFromScrollEvent&&this.saveHistoryCurrentPageScrollPosition_(Ze.window.pageYOffset,Ze.window.pageXOffset)}},{key:"onStartNavigate_",value:function(e){var t=this;this.maybeDisableNativeScrollRestoration(),this.captureScrollPositionFromScrollEvent=!1,C(Ze.document.documentElement,this.loadingCssClass);var n={form:e.form,path:e.path};this.pendingNavigate=this.doNavigate_(e.path,e.replaceHistory)["catch"](function(e){throw n.error=e,e}).thenAlways(function(){t.pendingNavigate||t.scheduledNavigationQueue.length||(X(Ze.document.documentElement,t.loadingCssClass),t.maybeRestoreNativeScrollRestoration(),t.captureScrollPositionFromScrollEvent=!0),t.emit("endNavigate",n)}),this.pendingNavigate.path=e.path}},{key:"prefetch",value:function(e){var t=this,n=this.findRoute(e);if(!n)return ht.reject(new ht.CancellationError("No route for "+e));var r=this.createScreenInstance(e,n);return r.load(e).then(function(){return t.screens[e]=r})["catch"](function(n){throw t.handleNavigateError_(e,r,n),n})}},{key:"prepareNavigateHistory_",value:function(e,t,n){var r=t.getTitle();S(r)||(r=this.getDefaultTitle());var i=t.beforeUpdateHistoryPath(e),a={form:f(Ze.capturedFormElement),path:e,redirectPath:i,scrollLeft:0,scrollTop:0,senna:!0};n&&(a.scrollTop=this.popstateScrollTop,a.scrollLeft=this.popstateScrollLeft);var o=new at(e).getHash();i=this.maybeRestoreRedirectPathHash_(e,i,o),this.updateHistory_(r,i,t.beforeUpdateHistoryState(a),n),this.redirectPath=i}},{key:"prepareNavigateSurfaces_",value:function(e,t,n){Object.keys(t).forEach(function(r){var i=e.getSurfaceContent(r,n);t[r].addContent(e.getId(),i)})}},{key:"reloadPage",value:function(){Ze.window.location.reload()}},{key:"removeRoute",value:function(e){return Ne.remove(this.routes,e)}},{key:"removeScreen",value:function(e){var t=this,n=this.screens[e];n&&(Object.keys(this.surfaces).forEach(function(e){return t.surfaces[e].remove(n.getId())}),n.dispose(),delete this.screens[e])}},{key:"saveHistoryCurrentPageScrollPosition_",value:function(e,t){var n=Ze.window.history.state;if(n&&n.senna){var r=[e,t];n.scrollTop=r[0],n.scrollLeft=r[1],Ze.window.history.replaceState(n,null,null)}}},{key:"setAllowPreventNavigate",value:function(e){this.allowPreventNavigate=e}},{key:"setBasePath",value:function(e){this.basePath=ut.removePathTrailingSlash(e)}},{key:"setDefaultTitle",value:function(e){this.defaultTitle=e}},{key:"setFormSelector",value:function(e){this.formSelector=e,this.formEventHandler_&&this.formEventHandler_.removeListener(),this.formEventHandler_=x(document,"submit",this.formSelector,this.onDocSubmitDelegate_.bind(this),this.allowPreventNavigate)}},{key:"setIgnoreQueryStringFromRoutePath",value:function(e){this.ignoreQueryStringFromRoutePath=e}},{key:"setLinkSelector",value:function(e){this.linkSelector=e,this.linkEventHandler_&&this.linkEventHandler_.removeListener(),this.linkEventHandler_=x(document,"click",this.linkSelector,this.onDocClickDelegate_.bind(this),this.allowPreventNavigate)}},{key:"setLoadingCssClass",value:function(e){this.loadingCssClass=e}},{key:"setUpdateScrollPosition",value:function(e){this.updateScrollPosition=e}},{key:"stopPendingNavigate_",value:function(){this.pendingNavigate&&this.pendingNavigate.cancel("Cancel pending navigation"),this.pendingNavigate=null}},{key:"syncScrollPositionSyncThenAsync_",value:function(){var e=this,t=Ze.window.history.state;if(t){var n=t.scrollTop,r=t.scrollLeft,i=function(){e.updateScrollPosition&&Ze.window.scrollTo(r,n)};return new ht(function(e){return i()&Oe.nextTick(function(){return i()&e()})})}}},{key:"updateHistory_",value:function(e,t,n,r){var i=Ze.window.location.href;n&&(n.referrer=i),r?Ze.window.history.replaceState(n,e,t):Ze.window.history.pushState(n,e,t),ut.setReferrer(i);var a=Ze.document.querySelector("title");a?a.innerHTML=e:Ze.document.title=e}}]),t}(Me),_t=function(){function e(){Ee(this,e)}return Se(e,null,[{key:"parseResponseHeaders",value:function(e){var t=[];if(!e)return t;for(var n=e.split("\r\n"),r=0;r0){var a=n[r].substring(0,i),o=n[r].substring(i+2);t.push({name:a,value:o})}}return t}},{key:"request",value:function t(e,n,r,i,a,o,u,s){e=e||"",n=n||"GET";var t=new XMLHttpRequest,l=0,c=new ht(function(e,n){t.onload=function(){return t.aborted?void t.onerror():void e(t)},t.onreadystatechange=function(){l&&l<3&&4===t.readyState&&(t.terminatedPrematurely=!0),l=t.readyState},t.onerror=function(){var e="Request error";t.terminatedPrematurely&&(e="Request terminated prematurely");var r=new Error(e);r.request=t,n(r)}}).thenCatch(function(e){throw t.abort(),e}).thenAlways(function(){clearTimeout(d)});if(e=new at(e),a&&e.addParametersFromMultiMap(a).toString(),e=e.toString(),t.open(n,e,!u),s&&(t.withCredentials=!0),i&&i.names().forEach(function(e){t.setRequestHeader(e,i.getAll(e).join(", "))}),t.send(h(r)?r:null),f(o))var d=setTimeout(function(){c.cancel("Request timeout")},o);return c}}]),e}(),kt=function Lt(){Ee(this,Lt)};kt.INVALID_STATUS="Invalid status code",kt.REQUEST_ERROR="Request error",kt.REQUEST_TIMEOUT="Request timeout",kt.REQUEST_PREMATURE_TERMINATION="Request terminated prematurely";var Et=function(){function e(){Ee(this,e)}return Se(e,null,[{key:"getNativeUserAgent",value:function(){var t=e.globals.window&&e.globals.window.navigator;if(t){var n=t.userAgent;if(n)return n}return""}},{key:"getNativePlatform",value:function(){var t=e.globals.window&&e.globals.window.navigator;if(t){var n=t.platform;if(n)return n}return""}},{key:"matchPlatform",value:function(t){return e.platform.indexOf(t)!==-1}},{key:"matchUserAgent",value:function(t){return e.userAgent.indexOf(t)!==-1}},{key:"testUserAgent",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";e.userAgent=t,e.platform=n,e.isMac=e.matchPlatform("Mac"),e.isWin=e.matchPlatform("Win"),e.isOpera=e.matchUserAgent("Opera")||e.matchUserAgent("OPR"),e.isIe=e.matchUserAgent("Trident")||e.matchUserAgent("MSIE"),e.isEdge=e.matchUserAgent("Edge"),e.isIeOrEdge=e.isIe||e.isEdge,e.isChrome=(e.matchUserAgent("Chrome")||e.matchUserAgent("CriOS"))&&!e.isOpera&&!e.isEdge,e.isSafari=e.matchUserAgent("Safari")&&!(e.isChrome||e.isOpera||e.isEdge),e.isFirefox=e.matchUserAgent("Firefox")}}]),e}();Object.defineProperty(Et,"globals",{writable:!0,value:{window:b()?null:window}}),Et.testUserAgent(Et.getNativeUserAgent(),Et.getNativePlatform());var St=function(e){ -function t(){Ee(this,t);var e=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.cacheable=!0,e.httpHeaders={"X-PJAX":"true","X-Requested-With":"XMLHttpRequest"},e.httpMethod=t.GET,e.request=null,e.timeout=3e4,e}return Pe(t,e),Se(t,[{key:"assertValidResponseStatusCode",value:function(e){if(!this.isValidResponseStatusCode(e)){var t=new Error(kt.INVALID_STATUS);throw t.invalidStatus=!0,t.statusCode=e,t}}},{key:"beforeUpdateHistoryPath",value:function(e){var t=this.getRequestPath();return t&&t!==e?t:e}},{key:"beforeUpdateHistoryState",value:function(e){return e.senna&&e.form&&e.redirectPath===e.path?null:e}},{key:"formatLoadPath",value:function(e){var n=new at(e);return n.setHostname(Ze.window.location.hostname),n.setProtocol(Ze.window.location.protocol),Ze.window.location.port&&n.setPort(Ze.window.location.port),Et.isIeOrEdge&&this.httpMethod===t.GET?n.makeUnique().toString():n.toString()}},{key:"getHttpHeaders",value:function(){return this.httpHeaders}},{key:"getHttpMethod",value:function(){return this.httpMethod}},{key:"getRequestPath",value:function(){var e=this.getRequest();if(e){var n=e.requestPath,r=this.maybeExtractResponseUrlFromRequest(e);return r&&(n=r),Et.isIeOrEdge&&this.httpMethod===t.GET&&(n=new at(n).removeUnique().toString()),ut.getUrlPath(n)}return null}},{key:"getRequest",value:function(){return this.request}},{key:"getTimeout",value:function(){return this.timeout}},{key:"isValidResponseStatusCode",value:function(e){return e>=200&&e<=399}},{key:"load",value:function(e){var n=this,r=this.getCache();if(f(r))return ht.resolve(r);var i=null,a=this.httpMethod,o=new tt;Object.keys(this.httpHeaders).forEach(function(e){return o.add(e,n.httpHeaders[e])}),Ze.capturedFormElement&&(this.addSafariXHRPolyfill(),i=new FormData(Ze.capturedFormElement),this.maybeAppendSubmitButtonValue_(i),a=t.POST,Et.isIeOrEdge&&o.add("If-None-Match",'"0"'));var u=this.formatLoadPath(e);return _t.request(u,a,i,o,null,this.timeout).then(function(e){return n.removeSafariXHRPolyfill(),n.setRequest(e),n.assertValidResponseStatusCode(e.status),a===t.GET&&n.isCacheable()&&n.addCache(e.responseText),e.requestPath=u,e.responseText})["catch"](function(e){switch(n.removeSafariXHRPolyfill(),e.message){case kt.REQUEST_TIMEOUT:e.timeout=!0;break;case kt.REQUEST_ERROR:e.requestError=!0;break;case kt.REQUEST_PREMATURE_TERMINATION:e.requestError=!0,e.requestPrematureTermination=!0}throw e})}},{key:"maybeAppendSubmitButtonValue_",value:function(e){var t=Ze.capturedFormButtonElement;t&&t.name&&e.append(t.name,t.value)}},{key:"maybeExtractResponseUrlFromRequest",value:function(e){var n=e.responseURL;return n?n:e.getResponseHeader(t.X_REQUEST_URL_HEADER)}},{key:"addSafariXHRPolyfill",value:function(){if(Ze.capturedFormElement&&Et.isSafari)for(var e=Ze.capturedFormElement.querySelectorAll('input[type="file"]:not([disabled])'),t=0;t0)return;n.setAttribute("data-safari-temp-disabled","true"),n.setAttribute("disabled","")}}},{key:"removeSafariXHRPolyfill",value:function(){if(Ze.capturedFormElement&&Et.isSafari)for(var e=Ze.capturedFormElement.querySelectorAll('input[type="file"][data-safari-temp-disabled]'),t=0;t/gi,"/senna>");var n=void 0;if(Et.isIe){var r=Ze.document.createRange().createContextualFragment(e);n=r.querySelector("senna")}else t.innerHTML=e,n=t.querySelector("senna");n&&(ut.clearNodeAttributes(t),ut.copyNodeAttributes(n,t))}},{key:"disposeInternal",value:function(){this.disposePendingStyles(),be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"disposeInternal",this).call(this)}},{key:"disposePendingStyles",value:function(){this.pendingStyles&&ut.removeElementsFromDocument(this.pendingStyles)}},{key:"evaluateScripts",value:function(e){var n=this,r=this.evaluateTrackedResources_($e.runScriptsInElement,t.selectors.scripts,t.selectors.scriptsTemporary,t.selectors.scriptsPermanent);return r.then(function(){return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"evaluateScripts",n).call(n,e)})}},{key:"evaluateStyles",value:function(e){var n=this;this.pendingStyles=[];var r=this.evaluateTrackedResources_(Ke.runStylesInElement,t.selectors.styles,t.selectors.stylesTemporary,t.selectors.stylesPermanent,this.appendStyleIntoDocument_.bind(this));return r.then(function(){return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"evaluateStyles",n).call(n,e)})}},{key:"evaluateFavicon_",value:function(){var e=this,n=this.virtualQuerySelectorAll_(t.selectors.favicon),r=this.querySelectorAll_(t.selectors.favicon);return new ht(function(t){ut.removeElementsFromDocument(r),e.runFaviconInElement_(n).then(function(){return t()})})}},{key:"evaluateTrackedResources_",value:function(e,n,r,i,a){var o=this,u=this.virtualQuerySelectorAll_(n),s=this.querySelectorAll_(r),l=this.querySelectorAll_(i);l.forEach(function(e){var n=o.getResourceKey_(e);n&&(t.permanentResourcesInDoc[n]=!0)});var c=H();return u.forEach(function(e){var n=o.getResourceKey_(e);t.permanentResourcesInDoc[n]||c.appendChild(e),n&&B(e,i)&&(t.permanentResourcesInDoc[n]=!0)}),new ht(function(t){e(c,function(){ut.removeElementsFromDocument(s),t()},a)})}},{key:"flip",value:function(e){var n=this;return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"flip",this).call(this,e).then(function(){ut.clearNodeAttributes(Ze.document.documentElement),ut.copyNodeAttributes(n.virtualDocument,Ze.document.documentElement),n.evaluateFavicon_(),n.updateMetaTags_()})}},{key:"updateMetaTags_",value:function(){var e=this.querySelectorAll_("meta"),t=this.metas;e&&(ut.removeElementsFromDocument(e),t&&t.forEach(function(e){return Ze.document.head.appendChild(e)}))}},{key:"getResourceKey_",value:function(e){return e.id||e.href||e.src||""}},{key:"getSurfaceContent",value:function(e){var t=this.virtualDocument.querySelector("#"+e);if(t){var n=t.querySelector("#"+e+"-"+yt.DEFAULT);return n?n.innerHTML:t.innerHTML}}},{key:"getTitleSelector",value:function(){return this.titleSelector}},{key:"load",value:function(e){var n=this;return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"load",this).call(this,e).then(function(e){return n.allocateVirtualDocumentForContent(e),n.resolveTitleFromVirtualDocument(),n.resolveMetaTagsFromVirtualDocument(),n.assertSameBodyIdInVirtualDocument(),Et.isIe&&n.makeTemporaryStylesHrefsUnique_(),e})}},{key:"makeTemporaryStylesHrefsUnique_",value:function(){var e=this,n=this.virtualQuerySelectorAll_(t.selectors.stylesTemporary);n.forEach(function(t){return e.replaceStyleAndMakeUnique_(t)})}},{key:"replaceStyleAndMakeUnique_",value:function(e){if(e.href){var t=Ze.document.createElement(e.tagName);e.href=new at(e.href).makeUnique().toString(),ut.copyNodeAttributes(e,t),e.parentNode.replaceChild(t,e),e.disabled=!0}}},{key:"runFaviconInElement_",value:function(e){return new ht(function(t){e.forEach(function(e){return document.head.appendChild(Et.isIe?e:ut.setElementWithRandomHref(e))}),t()})}},{key:"virtualQuerySelectorAll_",value:function(e){return Array.prototype.slice.call(this.virtualDocument.querySelectorAll(e))}},{key:"querySelectorAll_",value:function(e){return Array.prototype.slice.call(Ze.document.querySelectorAll(e))}},{key:"releaseVirtualDocument",value:function(){this.virtualDocument=null}},{key:"resolveTitleFromVirtualDocument",value:function(){var e=this.virtualDocument.querySelector(this.titleSelector);e&&this.setTitle(e.textContent.trim())}},{key:"resolveMetaTagsFromVirtualDocument",value:function(){var e=this.virtualQuerySelectorAll_(this.metaTagsSelector);e&&this.setMetas(e)}},{key:"setTitleSelector",value:function(e){this.titleSelector=e}}]),t}(St),Pt=':not([rel="Shortcut Icon"]):not([rel="shortcut icon"]):not([rel="icon"]):not([href$="favicon.icon"])';bt.selectors={favicon:'link[rel="Shortcut Icon"],link[rel="shortcut icon"],link[rel="icon"],link[href$="favicon.icon"]',scripts:"script[data-senna-track]",scriptsPermanent:'script[data-senna-track="permanent"]',scriptsTemporary:'script[data-senna-track="temporary"]',styles:"style[data-senna-track],link[data-senna-track]"+Pt,stylesPermanent:'style[data-senna-track="permanent"],link[data-senna-track="permanent"]'+Pt,stylesTemporary:'style[data-senna-track="temporary"],link[data-senna-track="temporary"]'+Pt},bt.permanentResourcesInDoc={};var wt=function(e){function t(){Ee(this,t);var e=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.app=null,e.baseElement=null,e}return Pe(t,e),Se(t,[{key:"handle",value:function(){if(!p(this.baseElement))throw new Error("Senna data attribute handler base element not set or invalid, try setting a valid element that contains a `data-senna` attribute.");if(this.baseElement.hasAttribute(st.senna)){if(this.app)throw new Error("Senna app was already initialized.");this.app=new gt,this.maybeAddRoutes_(),this.maybeAddSurfaces_(),this.maybeSetBasePath_(),this.maybeSetLinkSelector_(),this.maybeSetLoadingCssClass_(),this.maybeSetUpdateScrollPosition_(),this.maybeDispatch_()}}},{key:"disposeInternal",value:function(){this.app&&this.app.dispose()}},{key:"getApp",value:function(){return this.app}},{key:"getBaseElement",value:function(){return this.baseElement}},{key:"maybeAddRoutes_",value:function(){var e=this,t='link[rel="senna-route"]';this.querySelectorAllAsArray_(t).forEach(function(t){return e.maybeParseLinkRoute_(t)}),this.app.hasRoutes()||this.app.addRoutes(new dt(/.*/,bt))}},{key:"maybeAddSurfaces_",value:function(){var e=this,t="["+st.surface+"]";this.querySelectorAllAsArray_(t).forEach(function(t){e.updateElementIdIfSpecialSurface_(t),e.app.addSurfaces(t.id)})}},{key:"maybeDispatch_",value:function(){this.baseElement.hasAttribute(st.dispatch)&&this.app.dispatch()}},{key:"maybeParseLinkRoute_",value:function(e){var t=new dt(this.maybeParseLinkRoutePath_(e),this.maybeParseLinkRouteHandler_(e));this.app.addRoutes(t)}},{key:"maybeParseLinkRouteHandler_",value:function(e){var t=e.getAttribute("type");return f(t)&&(t=Ie.getObjectByName(t)),t}},{key:"maybeParseLinkRoutePath_",value:function(e){var t=e.getAttribute("href");return f(t)&&0===t.indexOf("regex:")&&(t=new RegExp(t.substring(6))),t}},{key:"maybeSetBasePath_",value:function(){var e=this.baseElement.getAttribute(st.basePath);f(e)&&this.app.setBasePath(e)}},{key:"maybeSetLinkSelector_",value:function(){var e=this.baseElement.getAttribute(st.linkSelector);f(e)&&this.app.setLinkSelector(e)}},{key:"maybeSetLoadingCssClass_",value:function(){var e=this.baseElement.getAttribute(st.loadingCssClass);f(e)&&this.app.setLoadingCssClass(e)}},{key:"maybeSetUpdateScrollPosition_",value:function(){var e=this.baseElement.getAttribute(st.updateScrollPosition);f(e)&&("false"===e?this.app.setUpdateScrollPosition(!1):this.app.setUpdateScrollPosition(!0))}},{key:"querySelectorAllAsArray_",value:function(e){return Array.prototype.slice.call(Ze.document.querySelectorAll(e))}},{key:"updateElementIdIfSpecialSurface_",value:function(e){e.id||e!==Ze.document.body||(e.id="senna_surface_"+s())}},{key:"setBaseElement",value:function(e){this.baseElement=e}}]),t}(De),Ct=new wt;Ze.document.addEventListener("DOMContentLoaded",function(){Ct.setBaseElement(Ze.document.body),Ct.handle()});var At="2.7.5";e["default"]=gt,e.dataAttributeHandler=Ct,e.utils=ut,e.App=gt,e.HtmlScreen=bt,e.Route=dt,e.RequestScreen=St,e.Screen=pt,e.version=At,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file +function t(){Ee(this,t);var e=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.cacheable=!0,e.httpHeaders={"X-PJAX":"true","X-Requested-With":"XMLHttpRequest"},e.httpMethod=t.GET,e.request=null,e.timeout=3e4,e}return Pe(t,e),Se(t,[{key:"assertValidResponseStatusCode",value:function(e){if(!this.isValidResponseStatusCode(e)){var t=new Error(kt.INVALID_STATUS);throw t.invalidStatus=!0,t.statusCode=e,t}}},{key:"beforeUpdateHistoryPath",value:function(e){var t=this.getRequestPath();return t&&t!==e?t:e}},{key:"beforeUpdateHistoryState",value:function(e){return e.senna&&e.form&&e.redirectPath===e.path?null:e}},{key:"formatLoadPath",value:function(e){var n=new at(e);return n.setHostname(Ze.window.location.hostname),n.setProtocol(Ze.window.location.protocol),Ze.window.location.port&&n.setPort(Ze.window.location.port),Et.isIeOrEdge&&this.httpMethod===t.GET?n.makeUnique().toString():n.toString()}},{key:"getHttpHeaders",value:function(){return this.httpHeaders}},{key:"getHttpMethod",value:function(){return this.httpMethod}},{key:"getRequestPath",value:function(){var e=this.getRequest();if(e){var n=e.requestPath,r=this.maybeExtractResponseUrlFromRequest(e);return r&&(n=r),Et.isIeOrEdge&&this.httpMethod===t.GET&&(n=new at(n).removeUnique().toString()),ut.getUrlPath(n)}return null}},{key:"getRequest",value:function(){return this.request}},{key:"getTimeout",value:function(){return this.timeout}},{key:"isValidResponseStatusCode",value:function(e){return e>=200&&e<=399}},{key:"load",value:function(e){var n=this,r=this.getCache();if(f(r))return ht.resolve(r);var i=null,a=this.httpMethod,o=new tt;Object.keys(this.httpHeaders).forEach(function(e){return o.add(e,n.httpHeaders[e])}),Ze.capturedFormElement&&(this.addSafariXHRPolyfill(),i=new FormData(Ze.capturedFormElement),this.maybeAppendSubmitButtonValue_(i),a=t.POST,Et.isIeOrEdge&&o.add("If-None-Match",'"0"'));var u=this.formatLoadPath(e);return _t.request(u,a,i,o,null,this.timeout).then(function(e){return n.removeSafariXHRPolyfill(),n.setRequest(e),n.assertValidResponseStatusCode(e.status),a===t.GET&&n.isCacheable()&&n.addCache(e.responseText),e.requestPath=u,e.responseText})["catch"](function(e){switch(n.removeSafariXHRPolyfill(),e.message){case kt.REQUEST_TIMEOUT:e.timeout=!0;break;case kt.REQUEST_ERROR:e.requestError=!0;break;case kt.REQUEST_PREMATURE_TERMINATION:e.requestError=!0,e.requestPrematureTermination=!0}throw e})}},{key:"maybeAppendSubmitButtonValue_",value:function(e){var t=Ze.capturedFormButtonElement;t&&t.name&&e.append(t.name,t.value)}},{key:"maybeExtractResponseUrlFromRequest",value:function(e){var n=e.responseURL;return n?n:e.getResponseHeader(t.X_REQUEST_URL_HEADER)}},{key:"addSafariXHRPolyfill",value:function(){if(Ze.capturedFormElement&&Et.isSafari)for(var e=Ze.capturedFormElement.querySelectorAll('input[type="file"]:not([disabled])'),t=0;t0)return;n.setAttribute("data-safari-temp-disabled","true"),n.setAttribute("disabled","")}}},{key:"removeSafariXHRPolyfill",value:function(){if(Ze.capturedFormElement&&Et.isSafari)for(var e=Ze.capturedFormElement.querySelectorAll('input[type="file"][data-safari-temp-disabled]'),t=0;t/gi,"/senna>");var n=void 0;if(Et.isIe){var r=Ze.document.createRange().createContextualFragment(e);n=r.querySelector("senna")}else t.innerHTML=e,n=t.querySelector("senna");n&&(ut.clearNodeAttributes(t),ut.copyNodeAttributes(n,t))}},{key:"disposeInternal",value:function(){this.disposePendingStyles(),be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"disposeInternal",this).call(this)}},{key:"disposePendingStyles",value:function(){this.pendingStyles&&ut.removeElementsFromDocument(this.pendingStyles)}},{key:"evaluateScripts",value:function(e){var n=this,r=this.evaluateTrackedResources_($e.runScriptsInElement,t.selectors.scripts,t.selectors.scriptsTemporary,t.selectors.scriptsPermanent);return r.then(function(){return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"evaluateScripts",n).call(n,e)})}},{key:"evaluateStyles",value:function(e){var n=this;this.pendingStyles=[];var r=this.evaluateTrackedResources_(Ke.runStylesInElement,t.selectors.styles,t.selectors.stylesTemporary,t.selectors.stylesPermanent,this.appendStyleIntoDocument_.bind(this));return r.then(function(){return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"evaluateStyles",n).call(n,e)})}},{key:"evaluateFavicon_",value:function(){var e=this,n=this.virtualQuerySelectorAll_(t.selectors.favicon),r=this.querySelectorAll_(t.selectors.favicon);return new ht(function(t){ut.removeElementsFromDocument(r),e.runFaviconInElement_(n).then(function(){return t()})})}},{key:"evaluateTrackedResources_",value:function(e,n,r,i,a){var o=this,u=this.virtualQuerySelectorAll_(n),s=this.querySelectorAll_(r),l=this.querySelectorAll_(i);l.forEach(function(e){var n=o.getResourceKey_(e);n&&(t.permanentResourcesInDoc[n]=!0)});var c=H();return u.forEach(function(e){var n=o.getResourceKey_(e);t.permanentResourcesInDoc[n]||c.appendChild(e),n&&B(e,i)&&(t.permanentResourcesInDoc[n]=!0)}),new ht(function(t){e(c,function(){ut.removeElementsFromDocument(s),t()},a)})}},{key:"flip",value:function(e){var n=this;return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"flip",this).call(this,e).then(function(){ut.clearNodeAttributes(Ze.document.documentElement),ut.copyNodeAttributes(n.virtualDocument,Ze.document.documentElement),n.evaluateFavicon_(),n.updateMetaTags_()})}},{key:"updateMetaTags_",value:function(){var e=this.querySelectorAll_("meta"),t=this.metas;e&&(ut.removeElementsFromDocument(e),t&&t.forEach(function(e){return Ze.document.head.appendChild(e)}))}},{key:"getResourceKey_",value:function(e){return e.id||e.href||e.src||""}},{key:"getSurfaceContent",value:function(e){var t=this.virtualDocument.querySelector("#"+e);if(t){var n=t.querySelector("#"+e+"-"+yt.DEFAULT);return n?n.innerHTML:t.innerHTML}}},{key:"getTitleSelector",value:function(){return this.titleSelector}},{key:"load",value:function(e){var n=this;return be(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"load",this).call(this,e).then(function(e){return n.allocateVirtualDocumentForContent(e),n.resolveTitleFromVirtualDocument(),n.resolveMetaTagsFromVirtualDocument(),n.assertSameBodyIdInVirtualDocument(),Et.isIe&&n.makeTemporaryStylesHrefsUnique_(),e})}},{key:"makeTemporaryStylesHrefsUnique_",value:function(){var e=this,n=this.virtualQuerySelectorAll_(t.selectors.stylesTemporary);n.forEach(function(t){return e.replaceStyleAndMakeUnique_(t)})}},{key:"replaceStyleAndMakeUnique_",value:function(e){if(e.href){var t=Ze.document.createElement(e.tagName);e.href=new at(e.href).makeUnique().toString(),ut.copyNodeAttributes(e,t),e.parentNode.replaceChild(t,e),e.disabled=!0}}},{key:"runFaviconInElement_",value:function(e){return new ht(function(t){e.forEach(function(e){return document.head.appendChild(Et.isIe?e:ut.setElementWithRandomHref(e))}),t()})}},{key:"virtualQuerySelectorAll_",value:function(e){return Array.prototype.slice.call(this.virtualDocument.querySelectorAll(e))}},{key:"querySelectorAll_",value:function(e){return Array.prototype.slice.call(Ze.document.querySelectorAll(e))}},{key:"releaseVirtualDocument",value:function(){this.virtualDocument=null}},{key:"resolveTitleFromVirtualDocument",value:function(){var e=this.virtualDocument.querySelector(this.titleSelector);e&&this.setTitle(e.textContent.trim())}},{key:"resolveMetaTagsFromVirtualDocument",value:function(){var e=this.virtualQuerySelectorAll_(this.metaTagsSelector);e&&this.setMetas(e)}},{key:"setTitleSelector",value:function(e){this.titleSelector=e}}]),t}(St),Pt=':not([rel="Shortcut Icon"]):not([rel="shortcut icon"]):not([rel="icon"]):not([href$="favicon.icon"])';bt.selectors={favicon:'link[rel="Shortcut Icon"],link[rel="shortcut icon"],link[rel="icon"],link[href$="favicon.icon"]',scripts:"script[data-senna-track]",scriptsPermanent:'script[data-senna-track="permanent"]',scriptsTemporary:'script[data-senna-track="temporary"]',styles:"style[data-senna-track],link[data-senna-track]"+Pt,stylesPermanent:'style[data-senna-track="permanent"],link[data-senna-track="permanent"]'+Pt,stylesTemporary:'style[data-senna-track="temporary"],link[data-senna-track="temporary"]'+Pt},bt.permanentResourcesInDoc={};var wt=function(e){function t(){Ee(this,t);var e=we(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return e.app=null,e.baseElement=null,e}return Pe(t,e),Se(t,[{key:"handle",value:function(){if(!p(this.baseElement))throw new Error("Senna data attribute handler base element not set or invalid, try setting a valid element that contains a `data-senna` attribute.");if(this.baseElement.hasAttribute(st.senna)){if(this.app)throw new Error("Senna app was already initialized.");this.app=new gt,this.maybeAddRoutes_(),this.maybeAddSurfaces_(),this.maybeSetBasePath_(),this.maybeSetLinkSelector_(),this.maybeSetLoadingCssClass_(),this.maybeSetUpdateScrollPosition_(),this.maybeDispatch_()}}},{key:"disposeInternal",value:function(){this.app&&this.app.dispose()}},{key:"getApp",value:function(){return this.app}},{key:"getBaseElement",value:function(){return this.baseElement}},{key:"maybeAddRoutes_",value:function(){var e=this,t='link[rel="senna-route"]';this.querySelectorAllAsArray_(t).forEach(function(t){return e.maybeParseLinkRoute_(t)}),this.app.hasRoutes()||this.app.addRoutes(new dt(/.*/,bt))}},{key:"maybeAddSurfaces_",value:function(){var e=this,t="["+st.surface+"]";this.querySelectorAllAsArray_(t).forEach(function(t){e.updateElementIdIfSpecialSurface_(t),e.app.addSurfaces(t.id)})}},{key:"maybeDispatch_",value:function(){this.baseElement.hasAttribute(st.dispatch)&&this.app.dispatch()}},{key:"maybeParseLinkRoute_",value:function(e){var t=new dt(this.maybeParseLinkRoutePath_(e),this.maybeParseLinkRouteHandler_(e));this.app.addRoutes(t)}},{key:"maybeParseLinkRouteHandler_",value:function(e){var t=e.getAttribute("type");return f(t)&&(t=Ie.getObjectByName(t)),t}},{key:"maybeParseLinkRoutePath_",value:function(e){var t=e.getAttribute("href");return f(t)&&0===t.indexOf("regex:")&&(t=new RegExp(t.substring(6))),t}},{key:"maybeSetBasePath_",value:function(){var e=this.baseElement.getAttribute(st.basePath);f(e)&&this.app.setBasePath(e)}},{key:"maybeSetLinkSelector_",value:function(){var e=this.baseElement.getAttribute(st.linkSelector);f(e)&&this.app.setLinkSelector(e)}},{key:"maybeSetLoadingCssClass_",value:function(){var e=this.baseElement.getAttribute(st.loadingCssClass);f(e)&&this.app.setLoadingCssClass(e)}},{key:"maybeSetUpdateScrollPosition_",value:function(){var e=this.baseElement.getAttribute(st.updateScrollPosition);f(e)&&("false"===e?this.app.setUpdateScrollPosition(!1):this.app.setUpdateScrollPosition(!0))}},{key:"querySelectorAllAsArray_",value:function(e){return Array.prototype.slice.call(Ze.document.querySelectorAll(e))}},{key:"updateElementIdIfSpecialSurface_",value:function(e){e.id||e!==Ze.document.body||(e.id="senna_surface_"+s())}},{key:"setBaseElement",value:function(e){this.baseElement=e}}]),t}(De),Ct=new wt;Ze.document.addEventListener("DOMContentLoaded",function(){Ct.setBaseElement(Ze.document.body),Ct.handle()});var At="2.7.6";e["default"]=gt,e.dataAttributeHandler=Ct,e.utils=ut,e.App=gt,e.HtmlScreen=bt,e.Route=dt,e.RequestScreen=St,e.Screen=pt,e.version=At,Object.defineProperty(e,"__esModule",{value:!0})}); \ No newline at end of file diff --git a/build/globals/senna.js b/build/globals/senna.js index 8bbfc15..fe62d70 100644 --- a/build/globals/senna.js +++ b/build/globals/senna.js @@ -1,7 +1,7 @@ /** * Senna.js - A blazing-fast Single Page Application engine * @author Liferay, Inc. - * @version v2.7.5 + * @version v2.7.6 * @link http://sennajs.com * @license BSD-3-Clause */ @@ -9917,7 +9917,7 @@ globals.document.addEventListener('DOMContentLoaded', function () { * @returns String containing the current senna version */ -var version = '2.7.5'; +var version = '2.7.6'; exports['default'] = App$1; exports.dataAttributeHandler = dataAttributeHandler; diff --git a/build/globals/senna.js.map b/build/globals/senna.js.map index eb97309..fef2755 100644 --- a/build/globals/senna.js.map +++ b/build/globals/senna.js.map @@ -1 +1 @@ -{"version":3,"file":"senna.js","sources":["node_modules/metal/src/coreNamed.js","node_modules/metal/src/core.js","node_modules/metal/src/array/array.js","node_modules/metal/src/async/async.js","node_modules/metal/src/disposable/Disposable.js","node_modules/metal/src/object/object.js","node_modules/metal/src/string/string.js","node_modules/metal-dom/src/domData.js","node_modules/metal-events/src/EventHandle.js","node_modules/metal-events/src/EventEmitter.js","node_modules/metal-events/src/EventEmitterProxy.js","node_modules/metal-events/src/EventHandler.js","node_modules/metal-dom/src/DomDelegatedEventHandle.js","node_modules/metal-dom/src/DomEventHandle.js","node_modules/metal-dom/src/domNamed.js","node_modules/metal-dom/src/dom.js","node_modules/metal-dom/src/DomEventEmitterProxy.js","node_modules/metal-dom/src/features.js","node_modules/metal-dom/src/globalEval.js","node_modules/metal-dom/src/globalEvalStyles.js","node_modules/metal-dom/src/events.js","src/globals/globals.js","node_modules/metal-uri/src/parseFromAnchor.js","node_modules/metal-uri/src/parse.js","node_modules/metal-structs/src/MultiMap.js","node_modules/metal-structs/src/TreeNode.js","node_modules/metal-uri/src/Uri.js","src/utils/utils.js","src/app/dataAttributes.js","node_modules/metal-promise/src/promise/Promise.js","node_modules/metal-debounce/src/debounce.js","node_modules/metal-path-parser/src/pathParser.js","src/route/Route.js","src/cacheable/Cacheable.js","src/screen/Screen.js","src/surface/Surface.js","src/app/App.js","node_modules/metal-ajax/src/Ajax.js","src/errors/errors.js","node_modules/metal-useragent/src/UA.js","src/screen/RequestScreen.js","src/screen/HtmlScreen.js","src/app/AppDataAttributeHandler.js","src/app/dataAttributeHandler.js","src/app/version.js"],"sourcesContent":["'use strict';\n\n/**\n * A collection of core utility functions.\n * @const\n */\n\nlet compatibilityModeData_;\n\n/**\n * Counter for unique id.\n * @type {Number}\n * @private\n */\nlet uniqueIdCounter_ = 1;\n\n/**\n * Unique id property prefix.\n * @type {String}\n * @protected\n */\nexport const UID_PROPERTY = `core_${(Math.random() * 1e9) >>> 0}`;\n\n/**\n * When defining a class Foo with an abstract method bar(), you can do:\n * Foo.prototype.bar = abstractMethod\n *\n * Now if a subclass of Foo fails to override bar(), an error will be thrown\n * when bar() is invoked.\n *\n * @type {!Function}\n * @throws {Error} when invoked to indicate the method should be overridden.\n */\nexport function abstractMethod() {\n\tthrow Error('Unimplemented abstract method');\n}\n\n/**\n * Disables Metal.js's compatibility mode.\n */\nexport function disableCompatibilityMode() {\n\tcompatibilityModeData_ = undefined;\n}\n\n/**\n * Enables Metal.js's compatibility mode with the following features from rc\n * and 1.x versions:\n * - Using \"key\" to reference component instances. In the current version\n * this should be done via \"ref\" instead. This allows old code still\n * using \"key\" to keep working like before. NOTE: this may cause\n * problems, since \"key\" is meant to be used differently. Only use this\n * if it's not possible to upgrade the code to use \"ref\" instead.\n * @param {Object=} data Optional object with data to specify more\n * details, such as:\n * - renderers {Array} the template renderers that should be in\n * compatibility mode, either their constructors or strings\n * representing them (e.g. 'soy' or 'jsx'). By default, all the ones\n * that extend from IncrementalDomRenderer.\n * @type {Object}\n */\nexport function enableCompatibilityMode(data = {}) {\n\tcompatibilityModeData_ = data;\n}\n\n/**\n * Returns the data used for compatibility mode, or nothing if it hasn't been\n * enabled.\n * @return {Object}\n */\nexport function getCompatibilityModeData() {\n\t// Compatibility mode can be set via the __METAL_COMPATIBILITY__ global var.\n\tif (compatibilityModeData_ === undefined) {\n\t\tif (typeof window !== 'undefined' && window.__METAL_COMPATIBILITY__) {\n\t\t\tenableCompatibilityMode(window.__METAL_COMPATIBILITY__);\n\t\t}\n\t}\n\treturn compatibilityModeData_;\n}\n\n/**\n * Returns the first argument if it's truthy, or the second otherwise.\n * @param {*} a\n * @param {*} b\n * @return {*}\n * @protected\n */\nfunction getFirstTruthy_(a, b) {\n\treturn a || b;\n}\n\n/**\n * Gets the name of the given function. If the current browser doesn't\n * support the `name` property, this will calculate it from the function's\n * content string.\n * @param {!function()} fn\n * @return {string}\n */\nexport function getFunctionName(fn) {\n\tif (!fn.name) {\n\t\tconst str = fn.toString();\n\t\tfn.name = str.substring(9, str.indexOf('('));\n\t}\n\treturn fn.name;\n}\n\n/**\n * Gets the value of a static property in the given class. The value will be\n * inherited from ancestors as expected, unless a custom merge function is given,\n * which can change how the super classes' value for that property will be merged\n * together.\n * The final merged value will be stored in another property, so that it won't\n * be recalculated even if this function is called multiple times.\n * @param {!function()} ctor Class constructor.\n * @param {string} propertyName Property name to be merged.\n * @param {function(*, *):*=} mergeFn Function that receives the merged\n * value of the property so far and the next value to be merged to it.\n * Should return these two merged together. If not passed the final property\n * will be the first truthy value among ancestors.\n * @return {Object}\n */\nexport function getStaticProperty(\n\tctor,\n\tpropertyName,\n\tmergeFn = getFirstTruthy_\n) {\n\tconst mergedName = propertyName + '_MERGED';\n\tif (!ctor.hasOwnProperty(mergedName)) {\n\t\t// eslint-disable-next-line\n\t\tlet merged = ctor.hasOwnProperty(propertyName)\n\t\t\t? ctor[propertyName]\n\t\t\t: null;\n\t\tif (ctor.__proto__ && !ctor.__proto__.isPrototypeOf(Function)) {\n\t\t\tmerged = mergeFn(\n\t\t\t\tmerged,\n\t\t\t\tgetStaticProperty(ctor.__proto__, propertyName, mergeFn)\n\t\t\t);\n\t\t}\n\t\tctor[mergedName] = merged;\n\t}\n\treturn ctor[mergedName];\n}\n\n/**\n * Gets an unique id. If `object` argument is passed, the object is\n * mutated with an unique id. Consecutive calls with the same object\n * reference won't mutate the object again, instead the current object uid\n * returns. See {@link UID_PROPERTY}.\n * @param {Object=} object Optional object to be mutated with the uid. If\n * not specified this method only returns the uid.\n * @param {boolean=} noInheritance Optional flag indicating if this\n * object's uid property can be inherited from parents or not.\n * @throws {Error} when invoked to indicate the method should be overridden.\n * @return {number}\n */\nexport function getUid(object, noInheritance) {\n\tif (object) {\n\t\tlet id = object[UID_PROPERTY];\n\t\tif (noInheritance && !object.hasOwnProperty(UID_PROPERTY)) {\n\t\t\tid = null;\n\t\t}\n\t\treturn id || (object[UID_PROPERTY] = uniqueIdCounter_++);\n\t}\n\treturn uniqueIdCounter_++;\n}\n\n/**\n * The identity function. Returns its first argument.\n * @param {*=} returnValue The single value that will be returned.\n * @return {?} The first argument.\n */\nexport function identityFunction(returnValue) {\n\treturn returnValue;\n}\n\n/**\n * Returns true if the specified value is a boolean.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is boolean.\n */\nexport function isBoolean(val) {\n\treturn typeof val === 'boolean';\n}\n\n/**\n * Returns true if the specified value is not undefined.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is defined.\n */\nexport function isDef(val) {\n\treturn val !== undefined;\n}\n\n/**\n * Returns true if value is not undefined or null.\n * @param {*} val\n * @return {boolean}\n */\nexport function isDefAndNotNull(val) {\n\treturn isDef(val) && !isNull(val);\n}\n\n/**\n * Returns true if value is a document.\n * @param {*} val\n * @return {boolean}\n */\nexport function isDocument(val) {\n\treturn val && typeof val === 'object' && val.nodeType === 9;\n}\n\n/**\n * Returns true if value is a document-fragment.\n * @param {*} val\n * @return {boolean}\n */\nexport function isDocumentFragment(val) {\n\treturn val && typeof val === 'object' && val.nodeType === 11;\n}\n\n/**\n * Returns true if value is a dom element.\n * @param {*} val\n * @return {boolean}\n */\nexport function isElement(val) {\n\treturn val && typeof val === 'object' && val.nodeType === 1;\n}\n\n/**\n * Returns true if the specified value is a function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a function.\n */\nexport function isFunction(val) {\n\treturn typeof val === 'function';\n}\n\n/**\n * Returns true if value is null.\n * @param {*} val\n * @return {boolean}\n */\nexport function isNull(val) {\n\treturn val === null;\n}\n\n/**\n * Returns true if the specified value is a number.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a number.\n */\nexport function isNumber(val) {\n\treturn typeof val === 'number';\n}\n\n/**\n * Returns true if value is a window.\n * @param {*} val\n * @return {boolean}\n */\nexport function isWindow(val) {\n\treturn val !== null && val === val.window;\n}\n\n/**\n * Returns true if the specified value is an object. This includes arrays\n * and functions.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an object.\n */\nexport function isObject(val) {\n\tconst type = typeof val;\n\treturn (type === 'object' && val !== null) || type === 'function';\n}\n\n/**\n * Returns true if value is a Promise.\n * @param {*} val\n * @return {boolean}\n */\nexport function isPromise(val) {\n\treturn val && typeof val === 'object' && typeof val.then === 'function';\n}\n\n/**\n * Returns true if value is a string.\n * @param {*} val\n * @return {boolean}\n */\nexport function isString(val) {\n\treturn typeof val === 'string' || val instanceof String;\n}\n\n/**\n * Sets to true if running inside Node.js environment with extra check for\n * `process.browser` to skip Karma runner environment. Karma environment has\n * `process` defined even though it runs on the browser.\n * @param {?Object} options Contains `checkEnv` property which if true, checks\n * the NODE_ENV variable. If NODE_ENV equals 'test', the function returns false.\n * @return {boolean}\n */\nexport function isServerSide(options = {checkEnv: true}) {\n\tlet serverSide = typeof process !== 'undefined' && !process.browser;\n\tif (serverSide && options.checkEnv) {\n\t\tserverSide =\n\t\t\ttypeof process.env !== 'undefined' &&\n\t\t\tprocess.env.NODE_ENV !== 'test';\n\t}\n\treturn serverSide;\n}\n\n/**\n * Null function used for default values of callbacks, etc.\n * @return {void} Nothing.\n */\nexport function nullFunction() {}\n","'use strict';\n\n// This file exists just for backwards compatibility, making sure that old\n// default imports for this file still work. It's best to use the named exports\n// for each function instead though, since that allows bundlers like Rollup to\n// reduce the bundle size by removing unused code.\nimport * as core from './coreNamed';\n\nexport default core;\nexport {core};\nexport * from './coreNamed';\n","'use strict';\n\n/**\n * Set of utilities for array operations\n */\nclass array {\n\t/**\n\t * Checks if the given arrays have the same content.\n\t * @param {!Array<*>} arr1\n\t * @param {!Array<*>} arr2\n\t * @return {boolean}\n\t */\n\tstatic equal(arr1, arr2) {\n\t\tif (arr1 === arr2) {\n\t\t\treturn true;\n\t\t}\n\t\tif (arr1.length !== arr2.length) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (let i = 0; i < arr1.length; i++) {\n\t\t\tif (arr1[i] !== arr2[i]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the first value in the given array that isn't undefined.\n\t * @param {!Array} arr\n\t * @return {*}\n\t */\n\tstatic firstDefinedValue(arr) {\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\tif (arr[i] !== undefined) {\n\t\t\t\treturn arr[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Transforms the input nested array to become flat.\n\t * @param {Array.<*|Array.<*>>} arr Nested array to flatten.\n\t * @param {Array.<*>=} output Optional output array.\n\t * @return {Array.<*>} Flat array.\n\t */\n\tstatic flatten(arr, output = []) {\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\tif (Array.isArray(arr[i])) {\n\t\t\t\tarray.flatten(arr[i], output);\n\t\t\t} else {\n\t\t\t\toutput.push(arr[i]);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Removes the first occurrence of a particular value from an array.\n\t * @param {Array.} arr Array from which to remove value.\n\t * @param {T} obj Object to remove.\n\t * @return {boolean} True if an element was removed.\n\t * @template T\n\t */\n\tstatic remove(arr, obj) {\n\t\tconst i = arr.indexOf(obj);\n\t\tlet rv;\n\t\tif ((rv = i >= 0)) {\n\t\t\tarray.removeAt(arr, i);\n\t\t}\n\t\treturn rv;\n\t}\n\n\t/**\n\t * Removes from an array the element at index i\n\t * @param {Array} arr Array or array like object from which to remove value.\n\t * @param {number} i The index to remove.\n\t * @return {boolean} True if an element was removed.\n\t */\n\tstatic removeAt(arr, i) {\n\t\treturn Array.prototype.splice.call(arr, i, 1).length === 1;\n\t}\n\n\t/**\n\t * Slices the given array, just like Array.prototype.slice, but this\n\t * is faster and working on all array-like objects (like arguments).\n\t * @param {!Object} arr Array-like object to slice.\n\t * @param {number} start The index that should start the slice.\n\t * @param {number=} end The index where the slice should end, not\n\t * included in the final array. If not given, all elements after the\n\t * start index will be included.\n\t * @return {!Array}\n\t */\n\tstatic slice(arr, start, end = arr.length) {\n\t\tconst sliced = [];\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tsliced.push(arr[i]);\n\t\t}\n\t\treturn sliced;\n\t}\n}\n\nexport default array;\n","/* !\n * Polyfill from Google's Closure Library.\n * Copyright 2013 The Closure Library Authors. All Rights Reserved.\n */\n\n'use strict';\n\nimport {isServerSide} from '../coreNamed';\n\nconst async = {};\n\n/**\n * Throw an item without interrupting the current execution context. For\n * example, if processing a group of items in a loop, sometimes it is useful\n * to report an error while still allowing the rest of the batch to be\n * processed.\n * @param {*} exception\n */\nasync.throwException = function(exception) {\n\t// Each throw needs to be in its own context.\n\tasync.nextTick(function() {\n\t\tthrow exception;\n\t});\n};\n\n/**\n * Fires the provided callback just before the current callstack unwinds, or as\n * soon as possible after the current JS execution context.\n * @param {function(this:THIS)} callback\n * @param {THIS=} context Object to use as the \"this value\" when calling\n * the provided function.\n * @template THIS\n */\nasync.run = function(callback, context) {\n\tif (!async.run.workQueueScheduled_) {\n\t\t// Nothing is currently scheduled, schedule it now.\n\t\tasync.nextTick(async.run.processWorkQueue);\n\t\tasync.run.workQueueScheduled_ = true;\n\t}\n\n\tasync.run.workQueue_.push(new async.run.WorkItem_(callback, context));\n};\n\n/** @private {boolean} */\nasync.run.workQueueScheduled_ = false;\n\n/** @private {!Array.} */\nasync.run.workQueue_ = [];\n\n/**\n * Run any pending async.run work items. This function is not intended\n * for general use, but for use by entry point handlers to run items ahead of\n * async.nextTick.\n */\nasync.run.processWorkQueue = function() {\n\t// NOTE: additional work queue items may be pushed while processing.\n\twhile (async.run.workQueue_.length) {\n\t\t// Don't let the work queue grow indefinitely.\n\t\tconst workItems = async.run.workQueue_;\n\t\tasync.run.workQueue_ = [];\n\t\tfor (let i = 0; i < workItems.length; i++) {\n\t\t\tconst workItem = workItems[i];\n\t\t\ttry {\n\t\t\t\tworkItem.fn.call(workItem.scope);\n\t\t\t} catch (e) {\n\t\t\t\tasync.throwException(e);\n\t\t\t}\n\t\t}\n\t}\n\n\t// There are no more work items, reset the work queue.\n\tasync.run.workQueueScheduled_ = false;\n};\n\n/**\n * @constructor\n * @final\n * @struct\n * @private\n *\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\nasync.run.WorkItem_ = function(fn, scope) {\n\t/** @const */\n\tthis.fn = fn;\n\t/** @const */\n\tthis.scope = scope;\n};\n\n/**\n * Fires the provided callbacks as soon as possible after the current JS\n * execution context. setTimeout(…, 0) always takes at least 5ms for legacy\n * reasons.\n * @param {function(this:SCOPE)} callback Callback function to fire as soon as\n * possible.\n * @param {SCOPE=} context Object in whose scope to call the listener.\n * @template SCOPE\n */\nasync.nextTick = function(callback, context) {\n\tlet cb = callback;\n\tif (context) {\n\t\tcb = callback.bind(context);\n\t}\n\tcb = async.nextTick.wrapCallback_(cb);\n\t// Look for and cache the custom fallback version of setImmediate.\n\tif (!async.nextTick.setImmediate_) {\n\t\tif (\n\t\t\ttypeof setImmediate === 'function' &&\n\t\t\tisServerSide({checkEnv: false})\n\t\t) {\n\t\t\tasync.nextTick.setImmediate_ = setImmediate;\n\t\t} else {\n\t\t\t// eslint-disable-next-line\n\t\t\tasync.nextTick.setImmediate_ = async.nextTick.getSetImmediateEmulator_();\n\t\t}\n\t}\n\tasync.nextTick.setImmediate_(cb);\n};\n\n/**\n * Cache for the setImmediate implementation.\n * @type {function(function())}\n * @private\n */\nasync.nextTick.setImmediate_ = null;\n\n/**\n * Determines the best possible implementation to run a function as soon as\n * the JS event loop is idle.\n * @return {function(function())} The \"setImmediate\" implementation.\n * @private\n */\nasync.nextTick.getSetImmediateEmulator_ = function() {\n\t// Create a private message channel and use it to postMessage empty messages\n\t// to ourselves.\n\tlet Channel;\n\n\t// Verify if variable is defined on the current runtime (i.e., node, browser).\n\t// Can't use typeof enclosed in a function (such as core.isFunction) or an\n\t// exception will be thrown when the function is called on an environment\n\t// where the variable is undefined.\n\tif (typeof MessageChannel === 'function') {\n\t\tChannel = MessageChannel;\n\t}\n\n\t// If MessageChannel is not available and we are in a browser, implement\n\t// an iframe based polyfill in browsers that have postMessage and\n\t// document.addEventListener. The latter excludes IE8 because it has a\n\t// synchronous postMessage implementation.\n\tif (\n\t\ttypeof Channel === 'undefined' &&\n\t\ttypeof window !== 'undefined' &&\n\t\twindow.postMessage &&\n\t\twindow.addEventListener\n\t) {\n\t\t/** @constructor */\n\t\tChannel = function() {\n\t\t\t// Make an empty, invisible iframe.\n\t\t\tconst iframe = document.createElement('iframe');\n\t\t\tiframe.style.display = 'none';\n\t\t\tiframe.src = '';\n\t\t\tiframe.title = '';\n\t\t\tdocument.documentElement.appendChild(iframe);\n\t\t\tconst win = iframe.contentWindow;\n\t\t\tconst doc = win.document;\n\t\t\tdoc.open();\n\t\t\tdoc.write('');\n\t\t\tdoc.close();\n\t\t\tconst message = 'callImmediate' + Math.random();\n\t\t\tconst origin = win.location.protocol + '//' + win.location.host;\n\t\t\tconst onmessage = function(e) {\n\t\t\t\t// Validate origin and message to make sure that this message was\n\t\t\t\t// intended for us.\n\t\t\t\tif (e.origin !== origin && e.data !== message) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.port1.onmessage();\n\t\t\t}.bind(this);\n\t\t\twin.addEventListener('message', onmessage, false);\n\t\t\tthis.port1 = {};\n\t\t\tthis.port2 = {\n\t\t\t\tpostMessage: function() {\n\t\t\t\t\twin.postMessage(message, origin);\n\t\t\t\t},\n\t\t\t};\n\t\t};\n\t}\n\tif (typeof Channel !== 'undefined') {\n\t\tconst channel = new Channel();\n\t\t// Use a fifo linked list to call callbacks in the right order.\n\t\tlet head = {};\n\t\tlet tail = head;\n\t\tchannel.port1.onmessage = function() {\n\t\t\thead = head.next;\n\t\t\tconst cb = head.cb;\n\t\t\thead.cb = null;\n\t\t\tcb();\n\t\t};\n\t\treturn function(cb) {\n\t\t\ttail.next = {\n\t\t\t\tcb: cb,\n\t\t\t};\n\t\t\ttail = tail.next;\n\t\t\tchannel.port2.postMessage(0);\n\t\t};\n\t}\n\t// Implementation for IE6-8: Script elements fire an asynchronous\n\t// onreadystatechange event when inserted into the DOM.\n\tif (\n\t\ttypeof document !== 'undefined' &&\n\t\t'onreadystatechange' in document.createElement('script')\n\t) {\n\t\treturn function(cb) {\n\t\t\tlet script = document.createElement('script');\n\t\t\tscript.onreadystatechange = function() {\n\t\t\t\t// Clean up and call the callback.\n\t\t\t\tscript.onreadystatechange = null;\n\t\t\t\tscript.parentNode.removeChild(script);\n\t\t\t\tscript = null;\n\t\t\t\tcb();\n\t\t\t\tcb = null;\n\t\t\t};\n\t\t\tdocument.documentElement.appendChild(script);\n\t\t};\n\t}\n\t// Fall back to setTimeout with 0. In browsers this creates a delay of 5ms\n\t// or more.\n\treturn function(cb) {\n\t\tsetTimeout(cb, 0);\n\t};\n};\n\n/**\n * Helper function that is overrided to protect callbacks with entry point\n * monitor if the application monitors entry points.\n * @param {function()} callback Callback function to fire as soon as possible.\n * @return {function()} The wrapped callback.\n * @private\n */\nasync.nextTick.wrapCallback_ = function(callback) {\n\treturn callback;\n};\n\nexport default async;\n","'use strict';\n\n/**\n * Disposable utility. When inherited provides the `dispose` function to its\n * subclass, which is responsible for disposing of any object references\n * when an instance won't be used anymore. Subclasses should override\n * `disposeInternal` to implement any specific disposing logic.\n * @constructor\n */\nclass Disposable {\n\t/**\n\t * Disposable constructor\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Flag indicating if this instance has already been disposed.\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.disposed_ = false;\n\t}\n\n\t/**\n\t * Disposes of this instance's object references. Calls `disposeInternal`.\n\t */\n\tdispose() {\n\t\tif (!this.disposed_) {\n\t\t\tthis.disposeInternal();\n\t\t\tthis.disposed_ = true;\n\t\t}\n\t}\n\n\t/**\n\t * Subclasses should override this method to implement any specific\n\t * disposing logic (like clearing references and calling `dispose` on other\n\t * disposables).\n\t */\n\tdisposeInternal() {}\n\n\t/**\n\t * Checks if this instance has already been disposed.\n\t * @return {boolean}\n\t */\n\tisDisposed() {\n\t\treturn this.disposed_;\n\t}\n}\n\nexport default Disposable;\n","'use strict';\n\n/**\n * Set of utilities for object operations\n */\nclass object {\n\t/**\n\t * Copies all the members of a source object to a target object.\n\t * @param {Object} target Target object.\n\t * @param {...Object} var_args The objects from which values will be copied.\n\t * @return {Object} Returns the target object reference.\n\t */\n\tstatic mixin(target, ...args) {\n\t\tlet key;\n\t\tlet source;\n\t\tfor (let i = 0; i < args.length; i++) {\n\t\t\tsource = args[i];\n\t\t\t// Possible prototype chain leak, breaks 1 metal-dom and\n\t\t\t// 1 metal-incremental-dom test if guard-for-in rule is addressed\n\t\t\t// eslint-disable-next-line\n\t\t\tfor (key in source) {\n\t\t\t\ttarget[key] = source[key];\n\t\t\t}\n\t\t}\n\t\treturn target;\n\t}\n\n\t/**\n\t * Returns an object based on its fully qualified external name.\n\t * @param {string} name The fully qualified name.\n\t * @param {object=} scope The object within which to look; default is\n\t * window.\n\t * @return {?} The value (object or primitive) or, if not found, undefined.\n\t */\n\tstatic getObjectByName(name, scope = window) {\n\t\tconst parts = name.split('.');\n\t\treturn parts.reduce((part, key) => part[key], scope);\n\t}\n\n\t/**\n\t * Returns a new object with the same keys as the given one, but with\n\t * their values set to the return values of the specified function.\n\t * @param {!Object} obj\n\t * @param {!function(string, *)} fn\n\t * @return {!Object}\n\t */\n\tstatic map(obj, fn) {\n\t\tconst mappedObj = {};\n\t\tconst keys = Object.keys(obj);\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tmappedObj[keys[i]] = fn(keys[i], obj[keys[i]]);\n\t\t}\n\t\treturn mappedObj;\n\t}\n\n\t/**\n\t * Checks if the two given objects are equal. This is done via a shallow\n\t * check, including only the keys directly contained by the 2 objects.\n\t * @param {Object} obj1\n\t * @param {Object} obj2\n\t * @return {boolean}\n\t */\n\tstatic shallowEqual(obj1, obj2) {\n\t\tif (obj1 === obj2) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst keys1 = Object.keys(obj1);\n\t\tconst keys2 = Object.keys(obj2);\n\t\tif (keys1.length !== keys2.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = 0; i < keys1.length; i++) {\n\t\t\tif (obj1[keys1[i]] !== obj2[keys1[i]]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport default object;\n","'use strict';\n\n/**\n * Set of utilities for string operations\n */\nclass string {\n\t/**\n\t * Compares the given strings without taking the case into account.\n\t * @param {string|number} str1\n\t * @param {string|number} str2\n\t * @return {number} Either -1, 0 or 1, according to if the first string is\n\t * \"smaller\", equal or \"bigger\" than the second given string.\n\t */\n\tstatic caseInsensitiveCompare(str1, str2) {\n\t\tconst test1 = String(str1).toLowerCase();\n\t\tconst test2 = String(str2).toLowerCase();\n\n\t\tif (test1 < test2) {\n\t\t\treturn -1;\n\t\t} else if (test1 === test2) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t/**\n\t * Removes the breaking spaces from the left and right of the string and\n\t * collapses the sequences of breaking spaces in the middle into single spaces.\n\t * The original and the result strings render the same way in HTML.\n\t * @param {string} str A string in which to collapse spaces.\n\t * @return {string} Copy of the string with normalized breaking spaces.\n\t */\n\tstatic collapseBreakingSpaces(str) {\n\t\treturn str\n\t\t\t.replace(/[\\t\\r\\n ]+/g, ' ')\n\t\t\t.replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g, '');\n\t}\n\n\t/**\n\t * Escapes characters in the string that are not safe to use in a RegExp.\n\t * @param {*} str The string to escape. If not a string, it will be casted\n\t * to one.\n\t * @return {string} A RegExp safe, escaped copy of {@code s}.\n\t */\n\tstatic escapeRegex(str) {\n\t\treturn String(str)\n\t\t\t.replace(/([-()[\\]{}+?*.$^|,:#>}\n\t\t * @protected\n\t\t */\n\t\tthis.events_ = null;\n\n\t\t/**\n\t\t * Handlers that are triggered when an event is listened to.\n\t\t * @type {Array}\n\t\t */\n\t\tthis.listenerHandlers_ = null;\n\n\t\t/**\n\t\t * Configuration option which determines if an event facade should be sent\n\t\t * as a param of listeners when emitting events. If set to true, the facade\n\t\t * will be passed as the first argument of the listener.\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.shouldUseFacade_ = false;\n\t}\n\n\t/**\n\t * Adds a handler to given holder variable. If the holder doesn't have a\n\t * value yet, it will receive the handler directly. If the holder is an array,\n\t * the value will just be added to it. Otherwise, the holder will be set to a\n\t * new array containing its previous value plus the new handler.\n\t * @param {*} holder\n\t * @param {!function()|Object} handler\n\t * @return {*} The holder's new value.\n\t * @protected\n\t */\n\taddHandler_(holder, handler) {\n\t\tif (!holder) {\n\t\t\tholder = handler;\n\t\t} else {\n\t\t\tif (!Array.isArray(holder)) {\n\t\t\t\tholder = [holder];\n\t\t\t}\n\t\t\tholder.push(handler);\n\t\t}\n\t\treturn holder;\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for the specified events.\n\t * @param {!(Array|string)} event\n\t * @param {!Function} listener\n\t * @param {boolean} defaultListener Flag indicating if this listener is a default\n\t * action for this event. Default actions are run last, and only if no previous\n\t * listener call `preventDefault()` on the received event facade.\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\taddListener(event, listener, defaultListener) {\n\t\tthis.validateListener_(listener);\n\n\t\tconst events = this.toEventsArray_(event);\n\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\tthis.addSingleListener_(events[i], listener, defaultListener);\n\t\t}\n\n\t\treturn new EventHandle(this, event, listener);\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for a single event.\n\t * @param {string} event\n\t * @param {!Function} listener\n\t * @param {boolean} defaultListener Flag indicating if this listener is a default\n\t * action for this event. Default actions are run last, and only if no previous\n\t * listener call `preventDefault()` on the received event facade.\n\t * @param {Function=} origin The original function that was added as a\n\t * listener, if there is any.\n\t * @protected\n\t */\n\taddSingleListener_(event, listener, defaultListener, origin) {\n\t\tthis.runListenerHandlers_(event);\n\t\tif (defaultListener || origin) {\n\t\t\tlistener = {\n\t\t\t\tdefault: defaultListener,\n\t\t\t\tfn: listener,\n\t\t\t\torigin: origin,\n\t\t\t};\n\t\t}\n\t\tthis.events_ = this.events_ || {};\n\t\tthis.events_[event] = this.addHandler_(this.events_[event], listener);\n\t}\n\n\t/**\n\t * Builds facade for the given event.\n\t * @param {string} event\n\t * @return {Object}\n\t * @protected\n\t */\n\tbuildFacade_(event) {\n\t\tif (this.getShouldUseFacade()) {\n\t\t\tconst facade = {\n\t\t\t\tpreventDefault: function() {\n\t\t\t\t\tfacade.preventedDefault = true;\n\t\t\t\t},\n\t\t\t\ttarget: this,\n\t\t\t\ttype: event,\n\t\t\t};\n\t\t\treturn facade;\n\t\t}\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.events_ = null;\n\t}\n\n\t/**\n\t * Execute each of the listeners in order with the supplied arguments.\n\t * @param {string} event\n\t * @param {*} opt_args [arg1], [arg2], [...]\n\t * @return {boolean} Returns true if event had listeners, false otherwise.\n\t */\n\temit(event) {\n\t\tconst listeners = this.getRawListeners_(event);\n\t\tif (listeners.length === 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst args = array.slice(arguments, 1); // eslint-disable-line\n\t\tthis.runListeners_(listeners, args, this.buildFacade_(event));\n\t\treturn true;\n\t}\n\n\t/**\n\t * Gets the listener objects for the given event, if there are any.\n\t * @param {string} event\n\t * @return {!Array}\n\t * @protected\n\t */\n\tgetRawListeners_(event) {\n\t\tconst directListeners = toArray(this.events_ && this.events_[event]);\n\t\treturn directListeners.concat(\n\t\t\ttoArray(this.events_ && this.events_['*'])\n\t\t);\n\t}\n\n\t/**\n\t * Gets the configuration option which determines if an event facade should\n\t * be sent as a param of listeners when emitting events. If set to true, the\n\t * facade will be passed as the first argument of the listener.\n\t * @return {boolean}\n\t */\n\tgetShouldUseFacade() {\n\t\treturn this.shouldUseFacade_;\n\t}\n\n\t/**\n\t * Returns an array of listeners for the specified event.\n\t * @param {string} event\n\t * @return {Array} Array of listeners.\n\t */\n\tlisteners(event) {\n\t\treturn this.getRawListeners_(event).map(\n\t\t\tlistener => (listener.fn ? listener.fn : listener)\n\t\t);\n\t}\n\n\t/**\n\t * Adds a listener that will be invoked a fixed number of times for the\n\t * events. After each event is triggered the specified amount of times, the\n\t * listener is removed for it.\n\t * @param {!(Array|string)} event\n\t * @param {number} amount The amount of times this event should be listened\n\t * to.\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\tmany(event, amount, listener) {\n\t\tconst events = this.toEventsArray_(event);\n\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\tthis.many_(events[i], amount, listener);\n\t\t}\n\n\t\treturn new EventHandle(this, event, listener);\n\t}\n\n\t/**\n\t * Adds a listener that will be invoked a fixed number of times for a single\n\t * event. After the event is triggered the specified amount of times, the\n\t * listener is removed.\n\t * @param {string} event\n\t * @param {number} amount The amount of times this event should be listened\n\t * to.\n\t * @param {!Function} listener\n\t * @protected\n\t */\n\tmany_(event, amount, listener) {\n\t\tconst self = this;\n\n\t\tif (amount <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t *\n\t\t */\n\t\tfunction handlerInternal() {\n\t\t\tif (--amount === 0) {\n\t\t\t\tself.removeListener(event, handlerInternal);\n\t\t\t}\n\t\t\tlistener.apply(self, arguments); // eslint-disable-line\n\t\t}\n\n\t\tself.addSingleListener_(event, handlerInternal, false, listener);\n\t}\n\n\t/**\n\t * Checks if a listener object matches the given listener function. To match,\n\t * it needs to either point to that listener or have it as its origin.\n\t * @param {!Object} listenerObj\n\t * @param {!Function} listener\n\t * @return {boolean}\n\t * @protected\n\t */\n\tmatchesListener_(listenerObj, listener) {\n\t\tconst fn = listenerObj.fn || listenerObj;\n\t\treturn (\n\t\t\tfn === listener ||\n\t\t\t(listenerObj.origin && listenerObj.origin === listener) // eslint-disable-line\n\t\t);\n\t}\n\n\t/**\n\t * Removes a listener for the specified events.\n\t * Caution: changes array indices in the listener array behind the listener.\n\t * @param {!(Array|string)} event\n\t * @param {!Function} listener\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\toff(event, listener) {\n\t\tthis.validateListener_(listener);\n\t\tif (!this.events_) {\n\t\t\treturn this;\n\t\t}\n\n\t\tconst events = this.toEventsArray_(event);\n\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\tthis.events_[events[i]] = this.removeMatchingListenerObjs_(\n\t\t\t\ttoArray(this.events_[events[i]]),\n\t\t\t\tlistener\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for the specified events.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\ton() {\n\t\treturn this.addListener.apply(this, arguments); // eslint-disable-line\n\t}\n\n\t/**\n\t * Adds handler that gets triggered when an event is listened to on this\n\t * instance.\n\t * @param {!function()} handler\n\t */\n\tonListener(handler) {\n\t\tthis.listenerHandlers_ = this.addHandler_(\n\t\t\tthis.listenerHandlers_,\n\t\t\thandler\n\t\t); // eslint-disable-line\n\t}\n\n\t/**\n\t * Adds a one time listener for the events. This listener is invoked only the\n\t * next time each event is fired, after which it is removed.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\tonce(events, listener) {\n\t\treturn this.many(events, 1, listener);\n\t}\n\n\t/**\n\t * Removes all listeners, or those of the specified events. It's not a good\n\t * idea to remove listeners that were added elsewhere in the code,\n\t * especially when it's on an emitter that you didn't create.\n\t * @param {(Array|string)=} event\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\tremoveAllListeners(event) {\n\t\tif (this.events_) {\n\t\t\tif (event) {\n\t\t\t\tconst events = this.toEventsArray_(event);\n\t\t\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\t\t\tthis.events_[events[i]] = null;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.events_ = null;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes all listener objects from the given array that match the given\n\t * listener function.\n\t * @param {Array.} listenerObjs\n\t * @param {!Function} listener\n\t * @return {Array.|Object} The new listeners array for this event.\n\t * @protected\n\t */\n\tremoveMatchingListenerObjs_(listenerObjs, listener) {\n\t\tconst finalListeners = [];\n\t\tfor (let i = 0; i < listenerObjs.length; i++) {\n\t\t\tif (!this.matchesListener_(listenerObjs[i], listener)) {\n\t\t\t\tfinalListeners.push(listenerObjs[i]);\n\t\t\t}\n\t\t}\n\t\treturn finalListeners.length > 0 ? finalListeners : null;\n\t}\n\n\t/**\n\t * Removes a listener for the specified events.\n\t * Caution: changes array indices in the listener array behind the listener.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\tremoveListener() {\n\t\treturn this.off.apply(this, arguments); // eslint-disable-line\n\t}\n\n\t/**\n\t * Runs the handlers when an event is listened to.\n\t * @param {string} event\n\t * @protected\n\t */\n\trunListenerHandlers_(event) {\n\t\tlet handlers = this.listenerHandlers_;\n\t\tif (handlers) {\n\t\t\thandlers = toArray(handlers);\n\t\t\tfor (let i = 0; i < handlers.length; i++) {\n\t\t\t\thandlers[i](event);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Runs the given listeners.\n\t * @param {!Array} listeners\n\t * @param {!Array} args\n\t * @param {Object} facade\n\t * @protected\n\t */\n\trunListeners_(listeners, args, facade) {\n\t\tif (facade) {\n\t\t\targs.push(facade);\n\t\t}\n\n\t\tconst defaultListeners = [];\n\t\tfor (let i = 0; i < listeners.length; i++) {\n\t\t\tconst listener = listeners[i].fn || listeners[i];\n\t\t\tif (listeners[i].default) {\n\t\t\t\tdefaultListeners.push(listener);\n\t\t\t} else {\n\t\t\t\tlistener.apply(this, args);\n\t\t\t}\n\t\t}\n\t\tif (!facade || !facade.preventedDefault) {\n\t\t\tfor (let j = 0; j < defaultListeners.length; j++) {\n\t\t\t\tdefaultListeners[j].apply(this, args);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sets the configuration option which determines if an event facade should\n\t * be sent as a param of listeners when emitting events. If set to true, the\n\t * facade will be passed as the first argument of the listener.\n\t * @param {boolean} shouldUseFacade\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\tsetShouldUseFacade(shouldUseFacade) {\n\t\tthis.shouldUseFacade_ = shouldUseFacade;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Converts the parameter to an array if only one event is given. Reuses the\n\t * same array each time this conversion is done, to avoid using more memory\n\t * than necessary.\n\t * @param {!(Array|string)} events\n\t * @return {!Array}\n\t * @protected\n\t */\n\ttoEventsArray_(events) {\n\t\tif (isString(events)) {\n\t\t\tsingleArray_[0] = events;\n\t\t\tevents = singleArray_;\n\t\t}\n\t\treturn events;\n\t}\n\n\t/**\n\t * Checks if the given listener is valid, throwing an exception when it's not.\n\t * @param {*} listener\n\t * @protected\n\t */\n\tvalidateListener_(listener) {\n\t\tif (!isFunction(listener)) {\n\t\t\tthrow new TypeError('Listener must be a function');\n\t\t}\n\t}\n}\n\n/**\n * Converts to an array\n * @param {Object} val\n * @return {Array}\n */\nfunction toArray(val) {\n\tval = val || [];\n\treturn Array.isArray(val) ? val : [val];\n}\n\nexport default EventEmitter;\n","'use strict';\n\nimport {Disposable} from 'metal';\n\n/**\n * EventEmitterProxy utility. It's responsible for linking two EventEmitter\n * instances together, emitting events from the first emitter through the\n * second one. That means that listening to a supported event on the target\n * emitter will mean listening to it on the origin emitter as well.\n * @extends {Disposable}\n */\nclass EventEmitterProxy extends Disposable {\n\t/**\n\t * @param {EventEmitter} originEmitter Events originated on this emitter\n\t * will be fired for the target emitter's listeners as well.\n\t * @param {EventEmitter} targetEmitter Event listeners attached to this emitter\n\t * will also be triggered when the event is fired by the origin emitter.\n\t * @param {Object} blacklist Optional blacklist of events that should not be\n\t * proxied.\n\t * @param {Object} whitelist\n\t */\n\tconstructor(originEmitter, targetEmitter, blacklist, whitelist) {\n\t\tsuper();\n\n\t\t/**\n\t\t * Map of events that should not be proxied.\n\t\t * @type {Object}\n\t\t * @protected\n\t\t */\n\t\tthis.blacklist_ = blacklist;\n\n\t\t/**\n\t\t * The origin emitter. This emitter's events will be proxied through the\n\t\t * target emitter.\n\t\t * @type {EventEmitter}\n\t\t * @protected\n\t\t */\n\t\tthis.originEmitter_ = originEmitter;\n\n\t\t/**\n\t\t * A list of events that are pending to be listened by an actual origin\n\t\t * emitter. Events are stored here when the origin doesn't exist, so they\n\t\t * can be set on a new origin when one is set.\n\t\t * @type {Array}\n\t\t * @protected\n\t\t */\n\t\tthis.pendingEvents_ = null;\n\n\t\t/**\n\t\t * Holds a map of events from the origin emitter that are already being proxied.\n\t\t * @type {Object}\n\t\t * @protected\n\t\t */\n\t\tthis.proxiedEvents_ = null;\n\n\t\t/**\n\t\t * The target emitter. This emitter will emit all events that come from\n\t\t * the origin emitter.\n\t\t * @type {EventEmitter}\n\t\t * @protected\n\t\t */\n\t\tthis.targetEmitter_ = targetEmitter;\n\n\t\t/**\n\t\t * Map of events that should be proxied. If whitelist is set blacklist is ignored.\n\t\t * @type {Object}\n\t\t * @protected\n\t\t */\n\t\tthis.whitelist_ = whitelist;\n\n\t\tthis.startProxy_();\n\t}\n\n\t/**\n\t * Adds the given listener for the given event.\n\t * @param {string} event\n\t * @param {!function()} listener\n\t * @return {!EventHandle} The listened event's handle.\n\t * @protected\n\t */\n\taddListener_(event, listener) {\n\t\treturn this.originEmitter_.on(event, listener);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tthis.removeListeners_();\n\t\tthis.proxiedEvents_ = null;\n\t\tthis.originEmitter_ = null;\n\t\tthis.targetEmitter_ = null;\n\t}\n\n\t/**\n\t * Emits the specified event type on the target emitter.\n\t * @protected\n\t */\n\temitOnTarget_(...args) {\n\t\tthis.targetEmitter_.emit(...args);\n\t}\n\n\t/**\n\t * Proxies the given event from the origin to the target emitter.\n\t * @param {string} event\n\t */\n\tproxyEvent(event) {\n\t\tif (this.shouldProxyEvent_(event)) {\n\t\t\tthis.tryToAddListener_(event);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the proxy listener for all events.\n\t * @protected\n\t */\n\tremoveListeners_() {\n\t\tif (this.proxiedEvents_) {\n\t\t\tconst events = Object.keys(this.proxiedEvents_);\n\t\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\t\tthis.proxiedEvents_[events[i]].removeListener();\n\t\t\t}\n\t\t\tthis.proxiedEvents_ = null;\n\t\t}\n\t\tthis.pendingEvents_ = null;\n\t}\n\n\t/**\n\t * Changes the origin emitter. This automatically detaches any events that\n\t * were already being proxied from the previous emitter, and starts proxying\n\t * them on the new emitter instead.\n\t * @param {!EventEmitter} originEmitter\n\t */\n\tsetOriginEmitter(originEmitter) {\n\t\tconst events =\n\t\t\tthis.originEmitter_ && this.proxiedEvents_\n\t\t\t\t? Object.keys(this.proxiedEvents_)\n\t\t\t\t: this.pendingEvents_;\n\t\tthis.originEmitter_ = originEmitter;\n\t\tif (events) {\n\t\t\tthis.removeListeners_();\n\t\t\tevents.forEach(event => this.proxyEvent(event));\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given event should be proxied.\n\t * @param {string} event\n\t * @return {boolean}\n\t * @protected\n\t */\n\tshouldProxyEvent_(event) {\n\t\tif (this.whitelist_ && !this.whitelist_[event]) {\n\t\t\treturn false;\n\t\t}\n\t\tif (this.blacklist_ && this.blacklist_[event]) {\n\t\t\treturn false;\n\t\t}\n\t\treturn !this.proxiedEvents_ || !this.proxiedEvents_[event];\n\t}\n\n\t/**\n\t * Starts proxying all events from the origin to the target emitter.\n\t * @protected\n\t */\n\tstartProxy_() {\n\t\tthis.targetEmitter_.onListener(this.proxyEvent.bind(this));\n\t}\n\n\t/**\n\t * Adds a listener to the origin emitter, if it exists. Otherwise, stores\n\t * the pending listener so it can be used on a future origin emitter.\n\t * @param {string} event\n\t * @protected\n\t */\n\ttryToAddListener_(event) {\n\t\tif (this.originEmitter_) {\n\t\t\tthis.proxiedEvents_ = this.proxiedEvents_ || {};\n\t\t\tthis.proxiedEvents_[event] = this.addListener_(\n\t\t\t\tevent,\n\t\t\t\tthis.emitOnTarget_.bind(this, event)\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pendingEvents_ = this.pendingEvents_ || [];\n\t\t\tthis.pendingEvents_.push(event);\n\t\t}\n\t}\n}\n\nexport default EventEmitterProxy;\n","'use strict';\n\nimport {Disposable} from 'metal';\n\n/**\n * EventHandler utility. It's useful for easily removing a group of\n * listeners from different EventEmitter instances.\n * @extends {Disposable}\n */\nclass EventHandler extends Disposable {\n\t/**\n\t * EventHandler constructor\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * An array that holds the added event handles, so the listeners can be\n\t\t * removed later.\n\t\t * @type {Array.}\n\t\t * @protected\n\t\t */\n\t\tthis.eventHandles_ = [];\n\t}\n\n\t/**\n\t * Adds event handles to be removed later through the `removeAllListeners`\n\t * method.\n\t * @param {...(!EventHandle)} var_args\n\t */\n\tadd(...args) {\n\t\tfor (let i = 0; i < arguments.length; i++) {\n\t\t\tthis.eventHandles_.push(args[i]);\n\t\t}\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.eventHandles_ = null;\n\t}\n\n\t/**\n\t * Removes all listeners that have been added through the `add` method.\n\t */\n\tremoveAllListeners() {\n\t\tfor (let i = 0; i < this.eventHandles_.length; i++) {\n\t\t\tthis.eventHandles_[i].removeListener();\n\t\t}\n\n\t\tthis.eventHandles_ = [];\n\t}\n}\n\nexport default EventHandler;\n","'use strict';\n\nimport {array, isString} from 'metal';\nimport domData from './domData';\nimport {EventHandle} from 'metal-events';\n\n/**\n * This is a special EventHandle, that is responsible for dom delegated events\n * (only the ones that receive a target element, not a selector string).\n * @extends {EventHandle}\n */\nclass DomDelegatedEventHandle extends EventHandle {\n\t/**\n\t * The constructor for `DomDelegatedEventHandle`.\n\t * @param {!Event} emitter Element the event was subscribed to.\n\t * @param {string} event The name of the event that was subscribed to.\n\t * @param {!Function} listener The listener subscribed to the event.\n\t * @param {string=} selector An optional selector used when delegating\n\t * the event.\n\t * @constructor\n\t */\n\tconstructor(emitter, event, listener, selector) {\n\t\tsuper(emitter, event, listener);\n\t\tthis.selector_ = selector;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tremoveListener() {\n\t\tconst delegating = domData.get(this.emitter_, 'delegating', {});\n\t\tconst listeners = domData.get(this.emitter_, 'listeners', {});\n\t\tconst selector = this.selector_;\n\t\tconst arr = isString(selector)\n\t\t\t? delegating[this.event_].selectors\n\t\t\t: listeners;\n\t\tconst key = isString(selector) ? selector : this.event_;\n\n\t\tarray.remove(arr[key] || [], this.listener_);\n\t\tif (arr[key] && arr[key].length === 0) {\n\t\t\tdelete arr[key];\n\t\t}\n\t}\n}\n\nexport default DomDelegatedEventHandle;\n","'use strict';\n\nimport {EventHandle} from 'metal-events';\n\n/**\n * This is a special EventHandle, that is responsible for dom events, instead\n * of EventEmitter events.\n * @extends {EventHandle}\n */\nclass DomEventHandle extends EventHandle {\n\t/**\n\t * The constructor for `DomEventHandle`.\n\t * @param {!EventEmitter} emitter Emitter the event was subscribed to.\n\t * @param {string} event The name of the event that was subscribed to.\n\t * @param {!Function} listener The listener subscribed to the event.\n\t * @param {boolean} capture Flag indicating if listener should be triggered\n\t * during capture phase, instead of during the bubbling phase. Defaults to false.\n\t * @constructor\n\t */\n\tconstructor(emitter, event, listener, capture) {\n\t\tsuper(emitter, event, listener);\n\t\tthis.capture_ = capture;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tremoveListener() {\n\t\tthis.emitter_.removeEventListener(\n\t\t\tthis.event_,\n\t\t\tthis.listener_,\n\t\t\tthis.capture_\n\t\t);\n\t}\n}\n\nexport default DomEventHandle;\n","'use strict';\n\nimport {\n\tisDef,\n\tisDefAndNotNull,\n\tisDocument,\n\tisDocumentFragment,\n\tisElement,\n\tisObject,\n\tisString,\n\tobject,\n} from 'metal';\nimport domData from './domData';\nimport DomDelegatedEventHandle from './DomDelegatedEventHandle';\nimport DomEventHandle from './DomEventHandle';\n\nconst elementsByTag_ = {};\nconst supportCache_ = {};\nexport const customEvents = {};\n\nconst LAST_CONTAINER = '__metal_last_container__';\nconst USE_CAPTURE = {\n\tblur: true,\n\terror: true,\n\tfocus: true,\n\tinvalid: true,\n\tload: true,\n\tscroll: true,\n};\n\n/**\n * Adds the requested CSS classes to an element.\n * @param {!Element|!Nodelist} elements The element or elements to add CSS classes to.\n * @param {string} classes CSS classes to add.\n */\nexport function addClasses(elements, classes) {\n\tif (!isObject(elements) || !isString(classes)) {\n\t\treturn;\n\t}\n\n\tif (!elements.length) {\n\t\telements = [elements];\n\t}\n\n\tfor (let i = 0; i < elements.length; i++) {\n\t\tif ('classList' in elements[i]) {\n\t\t\taddClassesWithNative_(elements[i], classes);\n\t\t} else {\n\t\t\taddClassesWithoutNative_(elements[i], classes);\n\t\t}\n\t}\n}\n\n/**\n * Adds the requested CSS classes to an element using classList.\n * @param {!Element} element The element to add CSS classes to.\n * @param {string} classes CSS classes to add.\n * @private\n */\nfunction addClassesWithNative_(element, classes) {\n\tclasses.split(' ').forEach(function(className) {\n\t\tif (className) {\n\t\t\telement.classList.add(className);\n\t\t}\n\t});\n}\n\n/**\n * Adds the requested CSS classes to an element without using classList.\n * @param {!Element} element The element to add CSS classes to.\n * @param {string} classes CSS classes to add.\n * @private\n */\nfunction addClassesWithoutNative_(element, classes) {\n\tconst elementClassName = ` ${element.className} `;\n\tlet classesToAppend = '';\n\n\tclasses = classes.split(' ');\n\n\tfor (let i = 0; i < classes.length; i++) {\n\t\tconst className = classes[i];\n\n\t\tif (elementClassName.indexOf(` ${className} `) === -1) {\n\t\t\tclassesToAppend += ` ${className}`;\n\t\t}\n\t}\n\n\tif (classesToAppend) {\n\t\telement.className = element.className + classesToAppend;\n\t}\n}\n\n/**\n * Adds an event listener to the given element, to be triggered via delegate.\n * @param {!Element} element\n * @param {string} eventName\n * @param {!function()} listener\n * @private\n */\nfunction addElementListener_(element, eventName, listener) {\n\taddToArr_(domData.get(element, 'listeners', {}), eventName, listener);\n}\n\n/**\n * Adds an event listener to the given element, to be triggered via delegate\n * selectors.\n * @param {!Element} element\n * @param {string} eventName\n * @param {string} selector\n * @param {!function()} listener\n * @private\n */\nfunction addSelectorListener_(element, eventName, selector, listener) {\n\tconst delegatingData = domData.get(element, 'delegating', {});\n\taddToArr_(delegatingData[eventName].selectors, selector, listener);\n}\n\n/**\n * Adds a value to an array inside an object, creating it first if it doesn't\n * yet exist.\n * @param {!Array} arr\n * @param {string} key\n * @param {*} value\n * @private\n */\nfunction addToArr_(arr, key, value) {\n\tif (!arr[key]) {\n\t\tarr[key] = [];\n\t}\n\tarr[key].push(value);\n}\n\n/**\n * Attaches a delegate listener, unless there's already one attached.\n * @param {!Element} element\n * @param {string} eventName\n * @private\n */\nfunction attachDelegateEvent_(element, eventName) {\n\tlet delegatingData = domData.get(element, 'delegating', {});\n\tif (!delegatingData[eventName]) {\n\t\tdelegatingData[eventName] = {\n\t\t\thandle: on(\n\t\t\t\telement,\n\t\t\t\teventName,\n\t\t\t\thandleDelegateEvent_,\n\t\t\t\t!!USE_CAPTURE[eventName]\n\t\t\t),\n\t\t\tselectors: {},\n\t\t};\n\t}\n}\n\n/**\n * Gets the closest element up the tree from the given element (including\n * itself) that matches the specified selector, or null if none match.\n * @param {Element} element\n * @param {string} selector\n * @return {Element}\n */\nexport function closest(element, selector) {\n\twhile (element && !match(element, selector)) {\n\t\telement = element.parentNode;\n\t}\n\treturn element;\n}\n\n/**\n * Appends a child node with text or other nodes to a parent node. If\n * child is a HTML string it will be automatically converted to a document\n * fragment before appending it to the parent.\n * @param {!Element} parent The node to append nodes to.\n * @param {!(Element|NodeList|string)} child The thing to append to the parent.\n * @return {!Element} The appended child.\n */\nexport function append(parent, child) {\n\tif (isString(child)) {\n\t\tchild = buildFragment(child);\n\t}\n\tif (isNodeListLike(child)) {\n\t\tconst childArr = Array.prototype.slice.call(child);\n\t\tfor (let i = 0; i < childArr.length; i++) {\n\t\t\tparent.appendChild(childArr[i]);\n\t\t}\n\t} else {\n\t\tparent.appendChild(child);\n\t}\n\treturn child;\n}\n\n/**\n * Helper for converting a HTML string into a document fragment.\n * @param {string} htmlString The HTML string to convert.\n * @return {!Element} The resulting document fragment.\n */\nexport function buildFragment(htmlString) {\n\tconst tempDiv = document.createElement('div');\n\ttempDiv.innerHTML = `
${htmlString}`;\n\ttempDiv.removeChild(tempDiv.firstChild);\n\n\tconst fragment = document.createDocumentFragment();\n\twhile (tempDiv.firstChild) {\n\t\tfragment.appendChild(tempDiv.firstChild);\n\t}\n\treturn fragment;\n}\n\n/**\n * Checks if the first element contains the second one.\n * @param {!Element} element1\n * @param {!Element} element2\n * @return {boolean}\n */\nexport function contains(element1, element2) {\n\tif (isDocument(element1)) {\n\t\t// document.contains is not defined on IE9, so call it on documentElement instead.\n\t\treturn element1.documentElement.contains(element2);\n\t} else {\n\t\treturn element1.contains(element2);\n\t}\n}\n\n/**\n * Listens to the specified event on the given DOM element, but only calls the\n * given callback listener when it's triggered by elements that match the\n * given selector or target element.\n * @param {!Element} element The DOM element the event should be listened on.\n * @param {string} eventName The name of the event to listen to.\n * @param {!Element|string} selectorOrTarget Either an element or css selector\n * that should match the event for the listener to be triggered.\n * @param {!function(!Object)} callback Function to be called when the event\n * is triggered. It will receive the normalized event object.\n * @param {boolean=} defaultListener Optional flag indicating if this is a default\n * listener. That means that it would only be executed after all non\n * default listeners, and only if the event isn't prevented via\n * `preventDefault`.\n * @return {!EventHandle} Can be used to remove the listener.\n */\nexport function delegate(\n\telement,\n\teventName,\n\tselectorOrTarget,\n\tcallback,\n\tdefaultListener\n) {\n\tconst customConfig = customEvents[eventName];\n\tif (customConfig && customConfig.delegate) {\n\t\teventName = customConfig.originalEvent;\n\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t}\n\n\tif (defaultListener) {\n\t\t// Wrap callback so we don't set property directly on it.\n\t\tcallback = callback.bind();\n\t\tcallback.defaultListener_ = true;\n\t}\n\n\tattachDelegateEvent_(element, eventName);\n\tif (isString(selectorOrTarget)) {\n\t\taddSelectorListener_(element, eventName, selectorOrTarget, callback);\n\t} else {\n\t\taddElementListener_(selectorOrTarget, eventName, callback);\n\t}\n\n\treturn new DomDelegatedEventHandle(\n\t\tisString(selectorOrTarget) ? element : selectorOrTarget,\n\t\teventName,\n\t\tcallback,\n\t\tisString(selectorOrTarget) ? selectorOrTarget : null\n\t);\n}\n\n/**\n * Verifies if the element is able to trigger the Click event,\n * simulating browsers behaviour, avoiding event listeners to be called by triggerEvent method.\n * @param {Element} node Element to be checked.\n * @param {string} eventName The event name.\n * @param {Object=} eventObj\n * @private\n * @return {boolean}\n */\nfunction isAbleToInteractWith_(node, eventName, eventObj) {\n\tif (eventObj && eventName === 'click' && eventObj.button === 2) {\n\t\t// Firefox triggers \"click\" events on the document for right clicks. This\n\t\t// causes our delegate logic to trigger it for regular elements too, which\n\t\t// shouldn't happen. Ignoring them here.\n\t\treturn false;\n\t}\n\n\tconst matchesSelector = [\n\t\t'BUTTON',\n\t\t'INPUT',\n\t\t'SELECT',\n\t\t'TEXTAREA',\n\t\t'FIELDSET',\n\t];\n\tif (eventName === 'click' && matchesSelector.indexOf(node.tagName) > -1) {\n\t\treturn !(node.disabled || parent(node, 'fieldset[disabled]'));\n\t}\n\treturn true;\n}\n\n/**\n * Returns true if the specified value is a NodeList or like one.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is like a NodeList.\n */\nexport function isNodeListLike(val) {\n\treturn (\n\t\tisDefAndNotNull(val) &&\n\t\ttypeof val.length === 'number' &&\n\t\ttypeof val.item === 'function'\n\t);\n}\n\n/**\n * Inserts node in document as last element.\n * @param {Element} node Element to remove children from.\n */\nexport function enterDocument(node) {\n\tnode && append(document.body, node);\n}\n\n/**\n * Removes node from document.\n * @param {Element} node Element to remove children from.\n */\nexport function exitDocument(node) {\n\tif (node && node.parentNode) {\n\t\tnode.parentNode.removeChild(node);\n\t}\n}\n\n/**\n * This is called when an event is triggered by a delegate listener. All\n * matching listeners of this event type from `target` to `currentTarget` will\n * be triggered.\n * @param {!Event} event The event payload.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction handleDelegateEvent_(event) {\n\tnormalizeDelegateEvent_(event);\n\tlet ret = true;\n\tconst container = event.currentTarget;\n\tconst defFns = [];\n\n\tret &= triggerDelegatedListeners_(container, event, defFns);\n\tret &= triggerDefaultDelegatedListeners_(defFns, event);\n\n\tevent.delegateTarget = null;\n\tevent[LAST_CONTAINER] = container;\n\treturn ret;\n}\n\n/**\n * Checks if the given element has the requested css class.\n * @param {!Element} element\n * @param {string} className\n * @return {boolean}\n */\nexport function hasClass(element, className) {\n\tif ('classList' in element) {\n\t\treturn hasClassWithNative_(element, className);\n\t} else {\n\t\treturn hasClassWithoutNative_(element, className);\n\t}\n}\n\n/**\n * Checks if the given element has the requested css class using classList.\n * @param {!Element} element\n * @param {string} className\n * @return {boolean}\n * @private\n */\nfunction hasClassWithNative_(element, className) {\n\treturn (\n\t\tclassName.indexOf(' ') === -1 && element.classList.contains(className)\n\t);\n}\n\n/**\n * Checks if the given element has the requested css class without using classList.\n * @param {!Element} element\n * @param {string} className\n * @return {boolean}\n * @private\n */\nfunction hasClassWithoutNative_(element, className) {\n\treturn (\n\t\t` ${element.className} `.indexOf(` ${className} `) >= 0 &&\n\t\tclassName.split(' ').length === 1\n\t);\n}\n\n/**\n * Checks if the given element is empty or not.\n * @param {!Element} element\n * @return {boolean}\n */\nexport function isEmpty(element) {\n\treturn element.childNodes.length === 0;\n}\n\n/**\n * Check if an element matches a given selector.\n * @param {Element} element\n * @param {string} selector\n * @return {boolean}\n */\nexport function match(element, selector) {\n\tif (!element || element.nodeType !== 1) {\n\t\treturn false;\n\t}\n\n\tconst p = Element.prototype;\n\tconst m =\n\t\tp.matches ||\n\t\tp.webkitMatchesSelector ||\n\t\tp.mozMatchesSelector ||\n\t\tp.msMatchesSelector ||\n\t\tp.oMatchesSelector;\n\tif (m) {\n\t\treturn m.call(element, selector);\n\t}\n\n\treturn matchFallback_(element, selector);\n}\n\n/**\n * Check if an element matches a given selector, using an internal implementation\n * instead of calling existing javascript functions.\n * @param {Element} element\n * @param {string} selector\n * @return {boolean}\n * @private\n */\nfunction matchFallback_(element, selector) {\n\tconst parentNode = element.parentNode;\n\n\tif (parentNode) {\n\t\tconst nodes = parentNode.querySelectorAll(selector);\n\n\t\tfor (let i = 0; i < nodes.length; ++i) {\n\t\t\tif (nodes[i] === element) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Returns the next sibling of the given element that matches the specified\n * selector, or null if there is none.\n * @param {!Element} element\n * @param {?string} selector\n * @return {Element|null}\n */\nexport function next(element, selector) {\n\tdo {\n\t\telement = element.nextSibling;\n\t\tif (element && match(element, selector)) {\n\t\t\treturn element;\n\t\t}\n\t} while (element);\n\treturn null;\n}\n\n/**\n * Normalizes the event payload for delegate listeners.\n * @param {!Event} event\n * @private\n */\nfunction normalizeDelegateEvent_(event) {\n\tevent.stopPropagation = stopPropagation_;\n\tevent.stopImmediatePropagation = stopImmediatePropagation_;\n}\n\n/**\n * Listens to the specified event on the given DOM element. This function normalizes\n * DOM event payloads and functions so they'll work the same way on all supported\n * browsers.\n * @param {!Element|string} element The DOM element to listen to the event on, or\n * a selector that should be delegated on the entire document.\n * @param {string} eventName The name of the event to listen to.\n * @param {!function(!Object)} callback Function to be called when the event is\n * triggered. It will receive the normalized event object.\n * @param {boolean} capture Flag indicating if listener should be triggered\n * during capture phase, instead of during the bubbling phase. Defaults to false.\n * @return {!DomEventHandle} Can be used to remove the listener.\n */\nexport function on(element, eventName, callback, capture) {\n\tif (isString(element)) {\n\t\treturn delegate(document, eventName, element, callback);\n\t}\n\tconst customConfig = customEvents[eventName];\n\tif (customConfig && customConfig.event) {\n\t\teventName = customConfig.originalEvent;\n\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t}\n\telement.addEventListener(eventName, callback, capture);\n\treturn new DomEventHandle(element, eventName, callback, capture);\n}\n\n/**\n * Listens to the specified event on the given DOM element once. This\n * function normalizes DOM event payloads and functions so they'll work the\n * same way on all supported browsers.\n * @param {!Element} element The DOM element to listen to the event on.\n * @param {string} eventName The name of the event to listen to.\n * @param {!function(!Object)} callback Function to be called when the event\n * is triggered. It will receive the normalized event object.\n * @return {!DomEventHandle} Can be used to remove the listener.\n */\nexport function once(element, eventName, callback) {\n\tconst domEventHandle = on(element, eventName, function() {\n\t\tdomEventHandle.removeListener();\n\t\treturn callback.apply(this, arguments); // eslint-disable-line\n\t});\n\treturn domEventHandle;\n}\n\n/**\n * Gets the first parent from the given element that matches the specified\n * selector, or null if none match.\n * @param {!Element} element\n * @param {string} selector\n * @return {Element}\n */\nexport function parent(element, selector) {\n\treturn closest(element.parentNode, selector);\n}\n\n/**\n * Inserts a node before first child of the parent. If child is a HTML string\n * it will be converted to document fragment before prepending it to the parent.\n * @param {!Element} parent The node to prepend to.\n * @param {!(Element|NodeList|string)} child The thing to prepend to the parent.\n * @return {!Element} The prepended child.\n */\nexport function prepend(parent, child) {\n\tif (isString(child)) {\n\t\tchild = buildFragment(child);\n\t}\n\n\tif (!isNodeListLike(child) && !isDefAndNotNull(parent.firstChild)) {\n\t\treturn append(parent, child);\n\t}\n\n\tif (isNodeListLike(child)) {\n\t\tconst childArr = Array.prototype.slice.call(child);\n\t\tfor (let i = childArr.length - 1; i >= 0; i--) {\n\t\t\tparent.insertBefore(childArr[i], parent.firstChild);\n\t\t}\n\t} else {\n\t\tparent.insertBefore(child, parent.firstChild);\n\t}\n\n\treturn child;\n}\n\n/**\n * Registers a custom event.\n * @param {string} eventName The name of the custom event.\n * @param {!Object} customConfig An object with information about how the event\n * should be handled.\n */\nexport function registerCustomEvent(eventName, customConfig) {\n\tcustomEvents[eventName] = customConfig;\n}\n\n/**\n * Removes all the child nodes on a DOM node.\n * @param {Element} node Element to remove children from.\n */\nexport function removeChildren(node) {\n\tlet child;\n\twhile ((child = node.firstChild)) {\n\t\tnode.removeChild(child);\n\t}\n}\n\n/**\n * Removes the requested CSS classes from an element.\n * @param {!Element|!NodeList} elements The element or elements to remove CSS classes from.\n * @param {string} classes CSS classes to remove.\n */\nexport function removeClasses(elements, classes) {\n\tif (!isObject(elements) || !isString(classes)) {\n\t\treturn;\n\t}\n\n\tif (!elements.length) {\n\t\telements = [elements];\n\t}\n\n\tfor (let i = 0; i < elements.length; i++) {\n\t\tif ('classList' in elements[i]) {\n\t\t\tremoveClassesWithNative_(elements[i], classes);\n\t\t} else {\n\t\t\tremoveClassesWithoutNative_(elements[i], classes);\n\t\t}\n\t}\n}\n\n/**\n * Removes the requested CSS classes from an element using classList.\n * @param {!Element} element The element to remove CSS classes from.\n * @param {string} classes CSS classes to remove.\n * @private\n */\nfunction removeClassesWithNative_(element, classes) {\n\tclasses.split(' ').forEach(function(className) {\n\t\tif (className) {\n\t\t\telement.classList.remove(className);\n\t\t}\n\t});\n}\n\n/**\n * Removes the requested CSS classes from an element without using classList.\n * @param {!Element} element The element to remove CSS classes from.\n * @param {string} classes CSS classes to remove.\n * @private\n */\nfunction removeClassesWithoutNative_(element, classes) {\n\tlet elementClassName = ` ${element.className} `;\n\n\tclasses = classes.split(' ');\n\n\tfor (let i = 0; i < classes.length; i++) {\n\t\telementClassName = elementClassName.replace(` ${classes[i]} `, ' ');\n\t}\n\n\telement.className = elementClassName.trim();\n}\n\n/**\n * Replaces the first element with the second.\n * @param {Element} element1\n * @param {Element} element2\n */\nexport function replace(element1, element2) {\n\tif (element1 && element2 && element1 !== element2 && element1.parentNode) {\n\t\telement1.parentNode.insertBefore(element2, element1);\n\t\telement1.parentNode.removeChild(element1);\n\t}\n}\n\n/**\n * The function that replaces `stopImmediatePropagation_` for events.\n * @private\n */\nfunction stopImmediatePropagation_() {\n\tconst event = this; // eslint-disable-line\n\tevent.stopped = true;\n\tevent.stoppedImmediate = true;\n\tEvent.prototype.stopImmediatePropagation.call(event);\n}\n\n/**\n * The function that replaces `stopPropagation` for events.\n * @private\n */\nfunction stopPropagation_() {\n\tconst event = this; // eslint-disable-line\n\tevent.stopped = true;\n\tEvent.prototype.stopPropagation.call(event);\n}\n\n/**\n * Checks if the given element supports the given event type.\n * @param {!Element|string} element The DOM element or element tag name to check.\n * @param {string} eventName The name of the event to check.\n * @return {boolean}\n */\nexport function supportsEvent(element, eventName) {\n\tif (customEvents[eventName]) {\n\t\treturn true;\n\t}\n\n\tif (isString(element)) {\n\t\tif (!elementsByTag_[element]) {\n\t\t\telementsByTag_[element] = document.createElement(element);\n\t\t}\n\t\telement = elementsByTag_[element];\n\t}\n\n\tconst tag = element.tagName;\n\tif (!supportCache_[tag] || !supportCache_[tag].hasOwnProperty(eventName)) {\n\t\tsupportCache_[tag] = supportCache_[tag] || {};\n\t\tsupportCache_[tag][eventName] = 'on' + eventName in element;\n\t}\n\treturn supportCache_[tag][eventName];\n}\n\n/**\n * This triggers all default matched delegated listeners of a given event type.\n * @param {!Array} defFns Array to collect default listeners in, instead\n * @param {!Event} event\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerDefaultDelegatedListeners_(defFns, event) {\n\tlet ret = true;\n\n\tfor (let i = 0; i < defFns.length && !event.defaultPrevented; i++) {\n\t\tevent.delegateTarget = defFns[i].element;\n\t\tret &= defFns[i].fn(event);\n\t}\n\n\treturn ret;\n}\n\n/**\n * This triggers all matched delegated listeners of a given event type when its\n * delegated target is able to interact.\n * @param {!Element} container\n * @param {!Event} event\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerDelegatedListeners_(container, event, defaultFns) {\n\tlet ret = true;\n\tlet currElement = event.target;\n\tconst limit = container.parentNode;\n\n\twhile (currElement && currElement !== limit && !event.stopped) {\n\t\tif (isAbleToInteractWith_(currElement, event.type, event)) {\n\t\t\tevent.delegateTarget = currElement;\n\t\t\tret &= triggerElementListeners_(currElement, event, defaultFns);\n\t\t\tret &= triggerSelectorListeners_(\n\t\t\t\tcontainer,\n\t\t\t\tcurrElement,\n\t\t\t\tevent,\n\t\t\t\tdefaultFns\n\t\t\t);\n\t\t}\n\t\tcurrElement = currElement.parentNode;\n\t}\n\n\treturn ret;\n}\n\n/**\n * Converts the given argument to a DOM element. Strings are assumed to\n * be selectors, and so a matched element will be returned. If the arg\n * is already a DOM element it will be the return value.\n * @param {string|Element|Document} selectorOrElement\n * @return {Element} The converted element, or null if none was found.\n */\nexport function toElement(selectorOrElement) {\n\tif (\n\t\tisElement(selectorOrElement) ||\n\t\tisDocument(selectorOrElement) ||\n\t\tisDocumentFragment(selectorOrElement)\n\t) {\n\t\treturn selectorOrElement;\n\t} else if (isString(selectorOrElement)) {\n\t\tif (\n\t\t\tselectorOrElement[0] === '#' &&\n\t\t\tselectorOrElement.indexOf(' ') === -1\n\t\t) {\n\t\t\treturn document.getElementById(selectorOrElement.substr(1));\n\t\t} else {\n\t\t\treturn document.querySelector(selectorOrElement);\n\t\t}\n\t} else {\n\t\treturn null;\n\t}\n}\n\n/**\n * Adds or removes one or more classes from an element. If any of the classes\n * is present, it will be removed from the element, or added otherwise.\n * @param {!Element} element The element which classes will be toggled.\n * @param {string} classes The classes which have to added or removed from the element.\n */\nexport function toggleClasses(element, classes) {\n\tif (!isObject(element) || !isString(classes)) {\n\t\treturn;\n\t}\n\n\tif ('classList' in element) {\n\t\ttoggleClassesWithNative_(element, classes);\n\t} else {\n\t\ttoggleClassesWithoutNative_(element, classes);\n\t}\n}\n\n/**\n * Adds or removes one or more classes from an element using classList.\n * If any of the classes is present, it will be removed from the element,\n * or added otherwise.\n * @param {!Element} element The element which classes will be toggled.\n * @param {string} classes The classes which have to added or removed from the element.\n * @private\n */\nfunction toggleClassesWithNative_(element, classes) {\n\tclasses.split(' ').forEach(function(className) {\n\t\telement.classList.toggle(className);\n\t});\n}\n\n/**\n * Adds or removes one or more classes from an element without using classList.\n * If any of the classes is present, it will be removed from the element,\n * or added otherwise.\n * @param {!Element} element The element which classes will be toggled.\n * @param {string} classes The classes which have to added or removed from the element.\n * @private\n */\nfunction toggleClassesWithoutNative_(element, classes) {\n\tlet elementClassName = ` ${element.className} `;\n\n\tclasses = classes.split(' ');\n\n\tfor (let i = 0; i < classes.length; i++) {\n\t\tconst className = ` ${classes[i]} `;\n\t\tconst classIndex = elementClassName.indexOf(className);\n\n\t\tif (classIndex === -1) {\n\t\t\telementClassName = `${elementClassName}${classes[i]} `;\n\t\t} else {\n\t\t\tconst before = elementClassName.substring(0, classIndex);\n\t\t\tconst after = elementClassName.substring(\n\t\t\t\tclassIndex + className.length\n\t\t\t); // eslint-disable-line\n\t\t\telementClassName = `${before} ${after}`;\n\t\t}\n\t}\n\n\telement.className = elementClassName.trim();\n}\n\n/**\n * Triggers all listeners for the given event type that are stored in the\n * specified element.\n * @param {!Element} element\n * @param {!Event} event\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerElementListeners_(element, event, defaultFns) {\n\tconst lastContainer = event[LAST_CONTAINER];\n\tif (!isDef(lastContainer) || !contains(lastContainer, element)) {\n\t\tconst listeners = domData.get(element, 'listeners', {})[event.type];\n\t\treturn triggerListeners_(listeners, event, element, defaultFns);\n\t}\n\treturn true;\n}\n\n/**\n * Triggers the specified event on the given element.\n * NOTE: This should mostly be used for testing, not on real code.\n * @param {!Element} element The node that should trigger the event.\n * @param {string} eventName The name of the event to be triggred.\n * @param {Object=} eventObj An object with data that should be on the\n * triggered event's payload.\n */\nexport function triggerEvent(element, eventName, eventObj) {\n\tif (isAbleToInteractWith_(element, eventName, eventObj)) {\n\t\tconst payload = document.createEvent('HTMLEvents');\n\t\tpayload.initEvent(eventName, true, true);\n\t\tobject.mixin(payload, eventObj);\n\t\telement.dispatchEvent(payload);\n\t}\n}\n\n/**\n * Triggers the given listeners array.\n * @param {Array} listeners\n * @param {!Event} event\n * @param {!Element} element\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerListeners_(listeners, event, element, defaultFns) {\n\tlet ret = true;\n\tlisteners = listeners || [];\n\tfor (let i = 0; i < listeners.length && !event.stoppedImmediate; i++) {\n\t\tif (listeners[i].defaultListener_) {\n\t\t\tdefaultFns.push({\n\t\t\t\telement,\n\t\t\t\tfn: listeners[i],\n\t\t\t});\n\t\t} else {\n\t\t\tret &= listeners[i](event);\n\t\t}\n\t}\n\treturn ret;\n}\n\n/**\n * Triggers all selector listeners for the given event.\n * @param {!Element} container\n * @param {!Element} element\n * @param {!Event} event\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerSelectorListeners_(container, element, event, defaultFns) {\n\tlet ret = true;\n\tconst data = domData.get(container, 'delegating', {});\n\tconst map = data[event.type].selectors;\n\tconst selectors = Object.keys(map);\n\tfor (let i = 0; i < selectors.length && !event.stoppedImmediate; i++) {\n\t\tif (match(element, selectors[i])) {\n\t\t\tconst listeners = map[selectors[i]];\n\t\t\tret &= triggerListeners_(listeners, event, element, defaultFns);\n\t\t}\n\t}\n\treturn ret;\n}\n","'use strict';\n\n// This file exists just for backwards compatibility, making sure that old\n// default imports for this file still work. It's best to use the named exports\n// for each function instead though, since that allows bundlers like Rollup to\n// reduce the bundle size by removing unused code.\nimport * as dom from './domNamed';\n\nexport default dom;\nexport {dom};\nexport * from './domNamed';\n","'use strict';\n\nimport {delegate, on, supportsEvent} from './dom';\nimport {EventEmitterProxy} from 'metal-events';\n\n/**\n * DomEventEmitterProxy utility. It extends `EventEmitterProxy` to also accept\n * dom elements as origin emitters.\n * @extends {EventEmitterProxy}\n */\nclass DomEventEmitterProxy extends EventEmitterProxy {\n\t/**\n\t * Adds the given listener for the given event.\n\t * @param {string} event\n\t * @param {!function()} listener\n\t * @return {!EventHandle} The listened event's handle.\n\t * @protected\n\t * @override\n\t */\n\taddListener_(event, listener) {\n\t\tif (this.originEmitter_.addEventListener) {\n\t\t\tif (this.isDelegateEvent_(event)) {\n\t\t\t\tconst index = event.indexOf(':', 9);\n\t\t\t\tconst eventName = event.substring(9, index);\n\t\t\t\tconst selector = event.substring(index + 1);\n\t\t\t\treturn delegate(\n\t\t\t\t\tthis.originEmitter_,\n\t\t\t\t\teventName,\n\t\t\t\t\tselector,\n\t\t\t\t\tlistener\n\t\t\t\t); // eslint-disable-line\n\t\t\t} else {\n\t\t\t\treturn on(this.originEmitter_, event, listener);\n\t\t\t}\n\t\t} else {\n\t\t\treturn super.addListener_(event, listener);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given event is of the delegate type.\n\t * @param {string} event\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisDelegateEvent_(event) {\n\t\treturn event.substr(0, 9) === 'delegate:';\n\t}\n\n\t/**\n\t * Checks if the given event is supported by the origin element.\n\t * @param {string} event\n\t * @protected\n\t * @return {boolean}\n\t */\n\tisSupportedDomEvent_(event) {\n\t\tif (!this.originEmitter_ || !this.originEmitter_.addEventListener) {\n\t\t\treturn true;\n\t\t}\n\t\treturn (\n\t\t\t(this.isDelegateEvent_(event) && event.indexOf(':', 9) !== -1) ||\n\t\t\tsupportsEvent(this.originEmitter_, event)\n\t\t);\n\t}\n\n\t/**\n\t * Checks if the given event should be proxied.\n\t * @param {string} event\n\t * @return {boolean}\n\t * @protected\n\t * @override\n\t */\n\tshouldProxyEvent_(event) {\n\t\treturn (\n\t\t\tsuper.shouldProxyEvent_(event) && this.isSupportedDomEvent_(event)\n\t\t); // eslint-disable-line\n\t}\n}\n\nexport default DomEventEmitterProxy;\n","'use strict';\n\nimport {append} from './dom';\nimport {string} from 'metal';\n\n/**\n * Class with static methods responsible for doing browser feature checks.\n */\nclass features {\n\t/**\n\t * Some browsers still supports prefixed animation events. This method can\n\t * be used to retrieve the current browser event name for both, animation\n\t * and transition.\n\t * @return {object}\n\t */\n\tstatic checkAnimationEventName() {\n\t\tif (features.animationEventName_ === undefined) {\n\t\t\tfeatures.animationEventName_ = {\n\t\t\t\tanimation: features.checkAnimationEventName_('animation'),\n\t\t\t\ttransition: features.checkAnimationEventName_('transition'),\n\t\t\t};\n\t\t}\n\t\treturn features.animationEventName_;\n\t}\n\n\t/**\n\t * @protected\n\t * @param {string} type Type to test: animation, transition.\n\t * @return {string} Browser event name.\n\t */\n\tstatic checkAnimationEventName_(type) {\n\t\tconst prefixes = ['Webkit', 'MS', 'O', ''];\n\t\tconst typeTitleCase = string.replaceInterval(\n\t\t\ttype,\n\t\t\t0,\n\t\t\t1,\n\t\t\ttype.substring(0, 1).toUpperCase()\n\t\t);\n\t\tconst suffixes = [\n\t\t\t`${typeTitleCase}End`,\n\t\t\t`${typeTitleCase}End`,\n\t\t\t`${typeTitleCase}End`,\n\t\t\t`${type}end`,\n\t\t];\n\t\tif (!features.animationElement_) {\n\t\t\tfeatures.animationElement_ = document.createElement('div');\n\t\t}\n\t\tfor (let i = 0; i < prefixes.length; i++) {\n\t\t\tif (\n\t\t\t\tfeatures.animationElement_.style[\n\t\t\t\t\tprefixes[i] + typeTitleCase\n\t\t\t\t] !== undefined // eslint-disable-line\n\t\t\t) {\n\t\t\t\treturn prefixes[i].toLowerCase() + suffixes[i];\n\t\t\t}\n\t\t}\n\t\treturn `${type}end`;\n\t}\n\n\t/**\n\t * Some browsers (like IE9) change the order of element attributes, when html\n\t * is rendered. This method can be used to check if this behavior happens on\n\t * the current browser.\n\t * @return {boolean}\n\t */\n\tstatic checkAttrOrderChange() {\n\t\tif (features.attrOrderChange_ === undefined) {\n\t\t\tconst originalContent = '
';\n\t\t\tconst element = document.createElement('div');\n\t\t\tappend(element, originalContent);\n\t\t\tfeatures.attrOrderChange_ = originalContent !== element.innerHTML;\n\t\t}\n\t\treturn features.attrOrderChange_;\n\t}\n}\n\nfeatures.animationElement_ = undefined;\nfeatures.animationEventName_ = undefined;\nfeatures.attrOrderChange_ = undefined;\n\nexport default features;\n","'use strict';\n\nimport {async} from 'metal';\nimport {exitDocument, once} from './dom';\n\n/**\n * Utility functions for running javascript code in the global scope.\n */\nclass globalEval {\n\t/**\n\t * Evaluates the given string in the global scope.\n\t * @param {string} text\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} script\n\t */\n\tstatic run(text, appendFn) {\n\t\tconst script = document.createElement('script');\n\t\tscript.text = text;\n\t\tif (appendFn) {\n\t\t\tappendFn(script);\n\t\t} else {\n\t\t\tdocument.head.appendChild(script);\n\t\t}\n\t\texitDocument(script);\n\t\treturn script;\n\t}\n\n\t/**\n\t * Evaluates the given javascript file in the global scope.\n\t * @param {string} src The file's path.\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} script\n\t */\n\tstatic runFile(src, defaultFn, appendFn) {\n\t\tconst script = document.createElement('script');\n\t\tscript.src = src;\n\n\t\tconst callback = function() {\n\t\t\texitDocument(script);\n\t\t\tdefaultFn && defaultFn();\n\t\t};\n\t\tonce(script, 'load', callback);\n\t\tonce(script, 'error', callback);\n\n\t\tif (appendFn) {\n\t\t\tappendFn(script);\n\t\t} else {\n\t\t\tdocument.head.appendChild(script);\n\t\t}\n\n\t\treturn script;\n\t}\n\n\t/**\n\t * Evaluates the code referenced by the given script element.\n\t * @param {!Element} script\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} script\n\t */\n\tstatic runScript(script, defaultFn, appendFn) {\n\t\tconst callback = function() {\n\t\t\tdefaultFn && defaultFn();\n\t\t};\n\t\tif (script.type && script.type !== 'text/javascript') {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn;\n\t\t}\n\t\texitDocument(script);\n\t\tif (script.src) {\n\t\t\treturn globalEval.runFile(script.src, defaultFn, appendFn);\n\t\t} else {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn globalEval.run(script.text, appendFn);\n\t\t}\n\t}\n\n\t/**\n\t * Evaluates any script tags present in the given element.\n\t * @param {!Element} element\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t */\n\tstatic runScriptsInElement(element, defaultFn, appendFn) {\n\t\tconst scripts = element.querySelectorAll('script');\n\t\tif (scripts.length) {\n\t\t\tglobalEval.runScriptsInOrder(scripts, 0, defaultFn, appendFn);\n\t\t} else if (defaultFn) {\n\t\t\tasync.nextTick(defaultFn);\n\t\t}\n\t}\n\n\t/**\n\t * Runs the given scripts elements in the order that they appear.\n\t * @param {!NodeList} scripts\n\t * @param {number} index\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t */\n\tstatic runScriptsInOrder(scripts, index, defaultFn, appendFn) {\n\t\tglobalEval.runScript(\n\t\t\tscripts.item(index),\n\t\t\tfunction() {\n\t\t\t\tif (index < scripts.length - 1) {\n\t\t\t\t\tglobalEval.runScriptsInOrder(\n\t\t\t\t\t\tscripts,\n\t\t\t\t\t\tindex + 1,\n\t\t\t\t\t\tdefaultFn,\n\t\t\t\t\t\tappendFn\n\t\t\t\t\t); // eslint-disable-line\n\t\t\t\t} else if (defaultFn) {\n\t\t\t\t\tasync.nextTick(defaultFn);\n\t\t\t\t}\n\t\t\t},\n\t\t\tappendFn\n\t\t);\n\t}\n}\n\nexport default globalEval;\n","'use strict';\n\nimport {async} from 'metal';\nimport {once} from './dom';\n\n/**\n * Utility functions for running styles.\n */\nclass globalEvalStyles {\n\t/**\n\t * Evaluates the given style.\n\t * @param {string} text\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} style\n\t */\n\tstatic run(text, appendFn) {\n\t\tconst style = document.createElement('style');\n\t\tstyle.innerHTML = text;\n\t\tif (appendFn) {\n\t\t\tappendFn(style);\n\t\t} else {\n\t\t\tdocument.head.appendChild(style);\n\t\t}\n\t\treturn style;\n\t}\n\n\t/**\n\t * Evaluates the given style file.\n\t * @param {string} href The file's path.\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the styles has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} style\n\t */\n\tstatic runFile(href, defaultFn, appendFn) {\n\t\tconst link = document.createElement('link');\n\t\tlink.rel = 'stylesheet';\n\t\tlink.href = href;\n\t\tglobalEvalStyles.runStyle(link, defaultFn, appendFn);\n\t\treturn link;\n\t}\n\n\t/**\n\t * Evaluates the code referenced by the given style/link element.\n\t * @param {!Element} style\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} style\n\t */\n\tstatic runStyle(style, defaultFn, appendFn) {\n\t\tconst callback = function() {\n\t\t\tdefaultFn && defaultFn();\n\t\t};\n\t\tif (style.rel && style.rel !== 'stylesheet') {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn;\n\t\t}\n\n\t\tif (style.tagName === 'STYLE') {\n\t\t\tasync.nextTick(callback);\n\t\t} else {\n\t\t\tonce(style, 'load', callback);\n\t\t\tonce(style, 'error', callback);\n\t\t}\n\n\t\tif (appendFn) {\n\t\t\tappendFn(style);\n\t\t} else {\n\t\t\tdocument.head.appendChild(style);\n\t\t}\n\n\t\treturn style;\n\t}\n\n\t/**\n\t * Evaluates any style present in the given element.\n\t * @param {!Element} element\n\t * @param {function()=} defaultFn Optional function to be called when the\n\t * style has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t */\n\tstatic runStylesInElement(element, defaultFn, appendFn) {\n\t\tconst styles = element.querySelectorAll('style,link');\n\t\tif (styles.length === 0 && defaultFn) {\n\t\t\tasync.nextTick(defaultFn);\n\t\t\treturn;\n\t\t}\n\n\t\tlet loadCount = 0;\n\t\tconst callback = function() {\n\t\t\tif (defaultFn && ++loadCount === styles.length) {\n\t\t\t\tasync.nextTick(defaultFn);\n\t\t\t}\n\t\t};\n\t\tfor (let i = 0; i < styles.length; i++) {\n\t\t\tglobalEvalStyles.runStyle(styles[i], callback, appendFn);\n\t\t}\n\t}\n}\n\nexport default globalEvalStyles;\n","'use strict';\n\nimport {isServerSide} from 'metal';\nimport {registerCustomEvent, contains} from './dom';\nimport features from './features';\n\n/**\n * Register custom events for event delegation.\n */\nfunction registerEvents() {\n\tconst mouseEventMap = {\n\t\tmouseenter: 'mouseover',\n\t\tmouseleave: 'mouseout',\n\t\tpointerenter: 'pointerover',\n\t\tpointerleave: 'pointerout',\n\t};\n\tObject.keys(mouseEventMap).forEach(function(eventName) {\n\t\tregisterCustomEvent(eventName, {\n\t\t\tdelegate: true,\n\t\t\thandler: function(callback, event) {\n\t\t\t\tconst related = event.relatedTarget;\n\t\t\t\tconst target = event.delegateTarget;\n\t\t\t\t// eslint-disable-next-line\n\t\t\t\tif (\n\t\t\t\t\t!related ||\n\t\t\t\t\t(related !== target && !contains(target, related))\n\t\t\t\t) {\n\t\t\t\t\tevent.customType = eventName;\n\t\t\t\t\treturn callback(event);\n\t\t\t\t}\n\t\t\t},\n\t\t\toriginalEvent: mouseEventMap[eventName],\n\t\t});\n\t});\n\n\tconst animationEventMap = {\n\t\tanimation: 'animationend',\n\t\ttransition: 'transitionend',\n\t};\n\tObject.keys(animationEventMap).forEach(function(eventType) {\n\t\tconst eventName = animationEventMap[eventType];\n\t\tregisterCustomEvent(eventName, {\n\t\t\tevent: true,\n\t\t\tdelegate: true,\n\t\t\thandler: function(callback, event) {\n\t\t\t\tevent.customType = eventName;\n\t\t\t\treturn callback(event);\n\t\t\t},\n\t\t\toriginalEvent: features.checkAnimationEventName()[eventType],\n\t\t});\n\t});\n}\n\nif (!isServerSide()) {\n\tregisterEvents();\n}\n","var globals = globals || {};\n\nif (typeof window !== 'undefined') {\n\tglobals.window = window;\n}\n\nif (typeof document !== 'undefined') {\n\tglobals.document = document;\n}\n\nexport default globals;\n","'use strict';\n\n/**\n * Parses the given uri string into an object.\n * @param {*=} opt_uri Optional string URI to parse\n */\nfunction parseFromAnchor(opt_uri) {\n\tvar link = document.createElement('a');\n\tlink.href = opt_uri;\n\n\tif(link.protocol === ':' || !/:/.test(link.href)) {\n\t\tthrow new TypeError(`${opt_uri} is not a valid URL`);\n\t}\n\n\treturn {\n\t\thash: link.hash,\n\t\thostname: link.hostname,\n\t\tpassword: link.password,\n\t\tpathname: link.pathname[0] === '/' ? link.pathname : '/' + link.pathname,\n\t\tport: link.port,\n\t\tprotocol: link.protocol,\n\t\tsearch: link.search,\n\t\tusername: link.username\n\t};\n}\n\nexport default parseFromAnchor;\n","'use strict';\n\nimport { isFunction } from 'metal';\nimport parseFromAnchor from './parseFromAnchor';\n\n/**\n * Parses the given uri string into an object. The URL function will be used\n * when present, otherwise we'll fall back to the anchor node element.\n * @param {*=} opt_uri Optional string URI to parse\n */\nfunction parse(opt_uri) {\n\tif (isFunction(URL) && URL.length) {\n\t\tconst url = new URL(opt_uri);\n\n\t\t// Safari Browsers will cap port to the max 16-bit unsigned integer (65535) instead\n\t\t// of throwing a TypeError as per spec. It will still keep the port number in the\n\t\t// href attribute, so we can use this mismatch to raise the expected exception.\n\t\tif (url.port && url.href.indexOf(url.port) === -1) {\n\t\t\tthrow new TypeError(`${opt_uri} is not a valid URL`);\n\t\t}\n\n\t\treturn url;\n\t} else {\n\t\treturn parseFromAnchor(opt_uri);\n\t}\n}\n\nexport default parse;\n","'use strict';\n\nimport { Disposable } from 'metal';\n\n/**\n * A cached reference to the create function.\n */\nvar create = Object.create;\n\n/**\n * Case insensitive string Multimap implementation. Allows multiple values for\n * the same key name.\n * @extends {Disposable}\n */\nclass MultiMap extends Disposable {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.keys = create(null);\n\t\tthis.values = create(null);\n\t}\n\n\t/**\n\t * Adds value to a key name.\n\t * @param {string} name\n\t * @param {*} value\n\t * @chainable\n\t */\n\tadd(name, value) {\n\t\tthis.keys[name.toLowerCase()] = name;\n\t\tthis.values[name.toLowerCase()] = this.values[name.toLowerCase()] || [];\n\t\tthis.values[name.toLowerCase()].push(value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Clears map names and values.\n\t * @chainable\n\t */\n\tclear() {\n\t\tthis.keys = create(null);\n\t\tthis.values = create(null);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Checks if map contains a value to the key name.\n\t * @param {string} name\n\t * @return {boolean}\n\t * @chainable\n\t */\n\tcontains(name) {\n\t\treturn name.toLowerCase() in this.values;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tthis.values = null;\n\t}\n\n\t/**\n\t * Creates a `MultiMap` instance from the given object.\n\t * @param {!Object} obj\n\t * @return {!MultiMap}\n\t */\n\tstatic fromObject(obj) {\n\t\tvar map = new MultiMap();\n\t\tvar keys = Object.keys(obj);\n\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\tmap.set(keys[i], obj[keys[i]]);\n\t\t}\n\t\treturn map;\n\t}\n\n\t/**\n\t * Gets the first added value from a key name.\n\t * @param {string} name\n\t * @return {*}\n\t * @chainable\n\t */\n\tget(name) {\n\t\tvar values = this.values[name.toLowerCase()];\n\t\tif (values) {\n\t\t\treturn values[0];\n\t\t}\n\t}\n\n\t/**\n\t * Gets all values from a key name.\n\t * @param {string} name\n\t * @return {Array.<*>}\n\t */\n\tgetAll(name) {\n\t\treturn this.values[name.toLowerCase()];\n\t}\n\n\t/**\n\t * Returns true if the map is empty, false otherwise.\n\t * @return {boolean}\n\t */\n\tisEmpty() {\n\t\treturn this.size() === 0;\n\t}\n\n\t/**\n\t * Gets array of key names.\n\t * @return {Array.}\n\t */\n\tnames() {\n\t\treturn Object.keys(this.values).map((key) => this.keys[key]);\n\t}\n\n\t/**\n\t * Removes all values from a key name.\n\t * @param {string} name\n\t * @chainable\n\t */\n\tremove(name) {\n\t\tdelete this.keys[name.toLowerCase()];\n\t\tdelete this.values[name.toLowerCase()];\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of a key name. Relevant to replace the current values with\n\t * a new one.\n\t * @param {string} name\n\t * @param {*} value\n\t * @chainable\n\t */\n\tset(name, value) {\n\t\tthis.keys[name.toLowerCase()] = name;\n\t\tthis.values[name.toLowerCase()] = [value];\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the size of the map key names.\n\t * @return {number}\n\t */\n\tsize() {\n\t\treturn this.names().length;\n\t}\n\n\t/**\n\t * Returns the parsed values as a string.\n\t * @return {string}\n\t */\n\ttoString() {\n\t\treturn JSON.stringify(this.values);\n\t}\n}\n\nexport default MultiMap;\n","'use strict';\n\nimport { array } from 'metal';\n\n/**\n * Generic tree node data structure with arbitrary number of child nodes.\n * @param {V} value Value.\n * @constructor\n */\nclass TreeNode {\n\n\tconstructor(value) {\n\t\t/**\n\t\t * The value.\n\t\t * @private {V}\n\t\t */\n\t\tthis.value_ = value;\n\n\t\t/**\n\t\t * Reference to the parent node or null if it has no parent.\n\t\t * @private {TreeNode}\n\t\t */\n\t\tthis.parent_ = null;\n\n\t\t/**\n\t\t * Child nodes or null in case of leaf node.\n\t\t * @private {Array}\n\t\t */\n\t\tthis.children_ = null;\n\t}\n\n\t/**\n\t * Appends a child node to this node.\n\t * @param {!TreeNode} child Orphan child node.\n\t */\n\taddChild(child) {\n\t\tassertChildHasNoParent(child);\n\t\tchild.setParent(this);\n\t\tthis.children_ = this.children_ || [];\n\t\tthis.children_.push(child);\n\t}\n\n\t/**\n\t * Tells whether this node is the ancestor of the given node.\n\t * @param {!TreeNode} node A node.\n\t * @return {boolean} Whether this node is the ancestor of {@code node}.\n\t */\n\tcontains(node) {\n\t\tlet current = node.getParent();\n\t\twhile (current) {\n\t\t\tif (current === this) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcurrent = current.getParent();\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * @return {!Array} All ancestor nodes in bottom-up order.\n\t */\n\tgetAncestors() {\n\t\tlet ancestors = [];\n\t\tlet node = this.getParent();\n\t\twhile (node) {\n\t\t\tancestors.push(node);\n\t\t\tnode = node.getParent();\n\t\t}\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Gets the child node of this node at the given index.\n\t * @param {number} index Child index.\n\t * @return {?TreeNode} The node at the given index\n\t * or null if not found.\n\t */\n\tgetChildAt(index) {\n\t\treturn this.getChildren()[index] || null;\n\t}\n\n\t/**\n\t * @return {?Array} Child nodes or null in case of leaf node.\n\t */\n\tgetChildren() {\n\t\treturn this.children_ || TreeNode.EMPTY_ARRAY;\n\t}\n\n\t/**\n\t * @return {number} The number of children.\n\t */\n\tgetChildCount() {\n\t\treturn this.getChildren().length;\n\t}\n\n\t/**\n\t * @return {number} The number of ancestors of the node.\n\t */\n\tgetDepth() {\n\t\tlet depth = 0;\n\t\tlet node = this;\n\t\twhile (node.getParent()) {\n\t\t\tdepth++;\n\t\t\tnode = node.getParent();\n\t\t}\n\t\treturn depth;\n\t}\n\n\t/**\n\t * @return {?TreeNode} Parent node or null if it has no parent.\n\t */\n\tgetParent() {\n\t\treturn this.parent_;\n\t}\n\n\t/**\n\t * @return {!TreeNode} The root of the tree structure, i.e. the farthest\n\t * ancestor of the node or the node itself if it has no parents.\n\t */\n\tgetRoot() {\n\t\tlet root = this;\n\t\twhile (root.getParent()) {\n\t\t\troot = root.getParent();\n\t\t}\n\t\treturn root;\n\t}\n\n\t/**\n\t * Gets the value.\n\t * @return {V} The value.\n\t */\n\tgetValue() {\n\t\treturn this.value_;\n\t}\n\n\t/**\n\t * @return {boolean} Whether the node is a leaf node.\n\t */\n\tisLeaf() {\n\t\treturn !this.getChildCount();\n\t}\n\n\t/**\n\t * Removes the given child node of this node.\n\t * @param {TreeNode} child The node to remove.\n\t * @return {TreeNode} The removed node if any, null otherwise.\n\t */\n\tremoveChild(child) {\n\t\tif (array.remove(this.getChildren(), child)) {\n\t\t\treturn child;\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Sets the parent node of this node. The callers must ensure that the\n\t * parent node and only that has this node among its children.\n\t * @param {TreeNode} parent The parent to set. If null, the node will be\n\t * detached from the tree.\n\t * @protected\n\t */\n\tsetParent(parent) {\n\t\tthis.parent_ = parent;\n\t}\n\n\t/**\n\t * Traverses the subtree. The first callback starts with this node,\n\t * and visits the descendant nodes depth-first, in preorder.\n\t * The second callback, starts with deepest child then visits\n\t * the ancestor nodes depth-first, in postorder. E.g.\n\t *\n\t * \t A\n\t * / \\\n\t * B C\n\t * / / \\\n\t * D E F\n\t *\n\t * preorder -> ['A', 'B', 'D', 'C', 'E', 'F']\n\t * postorder -> ['D', 'B', 'E', 'F', 'C', 'A']\n\t *\n\t * @param {function=} opt_preorderFn The callback to execute when visiting a node.\n\t * @param {function=} opt_postorderFn The callback to execute before leaving a node.\n\t */\n\ttraverse(opt_preorderFn, opt_postorderFn) {\n\t\tif (opt_preorderFn) {\n\t\t\topt_preorderFn(this);\n\t\t}\n\t\tthis.getChildren().forEach((child) => child.traverse(opt_preorderFn, opt_postorderFn));\n\t\tif (opt_postorderFn) {\n\t\t\topt_postorderFn(this);\n\t\t}\n\t}\n\n}\n\n/**\n * Constant for empty array to avoid unnecessary allocations.\n * @private\n */\nTreeNode.EMPTY_ARRAY = [];\n\n/**\n * Asserts that child has no parent.\n * @param {TreeNode} child A child.\n * @private\n */\nconst assertChildHasNoParent = function(child) {\n\tif (child.getParent()) {\n\t\tthrow new Error('Cannot add child with parent.');\n\t}\n};\n\nexport default TreeNode;\n","'use strict';\n\nimport { isDef, string } from 'metal';\nimport parse from './parse';\nimport { MultiMap } from 'metal-structs';\n\nvar parseFn_ = parse;\n\nclass Uri {\n\n\t/**\n\t * This class contains setters and getters for the parts of the URI.\n\t * The following figure displays an example URIs and their component parts.\n\t *\n\t * path\n\t *\t ┌───┴────┐\n\t *\t abc://example.com:123/path/data?key=value#fragid1\n\t *\t └┬┘ └────┬────┘ └┬┘ └───┬───┘ └──┬──┘\n\t * protocol hostname port search hash\n\t * └──────┬───────┘\n\t * host\n\t *\n\t * @param {*=} opt_uri Optional string URI to parse\n\t * @constructor\n\t */\n\tconstructor(opt_uri = '') {\n\t\tthis.url = Uri.parse(this.maybeAddProtocolAndHostname_(opt_uri));\n\t}\n\n\t/**\n\t * Adds parameters to uri from a MultiMap as source.\n\t * @param {MultiMap} multimap The MultiMap containing the\n\t * parameters.\n\t * @protected\n\t * @chainable\n\t */\n\taddParametersFromMultiMap(multimap) {\n\t\tmultimap.names().forEach((name) => {\n\t\t\tmultimap.getAll(name).forEach((value) => {\n\t\t\t\tthis.addParameterValue(name, value);\n\t\t\t});\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds the value of the named query parameters.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value. Will be explicitly casted to String.\n\t * @chainable\n\t */\n\taddParameterValue(name, value) {\n\t\tthis.ensureQueryInitialized_();\n\t\tif (isDef(value)) {\n\t\t\tvalue = String(value);\n\t\t}\n\t\tthis.query.add(name, value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds the values of the named query parameter.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value.\n\t * @chainable\n\t */\n\taddParameterValues(name, values) {\n\t\tvalues.forEach((value) => this.addParameterValue(name, value));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Ensures query internal map is initialized and synced with initial value\n\t * extracted from URI search part.\n\t * @protected\n\t */\n\tensureQueryInitialized_() {\n\t\tif (this.query) {\n\t\t\treturn;\n\t\t}\n\t\tthis.query = new MultiMap();\n\t\tvar search = this.url.search;\n\t\tif (search) {\n\t\t\tsearch.substring(1).split('&').forEach((param) => {\n\t\t\t\tvar [key, value] = param.split('=');\n\t\t\t\tif (isDef(value)) {\n\t\t\t\t\tvalue = Uri.urlDecode(value);\n\t\t\t\t}\n\t\t\t\tthis.addParameterValue(key, value);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets the hash part of uri.\n\t * @return {string}\n\t */\n\tgetHash() {\n\t\treturn this.url.hash || '';\n\t}\n\n\t/**\n\t * Gets the host part of uri. E.g. [hostname]:[port].\n\t * @return {string}\n\t */\n\tgetHost() {\n\t\tvar host = this.getHostname();\n\t\tif (host) {\n\t\t\tvar port = this.getPort();\n\t\t\tif (port && port !== '80') {\n\t\t\t\thost += ':' + port;\n\t\t\t}\n\t\t}\n\t\treturn host;\n\t}\n\n\t/**\n\t * Gets the hostname part of uri without protocol and port.\n\t * @return {string}\n\t */\n\tgetHostname() {\n\t\tvar hostname = this.url.hostname;\n\t\tif (hostname === Uri.HOSTNAME_PLACEHOLDER) {\n\t\t\treturn '';\n\t\t}\n\t\treturn hostname;\n\t}\n\n\t/**\n\t * Gets the origin part of uri. E.g. http://[hostname]:[port].\n\t * @return {string}\n\t */\n\tgetOrigin() {\n\t\tvar host = this.getHost();\n\t\tif (host) {\n\t\t\treturn this.getProtocol() + '//' + host;\n\t\t}\n\t\treturn '';\n\t}\n\n\t/**\n\t * Returns the first value for a given parameter or undefined if the given\n\t * parameter name does not appear in the query string.\n\t * @param {string} paramName Unescaped parameter name.\n\t * @return {string|undefined} The first value for a given parameter or\n\t * undefined if the given parameter name does not appear in the query\n\t * string.\n\t */\n\tgetParameterValue(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.get(name);\n\t}\n\n\t/**\n\t * Returns the values for a given parameter as a list of decoded\n\t * query parameter values.\n\t * @param {string} name The parameter to get values for.\n\t * @return {!Array} The values for a given parameter as a list of decoded\n\t * query parameter values.\n\t */\n\tgetParameterValues(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.getAll(name);\n\t}\n\n\t/**\n\t * Returns the names of the parameters.\n\t * @return {!Array} The names for the parameters as a list of\n\t * strings.\n\t */\n\tgetParameterNames() {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.names();\n\t}\n\n\t/**\n\t * Gets the function currently being used to parse URIs.\n\t * @return {!function()}\n\t */\n\tstatic getParseFn() {\n\t\treturn parseFn_;\n\t}\n\n\t/**\n\t * Gets the pathname part of uri.\n\t * @return {string}\n\t */\n\tgetPathname() {\n\t\treturn this.url.pathname;\n\t}\n\n\t/**\n\t * Gets the port number part of uri as string.\n\t * @return {string}\n\t */\n\tgetPort() {\n\t\treturn this.url.port;\n\t}\n\n\t/**\n\t * Gets the protocol part of uri. E.g. http:.\n\t * @return {string}\n\t */\n\tgetProtocol() {\n\t\treturn this.url.protocol;\n\t}\n\n\t/**\n\t * Gets the search part of uri. Search value is retrieved from query\n\t * parameters.\n\t * @return {string}\n\t */\n\tgetSearch() {\n\t\tvar search = '';\n\t\tvar querystring = '';\n\t\tthis.getParameterNames().forEach((name) => {\n\t\t\tthis.getParameterValues(name).forEach((value) => {\n\t\t\t\tquerystring += name;\n\t\t\t\tif (isDef(value)) {\n\t\t\t\t\tquerystring += '=' + encodeURIComponent(value);\n\t\t\t\t}\n\t\t\t\tquerystring += '&';\n\t\t\t});\n\t\t});\n\t\tquerystring = querystring.slice(0, -1);\n\t\tif (querystring) {\n\t\t\tsearch += '?' + querystring;\n\t\t}\n\t\treturn search;\n\t}\n\n\t/**\n\t * Checks if uri contains the parameter.\n\t * @param {string} name\n\t * @return {boolean}\n\t */\n\thasParameter(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.contains(name);\n\t}\n\n\t/**\n\t * Makes this URL unique by adding a random param to it. Useful for avoiding\n\t * cache.\n\t */\n\tmakeUnique() {\n\t\tthis.setParameterValue(Uri.RANDOM_PARAM, string.getRandomString());\n\t\treturn this;\n\t}\n\n\t/**\n\t * Maybe adds protocol and a hostname placeholder on a parial URI if needed.\n\t * Relevent for compatibility with URL native object.\n\t * @param {string=} opt_uri\n\t * @return {string} URI with protocol and hostname placeholder.\n\t */\n\tmaybeAddProtocolAndHostname_(opt_uri) {\n\t\tvar url = opt_uri;\n\t\tif (opt_uri.indexOf('://') === -1 &&\n\t\t\topt_uri.indexOf('javascript:') !== 0) { // jshint ignore:line\n\n\t\t\turl = Uri.DEFAULT_PROTOCOL;\n\t\t\tif (opt_uri[0] !== '/' || opt_uri[1] !== '/') {\n\t\t\t\turl += '//';\n\t\t\t}\n\n\t\t\tswitch (opt_uri.charAt(0)) {\n\t\t\t\tcase '.':\n\t\t\t\tcase '?':\n\t\t\t\tcase '#':\n\t\t\t\t\turl += Uri.HOSTNAME_PLACEHOLDER;\n\t\t\t\t\turl += '/';\n\t\t\t\t\turl += opt_uri;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '':\n\t\t\t\tcase '/':\n\t\t\t\t\tif (opt_uri[1] !== '/') {\n\t\t\t\t\t\turl += Uri.HOSTNAME_PLACEHOLDER;\n\t\t\t\t\t}\n\t\t\t\t\turl += opt_uri;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\turl += opt_uri;\n\t\t\t}\n\t\t}\n\t\treturn url;\n\t}\n\n\t/**\n\t * Parses the given uri string into an object.\n\t * @param {*=} opt_uri Optional string URI to parse\n\t */\n\tstatic parse(opt_uri) {\n\t\treturn parseFn_(opt_uri);\n\t}\n\n\t/**\n\t * Removes the named query parameter.\n\t * @param {string} name The parameter to remove.\n\t * @chainable\n\t */\n\tremoveParameter(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\tthis.query.remove(name);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes uniqueness parameter of the uri.\n\t * @chainable\n\t */\n\tremoveUnique() {\n\t\tthis.removeParameter(Uri.RANDOM_PARAM);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the hash.\n\t * @param {string} hash\n\t * @chainable\n\t */\n\tsetHash(hash) {\n\t\tthis.url.hash = hash;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the hostname.\n\t * @param {string} hostname\n\t * @chainable\n\t */\n\tsetHostname(hostname) {\n\t\tthis.url.hostname = hostname;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of the named query parameters, clearing previous values\n\t * for that key.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value.\n\t * @chainable\n\t */\n\tsetParameterValue(name, value) {\n\t\tthis.removeParameter(name);\n\t\tthis.addParameterValue(name, value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the values of the named query parameters, clearing previous values\n\t * for that key.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value.\n\t * @chainable\n\t */\n\tsetParameterValues(name, values) {\n\t\tthis.removeParameter(name);\n\t\tvalues.forEach((value) => this.addParameterValue(name, value));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the pathname.\n\t * @param {string} pathname\n\t * @chainable\n\t */\n\tsetPathname(pathname) {\n\t\tthis.url.pathname = pathname;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the port number.\n\t * @param {*} port Port number.\n\t * @chainable\n\t */\n\tsetPort(port) {\n\t\tthis.url.port = port;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the function that will be used for parsing the original string uri\n\t * into an object.\n\t * @param {!function()} parseFn\n\t */\n\tstatic setParseFn(parseFn) {\n\t\tparseFn_ = parseFn;\n\t}\n\n\t/**\n\t * Sets the protocol. If missing http: is used as default.\n\t * @param {string} protocol\n\t * @chainable\n\t */\n\tsetProtocol(protocol) {\n\t\tthis.url.protocol = protocol;\n\t\tif (this.url.protocol[this.url.protocol.length - 1] !== ':') {\n\t\t\tthis.url.protocol += ':';\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * @return {string} The string form of the url.\n\t * @override\n\t */\n\ttoString() {\n\t\tvar href = '';\n\t\tvar host = this.getHost();\n\t\tif (host) {\n\t\t\thref += this.getProtocol() + '//';\n\t\t}\n\t\thref += host + this.getPathname() + this.getSearch() + this.getHash();\n\t\treturn href;\n\t}\n\n\t/**\n\t * Joins the given paths.\n\t * @param {string} basePath\n\t * @param {...string} ...paths Any number of paths to be joined with the base url.\n\t * @static\n\t */\n\tstatic joinPaths(basePath, ...paths) {\n\t\tif (basePath.charAt(basePath.length - 1) === '/') {\n\t\t\tbasePath = basePath.substring(0, basePath.length - 1);\n\t\t}\n\t\tpaths = paths.map(path => path.charAt(0) === '/' ? path.substring(1) : path);\n\t\treturn [basePath].concat(paths).join('/').replace(/\\/$/, '');\n\t}\n\n\t/**\n\t * URL-decodes the string. We need to specially handle '+'s because\n\t * the javascript library doesn't convert them to spaces.\n\t * @param {string} str The string to url decode.\n\t * @return {string} The decoded {@code str}.\n\t */\n\tstatic urlDecode(str) {\n\t\treturn decodeURIComponent(str.replace(/\\+/g, ' '));\n\t}\n\n}\n\n/**\n * Default protocol value.\n * @type {string}\n * @default http:\n * @static\n */\nconst isSecure = () =>\n\t(typeof window !== 'undefined' &&\n\t\twindow.location &&\n\t\twindow.location.protocol &&\n\t\twindow.location.protocol.indexOf('https') === 0);\n\nUri.DEFAULT_PROTOCOL = isSecure() ? 'https:' : 'http:';\n\n/**\n * Hostname placeholder. Relevant to internal usage only.\n * @type {string}\n * @static\n */\nUri.HOSTNAME_PLACEHOLDER = 'hostname' + Date.now();\n\n/**\n * Name used by the param generated by `makeUnique`.\n * @type {string}\n * @static\n */\nUri.RANDOM_PARAM = 'zx';\n\nexport default Uri;\n","'use strict';\n\nimport { exitDocument } from 'metal-dom';\nimport globals from '../globals/globals';\nimport Uri from 'metal-uri';\n\n/**\n * A collection of static utility functions.\n * @const\n */\nclass utils {\n\n\t/**\n\t * Copies attributes form source node to target node.\n\t * @return {void}\n\t * @static\n\t */\n\tstatic copyNodeAttributes(source, target) {\n\t\tArray.prototype.slice.call(source.attributes).forEach((attribute) => target.setAttribute(attribute.name, attribute.value));\n\t}\n\n\t/**\n\t * Gets the current browser path including hashbang.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getCurrentBrowserPath() {\n\t\treturn this.getCurrentBrowserPathWithoutHash() + globals.window.location.hash;\n\t}\n\n\t/**\n\t * Gets the current browser path excluding hashbang.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getCurrentBrowserPathWithoutHash() {\n\t\treturn globals.window.location.pathname + globals.window.location.search;\n\t}\n\n\t/**\n\t * Gets the given node offset coordinates.\n\t * @return {!object}\n\t * @static\n\t */\n\tstatic getNodeOffset(node) {\n\t\tlet [offsetLeft, offsetTop] = [0, 0];\n\t\tdo {\n\t\t\toffsetLeft += node.offsetLeft;\n\t\t\toffsetTop += node.offsetTop;\n\t\t\tnode = node.offsetParent;\n\t\t} while (node);\n\t\treturn {\n\t\t\toffsetLeft,\n\t\t\toffsetTop\n\t\t};\n\t}\n\n\t/**\n\t * Extracts the path part of an url.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getUrlPath(url) {\n\t\tvar uri = new Uri(url);\n\t\treturn uri.getPathname() + uri.getSearch() + uri.getHash();\n\t}\n\n\t/**\n\t * Extracts the path part of an url without hashbang.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getUrlPathWithoutHash(url) {\n\t\tvar uri = new Uri(url);\n\t\treturn uri.getPathname() + uri.getSearch();\n\t}\n\n\t/**\n\t * Extracts the path part of an url without hashbang and query search.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getUrlPathWithoutHashAndSearch(url) {\n\t\tvar uri = new Uri(url);\n\t\treturn uri.getPathname();\n\t}\n\n\t/**\n\t * Checks if url is in the same browser current url excluding the hashbang.\n\t * @param {!string} url\n\t * @return {boolean}\n\t * @static\n\t */\n\tstatic isCurrentBrowserPath(url) {\n\t\tif (url) {\n\t\t\tconst currentBrowserPath = this.getCurrentBrowserPathWithoutHash();\n\t\t\t// the getUrlPath will create a Uri and will normalize the path and\n\t\t\t// remove the trailling '/' for properly comparing paths.\n\t\t\treturn utils.getUrlPathWithoutHash(url) === this.getUrlPath(currentBrowserPath);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns true if HTML5 History api is supported.\n\t * @return {boolean}\n\t * @static\n\t */\n\tstatic isHtml5HistorySupported() {\n\t\treturn !!(globals.window.history && globals.window.history.pushState);\n\t}\n\n\t/**\n\t * Checks if a given url is a valid http(s) uri and returns the formed Uri\n\t * or false if the parsing failed\n\t * @return {Uri|boolean}\n\t * @static\n\t */\n\tstatic isWebUri(url) {\n\t\ttry {\n\t\t\treturn new Uri(url);\n\t\t} catch (err) {\n\t\t\tconsole.error(`${err.message} ${url}`);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Removes all attributes form node.\n\t * @return {void}\n\t * @static\n\t */\n\tstatic clearNodeAttributes(node) {\n\t\tArray.prototype.slice.call(node.attributes).forEach((attribute) => node.removeAttribute(attribute.name));\n\t}\n\n\t/**\n\t * Remove elements from the document.\n\t * @param {!Array} elements\n\t */\n\tstatic removeElementsFromDocument(elements) {\n\t\telements.forEach((element) => exitDocument(element));\n\t}\n\n\t/**\n\t* Removes trailing slash in path.\n\t* @param {!string}\n\t* @return {string}\n\t*/\n\tstatic removePathTrailingSlash(path) {\n\t\tvar length = path ? path.length : 0;\n\t\tif (length > 1 && path[length - 1] === '/') {\n\t\t\tpath = path.substr(0, length - 1);\n\t\t}\n\t\treturn path;\n\t}\n\n\t/**\n\t * Adds a random suffix to the href attribute of the element.\n\t * @param {!element} element\n\t * @return {element}\n\t */\n\tstatic setElementWithRandomHref(element) {\n\t\telement.href = element.href + '?q=' + Math.random();\n\t\treturn element;\n\t}\n\n\t/**\n\t * Overrides document referrer\n\t * @param {string} referrer\n\t * @static\n\t */\n\tstatic setReferrer(referrer) {\n\t\tObject.defineProperty(globals.document, 'referrer', {\n\t\t\tconfigurable: true,\n\t\t\tget: function() {\n\t\t\t\treturn referrer;\n\t\t\t}\n\t\t});\n\t}\n}\n\nexport default utils;\n","'use strict';\n\nexport default {\n\tbasePath: 'data-senna-base-path',\n\tlinkSelector: 'data-senna-link-selector',\n\tloadingCssClass: 'data-senna-loading-css-class',\n\tsenna: 'data-senna',\n\tdispatch: 'data-senna-dispatch',\n\tsurface: 'data-senna-surface',\n\tupdateScrollPosition: 'data-senna-update-scroll-position'\n};","/*!\n * Promises polyfill from Google's Closure Library.\n *\n * Copyright 2013 The Closure Library Authors. All Rights Reserved.\n *\n * NOTE(eduardo): Promise support is not ready on all supported browsers,\n * therefore metal-promise is temporarily using Google's promises as polyfill.\n * It supports cancellable promises and has clean and fast implementation.\n */\n\n'use strict';\n\nimport { isDef, isFunction, isObject } from 'metal';\nimport { async } from 'metal';\n\n/**\n * Provides a more strict interface for Thenables in terms of\n * http://promisesaplus.com for interop with {@see CancellablePromise}.\n *\n * @interface\n * @extends {IThenable.}\n * @template TYPE\n */\nvar Thenable = function() {};\n\n/**\n * Adds callbacks that will operate on the result of the Thenable, returning a\n * new child Promise.\n *\n * If the Thenable is fulfilled, the {@code onFulfilled} callback will be\n * invoked with the fulfillment value as argument, and the child Promise will\n * be fulfilled with the return value of the callback. If the callback throws\n * an exception, the child Promise will be rejected with the thrown value\n * instead.\n *\n * If the Thenable is rejected, the {@code onRejected} callback will be invoked\n * with the rejection reason as argument, and the child Promise will be rejected\n * with the return value of the callback or thrown value.\n *\n * @param {?(function(this:THIS, TYPE):\n * (RESULT|IThenable.|Thenable))=} opt_onFulfilled A\n * function that will be invoked with the fulfillment value if the Promise\n * is fullfilled.\n * @param {?(function(*): *)=} opt_onRejected A function that will be invoked\n * with the rejection reason if the Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * with the default this.\n * @return {!CancellablePromise.} A new Promise that will receive the\n * result of the fulfillment or rejection callback.\n * @template RESULT,THIS\n */\nThenable.prototype.then = function() {};\n\n\n/**\n * An expando property to indicate that an object implements\n * {@code Thenable}.\n *\n * {@see addImplementation}.\n *\n * @const\n */\nThenable.IMPLEMENTED_BY_PROP = '$goog_Thenable';\n\n\n/**\n * Marks a given class (constructor) as an implementation of Thenable, so\n * that we can query that fact at runtime. The class must have already\n * implemented the interface.\n * Exports a 'then' method on the constructor prototype, so that the objects\n * also implement the extern {@see Thenable} interface for interop with\n * other Promise implementations.\n * @param {function(new:Thenable,...[?])} ctor The class constructor. The\n * corresponding class must have already implemented the interface.\n */\nThenable.addImplementation = function(ctor) {\n ctor.prototype.then = ctor.prototype.then;\n ctor.prototype.$goog_Thenable = true;\n};\n\n\n/**\n * @param {*} object\n * @return {boolean} Whether a given instance implements {@code Thenable}.\n * The class/superclass of the instance must call {@code addImplementation}.\n */\nThenable.isImplementedBy = function(object) {\n if (!object) {\n return false;\n }\n try {\n return !!object.$goog_Thenable;\n } catch (e) {\n // Property access seems to be forbidden.\n return false;\n }\n};\n\n\n/**\n * Like bind(), except that a 'this object' is not required. Useful when the\n * target function is already bound.\n *\n * Usage:\n * var g = partial(f, arg1, arg2);\n * g(arg3, arg4);\n *\n * @param {Function} fn A function to partially apply.\n * @param {...*} var_args Additional arguments that are partially applied to fn.\n * @return {!Function} A partially-applied form of the function bind() was\n * invoked as a method of.\n */\nvar partial = function(fn) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function() {\n // Clone the array (with slice()) and append additional arguments\n // to the existing arguments.\n var newArgs = args.slice();\n newArgs.push.apply(newArgs, arguments);\n return fn.apply(this, newArgs);\n };\n};\n\n/**\n * Promises provide a result that may be resolved asynchronously. A Promise may\n * be resolved by being fulfilled or rejected with a value, which will be known\n * as the fulfillment value or the rejection reason. Whether fulfilled or\n * rejected, the Promise result is immutable once it is set.\n *\n * Promises may represent results of any type, including undefined. Rejection\n * reasons are typically Errors, but may also be of any type. Closure Promises\n * allow for optional type annotations that enforce that fulfillment values are\n * of the appropriate types at compile time.\n *\n * The result of a Promise is accessible by calling {@code then} and registering\n * {@code onFulfilled} and {@code onRejected} callbacks. Once the Promise\n * resolves, the relevant callbacks are invoked with the fulfillment value or\n * rejection reason as argument. Callbacks are always invoked in the order they\n * were registered, even when additional {@code then} calls are made from inside\n * another callback. A callback is always run asynchronously sometime after the\n * scope containing the registering {@code then} invocation has returned.\n *\n * If a Promise is resolved with another Promise, the first Promise will block\n * until the second is resolved, and then assumes the same result as the second\n * Promise. This allows Promises to depend on the results of other Promises,\n * linking together multiple asynchronous operations.\n *\n * This implementation is compatible with the Promises/A+ specification and\n * passes that specification's conformance test suite. A Closure Promise may be\n * resolved with a Promise instance (or sufficiently compatible Promise-like\n * object) created by other Promise implementations. From the specification,\n * Promise-like objects are known as \"Thenables\".\n *\n * @see http://promisesaplus.com/\n *\n * @param {function(\n * this:RESOLVER_CONTEXT,\n * function((TYPE|IThenable.|Thenable)),\n * function(*)): void} resolver\n * Initialization function that is invoked immediately with {@code resolve}\n * and {@code reject} functions as arguments. The Promise is resolved or\n * rejected with the first argument passed to either function.\n * @param {RESOLVER_CONTEXT=} opt_context An optional context for executing the\n * resolver function. If unspecified, the resolver function will be executed\n * in the default scope.\n * @constructor\n * @struct\n * @final\n * @implements {Thenable.}\n * @template TYPE,RESOLVER_CONTEXT\n */\nvar CancellablePromise = function(resolver, opt_context) {\n /**\n * The internal state of this Promise. Either PENDING, FULFILLED, REJECTED, or\n * BLOCKED.\n * @private {CancellablePromise.State_}\n */\n this.state_ = CancellablePromise.State_.PENDING;\n\n /**\n * The resolved result of the Promise. Immutable once set with either a\n * fulfillment value or rejection reason.\n * @private {*}\n */\n this.result_ = undefined;\n\n /**\n * For Promises created by calling {@code then()}, the originating parent.\n * @private {CancellablePromise}\n */\n this.parent_ = null;\n\n /**\n * The list of {@code onFulfilled} and {@code onRejected} callbacks added to\n * this Promise by calls to {@code then()}.\n * @private {Array.}\n */\n this.callbackEntries_ = null;\n\n /**\n * Whether the Promise is in the queue of Promises to execute.\n * @private {boolean}\n */\n this.executing_ = false;\n\n if (CancellablePromise.UNHANDLED_REJECTION_DELAY > 0) {\n /**\n * A timeout ID used when the {@code UNHANDLED_REJECTION_DELAY} is greater\n * than 0 milliseconds. The ID is set when the Promise is rejected, and\n * cleared only if an {@code onRejected} callback is invoked for the\n * Promise (or one of its descendants) before the delay is exceeded.\n *\n * If the rejection is not handled before the timeout completes, the\n * rejection reason is passed to the unhandled rejection handler.\n * @private {number}\n */\n this.unhandledRejectionId_ = 0;\n } else if (CancellablePromise.UNHANDLED_REJECTION_DELAY === 0) {\n /**\n * When the {@code UNHANDLED_REJECTION_DELAY} is set to 0 milliseconds, a\n * boolean that is set if the Promise is rejected, and reset to false if an\n * {@code onRejected} callback is invoked for the Promise (or one of its\n * descendants). If the rejection is not handled before the next timestep,\n * the rejection reason is passed to the unhandled rejection handler.\n * @private {boolean}\n */\n this.hadUnhandledRejection_ = false;\n }\n\n try {\n var self = this;\n resolver.call(\n opt_context, function(value) {\n self.resolve_(CancellablePromise.State_.FULFILLED, value);\n }, function(reason) {\n self.resolve_(CancellablePromise.State_.REJECTED, reason);\n });\n } catch (e) {\n this.resolve_(CancellablePromise.State_.REJECTED, e);\n }\n};\n\n/**\n * The delay in milliseconds before a rejected Promise's reason is passed to\n * the rejection handler. By default, the rejection handler rethrows the\n * rejection reason so that it appears in the developer console or\n * {@code window.onerror} handler.\n * Rejections are rethrown as quickly as possible by default. A negative value\n * disables rejection handling entirely.\n * @type {number}\n */\nCancellablePromise.UNHANDLED_REJECTION_DELAY = 0;\n\n\n/**\n * The possible internal states for a Promise. These states are not directly\n * observable to external callers.\n * @enum {number}\n * @private\n */\nCancellablePromise.State_ = {\n /** The Promise is waiting for resolution. */\n PENDING: 0,\n\n /** The Promise is blocked waiting for the result of another Thenable. */\n BLOCKED: 1,\n\n /** The Promise has been resolved with a fulfillment value. */\n FULFILLED: 2,\n\n /** The Promise has been resolved with a rejection reason. */\n REJECTED: 3\n};\n\n\n/**\n * Typedef for entries in the callback chain. Each call to {@code then},\n * {@code thenCatch}, or {@code thenAlways} creates an entry containing the\n * functions that may be invoked once the Promise is resolved.\n *\n * @typedef {{\n * child: CancellablePromise,\n * onFulfilled: function(*),\n * onRejected: function(*)\n * }}\n * @private\n */\nCancellablePromise.CallbackEntry_ = null;\n\n\n/**\n * @param {(TYPE|Thenable.|Thenable)=} opt_value\n * @return {!CancellablePromise.} A new Promise that is immediately resolved\n * with the given value.\n * @template TYPE\n */\nCancellablePromise.resolve = function(opt_value) {\n return new CancellablePromise(function(resolve) {\n resolve(opt_value);\n });\n};\n\n\n/**\n * @param {*=} opt_reason\n * @return {!CancellablePromise} A new Promise that is immediately rejected with the\n * given reason.\n */\nCancellablePromise.reject = function(opt_reason) {\n return new CancellablePromise(function(resolve, reject) {\n reject(opt_reason);\n });\n};\n\n\n/**\n * @param {!Array.|Thenable)>} promises\n * @return {!CancellablePromise.} A Promise that receives the result of the\n * first Promise (or Promise-like) input to complete.\n * @template TYPE\n */\nCancellablePromise.race = function(promises) {\n return new CancellablePromise(function(resolve, reject) {\n if (!promises.length) {\n resolve(undefined);\n }\n for (var i = 0, promise; (promise = promises[i]); i++) {\n promise.then(resolve, reject);\n }\n });\n};\n\n\n/**\n * @param {!Array.|Thenable)>} promises\n * @return {!CancellablePromise.>} A Promise that receives a list of\n * every fulfilled value once every input Promise (or Promise-like) is\n * successfully fulfilled, or is rejected by the first rejection result.\n * @template TYPE\n */\nCancellablePromise.all = function(promises) {\n return new CancellablePromise(function(resolve, reject) {\n var toFulfill = promises.length;\n var values = [];\n\n if (!toFulfill) {\n resolve(values);\n return;\n }\n\n var onFulfill = function(index, value) {\n toFulfill--;\n values[index] = value;\n if (toFulfill === 0) {\n resolve(values);\n }\n };\n\n var onReject = function(reason) {\n reject(reason);\n };\n\n for (var i = 0, promise; (promise = promises[i]); i++) {\n promise.then(partial(onFulfill, i), onReject);\n }\n });\n};\n\n\n/**\n * @param {!Array.|Thenable)>} promises\n * @return {!CancellablePromise.} A Promise that receives the value of\n * the first input to be fulfilled, or is rejected with a list of every\n * rejection reason if all inputs are rejected.\n * @template TYPE\n */\nCancellablePromise.firstFulfilled = function(promises) {\n return new CancellablePromise(function(resolve, reject) {\n var toReject = promises.length;\n var reasons = [];\n\n if (!toReject) {\n resolve(undefined);\n return;\n }\n\n var onFulfill = function(value) {\n resolve(value);\n };\n\n var onReject = function(index, reason) {\n toReject--;\n reasons[index] = reason;\n if (toReject === 0) {\n reject(reasons);\n }\n };\n\n for (var i = 0, promise; (promise = promises[i]); i++) {\n promise.then(onFulfill, partial(onReject, i));\n }\n });\n};\n\n\n/**\n * Adds callbacks that will operate on the result of the Promise, returning a\n * new child Promise.\n *\n * If the Promise is fulfilled, the {@code onFulfilled} callback will be invoked\n * with the fulfillment value as argument, and the child Promise will be\n * fulfilled with the return value of the callback. If the callback throws an\n * exception, the child Promise will be rejected with the thrown value instead.\n *\n * If the Promise is rejected, the {@code onRejected} callback will be invoked\n * with the rejection reason as argument, and the child Promise will be rejected\n * with the return value (or thrown value) of the callback.\n *\n * @override\n */\nCancellablePromise.prototype.then = function(opt_onFulfilled, opt_onRejected, opt_context) {\n return this.addChildPromise_(\n isFunction(opt_onFulfilled) ? opt_onFulfilled : null,\n isFunction(opt_onRejected) ? opt_onRejected : null,\n opt_context);\n};\nThenable.addImplementation(CancellablePromise);\n\n\n/**\n * Adds a callback that will be invoked whether the Promise is fulfilled or\n * rejected. The callback receives no argument, and no new child Promise is\n * created. This is useful for ensuring that cleanup takes place after certain\n * asynchronous operations. Callbacks added with {@code thenAlways} will be\n * executed in the same order with other calls to {@code then},\n * {@code thenAlways}, or {@code thenCatch}.\n *\n * Since it does not produce a new child Promise, cancellation propagation is\n * not prevented by adding callbacks with {@code thenAlways}. A Promise that has\n * a cleanup handler added with {@code thenAlways} will be canceled if all of\n * its children created by {@code then} (or {@code thenCatch}) are canceled.\n *\n * @param {function(this:THIS): void} onResolved A function that will be invoked\n * when the Promise is resolved.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * in the global scope.\n * @return {!CancellablePromise.} This Promise, for chaining additional calls.\n * @template THIS\n */\nCancellablePromise.prototype.thenAlways = function(onResolved, opt_context) {\n var callback = function() {\n try {\n // Ensure that no arguments are passed to onResolved.\n onResolved.call(opt_context);\n } catch (err) {\n CancellablePromise.handleRejection_.call(null, err);\n }\n };\n\n this.addCallbackEntry_({\n child: null,\n onRejected: callback,\n onFulfilled: callback\n });\n return this;\n};\n\n\n/**\n * Adds a callback that will be invoked only if the Promise is rejected. This\n * is equivalent to {@code then(null, onRejected)}.\n *\n * @param {!function(this:THIS, *): *} onRejected A function that will be\n * invoked with the rejection reason if the Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * in the global scope.\n * @return {!CancellablePromise} A new Promise that will receive the result of the\n * callback.\n * @template THIS\n */\nCancellablePromise.prototype.thenCatch = function(onRejected, opt_context) {\n return this.addChildPromise_(null, onRejected, opt_context);\n};\n\n/**\n * Alias of {@link CancellablePromise.prototype.thenCatch}\n */\nCancellablePromise.prototype.catch = CancellablePromise.prototype.thenCatch;\n\n\n/**\n * Cancels the Promise if it is still pending by rejecting it with a cancel\n * Error. No action is performed if the Promise is already resolved.\n *\n * All child Promises of the canceled Promise will be rejected with the same\n * cancel error, as with normal Promise rejection. If the Promise to be canceled\n * is the only child of a pending Promise, the parent Promise will also be\n * canceled. Cancellation may propagate upward through multiple generations.\n *\n * @param {string=} opt_message An optional debugging message for describing the\n * cancellation reason.\n */\nCancellablePromise.prototype.cancel = function(opt_message) {\n if (this.state_ === CancellablePromise.State_.PENDING) {\n async.run(function() {\n var err = new CancellablePromise.CancellationError(opt_message);\n err.IS_CANCELLATION_ERROR = true;\n this.cancelInternal_(err);\n }, this);\n }\n};\n\n\n/**\n * Cancels this Promise with the given error.\n *\n * @param {!Error} err The cancellation error.\n * @private\n */\nCancellablePromise.prototype.cancelInternal_ = function(err) {\n if (this.state_ === CancellablePromise.State_.PENDING) {\n if (this.parent_) {\n // Cancel the Promise and remove it from the parent's child list.\n this.parent_.cancelChild_(this, err);\n } else {\n this.resolve_(CancellablePromise.State_.REJECTED, err);\n }\n }\n};\n\n\n/**\n * Cancels a child Promise from the list of callback entries. If the Promise has\n * not already been resolved, reject it with a cancel error. If there are no\n * other children in the list of callback entries, propagate the cancellation\n * by canceling this Promise as well.\n *\n * @param {!CancellablePromise} childPromise The Promise to cancel.\n * @param {!Error} err The cancel error to use for rejecting the Promise.\n * @private\n */\nCancellablePromise.prototype.cancelChild_ = function(childPromise, err) {\n if (!this.callbackEntries_) {\n return;\n }\n var childCount = 0;\n var childIndex = -1;\n\n // Find the callback entry for the childPromise, and count whether there are\n // additional child Promises.\n for (var i = 0, entry; (entry = this.callbackEntries_[i]); i++) {\n var child = entry.child;\n if (child) {\n childCount++;\n if (child === childPromise) {\n childIndex = i;\n }\n if (childIndex >= 0 && childCount > 1) {\n break;\n }\n }\n }\n\n // If the child Promise was the only child, cancel this Promise as well.\n // Otherwise, reject only the child Promise with the cancel error.\n if (childIndex >= 0) {\n if (this.state_ === CancellablePromise.State_.PENDING && childCount === 1) {\n this.cancelInternal_(err);\n } else {\n var callbackEntry = this.callbackEntries_.splice(childIndex, 1)[0];\n this.executeCallback_(\n callbackEntry, CancellablePromise.State_.REJECTED, err);\n }\n }\n};\n\n\n/**\n * Adds a callback entry to the current Promise, and schedules callback\n * execution if the Promise has already been resolved.\n *\n * @param {CancellablePromise.CallbackEntry_} callbackEntry Record containing\n * {@code onFulfilled} and {@code onRejected} callbacks to execute after\n * the Promise is resolved.\n * @private\n */\nCancellablePromise.prototype.addCallbackEntry_ = function(callbackEntry) {\n if ((!this.callbackEntries_ || !this.callbackEntries_.length) &&\n (this.state_ === CancellablePromise.State_.FULFILLED ||\n this.state_ === CancellablePromise.State_.REJECTED)) {\n this.scheduleCallbacks_();\n }\n if (!this.callbackEntries_) {\n this.callbackEntries_ = [];\n }\n this.callbackEntries_.push(callbackEntry);\n};\n\n\n/**\n * Creates a child Promise and adds it to the callback entry list. The result of\n * the child Promise is determined by the state of the parent Promise and the\n * result of the {@code onFulfilled} or {@code onRejected} callbacks as\n * specified in the Promise resolution procedure.\n *\n * @see http://promisesaplus.com/#the__method\n *\n * @param {?function(this:THIS, TYPE):\n * (RESULT|CancellablePromise.|Thenable)} onFulfilled A callback that\n * will be invoked if the Promise is fullfilled, or null.\n * @param {?function(this:THIS, *): *} onRejected A callback that will be\n * invoked if the Promise is rejected, or null.\n * @param {THIS=} opt_context An optional execution context for the callbacks.\n * in the default calling context.\n * @return {!CancellablePromise} The child Promise.\n * @template RESULT,THIS\n * @private\n */\nCancellablePromise.prototype.addChildPromise_ = function(\nonFulfilled, onRejected, opt_context) {\n\n var callbackEntry = {\n child: null,\n onFulfilled: null,\n onRejected: null\n };\n\n callbackEntry.child = new CancellablePromise(function(resolve, reject) {\n // Invoke onFulfilled, or resolve with the parent's value if absent.\n callbackEntry.onFulfilled = onFulfilled ? function(value) {\n try {\n var result = onFulfilled.call(opt_context, value);\n resolve(result);\n } catch (err) {\n reject(err);\n }\n } : resolve;\n\n // Invoke onRejected, or reject with the parent's reason if absent.\n callbackEntry.onRejected = onRejected ? function(reason) {\n try {\n var result = onRejected.call(opt_context, reason);\n if (!isDef(result) && reason.IS_CANCELLATION_ERROR) {\n // Propagate cancellation to children if no other result is returned.\n reject(reason);\n } else {\n resolve(result);\n }\n } catch (err) {\n reject(err);\n }\n } : reject;\n });\n\n callbackEntry.child.parent_ = this;\n this.addCallbackEntry_(\n /** @type {CancellablePromise.CallbackEntry_} */ (callbackEntry));\n return callbackEntry.child;\n};\n\n\n/**\n * Unblocks the Promise and fulfills it with the given value.\n *\n * @param {TYPE} value\n * @private\n */\nCancellablePromise.prototype.unblockAndFulfill_ = function(value) {\n if (this.state_ !== CancellablePromise.State_.BLOCKED) {\n throw new Error('CancellablePromise is not blocked.');\n }\n this.state_ = CancellablePromise.State_.PENDING;\n this.resolve_(CancellablePromise.State_.FULFILLED, value);\n};\n\n\n/**\n * Unblocks the Promise and rejects it with the given rejection reason.\n *\n * @param {*} reason\n * @private\n */\nCancellablePromise.prototype.unblockAndReject_ = function(reason) {\n if (this.state_ !== CancellablePromise.State_.BLOCKED) {\n throw new Error('CancellablePromise is not blocked.');\n }\n this.state_ = CancellablePromise.State_.PENDING;\n this.resolve_(CancellablePromise.State_.REJECTED, reason);\n};\n\n\n/**\n * Attempts to resolve a Promise with a given resolution state and value. This\n * is a no-op if the given Promise has already been resolved.\n *\n * If the given result is a Thenable (such as another Promise), the Promise will\n * be resolved with the same state and result as the Thenable once it is itself\n * resolved.\n *\n * If the given result is not a Thenable, the Promise will be fulfilled or\n * rejected with that result based on the given state.\n *\n * @see http://promisesaplus.com/#the_promise_resolution_procedure\n *\n * @param {CancellablePromise.State_} state\n * @param {*} x The result to apply to the Promise.\n * @private\n */\nCancellablePromise.prototype.resolve_ = function(state, x) {\n if (this.state_ !== CancellablePromise.State_.PENDING) {\n return;\n }\n\n if (this === x) {\n state = CancellablePromise.State_.REJECTED;\n x = new TypeError('CancellablePromise cannot resolve to itself');\n\n } else if (Thenable.isImplementedBy(x)) {\n x = /** @type {!Thenable} */ (x);\n this.state_ = CancellablePromise.State_.BLOCKED;\n x.then(this.unblockAndFulfill_, this.unblockAndReject_, this);\n return;\n\n } else if (isObject(x)) {\n try {\n var then = x.then;\n if (isFunction(then)) {\n this.tryThen_(x, then);\n return;\n }\n } catch (e) {\n state = CancellablePromise.State_.REJECTED;\n x = e;\n }\n }\n\n this.result_ = x;\n this.state_ = state;\n this.scheduleCallbacks_();\n\n if (state === CancellablePromise.State_.REJECTED && !x.IS_CANCELLATION_ERROR) {\n CancellablePromise.addUnhandledRejection_(this, x);\n }\n};\n\n\n/**\n * Attempts to call the {@code then} method on an object in the hopes that it is\n * a Promise-compatible instance. This allows interoperation between different\n * Promise implementations, however a non-compliant object may cause a Promise\n * to hang indefinitely. If the {@code then} method throws an exception, the\n * dependent Promise will be rejected with the thrown value.\n *\n * @see http://promisesaplus.com/#point-70\n *\n * @param {Thenable} thenable An object with a {@code then} method that may be\n * compatible with the Promise/A+ specification.\n * @param {!Function} then The {@code then} method of the Thenable object.\n * @private\n */\nCancellablePromise.prototype.tryThen_ = function(thenable, then) {\n this.state_ = CancellablePromise.State_.BLOCKED;\n var promise = this;\n var called = false;\n\n var resolve = function(value) {\n if (!called) {\n called = true;\n promise.unblockAndFulfill_(value);\n }\n };\n\n var reject = function(reason) {\n if (!called) {\n called = true;\n promise.unblockAndReject_(reason);\n }\n };\n\n try {\n then.call(thenable, resolve, reject);\n } catch (e) {\n reject(e);\n }\n};\n\n\n/**\n * Executes the pending callbacks of a resolved Promise after a timeout.\n *\n * Section 2.2.4 of the Promises/A+ specification requires that Promise\n * callbacks must only be invoked from a call stack that only contains Promise\n * implementation code, which we accomplish by invoking callback execution after\n * a timeout. If {@code startExecution_} is called multiple times for the same\n * Promise, the callback chain will be evaluated only once. Additional callbacks\n * may be added during the evaluation phase, and will be executed in the same\n * event loop.\n *\n * All Promises added to the waiting list during the same browser event loop\n * will be executed in one batch to avoid using a separate timeout per Promise.\n *\n * @private\n */\nCancellablePromise.prototype.scheduleCallbacks_ = function() {\n if (!this.executing_) {\n this.executing_ = true;\n async.run(this.executeCallbacks_, this);\n }\n};\n\n\n/**\n * Executes all pending callbacks for this Promise.\n *\n * @private\n */\nCancellablePromise.prototype.executeCallbacks_ = function() {\n while (this.callbackEntries_ && this.callbackEntries_.length) {\n var entries = this.callbackEntries_;\n this.callbackEntries_ = [];\n\n for (var i = 0; i < entries.length; i++) {\n this.executeCallback_(entries[i], this.state_, this.result_);\n }\n }\n this.executing_ = false;\n};\n\n\n/**\n * Executes a pending callback for this Promise. Invokes an {@code onFulfilled}\n * or {@code onRejected} callback based on the resolved state of the Promise.\n *\n * @param {!CancellablePromise.CallbackEntry_} callbackEntry An entry containing the\n * onFulfilled and/or onRejected callbacks for this step.\n * @param {CancellablePromise.State_} state The resolution status of the Promise,\n * either FULFILLED or REJECTED.\n * @param {*} result The resolved result of the Promise.\n * @private\n */\nCancellablePromise.prototype.executeCallback_ = function(\ncallbackEntry, state, result) {\n if (state === CancellablePromise.State_.FULFILLED) {\n callbackEntry.onFulfilled(result);\n } else {\n this.removeUnhandledRejection_();\n callbackEntry.onRejected(result);\n }\n};\n\n\n/**\n * Marks this rejected Promise as having being handled. Also marks any parent\n * Promises in the rejected state as handled. The rejection handler will no\n * longer be invoked for this Promise (if it has not been called already).\n *\n * @private\n */\nCancellablePromise.prototype.removeUnhandledRejection_ = function() {\n var p;\n if (CancellablePromise.UNHANDLED_REJECTION_DELAY > 0) {\n for (p = this; p && p.unhandledRejectionId_; p = p.parent_) {\n clearTimeout(p.unhandledRejectionId_);\n p.unhandledRejectionId_ = 0;\n }\n } else if (CancellablePromise.UNHANDLED_REJECTION_DELAY === 0) {\n for (p = this; p && p.hadUnhandledRejection_; p = p.parent_) {\n p.hadUnhandledRejection_ = false;\n }\n }\n};\n\n\n/**\n * Marks this rejected Promise as unhandled. If no {@code onRejected} callback\n * is called for this Promise before the {@code UNHANDLED_REJECTION_DELAY}\n * expires, the reason will be passed to the unhandled rejection handler. The\n * handler typically rethrows the rejection reason so that it becomes visible in\n * the developer console.\n *\n * @param {!CancellablePromise} promise The rejected Promise.\n * @param {*} reason The Promise rejection reason.\n * @private\n */\nCancellablePromise.addUnhandledRejection_ = function(promise, reason) {\n if (CancellablePromise.UNHANDLED_REJECTION_DELAY > 0) {\n promise.unhandledRejectionId_ = setTimeout(function() {\n CancellablePromise.handleRejection_.call(null, reason);\n }, CancellablePromise.UNHANDLED_REJECTION_DELAY);\n\n } else if (CancellablePromise.UNHANDLED_REJECTION_DELAY === 0) {\n promise.hadUnhandledRejection_ = true;\n async.run(function() {\n if (promise.hadUnhandledRejection_) {\n CancellablePromise.handleRejection_.call(null, reason);\n }\n });\n }\n};\n\n\n/**\n * A method that is invoked with the rejection reasons for Promises that are\n * rejected but have no {@code onRejected} callbacks registered yet.\n * @type {function(*)}\n * @private\n */\nCancellablePromise.handleRejection_ = async.throwException;\n\n\n/**\n * Sets a handler that will be called with reasons from unhandled rejected\n * Promises. If the rejected Promise (or one of its descendants) has an\n * {@code onRejected} callback registered, the rejection will be considered\n * handled, and the rejection handler will not be called.\n *\n * By default, unhandled rejections are rethrown so that the error may be\n * captured by the developer console or a {@code window.onerror} handler.\n *\n * @param {function(*)} handler A function that will be called with reasons from\n * rejected Promises. Defaults to {@code async.throwException}.\n */\nCancellablePromise.setUnhandledRejectionHandler = function(handler) {\n CancellablePromise.handleRejection_ = handler;\n};\n\n\n\n/**\n * Error used as a rejection reason for canceled Promises.\n *\n * @param {string=} opt_message\n * @constructor\n * @extends {Error}\n * @final\n */\nCancellablePromise.CancellationError = class extends Error {\n constructor(opt_message) {\n super(opt_message);\n\n if (opt_message) {\n this.message = opt_message;\n }\n }\n};\n\n/** @override */\nCancellablePromise.CancellationError.prototype.name = 'cancel';\n\nexport {CancellablePromise};\nexport default CancellablePromise;\n","'use strict';\n\n/**\n * Debounces function execution.\n * @param {!function()} fn\n * @param {number} delay\n * @return {!function()}\n */\nfunction debounce(fn, delay) {\n\treturn function debounced() {\n\t\tvar args = arguments;\n\t\tcancelDebounce(debounced);\n\t\tdebounced.id = setTimeout(function() {\n\t\t\tfn.apply(null, args);\n\t\t}, delay);\n\t};\n}\n\n/**\n * Cancels the scheduled debounced function.\n */\nfunction cancelDebounce(debounced) {\n\tclearTimeout(debounced.id);\n}\n\nexport default debounce;\nexport { cancelDebounce, debounce };\n","'use strict';\n\nimport core from 'metal';\n\nconst REGEX = /([\\/])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])*)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?)/g;\n\n/**\n * Converts the given array of regex matches to a more readable object format.\n * @param {!Array} matches\n * @return {!Object}\n */\nfunction convertMatchesToObj(matches) {\n\treturn {\n\t\tmatch: matches[0],\n\t\tprefix: matches[1],\n\t\tname: matches[2],\n\t\tparamPattern: matches[3],\n\t\tunnamedPattern: matches[4],\n\t\tmodifier: matches[5]\n\t};\n}\n\n/**\n * Converts the given tokens parsed from a route format string to a regex.\n * @param {!Array} tokens\n * @return {!RegExp}\n */\nfunction convertTokensToRegex(tokens) {\n\tlet regex = '';\n\tfor (let i = 0; i < tokens.length; i++) {\n\t\tif (core.isString(tokens[i])) {\n\t\t\tregex += escape(tokens[i]);\n\t\t} else {\n\t\t\tlet capture = encloseNonCapturingGroup(tokens[i].pattern);\n\t\t\tif (tokens[i].repeat) {\n\t\t\t\tcapture += encloseNonCapturingGroup('\\\\/' + capture) + '*';\n\t\t\t}\n\t\t\tcapture = escape(tokens[i].prefix) + `(${capture})`;\n\t\t\tif (tokens[i].optional) {\n\t\t\t\tif (!tokens[i].partial) {\n\t\t\t\t\tcapture = encloseNonCapturingGroup(capture);\n\t\t\t\t}\n\t\t\t\tcapture += '?';\n\t\t\t}\n\t\t\tregex += capture;\n\t\t}\n\t}\n\treturn new RegExp('^' + makeTrailingSlashOptional(regex) + '$');\n}\n\n/**\n * Encloses the given regex pattern into a non capturing group.\n * @param {string} pattern\n * @return {string}\n */\nfunction encloseNonCapturingGroup(pattern) {\n\treturn `(?:${pattern})`;\n}\n\n/**\n * Escapes the given string to show up in the path regex.\n * @param {string} str\n * @return {string}\n */\nfunction escape(str) {\n\treturn str.replace(/([.+*?=^!:${}()[\\]|\\/\\\\])/g, '\\\\$1');\n}\n\n/**\n * Makes trailing slash optional on paths.\n * @param {string} regex\n * @param {string}\n */\nfunction makeTrailingSlashOptional(regex) {\n\tif (/\\/$/.test(regex)) {\n\t\tregex += '?';\n\t} else {\n\t\tregex += '\\\\/?';\n\t}\n\treturn regex;\n}\n\n/**\n * Parses the given route format string into tokens representing its contents.\n * @param {!Array|string} routeOrTokens Either a route format string or tokens\n * previously parsed via the `parse` function.\n * @return {!Array} An array of tokens that can be either plain\n * strings (part of the route) or objects containing informations on params.\n */\nexport function parse(routeOrTokens) {\n\tif (!core.isString(routeOrTokens)) {\n\t\treturn routeOrTokens;\n\t}\n\n\tconst route = routeOrTokens;\n\tlet unnamedCount = 0;\n\tconst tokens = [];\n\tlet currPath = '';\n\tlet index = 0;\n\n\tlet matches = REGEX.exec(route);\n\twhile (matches) {\n\t\tconst data = convertMatchesToObj(matches);\n\n\t\tcurrPath = route.slice(index, matches.index);\n\t\tindex = matches.index + data.match.length;\n\t\ttokens.push(currPath);\n\n\t\ttokens.push({\n\t\t\tname: data.name ? data.name : '' + unnamedCount++,\n\t\t\tpartial: route[index] && route[index] !== data.prefix,\n\t\t\tprefix: data.prefix || '',\n\t\t\tpattern: data.paramPattern || data.unnamedPattern || '[^\\\\/]+',\n\t\t\trepeat: data.modifier === '*' || data.modifier === '+',\n\t\t\toptional: data.modifier === '*' || data.modifier === '?'\n\t\t});\n\n\t\tmatches = REGEX.exec(route);\n\t}\n\n\tif (index < route.length) {\n\t\ttokens.push(route.substr(index));\n\t}\n\treturn tokens;\n}\n\n/**\n * Converts the given route format string to a regex that can extract param\n * data from paths matching it.\n * @param {!Array|string} routeOrTokens Either a route format string or tokens\n * previously parsed via the `parse` function.\n * @return {!RegExp}\n */\nexport function toRegex(routeOrTokens) {\n\treturn convertTokensToRegex(parse(routeOrTokens));\n}\n\n/**\n * Extracts data from the given path according to the specified route format.\n * @param {!Array|string} routeOrTokens Either a route format string or tokens\n * previously parsed via the `parse` function.\n * @param {string} The path to extract param data from.\n * @return {Object} The data object, or null if the path doesn't\n * match the given format.\n */\nexport function extractData(routeOrTokens, path) {\n\tconst data = {};\n\tconst tokens = parse(routeOrTokens);\n\tconst match = path.match(convertTokensToRegex(tokens));\n\n\tif (!match) {\n\t\treturn null;\n\t}\n\n\tlet paramIndex = 1;\n\tfor (let i = 0; i < tokens.length; i++) {\n\t\tif (!core.isString(tokens[i])) {\n\t\t\tlet value = match[paramIndex++];\n\t\t\tif (core.isDef(value)) {\n\t\t\t\tif (tokens[i].repeat) {\n\t\t\t\t\tvalue = value.split('/');\n\t\t\t\t}\n\t\t\t\tdata[tokens[i].name] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn data;\n}\n","'use strict';\n\nimport { isDefAndNotNull, isFunction, isString } from 'metal';\nimport { extractData, parse, toRegex } from 'metal-path-parser';\n\nclass Route {\n\n\t/**\n\t * Route class.\n\t * @param {!string|RegExp|Function} path\n\t * @param {!Function} handler\n\t * @constructor\n\t */\n\tconstructor(path, handler) {\n\t\tif (!isDefAndNotNull(path)) {\n\t\t\tthrow new Error('Route path not specified.');\n\t\t}\n\t\tif (!isFunction(handler)) {\n\t\t\tthrow new Error('Route handler is not a function.');\n\t\t}\n\n\t\t/**\n\t\t * Defines the handler which will execute once a URL in the application\n\t\t * matches the path.\n\t\t * @type {!Function}\n\t\t * @protected\n\t\t */\n\t\tthis.handler = handler;\n\n\t\t/**\n\t\t * Defines the path which will trigger the route handler.\n\t\t * @type {!string|RegExp|Function}\n\t\t * @protected\n\t\t */\n\t\tthis.path = path;\n\t}\n\n\t/**\n\t* Builds parsed data (regex and tokens) for this route.\n\t* @return {!Object}\n\t* @protected\n\t*/\n\tbuildParsedData_() {\n\t\tif (!this.parsedData_) {\n\t\t\tvar tokens = parse(this.path);\n\t\t\tvar regex = toRegex(tokens);\n\t\t\tthis.parsedData_ = {\n\t\t\t\tregex,\n\t\t\t\ttokens\n\t\t\t};\n\t\t}\n\t\treturn this.parsedData_;\n\t}\n\n\t/**\n\t * Extracts param data from the given path, according to this route.\n\t * @param {string} path The url path to extract params from.\n\t * @return {Object} The extracted data, if the path matches this route, or\n\t * null otherwise.\n\t */\n\textractParams(path) {\n\t\tif (isString(this.path)) {\n\t\t\treturn extractData(this.buildParsedData_().tokens, path);\n\t\t}\n\t\treturn {};\n\t}\n\n\t/**\n\t * Gets the route handler.\n\t * @return {!Function}\n\t */\n\tgetHandler() {\n\t\treturn this.handler;\n\t}\n\n\t/**\n\t * Gets the route path.\n\t * @return {!string|RegExp|Function}\n\t */\n\tgetPath() {\n\t\treturn this.path;\n\t}\n\n\t/**\n \t * Matches if the router can handle the tested path.\n \t * @param {!string} value Path to test (may contain the querystring part).\n\t * @return {boolean} Returns true if matches any route.\n\t */\n\tmatchesPath(value) {\n\t\tvar path = this.path;\n\n\t\tif (isFunction(path)) {\n\t\t\treturn path(value);\n\t\t}\n\t\tif (isString(path)) {\n\t\t\tpath = this.buildParsedData_().regex;\n\t\t}\n\t\tif (path instanceof RegExp) {\n\t\t\treturn value.search(path) > -1;\n\t\t}\n\n\t\treturn false;\n\t}\n\n}\n\nexport default Route;\n","'use strict';\n\nimport { Disposable } from 'metal';\n\nclass Cacheable extends Disposable {\n\n\t/**\n\t * Abstract class for defining cacheable behavior.\n\t * @constructor\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the cached data.\n\t\t * @type {!Object}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.cache = null;\n\n\t\t/**\n\t\t * Holds whether class is cacheable.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.cacheable = false;\n\t}\n\n\t/**\n\t * Adds content to the cache.\n\t * @param {string} content Content to be cached.\n\t * @chainable\n\t */\n\taddCache(content) {\n\t\tif (this.cacheable) {\n\t\t\tthis.cache = content;\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Clears the cache.\n\t * @chainable\n\t */\n\tclearCache() {\n\t\tthis.cache = null;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.clearCache();\n\t}\n\n\t/**\n\t * Gets the cached content.\n\t * @return {Object} Cached content.\n\t * @protected\n\t */\n\tgetCache() {\n\t\treturn this.cache;\n\t}\n\n\t/**\n\t * Whether the class is cacheable.\n\t * @return {boolean} Returns true when class is cacheable, false otherwise.\n\t */\n\tisCacheable() {\n\t\treturn this.cacheable;\n\t}\n\n\t/**\n\t * Sets whether the class is cacheable.\n\t * @param {boolean} cacheable\n\t */\n\tsetCacheable(cacheable) {\n\t\tif (!cacheable) {\n\t\t\tthis.clearCache();\n\t\t}\n\t\tthis.cacheable = cacheable;\n\t}\n\n}\n\nexport default Cacheable;\n","'use strict';\n\nimport { getUid } from 'metal';\nimport { globalEval } from 'metal-dom';\nimport Cacheable from '../cacheable/Cacheable';\nimport CancellablePromise from 'metal-promise';\n\nclass Screen extends Cacheable {\n\n\t/**\n\t * Screen class is a special type of route handler that provides helper\n\t * utilities that adds lifecycle and methods to provide content to each\n\t * registered surface.\n\t * @constructor\n\t * @extends {Cacheable}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the screen id.\n\t\t * @type {string}\n\t\t * @protected\n\t\t */\n\t\tthis.id = this.makeId_(getUid());\n\n\t\t/**\n\t\t * Holds the screen meta tags. Relevant when the meta tags\n\t\t * should be updated when screen is rendered.\n\t\t */\n\t\tthis.metas = null;\n\n\t\t/**\n\t\t * Holds the screen title. Relevant when the page title should be\n\t\t * upadated when screen is rendered.\n\t\t * @type {?string=}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.title = null;\n\t}\n\n\t/**\n\t * Fires when the screen is active. Allows a screen to perform any setup\n\t * that requires its DOM to be visible. Lifecycle.\n\t */\n\tactivate() {\n\t\tconsole.log('Screen [' + this + '] activate');\n\t}\n\n\t/**\n\t * Gives the Screen a chance to cancel the navigation and stop itself from\n\t * activating. Can be used, for example, to prevent navigation if a user\n\t * is not authenticated. Lifecycle.\n\t * @return {boolean=|?CancellablePromise=} If returns or resolves to true,\n\t * the current screen is locked and the next nagivation interrupted.\n\t */\n\tbeforeActivate() {\n\t\tconsole.log('Screen [' + this + '] beforeActivate');\n\t}\n\n\t/**\n\t * Gives the Screen a chance to cancel the navigation and stop itself from\n\t * being deactivated. Can be used, for example, if the screen has unsaved\n\t * state. Lifecycle. Clean-up should not be preformed here, since the\n\t * navigation may still be cancelled. Do clean-up in deactivate.\n\t * @return {boolean=|?CancellablePromise=} If returns or resolves to true,\n\t * the current screen is locked and the next nagivation interrupted.\n\t */\n\tbeforeDeactivate() {\n\t\tconsole.log('Screen [' + this + '] beforeDeactivate');\n\t}\n\n\t/**\n\t * Gives the Screen a chance format the path before history update.\n\t * @path {!string} path Navigation path.\n\t * @return {!string} Navigation path to use on history.\n\t */\n\tbeforeUpdateHistoryPath(path) {\n\t\treturn path;\n\t}\n\n\t/**\n\t * Gives the Screen a chance format the state before history update.\n\t * @path {!object} state History state.\n\t * @return {!object} History state to use on history.\n\t */\n\tbeforeUpdateHistoryState(state) {\n\t\treturn state;\n\t}\n\n\t/**\n\t * Allows a screen to do any cleanup necessary after it has been\n\t * deactivated, for example cancelling outstanding requests or stopping\n\t * timers. Lifecycle.\n\t */\n\tdeactivate() {\n\t\tconsole.log('Screen [' + this + '] deactivate');\n\t}\n\n\t/**\n\t * Dispose a screen, either after it is deactivated (in the case of a\n\t * non-cacheable view) or when the App is itself disposed for whatever\n\t * reason. Lifecycle.\n\t */\n\tdisposeInternal() {\n\t\tsuper.disposeInternal();\n\t\tconsole.log('Screen [' + this + '] dispose');\n\t}\n\n\t/**\n\t * Allows a screen to evaluate scripts before the element is made visible.\n\t * Lifecycle.\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @return {?CancellablePromise=} This can return a promise, which will\n\t * pause the navigation until it is resolved.\n\t */\n\tevaluateScripts(surfaces) {\n\t\tObject.keys(surfaces).forEach(sId => {\n\t\t\tif (surfaces[sId].activeChild) {\n\t\t\t\tglobalEval.runScriptsInElement(surfaces[sId].activeChild);\n\t\t\t}\n\t\t});\n\t\treturn CancellablePromise.resolve();\n\t}\n\n\t/**\n\t * Allows a screen to evaluate styles before the element is made visible.\n\t * Lifecycle.\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @return {?CancellablePromise=} This can return a promise, which will\n\t * pause the navigation until it is resolved.\n\t */\n\tevaluateStyles() {\n\t\treturn CancellablePromise.resolve();\n\t}\n\n\t/**\n\t * Allows a screen to perform any setup immediately before the element is\n\t * made visible. Lifecycle.\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @return {?CancellablePromise=} This can return a promise, which will pause the\n\t * navigation until it is resolved.\n\t */\n\tflip(surfaces) {\n\t\tconsole.log('Screen [' + this + '] flip');\n\n\t\tvar transitions = [];\n\n\t\tObject.keys(surfaces).forEach(sId => {\n\t\t\tvar surface = surfaces[sId];\n\t\t\tvar deferred = surface.show(this.id);\n\t\t\ttransitions.push(deferred);\n\t\t});\n\n\t\treturn CancellablePromise.all(transitions);\n\t}\n\n\t/**\n\t * Gets the screen id.\n\t * @return {string}\n\t */\n\tgetId() {\n\t\treturn this.id;\n\t}\n\n\t/**\n\t * Gets the screen meta tags.\n\t * @return {NodeList|Node}\n\t */\n\tgetMetas() {\n\t\treturn this.metas;\n\t}\n\n\t/**\n\t * Returns the content for the given surface, or null if the surface isn't\n\t * used by this screen. This will be called when a screen is initially\n\t * constructed or, if a screen is non-cacheable, when navigated.\n\t * @param {!string} surfaceId The id of the surface DOM element.\n\t * @param {!Object} params Params extracted from the current path.\n\t * @return {?string|Element=} This can return a string or node representing\n\t * the content of the surface. If returns falsy values surface default\n\t * content is restored.\n\t */\n\tgetSurfaceContent() {\n\t\tconsole.log('Screen [' + this + '] getSurfaceContent');\n\t}\n\n\t/**\n\t * Gets the screen title.\n\t * @return {?string=}\n\t */\n\tgetTitle() {\n\t\treturn this.title;\n\t}\n\n\t/**\n\t * Returns all contents for the surfaces. This will pass the loaded content\n\t * to Screen.load with all information you\n\t * need to fulfill the surfaces. Lifecycle.\n\t * @param {!string=} path The requested path.\n\t * @return {!CancellablePromise} This can return a string representing the\n\t * contents of the surfaces or a promise, which will pause the navigation\n\t * until it is resolved. This is useful for loading async content.\n\t */\n\tload() {\n\t\tconsole.log('Screen [' + this + '] load');\n\t\treturn CancellablePromise.resolve();\n\t}\n\n\t/**\n\t * Makes the id for the screen.\n\t * @param {!string} id The screen id the content belongs too.\n\t * @return {string}\n\t * @private\n\t */\n\tmakeId_(id) {\n\t\treturn 'screen_' + id;\n\t}\n\n\t/**\n\t * Sets the screen id.\n\t * @param {!string} id\n\t */\n\tsetId(id) {\n\t\tthis.id = id;\n\t}\n\n\t/**\n\t * Sets the screen meta tags.\n\t * @param {NodeList|Node} metas\n\t */\n\tsetMetas(metas) {\n\t\tthis.metas = metas;\n\t}\n\n\t/**\n\t * Sets the screen title.\n\t * @param {?string=} title\n\t */\n\tsetTitle(title) {\n\t\tthis.title = title;\n\t}\n\n\t/**\n\t * @return {string}\n\t */\n\ttoString() {\n\t\treturn this.id;\n\t}\n\n}\n\n/**\n * @param {*} object\n * @return {boolean} Whether a given instance implements\n * Screen.\n */\nScreen.isImplementedBy = function(object) {\n\treturn object instanceof Screen;\n};\n\nexport default Screen;\n","'use strict';\n\nimport globals from '../globals/globals';\nimport { Disposable, isDefAndNotNull } from 'metal';\nimport { append, removeChildren, exitDocument } from 'metal-dom';\nimport CancellablePromise from 'metal-promise';\n\nclass Surface extends Disposable {\n\n\t/**\n\t * Surface class representing the references to elements on the page that\n\t * can potentially be updated by App.\n\t * @param {string} id\n\t * @constructor\n\t */\n\tconstructor(id) {\n\t\tsuper();\n\n\t\tif (!id) {\n\t\t\tthrow new Error('Surface element id not specified. A surface element requires a valid id.');\n\t\t}\n\n\t\t/**\n\t\t * Holds the active child element.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.activeChild = null;\n\n\t\t/**\n\t\t * Holds the default child element.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.defaultChild = null;\n\n\t\t/**\n\t\t * Holds the element with the specified surface id, if not found creates a\n\t\t * new element with the specified id.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.element = null;\n\n\t\t/**\n\t\t * Holds the surface id.\n\t\t * @type {String}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.id = id;\n\n\t\t/**\n\t\t * Holds the default transitionFn for the surfaces.\n\t\t * @param {?Element=} from The visible surface element.\n\t\t * @param {?Element=} to The surface element to be flipped.\n\t\t * @default null\n\t\t */\n\t\tthis.transitionFn = null;\n\n\t\tthis.defaultChild = this.getChild(Surface.DEFAULT);\n\t\tthis.maybeWrapContentAsDefault_();\n\t\tthis.activeChild = this.defaultChild;\n\t}\n\n\t/**\n\t * Adds screen content to a surface. If content hasn't been passed, see if\n\t * an element exists in the DOM that matches the id. By convention, the\n\t * element should already be nested in the right element and should have an\n\t * id that is a concatentation of the surface id + '-' + the screen id.\n\t * @param {!string} screenId The screen id the content belongs too.\n\t * @param {?string|Element=} opt_content The string content or element to\n\t * add be added as surface content.\n\t * @return {Element}\n\t */\n\taddContent(screenId, opt_content) {\n\t\tvar child = this.defaultChild;\n\n\t\tif (isDefAndNotNull(opt_content)) {\n\t\t\tchild = this.getChild(screenId);\n\t\t\tif (child) {\n\t\t\t\tremoveChildren(child);\n\t\t\t} else {\n\t\t\t\tchild = this.createChild(screenId);\n\t\t\t\tthis.transition(child, null);\n\t\t\t}\n\t\t\tappend(child, opt_content);\n\t\t}\n\n\t\tvar element = this.getElement();\n\n\t\tif (element && child) {\n\t\t\tappend(element, child);\n\t\t}\n\n\t\treturn child;\n\t}\n\n\t/**\n\t * Creates child node for the surface.\n\t * @param {!string} screenId The screen id.\n\t * @return {Element}\n\t */\n\tcreateChild(screenId) {\n\t\tvar child = globals.document.createElement('div');\n\t\tchild.setAttribute('id', this.makeId_(screenId));\n\t\treturn child;\n\t}\n\n\t/**\n\t * Gets child node of the surface.\n\t * @param {!string} screenId The screen id.\n\t * @return {?Element}\n\t */\n\tgetChild(screenId) {\n\t\treturn globals.document.getElementById(this.makeId_(screenId));\n\t}\n\n\t/**\n\t * Gets the surface element from element, and sets it to the el property of\n\t * the current instance.\n\t * this.element will be used.\n\t * @return {?Element} The current surface element.\n\t */\n\tgetElement() {\n\t\tif (this.element) {\n\t\t\treturn this.element;\n\t\t}\n\t\tthis.element = globals.document.getElementById(this.id);\n\t\treturn this.element;\n\t}\n\n\t/**\n\t * Gets the surface id.\n\t * @return {String}\n\t */\n\tgetId() {\n\t\treturn this.id;\n\t}\n\n\t/**\n\t * Gets the surface transition function.\n\t * See Surface.defaultTransition.\n\t * @return {?Function=} The transition function.\n\t */\n\tgetTransitionFn() {\n\t\treturn this.transitionFn;\n\t}\n\n\t/**\n\t * Makes the id for the element that holds content for a screen.\n\t * @param {!string} screenId The screen id the content belongs too.\n\t * @return {String}\n\t * @private\n\t */\n\tmakeId_(screenId) {\n\t\treturn this.id + '-' + screenId;\n\t}\n\n\t/**\n\t * If default child is missing, wraps surface content as default child. If\n\t * surface have static content, make sure to place a\n\t * surfaceId-default element inside surface, only contents\n\t * inside the default child will be replaced by navigation.\n\t */\n\tmaybeWrapContentAsDefault_() {\n\t\tvar element = this.getElement();\n\t\tif (element && !this.defaultChild) {\n\t\t\tvar fragment = globals.document.createDocumentFragment();\n\t\t\twhile (element.firstChild) {\n\t\t\t\tfragment.appendChild(element.firstChild);\n\t\t\t}\n\t\t\tthis.defaultChild = this.addContent(Surface.DEFAULT, fragment);\n\t\t\tthis.transition(null, this.defaultChild);\n\t\t}\n\t}\n\n\t/**\n\t * Sets the surface id.\n\t * @param {!string} id\n\t */\n\tsetId(id) {\n\t\tthis.id = id;\n\t}\n\n\t/**\n\t * Sets the surface transition function.\n\t * See Surface.defaultTransition.\n\t * @param {?Function=} transitionFn The transition function.\n\t */\n\tsetTransitionFn(transitionFn) {\n\t\tthis.transitionFn = transitionFn;\n\t}\n\n\t/**\n\t * Shows screen content from a surface.\n\t * @param {String} screenId The screen id to show.\n\t * @return {CancellablePromise} Pauses the navigation until it is resolved.\n\t */\n\tshow(screenId) {\n\t\tvar from = this.activeChild;\n\t\tvar to = this.getChild(screenId);\n\t\tif (!to) {\n\t\t\tto = this.defaultChild;\n\t\t}\n\t\tthis.activeChild = to;\n\t\treturn this.transition(from, to).thenAlways(() => {\n\t\t\tif (from && from !== to) {\n\t\t\t\texitDocument(from);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Removes screen content from a surface.\n\t * @param {!string} screenId The screen id to remove.\n\t */\n\tremove(screenId) {\n\t\tvar child = this.getChild(screenId);\n\t\tif (child) {\n\t\t\texitDocument(child);\n\t\t}\n\t}\n\n\t/**\n\t * @return {String}\n\t */\n\ttoString() {\n\t\treturn this.id;\n\t}\n\n\t/**\n\t * Invokes the transition function specified on transition attribute.\n\t * @param {?Element=} from\n\t * @param {?Element=} to\n\t * @return {?CancellablePromise=} This can return a promise, which will pause the\n\t * navigation until it is resolved.\n\t */\n\ttransition(from, to) {\n\t\tvar transitionFn = this.transitionFn || Surface.defaultTransition;\n\t\treturn CancellablePromise.resolve(transitionFn.call(this, from, to));\n\t}\n\n}\n\n/**\n * Holds the default surface name. Elements on the page must contain a child\n * element containing the default content, this element must be as following:\n *\n * Example:\n * \n *
\n *
Default surface content.
\n *
\n *
\n *\n * The default content is relevant for the initial page content. When a\n * screen doesn't provide content for the surface the default content is\n * restored into the page.\n *\n * @type {!String}\n * @default default\n * @static\n */\nSurface.DEFAULT = 'default';\n\n/**\n * Holds the default transition for all surfaces. Each surface could have its\n * own transition.\n *\n * Example:\n *\n * \n * surface.setTransitionFn(function(from, to) {\n * if (from) {\n * from.style.display = 'none';\n * from.classList.remove('flipped');\n * }\n * if (to) {\n * to.style.display = 'block';\n * to.classList.add('flipped');\n * }\n * return null;\n * });\n * \n *\n * @param {?Element=} from The visible surface element.\n * @param {?Element=} to The surface element to be flipped.\n * @static\n */\nSurface.defaultTransition = function(from, to) {\n\tif (from) {\n\t\tfrom.style.display = 'none';\n\t\tfrom.classList.remove('flipped');\n\t}\n\tif (to) {\n\t\tto.style.display = 'block';\n\t\tto.classList.add('flipped');\n\t}\n};\n\nexport default Surface;\n","'use strict';\n\nimport { addClasses, delegate, match, on, removeClasses } from 'metal-dom';\nimport { array, async, isDefAndNotNull, isString, object } from 'metal';\nimport { EventEmitter, EventHandler } from 'metal-events';\nimport CancellablePromise from 'metal-promise';\nimport debounce from 'metal-debounce';\nimport globals from '../globals/globals';\nimport Route from '../route/Route';\nimport Screen from '../screen/Screen';\nimport Surface from '../surface/Surface';\nimport Uri from 'metal-uri';\nimport utils from '../utils/utils';\n\nconst NavigationStrategy = {\n\tIMMEDIATE: 'immediate',\n\tSCHEDULE_LAST: 'scheduleLast'\n};\n\nclass App extends EventEmitter {\n\n\t/**\n\t * App class that handle routes and screens lifecycle.\n\t * @constructor\n\t * @extends {EventEmitter}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the active screen.\n\t\t * @type {?Screen}\n\t\t * @protected\n\t\t */\n\t\tthis.activeScreen = null;\n\n\t\t/**\n\t\t * Holds the active path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.activePath = null;\n\n\t\t/**\n\t\t * Allows prevent navigate from dom prevented event.\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.allowPreventNavigate = true;\n\n\t\t/**\n\t\t * Holds link base path.\n\t\t * @type {!string}\n\t\t * @default ''\n\t\t * @protected\n\t\t */\n\t\tthis.basePath = '';\n\n\t\t/**\n\t\t * Holds the value of the browser path before a navigation is performed.\n\t\t * @type {!string}\n\t\t * @default the current browser path.\n\t\t * @protected\n\t\t */\n\t\tthis.browserPathBeforeNavigate = utils.getCurrentBrowserPathWithoutHash();\n\n\t\t/**\n\t\t * Captures scroll position from scroll event.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.captureScrollPositionFromScrollEvent = true;\n\n\t\t/**\n\t\t * Holds the default page title.\n\t\t * @type {string}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.defaultTitle = globals.document.title;\n\n\t\t/**\n\t\t * Holds the form selector to define forms that are routed.\n\t\t * @type {!string}\n\t\t * @default form[enctype=\"multipart/form-data\"]:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.formSelector = 'form[enctype=\"multipart/form-data\"]:not([data-senna-off])';\n\n\t\t/**\n\t\t * When enabled, the route matching ignores query string from the path.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.ignoreQueryStringFromRoutePath = false;\n\n\t\t/**\n\t\t * Holds the link selector to define links that are routed.\n\t\t * @type {!string}\n\t\t * @default a:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.linkSelector = 'a:not([data-senna-off]):not([target=\"_blank\"])';\n\n\t\t/**\n\t\t * Holds the loading css class.\n\t\t * @type {!string}\n\t\t * @default senna-loading\n\t\t * @protected\n\t\t */\n\t\tthis.loadingCssClass = 'senna-loading';\n\n\t\t/**\n\t\t * Using the History API to manage your URLs is awesome and, as it happens,\n\t\t * a crucial feature of good web apps. One of its downsides, however, is\n\t\t * that scroll positions are stored and then, more importantly, restored\n\t\t * whenever you traverse the history. This often means unsightly jumps as\n\t\t * the scroll position changes automatically, and especially so if your app\n\t\t * does transitions, or changes the contents of the page in any way.\n\t\t * Ultimately this leads to an horrible user experience. The good news is,\n\t\t * however, that there’s a potential fix: history.scrollRestoration.\n\t\t * https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.nativeScrollRestorationSupported = ('scrollRestoration' in globals.window.history);\n\n\t\t/**\n\t\t * When set to NavigationStrategy.SCHEDULE_LAST means that the current navigation\n\t\t * cannot be Cancelled to start another and will be queued in\n\t\t * scheduledNavigationQueue. When NavigationStrategy.IMMEDIATE means that all\n\t\t * navigation will be cancelled to start another.\n\t\t * @type {!string}\n\t\t * @default immediate\n\t\t * @protected\n\t\t */\n\t\tthis.navigationStrategy = NavigationStrategy.IMMEDIATE;\n\n\t\t/**\n\t\t * When set to true there is a pendingNavigate that has not yet been\n\t\t * resolved or rejected.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.isNavigationPending = false;\n\n\t\t/**\n\t\t * Holds a deferred with the current navigation.\n\t\t * @type {?CancellablePromise}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.pendingNavigate = null;\n\n\t\t/**\n\t\t * Holds the window horizontal scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollLeft = 0;\n\n\t\t/**\n\t\t * Holds the window vertical scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollTop = 0;\n\n\t\t/**\n\t\t * Holds the redirect path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.redirectPath = null;\n\n\t\t/**\n\t\t * Holds the screen routes configuration.\n\t\t * @type {?Array}\n\t\t * @default []\n\t\t * @protected\n\t\t */\n\t\tthis.routes = [];\n\n\t\t/**\n\t\t * Holds a queue that stores every DOM event that can initiate a navigation.\n\t\t * @type {!Event}\n\t\t * @default []\n\t\t * @protected\n\t\t */\n\t\tthis.scheduledNavigationQueue = [];\n\n\t\t/**\n\t\t * Maps the screen instances by the url containing the parameters.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.screens = {};\n\n\t\t/**\n\t\t * When set to true the first erroneous popstate fired on page load will be\n\t\t * ignored, only if globals.window.history.state is also\n\t\t * null.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.skipLoadPopstate = false;\n\n\t\t/**\n\t\t * Maps that index the surfaces instances by the surface id.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.surfaces = {};\n\n\t\t/**\n\t\t * When set to true, moves the scroll position after popstate, or to the\n\t\t * top of the viewport for new navigation. If false, the browser will\n\t\t * take care of scroll restoration.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.updateScrollPosition = true;\n\n\t\tthis.appEventHandlers_ = new EventHandler();\n\n\t\tthis.appEventHandlers_.add(\n\t\t\ton(globals.window, 'scroll', debounce(this.onScroll_.bind(this), 100)),\n\t\t\ton(globals.window, 'load', this.onLoad_.bind(this)),\n\t\t\ton(globals.window, 'popstate', this.onPopstate_.bind(this))\n\t\t);\n\n\t\tthis.on('startNavigate', this.onStartNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigateDefault_, true);\n\t\tthis.on('beforeUnload', this.onBeforeUnloadDefault_);\n\n\t\tthis.setLinkSelector(this.linkSelector);\n\t\tthis.setFormSelector(this.formSelector);\n\n\t\tthis.maybeOverloadBeforeUnload_();\n\t}\n\n\t/**\n\t * Adds one or more screens to the application.\n\t *\n\t * Example:\n\t *\n\t * \n\t * app.addRoutes({ path: '/foo', handler: FooScreen });\n\t * or\n\t * app.addRoutes([{ path: '/foo', handler: function(route) { return new FooScreen(); } }]);\n\t * \n\t *\n\t * @param {Object} or {Array} routes Single object or an array of object.\n\t * Each object should contain path and screen.\n\t * The path should be a string or a regex that maps the\n\t * navigation route to a screen class definition (not an instance), e.g:\n\t * { path: \"/home:param1\", handler: MyScreen }\n\t * { path: /foo.+/, handler: MyScreen }\n\t * @chainable\n\t */\n\taddRoutes(routes) {\n\t\tif (!Array.isArray(routes)) {\n\t\t\troutes = [routes];\n\t\t}\n\t\troutes.forEach((route) => {\n\t\t\tif (!(route instanceof Route)) {\n\t\t\t\troute = new Route(route.path, route.handler);\n\t\t\t}\n\t\t\tthis.routes.push(route);\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds one or more surfaces to the application.\n\t * @param {Surface|String|Array.} surfaces\n\t * Surface element id or surface instance. You can also pass an Array\n\t * whichcontains surface instances or id. In case of ID, these should be\n\t * the id of surface element.\n\t * @chainable\n\t */\n\taddSurfaces(surfaces) {\n\t\tif (!Array.isArray(surfaces)) {\n\t\t\tsurfaces = [surfaces];\n\t\t}\n\t\tsurfaces.forEach((surface) => {\n\t\t\tif (isString(surface)) {\n\t\t\t\tsurface = new Surface(surface);\n\t\t\t}\n\t\t\tthis.surfaces[surface.getId()] = surface;\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns if can navigate to path.\n\t * @param {!string} url\n\t * @return {boolean}\n\t */\n\tcanNavigate(url) {\n\t\tconst uri = utils.isWebUri(url);\n\n\t\tif (!uri) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst path = utils.getUrlPath(url);\n\n\t\tif (!this.isLinkSameOrigin_(uri.getHost())) {\n\t\t\tconsole.log('Offsite link clicked');\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.isSameBasePath_(path)) {\n\t\t\tconsole.log('Link clicked outside app\\'s base path');\n\t\t\treturn false;\n\t\t}\n\t\t// Prevents navigation if it's a hash change on the same url.\n\t\tif (uri.getHash() && utils.isCurrentBrowserPath(path)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.findRoute(path)) {\n\t\t\tconsole.log('No route for ' + path);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear screens cache.\n\t * @chainable\n\t */\n\tclearScreensCache() {\n\t\tObject.keys(this.screens).forEach((path) => {\n\t\t\tif (path === this.activePath) {\n\t\t\t\tthis.activeScreen.clearCache();\n\t\t\t} else if (!(this.isNavigationPending && this.pendingNavigate.path === path)) {\n\t\t\t\tthis.removeScreen(path);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves or create a screen instance to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {Screen}\n\t */\n\tcreateScreenInstance(path, route) {\n\t\tif (!this.pendingNavigate && path === this.activePath) {\n\t\t\tconsole.log('Already at destination, refresh navigation');\n\t\t\treturn this.activeScreen;\n\t\t}\n\t\t/* jshint newcap: false */\n\t\tvar screen = this.screens[path];\n\t\tif (!screen) {\n\t\t\tvar handler = route.getHandler();\n\t\t\tif (handler === Screen || Screen.isImplementedBy(handler.prototype)) {\n\t\t\t\tscreen = new handler();\n\t\t\t} else {\n\t\t\t\tscreen = handler(route) || new Screen();\n\t\t\t}\n\t\t\tconsole.log('Create screen for [' + path + '] [' + screen + ']');\n\t\t}\n\t\treturn screen;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tif (this.activeScreen) {\n\t\t\tthis.removeScreen(this.activePath);\n\t\t}\n\t\tthis.clearScreensCache();\n\t\tthis.formEventHandler_.removeListener();\n\t\tthis.linkEventHandler_.removeListener();\n\t\tthis.appEventHandlers_.removeAllListeners();\n\t\tsuper.disposeInternal();\n\t}\n\n\t/**\n\t * Dispatches to the first route handler that matches the current path, if\n\t * any.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdispatch() {\n\t\treturn this.navigate(utils.getCurrentBrowserPath(), true);\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdoNavigate_(path, opt_replaceHistory) {\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t\treturn this.pendingNavigate;\n\t\t}\n\n\t\tconsole.log('Navigate to [' + path + ']');\n\n\t\tthis.stopPendingNavigate_();\n\t\tthis.isNavigationPending = true;\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn this.maybePreventDeactivate_()\n\t\t\t.then(() => this.maybePreventActivate_(nextScreen))\n\t\t\t.then(() => nextScreen.load(path))\n\t\t\t.then(() => {\n\t\t\t\t// At this point we cannot stop navigation and all received\n\t\t\t\t// navigate candidates will be queued at scheduledNavigationQueue.\n\t\t\t\tthis.navigationStrategy = NavigationStrategy.SCHEDULE_LAST;\n\n\t\t\t\tif (this.activeScreen) {\n\t\t\t\t\tthis.activeScreen.deactivate();\n\t\t\t\t}\n\t\t\t\tthis.prepareNavigateHistory_(path, nextScreen, opt_replaceHistory);\n\t\t\t\tthis.prepareNavigateSurfaces_(\n\t\t\t\t\tnextScreen,\n\t\t\t\t\tthis.surfaces,\n\t\t\t\t\tthis.extractParams(route, path)\n\t\t\t\t);\n\t\t\t})\n\t\t\t.then(() => nextScreen.evaluateStyles(this.surfaces))\n\t\t\t.then(() => nextScreen.flip(this.surfaces))\n\t\t\t.then(() => nextScreen.evaluateScripts(this.surfaces))\n\t\t\t.then(() => this.maybeUpdateScrollPositionState_())\n\t\t\t.then(() => this.syncScrollPositionSyncThenAsync_())\n\t\t\t.then(() => this.finalizeNavigate_(path, nextScreen))\n\t\t\t.then(() => this.maybeOverloadBeforeUnload_())\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.isNavigationPending = false;\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t})\n\t\t\t.thenAlways(() => {\n\t\t\t\tthis.navigationStrategy = NavigationStrategy.IMMEDIATE;\n\n\t\t\t\tif (this.scheduledNavigationQueue.length) {\n\t\t\t\t\tconst scheduledNavigation = this.scheduledNavigationQueue.shift();\n\t\t\t\t\tthis.maybeNavigate_(scheduledNavigation.href, scheduledNavigation);\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Extracts params according to the given path and route.\n\t * @param {!Route} route\n\t * @param {string} path\n\t * @param {!Object}\n\t */\n\textractParams(route, path) {\n\t\treturn route.extractParams(this.getRoutePath(path));\n\t}\n\n\t/**\n\t * Finalizes a screen navigation.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @protected\n\t */\n\tfinalizeNavigate_(path, nextScreen) {\n\t\tnextScreen.activate();\n\n\t\tif (this.activeScreen && !this.activeScreen.isCacheable()) {\n\t\t\tif (this.activeScreen !== nextScreen) {\n\t\t\t\tthis.removeScreen(this.activePath);\n\t\t\t}\n\t\t}\n\n\t\tthis.activePath = path;\n\t\tthis.activeScreen = nextScreen;\n\t\tthis.browserPathBeforeNavigate = utils.getCurrentBrowserPathWithoutHash();\n\t\tthis.screens[path] = nextScreen;\n\t\tthis.isNavigationPending = false;\n\t\tthis.pendingNavigate = null;\n\t\tglobals.capturedFormElement = null;\n\t\tglobals.capturedFormButtonElement = null;\n\t\tconsole.log('Navigation done');\n\t}\n\n\t/**\n\t * Finds a route for the test path. Returns true if matches has a route,\n\t * otherwise returns null.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {?Object} Route handler if match any or null if the\n\t * path is the same as the current url and the path contains a fragment.\n\t */\n\tfindRoute(path) {\n\t\tpath = this.getRoutePath(path);\n\t\tfor (var i = 0; i < this.routes.length; i++) {\n\t\t\tvar route = this.routes[i];\n\t\t\tif (route.matchesPath(path)) {\n\t\t\t\treturn route;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets allow prevent navigate.\n\t * @return {boolean}\n\t */\n\tgetAllowPreventNavigate() {\n\t\treturn this.allowPreventNavigate;\n\t}\n\n\t/**\n\t * Gets link base path.\n\t * @return {!string}\n\t */\n\tgetBasePath() {\n\t\treturn this.basePath;\n\t}\n\n\t/**\n\t * Gets the default page title.\n\t * @return {string} defaultTitle\n\t */\n\tgetDefaultTitle() {\n\t\treturn this.defaultTitle;\n\t}\n\n\t/**\n\t * Gets the form selector.\n\t * @return {!string}\n\t */\n\tgetFormSelector() {\n\t\treturn this.formSelector;\n\t}\n\n\t/**\n\t * Check if route matching is ignoring query string from the route path.\n\t * @return {boolean}\n\t */\n\tgetIgnoreQueryStringFromRoutePath() {\n\t\treturn this.ignoreQueryStringFromRoutePath;\n\t}\n\n\t/**\n\t * Gets the link selector.\n\t * @return {!string}\n\t */\n\tgetLinkSelector() {\n\t\treturn this.linkSelector;\n\t}\n\n\t/**\n\t * Gets the loading css class.\n\t * @return {!string}\n\t */\n\tgetLoadingCssClass() {\n\t\treturn this.loadingCssClass;\n\t}\n\n\t/**\n\t * Returns the given path formatted to be matched by a route. This will,\n\t * for example, remove the base path from it, but make sure it will end\n\t * with a '/'.\n\t * @param {string} path\n\t * @return {string}\n\t */\n\tgetRoutePath(path) {\n\t\tif (this.getIgnoreQueryStringFromRoutePath()) {\n\t\t\tpath = utils.getUrlPathWithoutHashAndSearch(path);\n\t\t\treturn utils.getUrlPathWithoutHashAndSearch(path.substr(this.basePath.length));\n\t\t}\n\n\t\tpath = utils.getUrlPathWithoutHash(path);\n\t\treturn utils.getUrlPathWithoutHash(path.substr(this.basePath.length));\n\t}\n\n\t/**\n\t * Gets the update scroll position value.\n\t * @return {boolean}\n\t */\n\tgetUpdateScrollPosition() {\n\t\treturn this.updateScrollPosition;\n\t}\n\n\t/**\n\t * Handle navigation error.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {!Error} error\n\t * @protected\n\t */\n\thandleNavigateError_(path, nextScreen, error) {\n\t\tconsole.log('Navigation error for [' + nextScreen + '] (' + error.stack + ')');\n\t\tthis.emit('navigationError', {\n\t\t\terror,\n\t\t\tnextScreen,\n\t\t\tpath\n\t\t});\n\t\tif (!utils.isCurrentBrowserPath(path)) {\n\t\t\tif (this.isNavigationPending && this.pendingNavigate) {\n\t\t\t\tthis.pendingNavigate.thenAlways(() => this.removeScreen(path), this);\n\t\t\t} else {\n\t\t\t\tthis.removeScreen(path);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if app has routes.\n\t * @return {boolean}\n\t */\n\thasRoutes() {\n\t\treturn this.routes.length > 0;\n\t}\n\n\t/**\n\t * Tests if host is an offsite link.\n\t * @param {!string} host Link host to compare with\n\t * globals.window.location.host.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisLinkSameOrigin_(host) {\n\t\tconst hostUri = new Uri(host);\n\t\tconst locationHostUri = new Uri(globals.window.location.host);\n\n\t\treturn hostUri.getPort() === locationHostUri.getPort() && hostUri.getHostname() === locationHostUri.getHostname();\n\t}\n\n\t/**\n\t * Tests if link element has the same app's base path.\n\t * @param {!string} path Link path containing the querystring part.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisSameBasePath_(path) {\n\t\treturn path.indexOf(this.basePath) === 0;\n\t}\n\n\t/**\n\t * Lock the document scroll in order to avoid the browser native back and\n\t * forward navigation to change the scroll position. In the end of\n\t * navigation lifecycle scroll is repositioned.\n\t * @protected\n\t */\n\tlockHistoryScrollPosition_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\t\t// Browsers are inconsistent when re-positioning the scroll history on\n\t\t// popstate. At some browsers, history scroll happens before popstate, then\n\t\t// lock the scroll on the last known position as soon as possible after the\n\t\t// current JS execution context and capture the current value. Some others,\n\t\t// history scroll happens after popstate, in this case, we bind an once\n\t\t// scroll event to lock the las known position. Lastly, the previous two\n\t\t// behaviors can happen even on the same browser, hence the race will decide\n\t\t// the winner.\n\t\tvar winner = false;\n\t\tvar switchScrollPositionRace = function() {\n\t\t\tglobals.document.removeEventListener('scroll', switchScrollPositionRace, false);\n\t\t\tif (!winner) {\n\t\t\t\tglobals.window.scrollTo(state.scrollLeft, state.scrollTop);\n\t\t\t\twinner = true;\n\t\t\t}\n\t\t};\n\t\tasync.nextTick(switchScrollPositionRace);\n\t\tglobals.document.addEventListener('scroll', switchScrollPositionRace, false);\n\t}\n\n\t/**\n\t * If supported by the browser, disables native scroll restoration and\n\t * stores current value.\n\t */\n\tmaybeDisableNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported) {\n\t\t\tthis.nativeScrollRestoration_ = globals.window.history.scrollRestoration;\n\t\t\tglobals.window.history.scrollRestoration = 'manual';\n\t\t}\n\t}\n\n\t/**\n\t * This method is used to evaluate if is possible to queue received\n\t * dom event to scheduleNavigationQueue and enqueue it.\n\t * @param {string} href Information about the link's href.\n\t * @param {Event} event Dom event that initiated the navigation.\n\t */\n\tmaybeScheduleNavigation_(href, event) {\n\t\tif (this.isNavigationPending && this.navigationStrategy === NavigationStrategy.SCHEDULE_LAST) {\n\t\t\tthis.scheduledNavigationQueue = [object.mixin({\n\t\t\t\thref,\n\t\t\t\tisScheduledNavigation: true\n\t\t\t}, event)];\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Maybe navigate to a path.\n\t * @param {string} href Information about the link's href.\n\t * @param {Event} event Dom event that initiated the navigation.\n\t */\n\tmaybeNavigate_(href, event) {\n\t\tif (!this.canNavigate(href)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isNavigationScheduled = this.maybeScheduleNavigation_(href, event);\n\n\t\tif (isNavigationScheduled) {\n\t\t\tevent.preventDefault();\n\t\t\treturn;\n\t\t}\n\n\t\tvar navigateFailed = false;\n\t\ttry {\n\t\t\tthis.navigate(utils.getUrlPath(href), false, event);\n\t\t} catch (err) {\n\t\t\t// Do not prevent link navigation in case some synchronous error occurs\n\t\t\tnavigateFailed = true;\n\t\t}\n\n\t\tif (!navigateFailed && !event.isScheduledNavigation) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether the onbeforeunload global event handler is overloaded\n\t * by client code. If so, it replaces with a function that halts the normal\n\t * event flow in relation with the client onbeforeunload function.\n\t * This can be in most part used to prematurely terminate navigation to other pages\n\t * according to the given constrait(s).\n\t * @protected\n\t */\n\tmaybeOverloadBeforeUnload_() {\n\t\tif ('function' === typeof window.onbeforeunload) {\n\t\t\twindow._onbeforeunload = window.onbeforeunload;\n\n\t\t\twindow.onbeforeunload = event => {\n\t\t\t\tthis.emit('beforeUnload', event);\n\t\t\t\tif (event && event.defaultPrevented) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// mark the updated handler due unwanted recursion\n\t\t\twindow.onbeforeunload._overloaded = true;\n\t\t}\n\t}\n\n\t/**\n\t * Cancels navigation if nextScreen's beforeActivate lifecycle method\n\t * resolves to true.\n\t * @param {!Screen} nextScreen\n\t * @return {!CancellablePromise}\n\t */\n\tmaybePreventActivate_(nextScreen) {\n\t\treturn CancellablePromise.resolve()\n\t\t\t.then(() => {\n\t\t\t\treturn nextScreen.beforeActivate();\n\t\t\t})\n\t\t\t.then(prevent => {\n\t\t\t\tif (prevent) {\n\t\t\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('Cancelled by next screen'));\n\t\t\t\t\treturn this.pendingNavigate;\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Cancels navigation if activeScreen's beforeDeactivate lifecycle\n\t * method resolves to true.\n\t * @return {!CancellablePromise}\n\t */\n\tmaybePreventDeactivate_() {\n\t\treturn CancellablePromise.resolve()\n\t\t\t.then(() => {\n\t\t\t\tif (this.activeScreen) {\n\t\t\t\t\treturn this.activeScreen.beforeDeactivate();\n\t\t\t\t}\n\t\t\t})\n\t\t\t.then(prevent => {\n\t\t\t\tif (prevent) {\n\t\t\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('Cancelled by active screen'));\n\t\t\t\t\treturn this.pendingNavigate;\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Maybe reposition scroll to hashed anchor.\n\t */\n\tmaybeRepositionScrollToHashedAnchor() {\n\t\tconst hash = globals.window.location.hash;\n\t\tif (hash) {\n\t\t\tlet anchorElement = globals.document.getElementById(hash.substring(1));\n\t\t\tif (anchorElement) {\n\t\t\t\tconst {offsetLeft, offsetTop} = utils.getNodeOffset(anchorElement);\n\t\t\t\tglobals.window.scrollTo(offsetLeft, offsetTop);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If supported by the browser, restores native scroll restoration to the\n\t * value captured by `maybeDisableNativeScrollRestoration`.\n\t */\n\tmaybeRestoreNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported && this.nativeScrollRestoration_) {\n\t\t\tglobals.window.history.scrollRestoration = this.nativeScrollRestoration_;\n\t\t}\n\t}\n\n\t/**\n\t * Maybe restore redirected path hash in case both the current path and\n\t * the given path are the same.\n\t * @param {!string} path Path before navigation.\n\t * @param {!string} redirectPath Path after navigation.\n\t * @param {!string} hash Hash to be added to the path.\n\t * @return {!string} Returns the path with the hash restored.\n\t */\n\tmaybeRestoreRedirectPathHash_(path, redirectPath, hash) {\n\t\tif (redirectPath === utils.getUrlPathWithoutHash(path)) {\n\t\t\treturn redirectPath + hash;\n\t\t}\n\t\treturn redirectPath;\n\t}\n\n\t/**\n\t * Maybe update scroll position in history state to anchor on path.\n\t * @param {!string} path Path containing anchor\n\t */\n\tmaybeUpdateScrollPositionState_() {\n\t\tvar hash = globals.window.location.hash;\n\t\tvar anchorElement = globals.document.getElementById(hash.substring(1));\n\t\tif (anchorElement) {\n\t\t\tconst {offsetLeft, offsetTop} = utils.getNodeOffset(anchorElement);\n\t\t\tthis.saveHistoryCurrentPageScrollPosition_(offsetTop, offsetLeft);\n\t\t}\n\t}\n\n\t/**\n\t * Navigates to the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @param {Event=} event Optional event object that triggered the navigation.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tnavigate(path, opt_replaceHistory, opt_event) {\n\t\tif (!utils.isHtml5HistorySupported()) {\n\t\t\tthrow new Error('HTML5 History is not supported. Senna will not intercept navigation.');\n\t\t}\n\n\t\tif (opt_event) {\n\t\t\tglobals.capturedFormElement = opt_event.capturedFormElement;\n\t\t\tglobals.capturedFormButtonElement = opt_event.capturedFormButtonElement;\n\t\t}\n\n\t\t// When reloading the same path do replaceState instead of pushState to\n\t\t// avoid polluting history with states with the same path.\n\t\tif (path === this.activePath) {\n\t\t\topt_replaceHistory = true;\n\t\t}\n\n\t\tthis.emit('beforeNavigate', {\n\t\t\tevent: opt_event,\n\t\t\tpath: path,\n\t\t\treplaceHistory: !!opt_replaceHistory\n\t\t});\n\n\t\treturn this.pendingNavigate;\n\t}\n\n\t/**\n\t * Befores navigation to a path.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonBeforeNavigate_(event) {\n\t\tif (globals.capturedFormElement) {\n\t\t\tevent.form = globals.capturedFormElement;\n\t\t}\n\t}\n\n\t/**\n\t * Befores navigation to a path. Runs after external listeners.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonBeforeNavigateDefault_(event) {\n\t\tif (this.pendingNavigate) {\n\t\t\tif (this.pendingNavigate.path === event.path || this.navigationStrategy === NavigationStrategy.SCHEDULE_LAST) {\n\t\t\t\tconsole.log('Waiting...');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.emit('beforeUnload', event);\n\n\t\tthis.emit('startNavigate', {\n\t\t\tform: event.form,\n\t\t\tpath: event.path,\n\t\t\treplaceHistory: event.replaceHistory\n\t\t});\n\t}\n\n\t/**\n\t * Custom event handler that executes the original listener that has been\n\t * added by the client code and terminates the navigation accordingly.\n\t * @param {!Event} event original Event facade.\n\t * @protected\n\t */\n\tonBeforeUnloadDefault_(event) {\n\t\tvar func = window._onbeforeunload;\n\t\tif (func && !func._overloaded && func()) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/**\n\t * Intercepts document clicks and test link elements in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocClickDelegate_(event) {\n\t\tif (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.button) {\n\t\t\tconsole.log('Navigate aborted, invalid mouse button or modifier key pressed.');\n\t\t\treturn;\n\t\t}\n\t\tthis.maybeNavigate_(event.delegateTarget.href, event);\n\t}\n\n\t/**\n\t * Intercepts document form submits and test action path in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocSubmitDelegate_(event) {\n\t\tvar form = event.delegateTarget;\n\t\tif (form.method === 'get') {\n\t\t\tconsole.log('GET method not supported');\n\t\t\treturn;\n\t\t}\n\t\tevent.capturedFormElement = form;\n\t\tconst buttonSelector = 'button:not([type]),button[type=submit],input[type=submit]';\n\t\tif (match(globals.document.activeElement, buttonSelector)) {\n\t\t\tevent.capturedFormButtonElement = globals.document.activeElement;\n\t\t} else {\n\t\t\tevent.capturedFormButtonElement = form.querySelector(buttonSelector);\n\t\t}\n\t\tthis.maybeNavigate_(form.action, event);\n\t}\n\n\t/**\n\t * Listens to the window's load event in order to avoid issues with some browsers\n\t * that trigger popstate calls on the first load. For more information see\n\t * http://stackoverflow.com/questions/6421769/popstate-on-pages-load-in-chrome.\n\t * @protected\n\t */\n\tonLoad_() {\n\t\tthis.skipLoadPopstate = true;\n\t\tsetTimeout(() => {\n\t\t\t// The timeout ensures that popstate events will be unblocked right\n\t\t\t// after the load event occured, but not in the same event-loop cycle.\n\t\t\tthis.skipLoadPopstate = false;\n\t\t}, 0);\n\t\t// Try to reposition scroll to the hashed anchor when page loads.\n\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t}\n\n\t/**\n\t * Handles browser history changes and fires app's navigation if the state\n\t * belows to us. If we detect a popstate and the state is null,\n\t * assume it is navigating to an external page or to a page we don't have\n\t * route, then globals.window.location.reload() is invoked in order to\n\t * reload the content to the current url.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonPopstate_(event) {\n\t\tif (this.skipLoadPopstate) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not navigate if the popstate was triggered by a hash change.\n\t\tif (utils.isCurrentBrowserPath(this.browserPathBeforeNavigate)) {\n\t\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t\t\treturn;\n\t\t}\n\n\t\tvar state = event.state;\n\n\t\tif (!state) {\n\t\t\tif (globals.window.location.hash) {\n\t\t\t\t// If senna is on an redirect path and a hash popstate happens\n\t\t\t\t// to a different url, reload the browser. This behavior doesn't\n\t\t\t\t// require senna to route hashed links and is closer to native\n\t\t\t\t// browser behavior.\n\t\t\t\tif (this.redirectPath && !utils.isCurrentBrowserPath(this.redirectPath)) {\n\t\t\t\t\tthis.reloadPage();\n\t\t\t\t}\n\t\t\t\t// Always try to reposition scroll to the hashed anchor when\n\t\t\t\t// hash popstate happens.\n\t\t\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t\t\t} else {\n\t\t\t\tthis.reloadPage();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (state.senna) {\n\t\t\tconsole.log('History navigation to [' + state.path + ']');\n\t\t\tthis.popstateScrollTop = state.scrollTop;\n\t\t\tthis.popstateScrollLeft = state.scrollLeft;\n\t\t\tif (!this.nativeScrollRestorationSupported) {\n\t\t\t\tthis.lockHistoryScrollPosition_();\n\t\t\t}\n\t\t\tthis.once('endNavigate', () => {\n\t\t\t\tif (state.referrer) {\n\t\t\t\t\tutils.setReferrer(state.referrer);\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst uri = new Uri(state.path);\n\t\t\turi.setHostname(globals.window.location.hostname);\n\t\t\turi.setPort(globals.window.location.port);\n\t\t\tconst isNavigationScheduled = this.maybeScheduleNavigation_(uri.toString(), {});\n\t\t\tif (isNavigationScheduled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.navigate(state.path, true);\n\t\t}\n\t}\n\n\t/**\n\t * Listens document scroll changes in order to capture the possible lock\n\t * scroll position for history scrolling.\n\t * @protected\n\t */\n\tonScroll_() {\n\t\tif (this.captureScrollPositionFromScrollEvent) {\n\t\t\tthis.saveHistoryCurrentPageScrollPosition_(globals.window.pageYOffset, globals.window.pageXOffset);\n\t\t}\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonStartNavigate_(event) {\n\t\tthis.maybeDisableNativeScrollRestoration();\n\t\tthis.captureScrollPositionFromScrollEvent = false;\n\t\taddClasses(globals.document.documentElement, this.loadingCssClass);\n\n\t\tvar endNavigatePayload = {\n\t\t\tform: event.form,\n\t\t\tpath: event.path\n\t\t};\n\n\t\tthis.pendingNavigate = this.doNavigate_(event.path, event.replaceHistory)\n\t\t\t.catch((reason) => {\n\t\t\t\tendNavigatePayload.error = reason;\n\t\t\t\tthrow reason;\n\t\t\t})\n\t\t\t.thenAlways(() => {\n\t\t\t\tif (!this.pendingNavigate && !this.scheduledNavigationQueue.length) {\n\t\t\t\t\tremoveClasses(globals.document.documentElement, this.loadingCssClass);\n\t\t\t\t\tthis.maybeRestoreNativeScrollRestoration();\n\t\t\t\t\tthis.captureScrollPositionFromScrollEvent = true;\n\t\t\t\t}\n\t\t\t\tthis.emit('endNavigate', endNavigatePayload);\n\t\t\t});\n\n\t\tthis.pendingNavigate.path = event.path;\n\t}\n\n\t/**\n\t * Prefetches the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tprefetch(path) {\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\treturn CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t}\n\n\t\tconsole.log('Prefetching [' + path + ']');\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn nextScreen.load(path)\n\t\t\t.then(() => this.screens[path] = nextScreen)\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t */\n\tprepareNavigateHistory_(path, nextScreen, opt_replaceHistory) {\n\t\tlet title = nextScreen.getTitle();\n\t\tif (!isString(title)) {\n\t\t\ttitle = this.getDefaultTitle();\n\t\t}\n\t\tlet redirectPath = nextScreen.beforeUpdateHistoryPath(path);\n\t\tconst historyState = {\n\t\t\tform: isDefAndNotNull(globals.capturedFormElement),\n\t\t\tpath,\n\t\t\tredirectPath,\n\t\t\tscrollLeft: 0,\n\t\t\tscrollTop: 0,\n\t\t\tsenna: true\n\t\t};\n\t\tif (opt_replaceHistory) {\n\t\t\thistoryState.scrollTop = this.popstateScrollTop;\n\t\t\thistoryState.scrollLeft = this.popstateScrollLeft;\n\t\t}\n\t\tconst hash = new Uri(path).getHash();\n\t\tredirectPath = this.maybeRestoreRedirectPathHash_(path, redirectPath, hash);\n\t\tthis.updateHistory_(title, redirectPath, nextScreen.beforeUpdateHistoryState(historyState), opt_replaceHistory);\n\t\tthis.redirectPath = redirectPath;\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!Screen} nextScreen\n\t * @param {!Object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @param {!Object} params Params extracted from the current path.\n\t */\n\tprepareNavigateSurfaces_(nextScreen, surfaces, params) {\n\t\tObject.keys(surfaces).forEach((id) => {\n\t\t\tvar surfaceContent = nextScreen.getSurfaceContent(id, params);\n\t\t\tsurfaces[id].addContent(nextScreen.getId(), surfaceContent);\n\t\t\tconsole.log('Screen [' + nextScreen.getId() + '] add content to surface ' +\n\t\t\t\t'[' + surfaces[id] + '] [' + (isDefAndNotNull(surfaceContent) ? '...' : 'empty') + ']');\n\t\t});\n\t}\n\n\t/**\n\t * Reloads the page by performing `window.location.reload()`.\n\t */\n\treloadPage() {\n\t\tglobals.window.location.reload();\n\t}\n\n\t/**\n\t * Removes route instance from app routes.\n\t * @param {Route} route\n\t * @return {boolean} True if an element was removed.\n\t */\n\tremoveRoute(route) {\n\t\treturn array.remove(this.routes, route);\n\t}\n\n\t/**\n\t * Removes a screen.\n\t * @param {!string} path Path containing the querystring part.\n\t */\n\tremoveScreen(path) {\n\t\tvar screen = this.screens[path];\n\t\tif (screen) {\n\t\t\tObject.keys(this.surfaces).forEach((surfaceId) => this.surfaces[surfaceId].remove(screen.getId()));\n\t\t\tscreen.dispose();\n\t\t\tdelete this.screens[path];\n\t\t}\n\t}\n\n\t/**\n\t * Saves given scroll position into history state.\n\t * @param {!number} scrollTop Number containing the top scroll position to be saved.\n\t * @param {!number} scrollLeft Number containing the left scroll position to be saved.\n\t */\n\tsaveHistoryCurrentPageScrollPosition_(scrollTop, scrollLeft) {\n\t\tvar state = globals.window.history.state;\n\t\tif (state && state.senna) {\n\t\t\t[state.scrollTop, state.scrollLeft] = [scrollTop, scrollLeft];\n\t\t\tglobals.window.history.replaceState(state, null, null);\n\t\t}\n\t}\n\n\t/**\n\t * Sets allow prevent navigate.\n\t * @param {boolean} allowPreventNavigate\n\t */\n\tsetAllowPreventNavigate(allowPreventNavigate) {\n\t\tthis.allowPreventNavigate = allowPreventNavigate;\n\t}\n\n\t/**\n\t * Sets link base path.\n\t * @param {!string} path\n\t */\n\tsetBasePath(basePath) {\n\t\tthis.basePath = utils.removePathTrailingSlash(basePath);\n\t}\n\n\t/**\n\t * Sets the default page title.\n\t * @param {string} defaultTitle\n\t */\n\tsetDefaultTitle(defaultTitle) {\n\t\tthis.defaultTitle = defaultTitle;\n\t}\n\n\t/**\n\t * Sets the form selector.\n\t * @param {!string} formSelector\n\t */\n\tsetFormSelector(formSelector) {\n\t\tthis.formSelector = formSelector;\n\t\tif (this.formEventHandler_) {\n\t\t\tthis.formEventHandler_.removeListener();\n\t\t}\n\t\tthis.formEventHandler_ = delegate(document, 'submit', this.formSelector, this.onDocSubmitDelegate_.bind(this), this.allowPreventNavigate);\n\t}\n\n\t/**\n\t * Sets if route matching should ignore query string from the route path.\n\t * @param {boolean} ignoreQueryStringFromRoutePath\n\t */\n\tsetIgnoreQueryStringFromRoutePath(ignoreQueryStringFromRoutePath) {\n\t\tthis.ignoreQueryStringFromRoutePath = ignoreQueryStringFromRoutePath;\n\t}\n\n\t/**\n\t * Sets the link selector.\n\t * @param {!string} linkSelector\n\t */\n\tsetLinkSelector(linkSelector) {\n\t\tthis.linkSelector = linkSelector;\n\t\tif (this.linkEventHandler_) {\n\t\t\tthis.linkEventHandler_.removeListener();\n\t\t}\n\t\tthis.linkEventHandler_ = delegate(document, 'click', this.linkSelector, this.onDocClickDelegate_.bind(this), this.allowPreventNavigate);\n\t}\n\n\t/**\n\t * Sets the loading css class.\n\t * @param {!string} loadingCssClass\n\t */\n\tsetLoadingCssClass(loadingCssClass) {\n\t\tthis.loadingCssClass = loadingCssClass;\n\t}\n\n\t/**\n\t * Sets the update scroll position value.\n\t * @param {boolean} updateScrollPosition\n\t */\n\tsetUpdateScrollPosition(updateScrollPosition) {\n\t\tthis.updateScrollPosition = updateScrollPosition;\n\t}\n\n\t/**\n\t * Cancels pending navigate with Cancel pending navigation error.\n\t * @protected\n\t */\n\tstopPendingNavigate_() {\n\t\tif (this.pendingNavigate) {\n\t\t\tthis.pendingNavigate.cancel('Cancel pending navigation');\n\t\t}\n\t\tthis.pendingNavigate = null;\n\t}\n\n\t/**\n\t * Sync document scroll position twice, the first one synchronous and then\n\t * one inside async.nextTick. Relevant to browsers that fires\n\t * scroll restoration asynchronously after popstate.\n\t * @protected\n\t * @return {?CancellablePromise=}\n\t */\n\tsyncScrollPositionSyncThenAsync_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar scrollTop = state.scrollTop;\n\t\tvar scrollLeft = state.scrollLeft;\n\n\t\tvar sync = () => {\n\t\t\tif (this.updateScrollPosition) {\n\t\t\t\tglobals.window.scrollTo(scrollLeft, scrollTop);\n\t\t\t}\n\t\t};\n\n\t\treturn new CancellablePromise((resolve) => sync() & async.nextTick(() => sync() & resolve()));\n\t}\n\n\t/**\n\t * Updates or replace browser history.\n\t * @param {?string} title Document title.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!object} state\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @protected\n\t */\n\tupdateHistory_(title, path, state, opt_replaceHistory) {\n\t\tconst referrer = globals.window.location.href;\n\n\t\tif (state) {\n\t\t\tstate.referrer = referrer;\n\t\t}\n\n\t\tif (opt_replaceHistory) {\n\t\t\tglobals.window.history.replaceState(state, title, path);\n\t\t} else {\n\t\t\tglobals.window.history.pushState(state, title, path);\n\t\t}\n\n\t\tutils.setReferrer(referrer);\n\n\t\tlet titleNode = globals.document.querySelector('title');\n\t\tif (titleNode) {\n\t\t\ttitleNode.innerHTML = title;\n\t\t} else {\n\t\t\tglobals.document.title = title;\n\t\t}\n\t}\n\n}\n\nexport default App;\n","'use strict';\n\nimport { isDef, isDefAndNotNull } from 'metal';\nimport Uri from 'metal-uri';\nimport { CancellablePromise as Promise } from 'metal-promise';\n\nclass Ajax {\n\n\t/**\n\t * XmlHttpRequest's getAllResponseHeaders() method returns a string of\n\t * response headers according to the format described on the spec:\n\t * {@link http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders-method}.\n\t * This method parses that string into a user-friendly name/value pair\n\t * object.\n\t * @param {string} allHeaders All headers as string.\n\t * @return {!Array.>}\n\t */\n\tstatic parseResponseHeaders(allHeaders) {\n\t\tvar headers = [];\n\t\tif (!allHeaders) {\n\t\t\treturn headers;\n\t\t}\n\t\tvar pairs = allHeaders.split('\\u000d\\u000a');\n\t\tfor (var i = 0; i < pairs.length; i++) {\n\t\t\tvar index = pairs[i].indexOf('\\u003a\\u0020');\n\t\t\tif (index > 0) {\n\t\t\t\tvar name = pairs[i].substring(0, index);\n\t\t\t\tvar value = pairs[i].substring(index + 2);\n\t\t\t\theaders.push({\n\t\t\t\t\tname: name,\n\t\t\t\t\tvalue: value\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn headers;\n\t}\n\n\t/**\n\t * Requests the url using XMLHttpRequest.\n\t * @param {!string} url\n\t * @param {!string} method\n\t * @param {?string} body\n\t * @param {MultiMap=} opt_headers\n\t * @param {MultiMap=} opt_params\n\t * @param {number=} opt_timeout\n\t * @param {boolean=} opt_sync\n\t * @param {boolean=} opt_withCredentials\n\t * @return {Promise} Deferred ajax request.\n\t * @protected\n\t */\n\tstatic request(url, method, body, opt_headers, opt_params, opt_timeout, opt_sync, opt_withCredentials) {\n\t\turl = url || '';\n\t\tmethod = method || 'GET';\n\n\t\tvar request = new XMLHttpRequest();\n\t\tvar previousReadyState = 0;\n\n\t\tvar promise = new Promise(function(resolve, reject) {\n\t\t\trequest.onload = function() {\n\t\t\t\tif (request.aborted) {\n\t\t\t\t\trequest.onerror();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tresolve(request);\n\t\t\t};\n\t\t\trequest.onreadystatechange = function() {\n\t\t\t\tif (previousReadyState && previousReadyState < 3 && 4 === request.readyState) {\n\t\t\t\t\trequest.terminatedPrematurely = true;\n\t\t\t\t}\n\t\t\t\tpreviousReadyState = request.readyState;\n\t\t\t};\n\t\t\trequest.onerror = function() {\n\t\t\t\tvar message = 'Request error';\n\t\t\t\tif (request.terminatedPrematurely) {\n\t\t\t\t\tmessage = 'Request terminated prematurely';\n\t\t\t\t} \n\t\t\t\tvar error = new Error(message);\n\t\t\t\terror.request = request;\n\t\t\t\treject(error);\n\t\t\t};\n\t\t}).thenCatch(function(reason) {\n\t\t\trequest.abort();\n\t\t\tthrow reason;\n\t\t}).thenAlways(function() {\n\t\t\tclearTimeout(timeout);\n\t\t});\n\n\t\turl = new Uri(url);\n\n\t\tif (opt_params) {\n\t\t\turl.addParametersFromMultiMap(opt_params).toString();\n\t\t}\n\n\t\turl = url.toString();\n\n\t\trequest.open(method, url, !opt_sync);\n\n\t\tif (opt_withCredentials) {\n\t\t\trequest.withCredentials = true;\n\t\t}\n\n\t\tif (opt_headers) {\n\t\t\topt_headers.names().forEach(function(name) {\n\t\t\t\trequest.setRequestHeader(name, opt_headers.getAll(name).join(', '));\n\t\t\t});\n\t\t}\n\n\t\trequest.send(isDef(body) ? body : null);\n\n\t\tif (isDefAndNotNull(opt_timeout)) {\n\t\t\tvar timeout = setTimeout(function() {\n\t\t\t\tpromise.cancel('Request timeout');\n\t\t\t}, opt_timeout);\n\t\t}\n\n\t\treturn promise;\n\t}\n\n}\n\nexport default Ajax;\n","'use strict';\n\n/**\n * Holds value error messages.\n * @const\n */\nclass errors {\n}\n\n/**\n * Invalid status error message.\n * @type {string}\n * @static\n */\nerrors.INVALID_STATUS = 'Invalid status code';\n\n/**\n * Request error message.\n * @type {string}\n * @static\n */\nerrors.REQUEST_ERROR = 'Request error';\n\n/**\n * Request timeout error message.\n * @type {string}\n * @static\n */\nerrors.REQUEST_TIMEOUT = 'Request timeout';\n\n/**\n * Request is blocked by CORS issue message.\n * @type {string}\n * @static\n */\nerrors.REQUEST_PREMATURE_TERMINATION = 'Request terminated prematurely';\n\nexport default errors;\n","'use strict';\n\nimport {isServerSide} from 'metal';\n\n/**\n * Metal.js browser user agent detection. It's extremely recommended the usage\n * of feature checking over browser user agent sniffing. Unfortunately, in some\n * situations feature checking can be slow or even impossible, therefore use\n * this utility with caution.\n * @see User agent strings.\n */\nclass UA {\n\t/**\n\t * Gets the native userAgent string from navigator if it exists. If\n\t * navigator or navigator.userAgent string is missing, returns an empty\n\t * string.\n\t * @return {string}\n\t * @private\n\t * @static\n\t */\n\tstatic getNativeUserAgent() {\n\t\tlet navigator = UA.globals.window && UA.globals.window.navigator;\n\t\tif (navigator) {\n\t\t\tlet userAgent = navigator.userAgent;\n\t\t\tif (userAgent) {\n\t\t\t\treturn userAgent;\n\t\t\t}\n\t\t}\n\t\treturn '';\n\t}\n\n\t/**\n\t * Gets the native platform string from navigator if it exists. If\n\t * navigator or navigator.platform string is missing, returns an empty\n\t * string.\n\t * @return {string}\n\t * @private\n\t * @static\n\t */\n\tstatic getNativePlatform() {\n\t\tlet navigator = UA.globals.window && UA.globals.window.navigator;\n\t\tif (navigator) {\n\t\t\tlet platform = navigator.platform;\n\t\t\tif (platform) {\n\t\t\t\treturn platform;\n\t\t\t}\n\t\t}\n\t\treturn '';\n\t}\n\n\t/**\n\t * Whether the platform contains the given string, ignoring case.\n\t * @param {string} str\n\t * @return {boolean}\n\t * @private\n\t * @static\n\t */\n\tstatic matchPlatform(str) {\n\t\treturn UA.platform.indexOf(str) !== -1;\n\t}\n\n\t/**\n\t * Whether the user agent contains the given string, ignoring case.\n\t * @param {string} str\n\t * @return {boolean}\n\t * @private\n\t * @static\n\t */\n\tstatic matchUserAgent(str) {\n\t\treturn UA.userAgent.indexOf(str) !== -1;\n\t}\n\n\t/**\n\t * Tests the user agent.\n\t * @param {string} userAgent The user agent string.\n\t * @param {string} platform\n\t * @static\n\t */\n\tstatic testUserAgent(userAgent = '', platform = '') {\n\t\t/**\n\t\t * Holds the user agent value extracted from browser native user agent.\n\t\t * @type {string}\n\t\t * @static\n\t\t */\n\t\tUA.userAgent = userAgent;\n\n\t\t/**\n\t\t * Holds the platform value extracted from browser native platform.\n\t\t * @type {string}\n\t\t * @static\n\t\t */\n\t\tUA.platform = platform;\n\n\t\t/**\n\t\t * Whether the user's OS is Mac.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isMac = UA.matchPlatform('Mac');\n\n\t\t/**\n\t\t * Whether the user's OS is Win.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isWin = UA.matchPlatform('Win');\n\n\t\t/**\n\t\t * Whether the user's browser is Opera.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isOpera = UA.matchUserAgent('Opera') || UA.matchUserAgent('OPR');\n\n\t\t/**\n\t\t * Whether the user's browser is IE.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isIe = UA.matchUserAgent('Trident') || UA.matchUserAgent('MSIE');\n\n\t\t/**\n\t\t * Whether the user's browser is Edge.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isEdge = UA.matchUserAgent('Edge');\n\n\t\t/**\n\t\t * Whether the user's browser is IE or Edge.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isIeOrEdge = UA.isIe || UA.isEdge;\n\n\t\t/**\n\t\t * Whether the user's browser is Chrome.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isChrome =\n\t\t\t(UA.matchUserAgent('Chrome') || UA.matchUserAgent('CriOS')) &&\n\t\t\t!UA.isOpera &&\n\t\t\t!UA.isEdge;\n\n\t\t/**\n\t\t * Whether the user's browser is Safari.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isSafari =\n\t\t\tUA.matchUserAgent('Safari') &&\n\t\t\t!(UA.isChrome || UA.isOpera || UA.isEdge);\n\n\t\t/**\n\t\t * Whether the user's browser is Firefox.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isFirefox = UA.matchUserAgent('Firefox');\n\t}\n}\n\n/**\n * Exposes global references.\n * @type {object}\n * @static\n */\nObject.defineProperty(UA, 'globals', {\n\twritable: true,\n\tvalue: {\n\t\twindow: isServerSide() ? null : window,\n\t},\n});\n\nUA.testUserAgent(UA.getNativeUserAgent(), UA.getNativePlatform());\n\nexport default UA;\n","'use strict';\n\nimport { isDefAndNotNull } from 'metal';\nimport Ajax from 'metal-ajax';\nimport { MultiMap } from 'metal-structs';\nimport CancellablePromise from 'metal-promise';\nimport errors from '../errors/errors';\nimport utils from '../utils/utils';\nimport globals from '../globals/globals';\nimport Screen from './Screen';\nimport Uri from 'metal-uri';\nimport UA from 'metal-useragent';\n\nclass RequestScreen extends Screen {\n\n\t/**\n\t * Request screen abstract class to perform io operations on descendant\n\t * screens.\n\t * @constructor\n\t * @extends {Screen}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t * @default true\n\t\t */\n\t\tthis.cacheable = true;\n\n\t\t/**\n\t\t * Holds default http headers to set on request.\n\t\t * @type {?Object=}\n\t\t * @default {\n\t\t * 'X-PJAX': 'true',\n\t\t * 'X-Requested-With': 'XMLHttpRequest'\n\t\t * }\n\t\t * @protected\n\t\t */\n\t\tthis.httpHeaders = {\n\t\t\t'X-PJAX': 'true',\n\t\t\t'X-Requested-With': 'XMLHttpRequest'\n\t\t};\n\n\t\t/**\n\t\t * Holds default http method to perform the request.\n\t\t * @type {!string}\n\t\t * @default RequestScreen.GET\n\t\t * @protected\n\t\t */\n\t\tthis.httpMethod = RequestScreen.GET;\n\n\t\t/**\n\t\t * Holds the XHR object responsible for the request.\n\t\t * @type {XMLHttpRequest}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.request = null;\n\n\t\t/**\n\t\t * Holds the request timeout in milliseconds.\n\t\t * @type {!number}\n\t\t * @default 30000\n\t\t * @protected\n\t\t */\n\t\tthis.timeout = 30000;\n\t}\n\n\t/**\n\t * Asserts that response status code is valid.\n\t * @param {number} status\n\t * @protected\n\t */\n\tassertValidResponseStatusCode(status) {\n\t\tif (!this.isValidResponseStatusCode(status)) {\n\t\t\tvar error = new Error(errors.INVALID_STATUS);\n\t\t\terror.invalidStatus = true;\n\t\t\terror.statusCode = status;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tbeforeUpdateHistoryPath(path) {\n\t\tvar redirectPath = this.getRequestPath();\n\t\tif (redirectPath && redirectPath !== path) {\n\t\t\treturn redirectPath;\n\t\t}\n\t\treturn path;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tbeforeUpdateHistoryState(state) {\n\t\t// If state is ours and navigate to post-without-redirect-get set\n\t\t// history state to null, that way Senna will reload the page on\n\t\t// popstate since it cannot predict post data.\n\t\tif (state.senna && state.form && state.redirectPath === state.path) {\n\t\t\treturn null;\n\t\t}\n\t\treturn state;\n\t}\n\n\t/**\n\t * Formats load path before invoking ajax call.\n\t * @param {string} path\n\t * @return {string} Formatted path;\n\t * @protected\n\t */\n\tformatLoadPath(path) {\n\t\tvar uri = new Uri(path);\n\n\t\turi.setHostname(globals.window.location.hostname);\n\t\turi.setProtocol(globals.window.location.protocol);\n\n\t\tif (globals.window.location.port) {\n\t\t\turi.setPort(globals.window.location.port);\n\t\t}\n\n\t\tif (UA.isIeOrEdge && this.httpMethod === RequestScreen.GET) {\n\t\t\treturn uri.makeUnique().toString();\n\t\t}\n\n\t\treturn uri.toString();\n\t}\n\n\t/**\n\t * Gets the http headers.\n\t * @return {?Object=}\n\t */\n\tgetHttpHeaders() {\n\t\treturn this.httpHeaders;\n\t}\n\n\t/**\n\t * Gets the http method.\n\t * @return {!string}\n\t */\n\tgetHttpMethod() {\n\t\treturn this.httpMethod;\n\t}\n\n\t/**\n\t * Gets request path.\n\t * @return {string=}\n\t */\n\tgetRequestPath() {\n\t\tvar request = this.getRequest();\n\t\tif (request) {\n\t\t\tvar requestPath = request.requestPath;\n\t\t\tvar responseUrl = this.maybeExtractResponseUrlFromRequest(request);\n\t\t\tif (responseUrl) {\n\t\t\t\trequestPath = responseUrl;\n\t\t\t}\n\t\t\tif (UA.isIeOrEdge && this.httpMethod === RequestScreen.GET) {\n\t\t\t\trequestPath = new Uri(requestPath).removeUnique().toString();\n\t\t\t}\n\t\t\treturn utils.getUrlPath(requestPath);\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets the request object.\n\t * @return {?Object}\n\t */\n\tgetRequest() {\n\t\treturn this.request;\n\t}\n\n\t/**\n\t * Gets the request timeout.\n\t * @return {!number}\n\t */\n\tgetTimeout() {\n\t\treturn this.timeout;\n\t}\n\n\t/**\n\t * Checks if response succeeded. Any status code 2xx or 3xx is considered\n\t * valid.\n\t * @param {number} statusCode\n\t */\n\tisValidResponseStatusCode(statusCode) {\n\t\treturn statusCode >= 200 && statusCode <= 399;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tload(path) {\n\t\tconst cache = this.getCache();\n\t\tif (isDefAndNotNull(cache)) {\n\t\t\treturn CancellablePromise.resolve(cache);\n\t\t}\n\t\tlet body = null;\n\t\tlet httpMethod = this.httpMethod;\n\t\tconst headers = new MultiMap();\n\t\tObject.keys(this.httpHeaders).forEach(header => headers.add(header, this.httpHeaders[header]));\n\t\tif (globals.capturedFormElement) {\n\t\t\tthis.addSafariXHRPolyfill();\n\t\t\tbody = new FormData(globals.capturedFormElement);\n\t\t\tthis.maybeAppendSubmitButtonValue_(body);\n\t\t\thttpMethod = RequestScreen.POST;\n\t\t\tif (UA.isIeOrEdge) {\n\t\t\t\theaders.add('If-None-Match', '\"0\"');\n\t\t\t}\n\t\t}\n\t\tconst requestPath = this.formatLoadPath(path);\n\t\treturn Ajax\n\t\t\t.request(requestPath, httpMethod, body, headers, null, this.timeout)\n\t\t\t.then(xhr => {\n\t\t\t\tthis.removeSafariXHRPolyfill();\n\t\t\t\tthis.setRequest(xhr);\n\t\t\t\tthis.assertValidResponseStatusCode(xhr.status);\n\t\t\t\tif (httpMethod === RequestScreen.GET && this.isCacheable()) {\n\t\t\t\t\tthis.addCache(xhr.responseText);\n\t\t\t\t}\n\t\t\t\txhr.requestPath = requestPath;\n\t\t\t\treturn xhr.responseText;\n\t\t\t})\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.removeSafariXHRPolyfill();\n\t\t\t\tswitch (reason.message) {\n\t\t\t\t\tcase errors.REQUEST_TIMEOUT:\n\t\t\t\t\t\treason.timeout = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase errors.REQUEST_ERROR:\n\t\t\t\t\t\treason.requestError = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase errors.REQUEST_PREMATURE_TERMINATION:\n\t\t\t\t\t\treason.requestError = true;\n\t\t\t\t\t\treason.requestPrematureTermination = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Adds aditional data to the body of the request in case a submit button\n\t * is captured during form submission.\n\t * @param {!FormData} body The FormData containing the request body.\n\t * @protected\n\t */\n\tmaybeAppendSubmitButtonValue_(body) {\n\t\tconst button = globals.capturedFormButtonElement;\n\t\tif (button && button.name) {\n\t\t\tbody.append(button.name, button.value);\n\t\t}\n\t}\n\n\t/**\n\t * The following method tries to extract the response url value by checking\n\t * the custom response header 'X-Request-URL' if proper value is not present\n\t * in XMLHttpRequest. The value of responseURL will be the final URL\n\t * obtained after any redirects. Internet Explorer, Edge and Safari <= 7\n\t * does not yet support the feature. For more information see:\n\t * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseURL\n\t * https://xhr.spec.whatwg.org/#the-responseurl-attribute\n\t * @param {XMLHttpRequest} request\n\t * @return {?string} Response url best match.\n\t */\n\tmaybeExtractResponseUrlFromRequest(request) {\n\t\tvar responseUrl = request.responseURL;\n\t\tif (responseUrl) {\n\t\t\treturn responseUrl;\n\t\t}\n\t\treturn request.getResponseHeader(RequestScreen.X_REQUEST_URL_HEADER);\n\t}\n\n\t/**\n\t * This function set attribute data-safari-temp-disabled to \n\t * true and set disable attribute of an input type=\"file\" tag\n\t * is used as a polyfill for iOS 11.3 Safari / macOS Safari 11.1 \n\t * empty XHR bug.\n\t * https://github.com/rails/rails/issues/32440\n\t * https://bugs.webkit.org/show_bug.cgi?id=184490\n\t */\n\taddSafariXHRPolyfill() {\n\t\tif (globals.capturedFormElement && UA.isSafari) {\n\t\t\tlet inputs = globals.capturedFormElement.querySelectorAll('input[type=\"file\"]:not([disabled])');\n\t\t\tfor (let index = 0; index < inputs.length; index++) {\n\t\t\t\tlet input = inputs[index];\n\t\t\t\tif (input.files.length > 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tinput.setAttribute('data-safari-temp-disabled', 'true');\n\t\t\t\tinput.setAttribute('disabled', '');\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * This function remove attribute data-safari-temp-disabled and disable attribute\n\t * of an input type=\"file\" tag is used as a polyfill for iOS 11.3 Safari / macOS Safari 11.1\n\t * empty XHR bug.\n\t * https://github.com/rails/rails/issues/32440\n\t * https://bugs.webkit.org/show_bug.cgi?id=184490\n\t */\n\tremoveSafariXHRPolyfill() {\n\t\tif (globals.capturedFormElement && UA.isSafari) {\n\t\t\tlet inputs = globals.capturedFormElement.querySelectorAll('input[type=\"file\"][data-safari-temp-disabled]');\n\t\t\tfor (let index = 0; index < inputs.length; index++) {\n\t\t\t\tconst input = inputs[index];\n\t\t\t\tinput.removeAttribute('data-safari-temp-disabled');\n\t\t\t\tinput.removeAttribute('disabled');\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sets the http headers.\n\t * @param {?Object=} httpHeaders\n\t */\n\tsetHttpHeaders(httpHeaders) {\n\t\tthis.httpHeaders = httpHeaders;\n\t}\n\n\t/**\n\t * Sets the http method.\n\t * @param {!string} httpMethod\n\t */\n\tsetHttpMethod(httpMethod) {\n\t\tthis.httpMethod = httpMethod.toLowerCase();\n\t}\n\n\t/**\n\t * Sets the request object.\n\t * @param {?Object} request\n\t */\n\tsetRequest(request) {\n\t\tthis.request = request;\n\t}\n\n\t/**\n\t * Sets the request timeout in milliseconds.\n\t * @param {!number} timeout\n\t */\n\tsetTimeout(timeout) {\n\t\tthis.timeout = timeout;\n\t}\n\n}\n\n/**\n * Holds value for method get.\n * @type {string}\n * @default 'get'\n * @static\n */\nRequestScreen.GET = 'get';\n\n/**\n * Holds value for method post.\n * @type {string}\n * @default 'post'\n * @static\n */\nRequestScreen.POST = 'post';\n\n/**\n * Fallback http header to retrieve response request url.\n * @type {string}\n * @default 'X-Request-URL'\n * @static\n */\nRequestScreen.X_REQUEST_URL_HEADER = 'X-Request-URL';\n\nexport default RequestScreen;\n","'use strict';\n\nimport { getUid } from 'metal';\nimport { buildFragment, globalEval, globalEvalStyles, match } from 'metal-dom';\nimport CancellablePromise from 'metal-promise';\nimport globals from '../globals/globals';\nimport RequestScreen from './RequestScreen';\nimport Surface from '../surface/Surface';\nimport UA from 'metal-useragent';\nimport Uri from 'metal-uri';\nimport utils from '../utils/utils';\n\nclass HtmlScreen extends RequestScreen {\n\n\t/**\n\t * Screen class that perform a request and extracts surface contents from\n\t * the response content.\n\t * @constructor\n\t * @extends {RequestScreen}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the meta selector. Relevant to extract meta tags\n\t\t * elements from request fragments to use as the screen.\n\t\t * @type {!string}\n\t\t * @default meta\n\t\t * @protected\n\t\t */\n\t\tthis.metaTagsSelector = 'meta';\n\n\t\t/**\n\t\t * Holds the title selector. Relevant to extract the </code>\n\t\t * element from request fragments to use as the screen title.\n\t\t * @type {!string}\n\t\t * @default title\n\t\t * @protected\n\t\t */\n\t\tthis.titleSelector = 'title';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tactivate() {\n\t\tsuper.activate();\n\t\tthis.releaseVirtualDocument();\n\t\tthis.pendingStyles = null;\n\t}\n\n\t/**\n\t * Allocates virtual document for content. After allocated virtual document\n\t * can be accessed by <code>this.virtualDocument</code>.\n\t * @param {!string} htmlString\n\t */\n\tallocateVirtualDocumentForContent(htmlString) {\n\t\tif (!this.virtualDocument) {\n\t\t\tthis.virtualDocument = globals.document.createElement('html');\n\t\t}\n\n\t\tthis.copyNodeAttributesFromContent_(htmlString, this.virtualDocument);\n\n\t\tthis.virtualDocument.innerHTML = htmlString;\n\t}\n\n\t/**\n\t * Customizes logic to append styles into document. Relevant to when\n\t * tracking a style by id make sure to re-positions the new style in the\n\t * same dom order.\n\t * @param {Element} newStyle\n\t */\n\tappendStyleIntoDocument_(newStyle) {\n\t\tvar isTemporaryStyle = match(newStyle, HtmlScreen.selectors.stylesTemporary);\n\t\tif (isTemporaryStyle) {\n\t\t\tthis.pendingStyles.push(newStyle);\n\t\t}\n\t\tif (newStyle.id) {\n\t\t\tvar styleInDoc = globals.document.getElementById(newStyle.id);\n\t\t\tif (styleInDoc) {\n\t\t\t\tstyleInDoc.parentNode.insertBefore(newStyle, styleInDoc.nextSibling);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tglobals.document.head.appendChild(newStyle);\n\t}\n\n\t/**\n\t * If body is used as surface forces the requested documents to have same id\n\t * of the initial page.\n\t */\n\tassertSameBodyIdInVirtualDocument() {\n\t\tvar bodySurface = this.virtualDocument.querySelector('body');\n\t\tif (!globals.document.body.id) {\n\t\t\tglobals.document.body.id = 'senna_surface_' + getUid();\n\t\t}\n\t\tif (bodySurface) {\n\t\t\tbodySurface.id = globals.document.body.id;\n\t\t}\n\t}\n\n\t/**\n\t * Copies attributes from the <html> tag of content to the given node.\n\t */\n\tcopyNodeAttributesFromContent_(content, node) {\n\t\tcontent = content.replace(/[<]\\s*html/ig, '<senna');\n\t\tcontent = content.replace(/\\/html\\s*\\>/ig, '/senna>');\n\t\tlet placeholder;\n\t\tif (UA.isIe) {\n\t\t\tconst tempNode = globals.document.createRange().createContextualFragment(content);\n\t\t\tplaceholder = tempNode.querySelector('senna');\n\t\t} else {\n\t\t\tnode.innerHTML = content;\n\t\t\tplaceholder = node.querySelector('senna');\n\t\t}\n\n\t\tif (placeholder) {\n\t\t\tutils.clearNodeAttributes(node);\n\t\t\tutils.copyNodeAttributes(placeholder, node);\n\t\t}\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tdisposeInternal() {\n\t\tthis.disposePendingStyles();\n\t\tsuper.disposeInternal();\n\t}\n\n\t/**\n\t * Disposes pending styles if screen get disposed prior to its loading.\n\t */\n\tdisposePendingStyles() {\n\t\tif (this.pendingStyles) {\n\t\t\tutils.removeElementsFromDocument(this.pendingStyles);\n\t\t}\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tevaluateScripts(surfaces) {\n\t\tvar evaluateTrackedScripts = this.evaluateTrackedResources_(\n\t\t\tglobalEval.runScriptsInElement, HtmlScreen.selectors.scripts,\n\t\t\tHtmlScreen.selectors.scriptsTemporary, HtmlScreen.selectors.scriptsPermanent);\n\n\t\treturn evaluateTrackedScripts.then(() => super.evaluateScripts(surfaces));\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tevaluateStyles(surfaces) {\n\t\tthis.pendingStyles = [];\n\t\tvar evaluateTrackedStyles = this.evaluateTrackedResources_(\n\t\t\tglobalEvalStyles.runStylesInElement, HtmlScreen.selectors.styles,\n\t\t\tHtmlScreen.selectors.stylesTemporary, HtmlScreen.selectors.stylesPermanent,\n\t\t\tthis.appendStyleIntoDocument_.bind(this));\n\n\t\treturn evaluateTrackedStyles.then(() => super.evaluateStyles(surfaces));\n\t}\n\n\t/**\n\t * Allows a screen to evaluate the favicon style before the screen becomes visible.\n\t * @return {CancellablePromise}\n\t */\n\tevaluateFavicon_() {\n\t\tconst resourcesInVirtual = this.virtualQuerySelectorAll_(HtmlScreen.selectors.favicon);\n\t\tconst resourcesInDocument = this.querySelectorAll_(HtmlScreen.selectors.favicon);\n\n\t\treturn new CancellablePromise((resolve) => {\n\t\t\tutils.removeElementsFromDocument(resourcesInDocument);\n\t\t\tthis.runFaviconInElement_(resourcesInVirtual).then(() => resolve());\n\t\t});\n\t}\n\n\t/**\n\t * Evaluates tracked resources inside incoming fragment and remove existing\n\t * temporary resources.\n\t * @param {?function()} appendFn Function to append the node into document.\n\t * @param {!string} selector Selector used to find resources to track.\n\t * @param {!string} selectorTemporary Selector used to find temporary\n\t * resources to track.\n\t * @param {!string} selectorPermanent Selector used to find permanent\n\t * resources to track.\n\t * @param {!function} opt_appendResourceFn Optional function used to\n\t * evaluate fragment containing resources.\n\t * @return {CancellablePromise} Deferred that waits resources evaluation to\n\t * complete.\n\t * @private\n\t */\n\tevaluateTrackedResources_(evaluatorFn, selector, selectorTemporary, selectorPermanent, opt_appendResourceFn) {\n\t\tvar tracked = this.virtualQuerySelectorAll_(selector);\n\t\tvar temporariesInDoc = this.querySelectorAll_(selectorTemporary);\n\t\tvar permanentsInDoc = this.querySelectorAll_(selectorPermanent);\n\n\t\t// Adds permanent resources in document to cache.\n\t\tpermanentsInDoc.forEach((resource) => {\n\t\t\tvar resourceKey = this.getResourceKey_(resource);\n\t\t\tif (resourceKey) {\n\t\t\t\tHtmlScreen.permanentResourcesInDoc[resourceKey] = true;\n\t\t\t}\n\t\t});\n\n\t\tvar frag = buildFragment();\n\t\ttracked.forEach((resource) => {\n\t\t\tvar resourceKey = this.getResourceKey_(resource);\n\t\t\t// Do not load permanent resources if already in document.\n\t\t\tif (!HtmlScreen.permanentResourcesInDoc[resourceKey]) {\n\t\t\t\tfrag.appendChild(resource);\n\t\t\t}\n\t\t\t// If resource has key and is permanent add to cache.\n\t\t\tif (resourceKey && match(resource, selectorPermanent)) {\n\t\t\t\tHtmlScreen.permanentResourcesInDoc[resourceKey] = true;\n\t\t\t}\n\t\t});\n\n\t\treturn new CancellablePromise((resolve) => {\n\t\t\tevaluatorFn(frag, () => {\n\t\t\t\tutils.removeElementsFromDocument(temporariesInDoc);\n\t\t\t\tresolve();\n\t\t\t}, opt_appendResourceFn);\n\t\t});\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tflip(surfaces) {\n\t\treturn super.flip(surfaces).then(() => {\n\t\t\tutils.clearNodeAttributes(globals.document.documentElement);\n\t\t\tutils.copyNodeAttributes(this.virtualDocument, globals.document.documentElement);\n\t\t\tthis.evaluateFavicon_();\n\t\t\tthis.updateMetaTags_();\n\t\t});\n\t}\n\n\tupdateMetaTags_() {\n\t\tconst currentMetaNodes = this.querySelectorAll_('meta');\n\t\tconst metasFromVirtualDocument = this.metas;\n\t\tif (currentMetaNodes) {\n\t\t\tutils.removeElementsFromDocument(currentMetaNodes);\n\t\t\tif (metasFromVirtualDocument) {\n\t\t\t\tmetasFromVirtualDocument.forEach((meta) => globals.document.head.appendChild(meta));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Extracts a key to identify the resource based on its attributes.\n\t * @param {Element} resource\n\t * @return {string} Extracted key based on resource attributes in order of\n\t * preference: id, href, src.\n\t */\n\tgetResourceKey_(resource) {\n\t\treturn resource.id || resource.href || resource.src || '';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tgetSurfaceContent(surfaceId) {\n\t\tvar surface = this.virtualDocument.querySelector('#' + surfaceId);\n\t\tif (surface) {\n\t\t\tvar defaultChild = surface.querySelector('#' + surfaceId + '-' + Surface.DEFAULT);\n\t\t\tif (defaultChild) {\n\t\t\t\treturn defaultChild.innerHTML;\n\t\t\t}\n\t\t\treturn surface.innerHTML; // If default content not found, use surface content\n\t\t}\n\t}\n\n\t/**\n\t * Gets the title selector.\n\t * @return {!string}\n\t */\n\tgetTitleSelector() {\n\t\treturn this.titleSelector;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tload(path) {\n\t\treturn super.load(path)\n\t\t\t.then(content => {\n\t\t\t\tthis.allocateVirtualDocumentForContent(content);\n\t\t\t\tthis.resolveTitleFromVirtualDocument();\n\t\t\t\tthis.resolveMetaTagsFromVirtualDocument();\n\t\t\t\tthis.assertSameBodyIdInVirtualDocument();\n\t\t\t\tif (UA.isIe) {\n\t\t\t\t\tthis.makeTemporaryStylesHrefsUnique_();\n\t\t\t\t}\n\t\t\t\treturn content;\n\t\t\t});\n\t}\n\n\t/**\n\t * Queries temporary styles from virtual document, and makes them unique.\n\t * This is necessary for caching and load event firing issues specific to\n\t * IE11. https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7940171/\n\t */\n\tmakeTemporaryStylesHrefsUnique_() {\n\t\tvar temporariesInDoc = this.virtualQuerySelectorAll_(HtmlScreen.selectors.stylesTemporary);\n\t\ttemporariesInDoc.forEach((style) => this.replaceStyleAndMakeUnique_(style));\n\t}\n\n\t/**\n\t * Creates a new element from given, copies attributes, mutates href to be\n\t * unique to prevent caching and more than one load/error event from firing.\n\t */\n\treplaceStyleAndMakeUnique_(style) {\n\t\tif (style.href) {\n\t\t\tvar newStyle = globals.document.createElement(style.tagName);\n\t\t\tstyle.href = new Uri(style.href).makeUnique().toString();\n\t\t\tutils.copyNodeAttributes(style, newStyle);\n\t\t\tstyle.parentNode.replaceChild(newStyle, style);\n\t\t\tstyle.disabled = true;\n\t\t}\n\t}\n\n\t/**\n\t * Adds the favicon elements to the document.\n\t * @param {!Array<Element>} elements\n\t * @private\n\t * @return {CancellablePromise}\n\t */\n\trunFaviconInElement_(elements) {\n\t\treturn new CancellablePromise((resolve) => {\n\t\t\telements.forEach((element) => document.head.appendChild(\n\t\t\t\tUA.isIe ? element : utils.setElementWithRandomHref(element)\n\t\t\t));\n\t\t\tresolve();\n\t\t});\n\t}\n\n\t/**\n\t * Queries elements from virtual document and returns an array of elements.\n\t * @param {!string} selector\n\t * @return {array.<Element>}\n\t */\n\tvirtualQuerySelectorAll_(selector) {\n\t\treturn Array.prototype.slice.call(this.virtualDocument.querySelectorAll(selector));\n\t}\n\n\t/**\n\t * Queries elements from document and returns an array of elements.\n\t * @param {!string} selector\n\t * @return {array.<Element>}\n\t */\n\tquerySelectorAll_(selector) {\n\t\treturn Array.prototype.slice.call(globals.document.querySelectorAll(selector));\n\t}\n\n\t/**\n\t * Releases virtual document allocated for content.\n\t */\n\treleaseVirtualDocument() {\n\t\tthis.virtualDocument = null;\n\t}\n\n\t/**\n\t * Resolves title from allocated virtual document.\n\t */\n\tresolveTitleFromVirtualDocument() {\n\t\tconst title = this.virtualDocument.querySelector(this.titleSelector);\n\t\tif (title) {\n\t\t\tthis.setTitle(title.textContent.trim());\n\t\t}\n\t}\n\n\tresolveMetaTagsFromVirtualDocument() {\n\t\tconst metas = this.virtualQuerySelectorAll_(this.metaTagsSelector);\n\t\tif (metas) {\n\t\t\tthis.setMetas(metas);\n\t\t}\n\t}\n\n\t/**\n\t * Sets the title selector.\n\t * @param {!string} titleSelector\n\t */\n\tsetTitleSelector(titleSelector) {\n\t\tthis.titleSelector = titleSelector;\n\t}\n\n}\n\n/**\n * Helper selector for ignore favicon when exist data-senna-track.\n */\nconst ignoreFavicon = ':not([rel=\"Shortcut Icon\"]):not([rel=\"shortcut icon\"]):not([rel=\"icon\"]):not([href$=\"favicon.icon\"])';\n\n/**\n * Helper selectors for tracking resources.\n * @type {object}\n * @protected\n * @static\n */\nHtmlScreen.selectors = {\n\tfavicon: 'link[rel=\"Shortcut Icon\"],link[rel=\"shortcut icon\"],link[rel=\"icon\"],link[href$=\"favicon.icon\"]',\n\tscripts: 'script[data-senna-track]',\n\tscriptsPermanent: 'script[data-senna-track=\"permanent\"]',\n\tscriptsTemporary: 'script[data-senna-track=\"temporary\"]',\n\tstyles: `style[data-senna-track],link[data-senna-track]${ignoreFavicon}`,\n\tstylesPermanent: `style[data-senna-track=\"permanent\"],link[data-senna-track=\"permanent\"]${ignoreFavicon}`,\n\tstylesTemporary: `style[data-senna-track=\"temporary\"],link[data-senna-track=\"temporary\"]${ignoreFavicon}`\n};\n\n/**\n * Caches permanent resource keys.\n * @type {object}\n * @protected\n * @static\n */\nHtmlScreen.permanentResourcesInDoc = {};\n\nexport default HtmlScreen;\n","'use strict';\n\nimport { Disposable, getUid, isDefAndNotNull, isElement, object } from 'metal';\nimport dataAttributes from './dataAttributes';\nimport globals from '../globals/globals';\nimport App from './App';\nimport HtmlScreen from '../screen/HtmlScreen';\nimport Route from '../route/Route';\n\nclass AppDataAttributeHandler extends Disposable {\n\n\t/**\n\t * Initilizes App, register surfaces and routes from data attributes.\n\t * @constructor\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the app reference initialized by data attributes.\n\t\t * @type {App}\n\t\t * @default null\n\t\t */\n\t\tthis.app = null;\n\n\t\t/**\n\t\t * Holds the base element to search initialization data attributes. This\n\t\t * element is the container used to enable initialization based on the\n\t\t * presence of `data-senna` attribute.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t */\n\t\tthis.baseElement = null;\n\t}\n\n\t/**\n\t * Inits application based on information scanned from document.\n\t */\n\thandle() {\n\t\tif (!isElement(this.baseElement)) {\n\t\t\tthrow new Error('Senna data attribute handler base element ' +\n\t\t\t\t'not set or invalid, try setting a valid element that ' +\n\t\t\t\t'contains a `data-senna` attribute.');\n\t\t}\n\n\t\tif (!this.baseElement.hasAttribute(dataAttributes.senna)) {\n\t\t\tconsole.log('Senna was not initialized from data attributes. ' +\n\t\t\t\t'In order to enable its usage from data attributes try setting ' +\n\t\t\t\t'in the base element, e.g. `<body data-senna>`.');\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.app) {\n\t\t\tthrow new Error('Senna app was already initialized.');\n\t\t}\n\n\t\tconsole.log('Senna initialized from data attribute.');\n\n\t\tthis.app = new App();\n\t\tthis.maybeAddRoutes_();\n\t\tthis.maybeAddSurfaces_();\n\t\tthis.maybeSetBasePath_();\n\t\tthis.maybeSetLinkSelector_();\n\t\tthis.maybeSetLoadingCssClass_();\n\t\tthis.maybeSetUpdateScrollPosition_();\n\t\tthis.maybeDispatch_();\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tif (this.app) {\n\t\t\tthis.app.dispose();\n\t\t}\n\t}\n\n\t/**\n\t * Gets the app reference.\n\t * @return {App}\n\t */\n\tgetApp() {\n\t\treturn this.app;\n\t}\n\n\t/**\n\t * Gets the base element.\n\t * @return {Element} baseElement\n\t */\n\tgetBaseElement() {\n\t\treturn this.baseElement;\n\t}\n\n\t/**\n\t * Maybe adds app routes from link elements that are `senna-route`.\n\t */\n\tmaybeAddRoutes_() {\n\t\tvar routesSelector = 'link[rel=\"senna-route\"]';\n\t\tthis.querySelectorAllAsArray_(routesSelector).forEach((link) => this.maybeParseLinkRoute_(link));\n\t\tif (!this.app.hasRoutes()) {\n\t\t\tthis.app.addRoutes(new Route(/.*/, HtmlScreen));\n\t\t\tconsole.log('Senna can\\'t find route elements, adding default.');\n\t\t}\n\t}\n\n\t/**\n\t * Maybe adds app surfaces by scanning `data-senna-surface` data attribute.\n\t */\n\tmaybeAddSurfaces_() {\n\t\tvar surfacesSelector = '[' + dataAttributes.surface + ']';\n\t\tthis.querySelectorAllAsArray_(surfacesSelector).forEach((surfaceElement) => {\n\t\t\tthis.updateElementIdIfSpecialSurface_(surfaceElement);\n\t\t\tthis.app.addSurfaces(surfaceElement.id);\n\t\t});\n\t}\n\n\t/**\n\t * Dispatches app navigation to the current path when initializes.\n\t */\n\tmaybeDispatch_() {\n\t\tif (this.baseElement.hasAttribute(dataAttributes.dispatch)) {\n\t\t\tthis.app.dispatch();\n\t\t}\n\t}\n\n\t/**\n\t * Adds app route by parsing valid link elements. A valid link element is of\n\t * the kind `rel=\"senna-route\"`.\n\t * @param {Element} link\n\t */\n\tmaybeParseLinkRoute_(link) {\n\t\tvar route = new Route(this.maybeParseLinkRoutePath_(link), this.maybeParseLinkRouteHandler_(link));\n\t\tthis.app.addRoutes(route);\n\t\tconsole.log('Senna scanned route ' + route.getPath());\n\t}\n\n\t/**\n\t * Maybe parse link route handler.\n\t * @param {Element} link\n\t * @return {?string}\n\t */\n\tmaybeParseLinkRouteHandler_(link) {\n\t\tvar handler = link.getAttribute('type');\n\t\tif (isDefAndNotNull(handler)) {\n\t\t\thandler = object.getObjectByName(handler);\n\t\t}\n\t\treturn handler;\n\t}\n\n\t/**\n\t * Maybe parse link route path.\n\t * @param {Element} link\n\t * @return {?string}\n\t */\n\tmaybeParseLinkRoutePath_(link) {\n\t\tvar path = link.getAttribute('href');\n\t\tif (isDefAndNotNull(path)) {\n\t\t\tif (path.indexOf('regex:') === 0) {\n\t\t\t\tpath = new RegExp(path.substring(6));\n\t\t\t}\n\t\t}\n\t\treturn path;\n\t}\n\n\t/**\n\t * Maybe sets app base path from `data-senna-base-path` data attribute.\n\t */\n\tmaybeSetBasePath_() {\n\t\tvar basePath = this.baseElement.getAttribute(dataAttributes.basePath);\n\t\tif (isDefAndNotNull(basePath)) {\n\t\t\tthis.app.setBasePath(basePath);\n\t\t\tconsole.log('Senna scanned base path ' + basePath);\n\t\t}\n\t}\n\n\t/**\n\t * Maybe sets app link selector from `data-senna-link-selector` data\n\t * attribute.\n\t */\n\tmaybeSetLinkSelector_() {\n\t\tvar linkSelector = this.baseElement.getAttribute(dataAttributes.linkSelector);\n\t\tif (isDefAndNotNull(linkSelector)) {\n\t\t\tthis.app.setLinkSelector(linkSelector);\n\t\t\tconsole.log('Senna scanned link selector ' + linkSelector);\n\t\t}\n\t}\n\n\t/**\n\t * Maybe sets app link loading css class from `data-senna-loading-css-class`\n\t * data attribute.\n\t */\n\tmaybeSetLoadingCssClass_() {\n\t\tvar loadingCssClass = this.baseElement.getAttribute(dataAttributes.loadingCssClass);\n\t\tif (isDefAndNotNull(loadingCssClass)) {\n\t\t\tthis.app.setLoadingCssClass(loadingCssClass);\n\t\t\tconsole.log('Senna scanned loading css class ' + loadingCssClass);\n\t\t}\n\t}\n\n\t/**\n\t * Maybe sets app update scroll position from\n\t * `data-senna-update-scroll-position` data attribute.\n\t */\n\tmaybeSetUpdateScrollPosition_() {\n\t\tvar updateScrollPosition = this.baseElement.getAttribute(dataAttributes.updateScrollPosition);\n\t\tif (isDefAndNotNull(updateScrollPosition)) {\n\t\t\tif (updateScrollPosition === 'false') {\n\t\t\t\tthis.app.setUpdateScrollPosition(false);\n\t\t\t} else {\n\t\t\t\tthis.app.setUpdateScrollPosition(true);\n\t\t\t}\n\t\t\tconsole.log('Senna scanned update scroll position ' + updateScrollPosition);\n\t\t}\n\t}\n\n\t/**\n\t * Queries elements from document and returns an array of elements.\n\t * @param {!string} selector\n\t * @return {array.<Element>}\n\t */\n\tquerySelectorAllAsArray_(selector) {\n\t\treturn Array.prototype.slice.call(globals.document.querySelectorAll(selector));\n\t}\n\n\t/**\n\t * Updates element id if handled as special surface element. Some surfaces\n\t * are slightly different from others, like when threating <code>body</code>\n\t * as surface.\n\t * @param {Element} element\n\t */\n\tupdateElementIdIfSpecialSurface_(element) {\n\t\tif (!element.id && element === globals.document.body) {\n\t\t\telement.id = 'senna_surface_' + getUid();\n\t\t}\n\t}\n\n\t/**\n\t * Sets the base element.\n\t * @param {Element} baseElement\n\t */\n\tsetBaseElement(baseElement) {\n\t\tthis.baseElement = baseElement;\n\t}\n\n}\n\nexport default AppDataAttributeHandler;\n","'use strict';\n\nimport globals from '../globals/globals';\nimport AppDataAttributeHandler from './AppDataAttributeHandler';\n\n/**\n * Data attribute handler.\n * @type {AppDataAttributeHandler}\n */\nvar dataAttributeHandler = new AppDataAttributeHandler();\n\nglobals.document.addEventListener('DOMContentLoaded', function() {\n\tdataAttributeHandler.setBaseElement(globals.document.body);\n\tdataAttributeHandler.handle();\n});\n\nexport default dataAttributeHandler;","/**\n * @returns String containing the current senna version\n */\n\nconst version = '<%= version %>';\n\nexport default version;"],"names":["compatibilityModeData_","uniqueIdCounter_","UID_PROPERTY","Math","random","abstractMethod","Error","disableCompatibilityMode","undefined","enableCompatibilityMode","data","getCompatibilityModeData","window","__METAL_COMPATIBILITY__","getFirstTruthy_","a","b","getFunctionName","fn","name","str","toString","substring","indexOf","getStaticProperty","ctor","propertyName","mergeFn","mergedName","hasOwnProperty","merged","__proto__","isPrototypeOf","Function","getUid","object","noInheritance","id","identityFunction","returnValue","isBoolean","val","isDef","isDefAndNotNull","isNull","isDocument","nodeType","isDocumentFragment","isElement","isFunction","isNumber","isWindow","isObject","type","isPromise","then","isString","String","isServerSide","options","checkEnv","serverSide","process","browser","env","NODE_ENV","nullFunction","array","arr1","arr2","length","i","arr","output","Array","isArray","flatten","push","obj","rv","removeAt","prototype","splice","call","start","end","sliced","async","throwException","exception","nextTick","run","callback","context","workQueueScheduled_","processWorkQueue","workQueue_","WorkItem_","workItems","workItem","scope","e","cb","bind","wrapCallback_","setImmediate_","setImmediate","getSetImmediateEmulator_","Channel","MessageChannel","postMessage","addEventListener","iframe","document","createElement","style","display","src","title","documentElement","appendChild","win","contentWindow","doc","open","write","close","message","origin","location","protocol","host","onmessage","port1","port2","channel","head","tail","next","script","onreadystatechange","parentNode","removeChild","Disposable","disposed_","disposeInternal","target","key","source","args","parts","split","reduce","part","mappedObj","keys","Object","obj1","obj2","keys1","keys2","string","str1","str2","test1","toLowerCase","test2","replace","x","floor","abs","Date","now","hash","len","charCodeAt","value","METAL_DATA","domData","element","initialValue","EventHandle","emitter","event","listener","emitter_","event_","listener_","removeListener","isDisposed","singleArray_","EventEmitter","events_","listenerHandlers_","shouldUseFacade_","holder","handler","defaultListener","validateListener_","events","toEventsArray_","addSingleListener_","runListenerHandlers_","addHandler_","getShouldUseFacade","facade","preventedDefault","listeners","getRawListeners_","slice","arguments","runListeners_","buildFacade_","directListeners","toArray","concat","map","amount","many_","self","handlerInternal","apply","listenerObj","removeMatchingListenerObjs_","addListener","many","listenerObjs","finalListeners","matchesListener_","off","handlers","defaultListeners","default","j","shouldUseFacade","TypeError","EventEmitterProxy","originEmitter","targetEmitter","blacklist","whitelist","blacklist_","originEmitter_","pendingEvents_","proxiedEvents_","targetEmitter_","whitelist_","startProxy_","on","removeListeners_","emit","shouldProxyEvent_","tryToAddListener_","forEach","proxyEvent","onListener","addListener_","emitOnTarget_","EventHandler","eventHandles_","DomDelegatedEventHandle","selector","selector_","delegating","get","selectors","remove","DomEventHandle","capture","capture_","removeEventListener","elementsByTag_","supportCache_","customEvents","LAST_CONTAINER","USE_CAPTURE","addClasses","elements","classes","addClassesWithNative_","className","classList","add","addClassesWithoutNative_","elementClassName","classesToAppend","addElementListener_","eventName","addSelectorListener_","delegatingData","addToArr_","attachDelegateEvent_","handleDelegateEvent_","closest","match","append","parent","child","buildFragment","isNodeListLike","childArr","htmlString","tempDiv","innerHTML","firstChild","fragment","createDocumentFragment","contains","element1","element2","delegate","selectorOrTarget","customConfig","originalEvent","defaultListener_","isAbleToInteractWith_","node","eventObj","button","matchesSelector","tagName","disabled","item","exitDocument","ret","container","currentTarget","defFns","triggerDelegatedListeners_","triggerDefaultDelegatedListeners_","delegateTarget","p","Element","m","matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","matchFallback_","nodes","querySelectorAll","normalizeDelegateEvent_","stopPropagation","stopPropagation_","stopImmediatePropagation","stopImmediatePropagation_","once","domEventHandle","registerCustomEvent","removeChildren","removeClasses","removeClassesWithNative_","removeClassesWithoutNative_","trim","stopped","stoppedImmediate","supportsEvent","tag","defaultPrevented","defaultFns","currElement","limit","triggerElementListeners_","triggerSelectorListeners_","lastContainer","triggerListeners_","DomEventEmitterProxy","isDelegateEvent_","index","substr","babelHelpers.get","isSupportedDomEvent_","features","animationEventName_","checkAnimationEventName_","prefixes","typeTitleCase","replaceInterval","toUpperCase","suffixes","animationElement_","attrOrderChange_","originalContent","globalEval","text","appendFn","defaultFn","runFile","scripts","runScriptsInOrder","runScript","globalEvalStyles","href","link","rel","runStyle","styles","loadCount","registerEvents","mouseEventMap","related","relatedTarget","customType","animationEventMap","eventType","checkAnimationEventName","globals","parseFromAnchor","opt_uri","test","hostname","password","pathname","port","search","username","parse","URL","url","create","MultiMap","values","size","names","JSON","stringify","set","TreeNode","value_","parent_","children_","setParent","current","getParent","ancestors","getChildren","EMPTY_ARRAY","depth","root","getChildCount","opt_preorderFn","opt_postorderFn","traverse","assertChildHasNoParent","parseFn_","Uri","maybeAddProtocolAndHostname_","multimap","getAll","addParameterValue","ensureQueryInitialized_","query","param","urlDecode","getHostname","getPort","HOSTNAME_PLACEHOLDER","getHost","getProtocol","querystring","getParameterNames","getParameterValues","encodeURIComponent","setParameterValue","RANDOM_PARAM","getRandomString","DEFAULT_PROTOCOL","charAt","removeParameter","getPathname","getSearch","getHash","parseFn","basePath","paths","path","join","decodeURIComponent","isSecure","utils","attributes","attribute","setAttribute","getCurrentBrowserPathWithoutHash","offsetLeft","offsetTop","offsetParent","uri","currentBrowserPath","getUrlPathWithoutHash","getUrlPath","history","pushState","err","error","removeAttribute","referrer","defineProperty","Thenable","IMPLEMENTED_BY_PROP","addImplementation","$goog_Thenable","isImplementedBy","partial","newArgs","CancellablePromise","resolver","opt_context","state_","State_","PENDING","result_","callbackEntries_","executing_","UNHANDLED_REJECTION_DELAY","unhandledRejectionId_","hadUnhandledRejection_","resolve_","FULFILLED","reason","REJECTED","CallbackEntry_","resolve","opt_value","reject","opt_reason","race","promises","promise","all","toFulfill","onFulfill","onReject","firstFulfilled","toReject","reasons","opt_onFulfilled","opt_onRejected","addChildPromise_","thenAlways","onResolved","handleRejection_","addCallbackEntry_","thenCatch","onRejected","catch","cancel","opt_message","CancellationError","IS_CANCELLATION_ERROR","cancelInternal_","cancelChild_","childPromise","childCount","childIndex","entry","callbackEntry","executeCallback_","scheduleCallbacks_","onFulfilled","result","unblockAndFulfill_","BLOCKED","unblockAndReject_","state","tryThen_","addUnhandledRejection_","thenable","called","executeCallbacks_","entries","removeUnhandledRejection_","setTimeout","setUnhandledRejectionHandler","debounce","delay","debounced","cancelDebounce","REGEX","convertMatchesToObj","convertTokensToRegex","tokens","regex","core","escape","encloseNonCapturingGroup","pattern","repeat","prefix","optional","RegExp","makeTrailingSlashOptional","routeOrTokens","route","unnamedCount","currPath","exec","paramPattern","unnamedPattern","modifier","toRegex","extractData","paramIndex","Route","parsedData_","buildParsedData_","Cacheable","cache","cacheable","content","clearCache","Screen","makeId_","metas","log","surfaces","sId","activeChild","runScriptsInElement","transitions","surface","deferred","show","Surface","defaultChild","transitionFn","getChild","DEFAULT","maybeWrapContentAsDefault_","screenId","opt_content","createChild","transition","getElement","getElementById","addContent","from","to","defaultTransition","NavigationStrategy","App","activeScreen","activePath","allowPreventNavigate","browserPathBeforeNavigate","captureScrollPositionFromScrollEvent","defaultTitle","formSelector","ignoreQueryStringFromRoutePath","linkSelector","loadingCssClass","nativeScrollRestorationSupported","navigationStrategy","IMMEDIATE","isNavigationPending","pendingNavigate","popstateScrollLeft","popstateScrollTop","redirectPath","routes","scheduledNavigationQueue","screens","skipLoadPopstate","updateScrollPosition","appEventHandlers_","onScroll_","onLoad_","onPopstate_","onStartNavigate_","onBeforeNavigate_","onBeforeNavigateDefault_","onBeforeUnloadDefault_","setLinkSelector","setFormSelector","maybeOverloadBeforeUnload_","getId","isWebUri","isLinkSameOrigin_","isSameBasePath_","isCurrentBrowserPath","findRoute","removeScreen","screen","getHandler","clearScreensCache","formEventHandler_","linkEventHandler_","removeAllListeners","navigate","getCurrentBrowserPath","opt_replaceHistory","stopPendingNavigate_","nextScreen","createScreenInstance","maybePreventDeactivate_","maybePreventActivate_","load","SCHEDULE_LAST","deactivate","prepareNavigateHistory_","prepareNavigateSurfaces_","extractParams","evaluateStyles","flip","evaluateScripts","maybeUpdateScrollPositionState_","syncScrollPositionSyncThenAsync_","finalizeNavigate_","handleNavigateError_","scheduledNavigation","shift","maybeNavigate_","getRoutePath","activate","isCacheable","capturedFormElement","capturedFormButtonElement","matchesPath","getIgnoreQueryStringFromRoutePath","getUrlPathWithoutHashAndSearch","stack","hostUri","locationHostUri","winner","switchScrollPositionRace","scrollTo","scrollLeft","scrollTop","nativeScrollRestoration_","scrollRestoration","mixin","canNavigate","isNavigationScheduled","maybeScheduleNavigation_","preventDefault","navigateFailed","isScheduledNavigation","onbeforeunload","_onbeforeunload","_overloaded","beforeActivate","prevent","beforeDeactivate","anchorElement","getNodeOffset","saveHistoryCurrentPageScrollPosition_","opt_event","isHtml5HistorySupported","form","replaceHistory","func","altKey","ctrlKey","metaKey","shiftKey","method","buttonSelector","activeElement","querySelector","action","maybeRepositionScrollToHashedAnchor","reloadPage","senna","lockHistoryScrollPosition_","setReferrer","setHostname","setPort","pageYOffset","pageXOffset","maybeDisableNativeScrollRestoration","endNavigatePayload","doNavigate_","maybeRestoreNativeScrollRestoration","getTitle","getDefaultTitle","beforeUpdateHistoryPath","historyState","maybeRestoreRedirectPathHash_","updateHistory_","beforeUpdateHistoryState","params","surfaceContent","getSurfaceContent","reload","surfaceId","dispose","replaceState","removePathTrailingSlash","onDocSubmitDelegate_","onDocClickDelegate_","sync","titleNode","Ajax","allHeaders","headers","pairs","body","opt_headers","opt_params","opt_timeout","opt_sync","opt_withCredentials","request","XMLHttpRequest","previousReadyState","Promise","onload","aborted","onerror","readyState","terminatedPrematurely","abort","timeout","addParametersFromMultiMap","withCredentials","setRequestHeader","send","errors","INVALID_STATUS","REQUEST_ERROR","REQUEST_TIMEOUT","REQUEST_PREMATURE_TERMINATION","UA","navigator","userAgent","platform","isMac","matchPlatform","isWin","isOpera","matchUserAgent","isIe","isEdge","isIeOrEdge","isChrome","isSafari","isFirefox","testUserAgent","getNativeUserAgent","getNativePlatform","RequestScreen","httpHeaders","httpMethod","GET","status","isValidResponseStatusCode","invalidStatus","statusCode","getRequestPath","setProtocol","makeUnique","getRequest","requestPath","responseUrl","maybeExtractResponseUrlFromRequest","removeUnique","getCache","header","addSafariXHRPolyfill","FormData","maybeAppendSubmitButtonValue_","POST","formatLoadPath","removeSafariXHRPolyfill","setRequest","xhr","assertValidResponseStatusCode","addCache","responseText","requestError","requestPrematureTermination","responseURL","getResponseHeader","X_REQUEST_URL_HEADER","inputs","input","files","HtmlScreen","metaTagsSelector","titleSelector","releaseVirtualDocument","pendingStyles","virtualDocument","copyNodeAttributesFromContent_","newStyle","isTemporaryStyle","stylesTemporary","styleInDoc","insertBefore","nextSibling","bodySurface","placeholder","tempNode","createRange","createContextualFragment","clearNodeAttributes","copyNodeAttributes","disposePendingStyles","removeElementsFromDocument","evaluateTrackedScripts","evaluateTrackedResources_","scriptsTemporary","scriptsPermanent","evaluateTrackedStyles","runStylesInElement","stylesPermanent","appendStyleIntoDocument_","resourcesInVirtual","virtualQuerySelectorAll_","favicon","resourcesInDocument","querySelectorAll_","runFaviconInElement_","evaluatorFn","selectorTemporary","selectorPermanent","opt_appendResourceFn","tracked","temporariesInDoc","permanentsInDoc","resource","resourceKey","getResourceKey_","permanentResourcesInDoc","frag","evaluateFavicon_","updateMetaTags_","currentMetaNodes","metasFromVirtualDocument","meta","allocateVirtualDocumentForContent","resolveTitleFromVirtualDocument","resolveMetaTagsFromVirtualDocument","assertSameBodyIdInVirtualDocument","makeTemporaryStylesHrefsUnique_","replaceStyleAndMakeUnique_","replaceChild","setElementWithRandomHref","setTitle","textContent","setMetas","ignoreFavicon","AppDataAttributeHandler","app","baseElement","hasAttribute","dataAttributes","maybeAddRoutes_","maybeAddSurfaces_","maybeSetBasePath_","maybeSetLinkSelector_","maybeSetLoadingCssClass_","maybeSetUpdateScrollPosition_","maybeDispatch_","routesSelector","querySelectorAllAsArray_","maybeParseLinkRoute_","hasRoutes","addRoutes","surfacesSelector","surfaceElement","updateElementIdIfSpecialSurface_","addSurfaces","dispatch","maybeParseLinkRoutePath_","maybeParseLinkRouteHandler_","getPath","getAttribute","getObjectByName","setBasePath","setLoadingCssClass","setUpdateScrollPosition","dataAttributeHandler","setBaseElement","handle","version"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;;;;;AAKA,IAAIA,+BAAJ;;;;;;;AAOA,IAAIC,mBAAmB,CAAvB;;;;;;;AAOA,AAAO,IAAMC,0BAAwBC,KAAKC,MAAL,KAAgB,GAAjB,KAA0B,CAAjD,CAAN;;;;;;;;;;;;AAYP,AAAO,SAASC,cAAT,GAA0B;QAC1BC,MAAM,+BAAN,CAAN;;;;;;AAMD,AAAO,SAASC,wBAAT,GAAoC;2BACjBC,SAAzB;;;;;;;;;;;;;;;;;;;AAmBD,AAAO,SAASC,uBAAT,GAA4C;MAAXC,IAAW,uEAAJ,EAAI;;2BACzBA,IAAzB;;;;;;;;AAQD,AAAO,SAASC,wBAAT,GAAoC;;MAEtCX,2BAA2BQ,SAA/B,EAA0C;QACrC,OAAOI,MAAP,KAAkB,WAAlB,IAAiCA,OAAOC,uBAA5C,EAAqE;8BAC5CD,OAAOC,uBAA/B;;;SAGKb,sBAAP;;;;;;;;;;AAUD,SAASc,eAAT,CAAyBC,CAAzB,EAA4BC,CAA5B,EAA+B;SACvBD,KAAKC,CAAZ;;;;;;;;;;AAUD,AAAO,SAASC,eAAT,CAAyBC,EAAzB,EAA6B;MAC/B,CAACA,GAAGC,IAAR,EAAc;QACPC,MAAMF,GAAGG,QAAH,EAAZ;OACGF,IAAH,GAAUC,IAAIE,SAAJ,CAAc,CAAd,EAAiBF,IAAIG,OAAJ,CAAY,GAAZ,CAAjB,CAAV;;SAEML,GAAGC,IAAV;;;;;;;;;;;;;;;;;;AAkBD,AAAO,SAASK,iBAAT,CACNC,IADM,EAENC,YAFM,EAIL;MADDC,OACC,uEADSb,eACT;;MACKc,aAAaF,eAAe,SAAlC;MACI,CAACD,KAAKI,cAAL,CAAoBD,UAApB,CAAL,EAAsC;;QAEjCE,SAASL,KAAKI,cAAL,CAAoBH,YAApB,IACVD,KAAKC,YAAL,CADU,GAEV,IAFH;QAGID,KAAKM,SAAL,IAAkB,CAACN,KAAKM,SAAL,CAAeC,aAAf,CAA6BC,QAA7B,CAAvB,EAA+D;eACrDN,QACRG,MADQ,EAERN,kBAAkBC,KAAKM,SAAvB,EAAkCL,YAAlC,EAAgDC,OAAhD,CAFQ,CAAT;;SAKIC,UAAL,IAAmBE,MAAnB;;SAEML,KAAKG,UAAL,CAAP;;;;;;;;;;;;;;;AAeD,AAAO,SAASM,MAAT,CAAgBC,MAAhB,EAAwBC,aAAxB,EAAuC;MACzCD,MAAJ,EAAY;QACPE,KAAKF,OAAOjC,YAAP,CAAT;QACIkC,iBAAiB,CAACD,OAAON,cAAP,CAAsB3B,YAAtB,CAAtB,EAA2D;WACrD,IAAL;;WAEMmC,OAAOF,OAAOjC,YAAP,IAAuBD,kBAA9B,CAAP;;SAEMA,kBAAP;;;;;;;;AAQD,AAAO,SAASqC,gBAAT,CAA0BC,WAA1B,EAAuC;SACtCA,WAAP;;;;;;;;AAQD,AAAO,SAASC,SAAT,CAAmBC,GAAnB,EAAwB;SACvB,OAAOA,GAAP,KAAe,SAAtB;;;;;;;;AAQD,AAAO,SAASC,KAAT,CAAeD,GAAf,EAAoB;SACnBA,QAAQjC,SAAf;;;;;;;;AAQD,AAAO,SAASmC,eAAT,CAAyBF,GAAzB,EAA8B;SAC7BC,MAAMD,GAAN,KAAc,CAACG,OAAOH,GAAP,CAAtB;;;;;;;;AAQD,AAAO,SAASI,UAAT,CAAoBJ,GAApB,EAAyB;SACxBA,OAAO,QAAOA,GAAP,yCAAOA,GAAP,OAAe,QAAtB,IAAkCA,IAAIK,QAAJ,KAAiB,CAA1D;;;;;;;;AAQD,AAAO,SAASC,kBAAT,CAA4BN,GAA5B,EAAiC;SAChCA,OAAO,QAAOA,GAAP,yCAAOA,GAAP,OAAe,QAAtB,IAAkCA,IAAIK,QAAJ,KAAiB,EAA1D;;;;;;;;AAQD,AAAO,SAASE,SAAT,CAAmBP,GAAnB,EAAwB;SACvBA,OAAO,QAAOA,GAAP,yCAAOA,GAAP,OAAe,QAAtB,IAAkCA,IAAIK,QAAJ,KAAiB,CAA1D;;;;;;;;AAQD,AAAO,SAASG,UAAT,CAAoBR,GAApB,EAAyB;SACxB,OAAOA,GAAP,KAAe,UAAtB;;;;;;;;AAQD,AAAO,SAASG,MAAT,CAAgBH,GAAhB,EAAqB;SACpBA,QAAQ,IAAf;;;;;;;;AAQD,AAAO,SAASS,QAAT,CAAkBT,GAAlB,EAAuB;SACtB,OAAOA,GAAP,KAAe,QAAtB;;;;;;;;AAQD,AAAO,SAASU,QAAT,CAAkBV,GAAlB,EAAuB;SACtBA,QAAQ,IAAR,IAAgBA,QAAQA,IAAI7B,MAAnC;;;;;;;;;AASD,AAAO,SAASwC,QAAT,CAAkBX,GAAlB,EAAuB;MACvBY,cAAcZ,GAAd,yCAAcA,GAAd,CAAN;SACQY,SAAS,QAAT,IAAqBZ,QAAQ,IAA9B,IAAuCY,SAAS,UAAvD;;;;;;;;AAQD,AAAO,SAASC,SAAT,CAAmBb,GAAnB,EAAwB;SACvBA,OAAO,QAAOA,GAAP,yCAAOA,GAAP,OAAe,QAAtB,IAAkC,OAAOA,IAAIc,IAAX,KAAoB,UAA7D;;;;;;;;AAQD,AAAO,SAASC,QAAT,CAAkBf,GAAlB,EAAuB;SACtB,OAAOA,GAAP,KAAe,QAAf,IAA2BA,eAAegB,MAAjD;;;;;;;;;;;AAWD,AAAO,SAASC,YAAT,GAAkD;MAA5BC,OAA4B,uEAAlB,EAACC,UAAU,IAAX,EAAkB;;MACpDC,aAAa,OAAOC,OAAP,KAAmB,WAAnB,IAAkC,CAACA,QAAQC,OAA5D;MACIF,cAAcF,QAAQC,QAA1B,EAAoC;iBAElC,OAAOE,QAAQE,GAAf,KAAuB,WAAvB,IACAF,QAAQE,GAAR,CAAYC,QAAZ,KAAyB,MAF1B;;SAIMJ,UAAP;;;;;;;AAOD,AAAO,SAASK,YAAT,GAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzT/B;;;;;ACAA;;;;IAGMC;;;;;;;;;;;;;;wBAOQC,MAAMC,MAAM;OACpBD,SAASC,IAAb,EAAmB;WACX,IAAP;;OAEGD,KAAKE,MAAL,KAAgBD,KAAKC,MAAzB,EAAiC;WACzB,KAAP;;QAEI,IAAIC,IAAI,CAAb,EAAgBA,IAAIH,KAAKE,MAAzB,EAAiCC,GAAjC,EAAsC;QACjCH,KAAKG,CAAL,MAAYF,KAAKE,CAAL,CAAhB,EAAyB;YACjB,KAAP;;;UAGK,IAAP;;;;;;;;;;;oCAQwBC,KAAK;QACxB,IAAID,IAAI,CAAb,EAAgBA,IAAIC,IAAIF,MAAxB,EAAgCC,GAAhC,EAAqC;QAChCC,IAAID,CAAJ,MAAW/D,SAAf,EAA0B;YAClBgE,IAAID,CAAJ,CAAP;;;;;;;;;;;;;;0BAWYC,KAAkB;OAAbC,MAAa,uEAAJ,EAAI;;QAC3B,IAAIF,IAAI,CAAb,EAAgBA,IAAIC,IAAIF,MAAxB,EAAgCC,GAAhC,EAAqC;QAChCG,MAAMC,OAAN,CAAcH,IAAID,CAAJ,CAAd,CAAJ,EAA2B;WACpBK,OAAN,CAAcJ,IAAID,CAAJ,CAAd,EAAsBE,MAAtB;KADD,MAEO;YACCI,IAAP,CAAYL,IAAID,CAAJ,CAAZ;;;UAGKE,MAAP;;;;;;;;;;;;;yBAUaD,KAAKM,KAAK;OACjBP,IAAIC,IAAIjD,OAAJ,CAAYuD,GAAZ,CAAV;OACIC,WAAJ;OACKA,KAAKR,KAAK,CAAf,EAAmB;UACZS,QAAN,CAAeR,GAAf,EAAoBD,CAApB;;UAEMQ,EAAP;;;;;;;;;;;;2BASeP,KAAKD,GAAG;UAChBG,MAAMO,SAAN,CAAgBC,MAAhB,CAAuBC,IAAvB,CAA4BX,GAA5B,EAAiCD,CAAjC,EAAoC,CAApC,EAAuCD,MAAvC,KAAkD,CAAzD;;;;;;;;;;;;;;;;wBAaYE,KAAKY,OAAyB;OAAlBC,GAAkB,uEAAZb,IAAIF,MAAQ;;OACpCgB,SAAS,EAAf;QACK,IAAIf,IAAIa,KAAb,EAAoBb,IAAIc,GAAxB,EAA6Bd,GAA7B,EAAkC;WAC1BM,IAAP,CAAYL,IAAID,CAAJ,CAAZ;;UAEMe,MAAP;;;;;;AClGF;;;;;AAKA,AAIA,IAAMC,QAAQ,EAAd;;;;;;;;;AASAA,MAAMC,cAAN,GAAuB,UAASC,SAAT,EAAoB;;OAEpCC,QAAN,CAAe,YAAW;QACnBD,SAAN;EADD;CAFD;;;;;;;;;;AAeAF,MAAMI,GAAN,GAAY,UAASC,QAAT,EAAmBC,OAAnB,EAA4B;KACnC,CAACN,MAAMI,GAAN,CAAUG,mBAAf,EAAoC;;QAE7BJ,QAAN,CAAeH,MAAMI,GAAN,CAAUI,gBAAzB;QACMJ,GAAN,CAAUG,mBAAV,GAAgC,IAAhC;;;OAGKH,GAAN,CAAUK,UAAV,CAAqBnB,IAArB,CAA0B,IAAIU,MAAMI,GAAN,CAAUM,SAAd,CAAwBL,QAAxB,EAAkCC,OAAlC,CAA1B;CAPD;;;AAWAN,MAAMI,GAAN,CAAUG,mBAAV,GAAgC,KAAhC;;;AAGAP,MAAMI,GAAN,CAAUK,UAAV,GAAuB,EAAvB;;;;;;;AAOAT,MAAMI,GAAN,CAAUI,gBAAV,GAA6B,YAAW;;QAEhCR,MAAMI,GAAN,CAAUK,UAAV,CAAqB1B,MAA5B,EAAoC;;MAE7B4B,YAAYX,MAAMI,GAAN,CAAUK,UAA5B;QACML,GAAN,CAAUK,UAAV,GAAuB,EAAvB;OACK,IAAIzB,IAAI,CAAb,EAAgBA,IAAI2B,UAAU5B,MAA9B,EAAsCC,GAAtC,EAA2C;OACpC4B,WAAWD,UAAU3B,CAAV,CAAjB;OACI;aACMrD,EAAT,CAAYiE,IAAZ,CAAiBgB,SAASC,KAA1B;IADD,CAEE,OAAOC,CAAP,EAAU;UACLb,cAAN,CAAqBa,CAArB;;;;;;OAMGV,GAAN,CAAUG,mBAAV,GAAgC,KAAhC;CAjBD;;;;;;;;;;;AA6BAP,MAAMI,GAAN,CAAUM,SAAV,GAAsB,UAAS/E,EAAT,EAAakF,KAAb,EAAoB;;MAEpClF,EAAL,GAAUA,EAAV;;MAEKkF,KAAL,GAAaA,KAAb;CAJD;;;;;;;;;;;AAgBAb,MAAMG,QAAN,GAAiB,UAASE,QAAT,EAAmBC,OAAnB,EAA4B;KACxCS,KAAKV,QAAT;KACIC,OAAJ,EAAa;OACPD,SAASW,IAAT,CAAcV,OAAd,CAAL;;MAEIN,MAAMG,QAAN,CAAec,aAAf,CAA6BF,EAA7B,CAAL;;KAEI,CAACf,MAAMG,QAAN,CAAee,aAApB,EAAmC;MAEjC,OAAOC,YAAP,KAAwB,UAAxB,IACAhD,aAAa,EAACE,UAAU,KAAX,EAAb,CAFD,EAGE;SACK8B,QAAN,CAAee,aAAf,GAA+BC,YAA/B;GAJD,MAKO;;SAEAhB,QAAN,CAAee,aAAf,GAA+BlB,MAAMG,QAAN,CAAeiB,wBAAf,EAA/B;;;OAGIjB,QAAN,CAAee,aAAf,CAA6BH,EAA7B;CAlBD;;;;;;;AA0BAf,MAAMG,QAAN,CAAee,aAAf,GAA+B,IAA/B;;;;;;;;AAQAlB,MAAMG,QAAN,CAAeiB,wBAAf,GAA0C,YAAW;;;KAGhDC,gBAAJ;;;;;;KAMI,OAAOC,cAAP,KAA0B,UAA9B,EAA0C;YAC/BA,cAAV;;;;;;;KAQA,OAAOD,OAAP,KAAmB,WAAnB,IACA,OAAOhG,MAAP,KAAkB,WADlB,IAEAA,OAAOkG,WAFP,IAGAlG,OAAOmG,gBAJR,EAKE;;YAES,mBAAW;;OAEdC,SAASC,SAASC,aAAT,CAAuB,QAAvB,CAAf;UACOC,KAAP,CAAaC,OAAb,GAAuB,MAAvB;UACOC,GAAP,GAAa,EAAb;UACOC,KAAP,GAAe,EAAf;YACSC,eAAT,CAAyBC,WAAzB,CAAqCR,MAArC;OACMS,MAAMT,OAAOU,aAAnB;OACMC,MAAMF,IAAIR,QAAhB;OACIW,IAAJ;OACIC,KAAJ,CAAU,EAAV;OACIC,KAAJ;OACMC,UAAU,kBAAkB5H,KAAKC,MAAL,EAAlC;OACM4H,SAASP,IAAIQ,QAAJ,CAAaC,QAAb,GAAwB,IAAxB,GAA+BT,IAAIQ,QAAJ,CAAaE,IAA3D;OACMC,YAAY,UAAS/B,CAAT,EAAY;;;QAGzBA,EAAE2B,MAAF,KAAaA,MAAb,IAAuB3B,EAAE3F,IAAF,KAAWqH,OAAtC,EAA+C;;;SAG1CM,KAAL,CAAWD,SAAX;IANiB,CAOhB7B,IAPgB,CAOX,IAPW,CAAlB;OAQIQ,gBAAJ,CAAqB,SAArB,EAAgCqB,SAAhC,EAA2C,KAA3C;QACKC,KAAL,GAAa,EAAb;QACKC,KAAL,GAAa;iBACC,uBAAW;SACnBxB,WAAJ,CAAgBiB,OAAhB,EAAyBC,MAAzB;;IAFF;GAxBD;;KA+BG,OAAOpB,OAAP,KAAmB,WAAvB,EAAoC;MAC7B2B,UAAU,IAAI3B,OAAJ,EAAhB;;MAEI4B,OAAO,EAAX;MACIC,OAAOD,IAAX;UACQH,KAAR,CAAcD,SAAd,GAA0B,YAAW;UAC7BI,KAAKE,IAAZ;OACMpC,KAAKkC,KAAKlC,EAAhB;QACKA,EAAL,GAAU,IAAV;;GAHD;SAMO,UAASA,EAAT,EAAa;QACdoC,IAAL,GAAY;QACPpC;IADL;UAGOmC,KAAKC,IAAZ;WACQJ,KAAR,CAAcxB,WAAd,CAA0B,CAA1B;GALD;;;;KAWA,OAAOG,QAAP,KAAoB,WAApB,IACA,wBAAwBA,SAASC,aAAT,CAAuB,QAAvB,CAFzB,EAGE;SACM,UAASZ,EAAT,EAAa;OACfqC,SAAS1B,SAASC,aAAT,CAAuB,QAAvB,CAAb;UACO0B,kBAAP,GAA4B,YAAW;;WAE/BA,kBAAP,GAA4B,IAA5B;WACOC,UAAP,CAAkBC,WAAlB,CAA8BH,MAA9B;aACS,IAAT;;SAEK,IAAL;IAND;YAQSpB,eAAT,CAAyBC,WAAzB,CAAqCmB,MAArC;GAVD;;;;QAeM,UAASrC,EAAT,EAAa;aACRA,EAAX,EAAe,CAAf;EADD;CA/FD;;;;;;;;;AA2GAf,MAAMG,QAAN,CAAec,aAAf,GAA+B,UAASZ,QAAT,EAAmB;QAC1CA,QAAP;CADD;;AC9OA;;;;;;;;IAOMmD;;;;uBAIS;;;;;;;;OAMRC,SAAL,GAAiB,KAAjB;;;;;;;;;;4BAMS;OACL,CAAC,KAAKA,SAAV,EAAqB;SACfC,eAAL;SACKD,SAAL,GAAiB,IAAjB;;;;;;;;;;;;oCASgB;;;;;;;;;+BAML;UACL,KAAKA,SAAZ;;;;;;AC1CF;;;;IAGM7G;;;;;;;;;;;;;;wBAOQ+G,QAAiB;OACzBC,YAAJ;OACIC,eAAJ;;qCAFuBC,IAAM;QAAA;;;QAGxB,IAAI9E,IAAI,CAAb,EAAgBA,IAAI8E,KAAK/E,MAAzB,EAAiCC,GAAjC,EAAsC;aAC5B8E,KAAK9E,CAAL,CAAT;;;;SAIK4E,GAAL,IAAYC,MAAZ,EAAoB;YACZD,GAAP,IAAcC,OAAOD,GAAP,CAAd;;;UAGKD,MAAP;;;;;;;;;;;;;kCAUsB/H,MAAsB;OAAhBiF,KAAgB,uEAARxF,MAAQ;;OACtC0I,QAAQnI,KAAKoI,KAAL,CAAW,GAAX,CAAd;UACOD,MAAME,MAAN,CAAa,UAACC,IAAD,EAAON,GAAP;WAAeM,KAAKN,GAAL,CAAf;IAAb,EAAuC/C,KAAvC,CAAP;;;;;;;;;;;;;sBAUUtB,KAAK5D,IAAI;OACbwI,YAAY,EAAlB;OACMC,OAAOC,OAAOD,IAAP,CAAY7E,GAAZ,CAAb;QACK,IAAIP,IAAI,CAAb,EAAgBA,IAAIoF,KAAKrF,MAAzB,EAAiCC,GAAjC,EAAsC;cAC3BoF,KAAKpF,CAAL,CAAV,IAAqBrD,GAAGyI,KAAKpF,CAAL,CAAH,EAAYO,IAAI6E,KAAKpF,CAAL,CAAJ,CAAZ,CAArB;;UAEMmF,SAAP;;;;;;;;;;;;;+BAUmBG,MAAMC,MAAM;OAC3BD,SAASC,IAAb,EAAmB;WACX,IAAP;;;OAGKC,QAAQH,OAAOD,IAAP,CAAYE,IAAZ,CAAd;OACMG,QAAQJ,OAAOD,IAAP,CAAYG,IAAZ,CAAd;OACIC,MAAMzF,MAAN,KAAiB0F,MAAM1F,MAA3B,EAAmC;WAC3B,KAAP;;;QAGI,IAAIC,IAAI,CAAb,EAAgBA,IAAIwF,MAAMzF,MAA1B,EAAkCC,GAAlC,EAAuC;QAClCsF,KAAKE,MAAMxF,CAAN,CAAL,MAAmBuF,KAAKC,MAAMxF,CAAN,CAAL,CAAvB,EAAuC;YAC/B,KAAP;;;UAGK,IAAP;;;;;;AC5EF;;;;IAGM0F;;;;;;;;;;;;;;;yCAQyBC,MAAMC,MAAM;OACnCC,QAAQ3G,OAAOyG,IAAP,EAAaG,WAAb,EAAd;OACMC,QAAQ7G,OAAO0G,IAAP,EAAaE,WAAb,EAAd;;OAEID,QAAQE,KAAZ,EAAmB;WACX,CAAC,CAAR;IADD,MAEO,IAAIF,UAAUE,KAAd,EAAqB;WACpB,CAAP;IADM,MAEA;WACC,CAAP;;;;;;;;;;;;;;yCAW4BlJ,KAAK;UAC3BA,IACLmJ,OADK,CACG,aADH,EACkB,GADlB,EAELA,OAFK,CAEG,0BAFH,EAE+B,EAF/B,CAAP;;;;;;;;;;;;8BAWkBnJ,KAAK;UAChBqC,OAAOrC,GAAP,EACLmJ,OADK,CACG,6BADH,EACkC,MADlC,EAELA,OAFK,CAEG,OAFH,EAEY,OAFZ,CAAP,CADuB;;;;;;;;;;oCAUC;OAClBC,IAAI,UAAV;UAECrK,KAAKsK,KAAL,CAAWtK,KAAKC,MAAL,KAAgBoK,CAA3B,EAA8BnJ,QAA9B,CAAuC,EAAvC,IACAlB,KAAKuK,GAAL,CAASvK,KAAKsK,KAAL,CAAWtK,KAAKC,MAAL,KAAgBoK,CAA3B,IAAgCG,KAAKC,GAAL,EAAzC,EAAqDvJ,QAArD,CAA8D,EAA9D,CAFD;;;;;;;;;;;;;;;2BAeeoB,KAAK;OAChBoI,OAAO,CAAX;QACK,IAAItG,IAAI,CAAR,EAAWuG,MAAMrI,IAAI6B,MAA1B,EAAkCC,IAAIuG,GAAtC,EAA2CvG,GAA3C,EAAgD;WACxC,KAAKsG,IAAL,GAAYpI,IAAIsI,UAAJ,CAAexG,CAAf,CAAnB;YACQ,WAAR;;UAEMsG,IAAP;;;;;;;;;;;;;;;kCAYsBzJ,KAAKgE,OAAOC,KAAK2F,OAAO;UACvC5J,IAAIE,SAAJ,CAAc,CAAd,EAAiB8D,KAAjB,IAA0B4F,KAA1B,GAAkC5J,IAAIE,SAAJ,CAAc+D,GAAd,CAAzC;;;;;;ACvFF,IAAM4F,aAAa,gBAAnB;;;;;;IAKMC;;;;;;;;;;;;;;;;yBASMC,SAAShK,MAAMiK,cAAc;OACnC,CAACD,QAAQF,UAAR,CAAL,EAA0B;YACjBA,UAAR,IAAsB,EAAtB;;OAEG,CAAC9J,IAAL,EAAW;WACHgK,QAAQF,UAAR,CAAP;;OAEG,CAACvI,MAAMyI,QAAQF,UAAR,EAAoB9J,IAApB,CAAN,CAAD,IAAqCuB,MAAM0I,YAAN,CAAzC,EAA8D;YACrDH,UAAR,EAAoB9J,IAApB,IAA4BiK,YAA5B;;UAEMD,QAAQF,UAAR,EAAoB9J,IAApB,CAAP;;;;;;;;;;;sBAQUgK,SAAS;UACZ,CAAC,CAACA,QAAQF,UAAR,CAAT;;;;;;;;;;;;;yBAUUE,SAAShK,MAAM6J,OAAO;OAC5B,CAACG,QAAQF,UAAR,CAAL,EAA0B;YACjBA,UAAR,IAAsB,EAAtB;;OAEG,CAAC9J,IAAD,IAAS,CAACuB,MAAMsI,KAAN,CAAd,EAA4B;WACpBG,QAAQF,UAAR,CAAP;;WAEOA,UAAR,EAAoB9J,IAApB,IAA4B6J,KAA5B;UACOG,QAAQF,UAAR,EAAoB9J,IAApB,CAAP;;;;;;ACnDF;;;;;;;;;IAQMkK;;;;;;;;;sBAOOC,OAAZ,EAAqBC,KAArB,EAA4BC,QAA5B,EAAsC;;;;;;;;;;QAQhCC,QAAL,GAAgBH,OAAhB;;;;;;;QAOKI,MAAL,GAAcH,KAAd;;;;;;;QAOKI,SAAL,GAAiBH,QAAjB;;;;;;;;;;;;oCAOiB;QACZI,cAAL;QACKH,QAAL,GAAgB,IAAhB;QACKE,SAAL,GAAiB,IAAjB;;;;;;;;;mCAMgB;OACZ,CAAC,KAAKF,QAAL,CAAcI,UAAd,EAAL,EAAiC;SAC3BJ,QAAL,CAAcG,cAAd,CAA6B,KAAKF,MAAlC,EAA0C,KAAKC,SAA/C;;;;;EA/CuB5C;;ACP1B,IAAM+C,eAAe,CAAC,CAAD,CAArB;;;;;;;IAMMC;;;;;;yBAIS;;;;;;;;;;QAQRC,OAAL,GAAe,IAAf;;;;;;QAMKC,iBAAL,GAAyB,IAAzB;;;;;;;;;QASKC,gBAAL,GAAwB,KAAxB;;;;;;;;;;;;;;;;;;8BAaWC,QAAQC,SAAS;OACxB,CAACD,MAAL,EAAa;aACHC,OAAT;IADD,MAEO;QACF,CAAC1H,MAAMC,OAAN,CAAcwH,MAAd,CAAL,EAA4B;cAClB,CAACA,MAAD,CAAT;;WAEMtH,IAAP,CAAYuH,OAAZ;;UAEMD,MAAP;;;;;;;;;;;;;;;8BAYWZ,OAAOC,UAAUa,iBAAiB;QACxCC,iBAAL,CAAuBd,QAAvB;;OAEMe,SAAS,KAAKC,cAAL,CAAoBjB,KAApB,CAAf;QACK,IAAIhH,IAAI,CAAb,EAAgBA,IAAIgI,OAAOjI,MAA3B,EAAmCC,GAAnC,EAAwC;SAClCkI,kBAAL,CAAwBF,OAAOhI,CAAP,CAAxB,EAAmCiH,QAAnC,EAA6Ca,eAA7C;;;UAGM,IAAIhB,WAAJ,CAAgB,IAAhB,EAAsBE,KAAtB,EAA6BC,QAA7B,CAAP;;;;;;;;;;;;;;;;;qCAckBD,OAAOC,UAAUa,iBAAiBrE,QAAQ;QACvD0E,oBAAL,CAA0BnB,KAA1B;OACIc,mBAAmBrE,MAAvB,EAA+B;eACnB;cACDqE,eADC;SAENb,QAFM;aAGFxD;KAHT;;QAMIgE,OAAL,GAAe,KAAKA,OAAL,IAAgB,EAA/B;QACKA,OAAL,CAAaT,KAAb,IAAsB,KAAKoB,WAAL,CAAiB,KAAKX,OAAL,CAAaT,KAAb,CAAjB,EAAsCC,QAAtC,CAAtB;;;;;;;;;;;;+BASYD,OAAO;OACf,KAAKqB,kBAAL,EAAJ,EAA+B;QACxBC,SAAS;qBACE,0BAAW;aACnBC,gBAAP,GAA0B,IAA1B;MAFa;aAIN,IAJM;WAKRvB;KALP;WAOOsB,MAAP;;;;;;;;;;;oCAQgB;QACZb,OAAL,GAAe,IAAf;;;;;;;;;;;;uBASIT,OAAO;OACLwB,YAAY,KAAKC,gBAAL,CAAsBzB,KAAtB,CAAlB;OACIwB,UAAUzI,MAAV,KAAqB,CAAzB,EAA4B;WACpB,KAAP;;;OAGK+E,OAAOlF,MAAM8I,KAAN,CAAYC,SAAZ,EAAuB,CAAvB,CAAb,CANW;QAONC,aAAL,CAAmBJ,SAAnB,EAA8B1D,IAA9B,EAAoC,KAAK+D,YAAL,CAAkB7B,KAAlB,CAApC;UACO,IAAP;;;;;;;;;;;;mCASgBA,OAAO;OACjB8B,kBAAkBC,UAAQ,KAAKtB,OAAL,IAAgB,KAAKA,OAAL,CAAaT,KAAb,CAAxB,CAAxB;UACO8B,gBAAgBE,MAAhB,CACND,UAAQ,KAAKtB,OAAL,IAAgB,KAAKA,OAAL,CAAa,GAAb,CAAxB,CADM,CAAP;;;;;;;;;;;;uCAWoB;UACb,KAAKE,gBAAZ;;;;;;;;;;;4BAQSX,OAAO;UACT,KAAKyB,gBAAL,CAAsBzB,KAAtB,EAA6BiC,GAA7B,CACN;WAAahC,SAAStK,EAAT,GAAcsK,SAAStK,EAAvB,GAA4BsK,QAAzC;IADM,CAAP;;;;;;;;;;;;;;;;uBAeID,OAAOkC,QAAQjC,UAAU;OACvBe,SAAS,KAAKC,cAAL,CAAoBjB,KAApB,CAAf;QACK,IAAIhH,IAAI,CAAb,EAAgBA,IAAIgI,OAAOjI,MAA3B,EAAmCC,GAAnC,EAAwC;SAClCmJ,KAAL,CAAWnB,OAAOhI,CAAP,CAAX,EAAsBkJ,MAAtB,EAA8BjC,QAA9B;;;UAGM,IAAIH,WAAJ,CAAgB,IAAhB,EAAsBE,KAAtB,EAA6BC,QAA7B,CAAP;;;;;;;;;;;;;;;;wBAaKD,OAAOkC,QAAQjC,UAAU;OACxBmC,OAAO,IAAb;;OAEIF,UAAU,CAAd,EAAiB;;;;;;;YAORG,eAAT,GAA2B;QACtB,EAAEH,MAAF,KAAa,CAAjB,EAAoB;UACd7B,cAAL,CAAoBL,KAApB,EAA2BqC,eAA3B;;aAEQC,KAAT,CAAeF,IAAf,EAAqBT,SAArB,EAJ0B;;;QAOtBT,kBAAL,CAAwBlB,KAAxB,EAA+BqC,eAA/B,EAAgD,KAAhD,EAAuDpC,QAAvD;;;;;;;;;;;;;;mCAWgBsC,aAAatC,UAAU;OACjCtK,KAAK4M,YAAY5M,EAAZ,IAAkB4M,WAA7B;UAEC5M,OAAOsK,QAAP,IACCsC,YAAY9F,MAAZ,IAAsB8F,YAAY9F,MAAZ,KAAuBwD,QAF/C;;;;;;;;;;;;;;sBAaGD,OAAOC,UAAU;QACfc,iBAAL,CAAuBd,QAAvB;OACI,CAAC,KAAKQ,OAAV,EAAmB;WACX,IAAP;;;OAGKO,SAAS,KAAKC,cAAL,CAAoBjB,KAApB,CAAf;QACK,IAAIhH,IAAI,CAAb,EAAgBA,IAAIgI,OAAOjI,MAA3B,EAAmCC,GAAnC,EAAwC;SAClCyH,OAAL,CAAaO,OAAOhI,CAAP,CAAb,IAA0B,KAAKwJ,2BAAL,CACzBT,UAAQ,KAAKtB,OAAL,CAAaO,OAAOhI,CAAP,CAAb,CAAR,CADyB,EAEzBiH,QAFyB,CAA1B;;;UAMM,IAAP;;;;;;;;;;;;uBASI;UACG,KAAKwC,WAAL,CAAiBH,KAAjB,CAAuB,IAAvB,EAA6BX,SAA7B,CAAP,CADI;;;;;;;;;;;6BASMd,SAAS;QACdH,iBAAL,GAAyB,KAAKU,WAAL,CACxB,KAAKV,iBADmB,EAExBG,OAFwB,CAAzB,CADmB;;;;;;;;;;;;;uBAcfG,QAAQf,UAAU;UACf,KAAKyC,IAAL,CAAU1B,MAAV,EAAkB,CAAlB,EAAqBf,QAArB,CAAP;;;;;;;;;;;;;qCAUkBD,OAAO;OACrB,KAAKS,OAAT,EAAkB;QACbT,KAAJ,EAAW;SACJgB,SAAS,KAAKC,cAAL,CAAoBjB,KAApB,CAAf;UACK,IAAIhH,IAAI,CAAb,EAAgBA,IAAIgI,OAAOjI,MAA3B,EAAmCC,GAAnC,EAAwC;WAClCyH,OAAL,CAAaO,OAAOhI,CAAP,CAAb,IAA0B,IAA1B;;KAHF,MAKO;UACDyH,OAAL,GAAe,IAAf;;;UAGK,IAAP;;;;;;;;;;;;;;8CAW2BkC,cAAc1C,UAAU;OAC7C2C,iBAAiB,EAAvB;QACK,IAAI5J,IAAI,CAAb,EAAgBA,IAAI2J,aAAa5J,MAAjC,EAAyCC,GAAzC,EAA8C;QACzC,CAAC,KAAK6J,gBAAL,CAAsBF,aAAa3J,CAAb,CAAtB,EAAuCiH,QAAvC,CAAL,EAAuD;oBACvC3G,IAAf,CAAoBqJ,aAAa3J,CAAb,CAApB;;;UAGK4J,eAAe7J,MAAf,GAAwB,CAAxB,GAA4B6J,cAA5B,GAA6C,IAApD;;;;;;;;;;;;;mCAUgB;UACT,KAAKE,GAAL,CAASR,KAAT,CAAe,IAAf,EAAqBX,SAArB,CAAP,CADgB;;;;;;;;;;;uCASI3B,OAAO;OACvB+C,WAAW,KAAKrC,iBAApB;OACIqC,QAAJ,EAAc;eACFhB,UAAQgB,QAAR,CAAX;SACK,IAAI/J,IAAI,CAAb,EAAgBA,IAAI+J,SAAShK,MAA7B,EAAqCC,GAArC,EAA0C;cAChCA,CAAT,EAAYgH,KAAZ;;;;;;;;;;;;;;;gCAYWwB,WAAW1D,MAAMwD,QAAQ;OAClCA,MAAJ,EAAY;SACNhI,IAAL,CAAUgI,MAAV;;;OAGK0B,mBAAmB,EAAzB;QACK,IAAIhK,IAAI,CAAb,EAAgBA,IAAIwI,UAAUzI,MAA9B,EAAsCC,GAAtC,EAA2C;QACpCiH,WAAWuB,UAAUxI,CAAV,EAAarD,EAAb,IAAmB6L,UAAUxI,CAAV,CAApC;QACIwI,UAAUxI,CAAV,EAAaiK,OAAjB,EAA0B;sBACR3J,IAAjB,CAAsB2G,QAAtB;KADD,MAEO;cACGqC,KAAT,CAAe,IAAf,EAAqBxE,IAArB;;;OAGE,CAACwD,MAAD,IAAW,CAACA,OAAOC,gBAAvB,EAAyC;SACnC,IAAI2B,IAAI,CAAb,EAAgBA,IAAIF,iBAAiBjK,MAArC,EAA6CmK,GAA7C,EAAkD;sBAChCA,CAAjB,EAAoBZ,KAApB,CAA0B,IAA1B,EAAgCxE,IAAhC;;;;;;;;;;;;;;;qCAYgBqF,iBAAiB;QAC9BxC,gBAAL,GAAwBwC,eAAxB;UACO,IAAP;;;;;;;;;;;;;;iCAWcnC,QAAQ;OAClB/I,SAAS+I,MAAT,CAAJ,EAAsB;iBACR,CAAb,IAAkBA,MAAlB;aACST,YAAT;;UAEMS,MAAP;;;;;;;;;;;oCAQiBf,UAAU;OACvB,CAACvI,WAAWuI,QAAX,CAAL,EAA2B;UACpB,IAAImD,SAAJ,CAAc,6BAAd,CAAN;;;;;EAxawB5F;;;;;;;;;AAkb3B,SAASuE,SAAT,CAAiB7K,GAAjB,EAAsB;OACfA,OAAO,EAAb;QACOiC,MAAMC,OAAN,CAAclC,GAAd,IAAqBA,GAArB,GAA2B,CAACA,GAAD,CAAlC;;;AC3bD;;;;;;;;IAOMmM;;;;;;;;;;;;4BAUOC,aAAZ,EAA2BC,aAA3B,EAA0CC,SAA1C,EAAqDC,SAArD,EAAgE;;;;;;;;;;QAQ1DC,UAAL,GAAkBF,SAAlB;;;;;;;;QAQKG,cAAL,GAAsBL,aAAtB;;;;;;;;;QASKM,cAAL,GAAsB,IAAtB;;;;;;;QAOKC,cAAL,GAAsB,IAAtB;;;;;;;;QAQKC,cAAL,GAAsBP,aAAtB;;;;;;;QAOKQ,UAAL,GAAkBN,SAAlB;;QAEKO,WAAL;;;;;;;;;;;;;;;+BAUYhE,OAAOC,UAAU;UACtB,KAAK0D,cAAL,CAAoBM,EAApB,CAAuBjE,KAAvB,EAA8BC,QAA9B,CAAP;;;;;;;;;oCAMiB;QACZiE,gBAAL;QACKL,cAAL,GAAsB,IAAtB;QACKF,cAAL,GAAsB,IAAtB;QACKG,cAAL,GAAsB,IAAtB;;;;;;;;;;kCAOsB;;;2BACjBA,cAAL,EAAoBK,IAApB;;;;;;;;;;6BAOUnE,OAAO;OACb,KAAKoE,iBAAL,CAAuBpE,KAAvB,CAAJ,EAAmC;SAC7BqE,iBAAL,CAAuBrE,KAAvB;;;;;;;;;;;qCAQiB;OACd,KAAK6D,cAAT,EAAyB;QAClB7C,SAAS3C,OAAOD,IAAP,CAAY,KAAKyF,cAAjB,CAAf;SACK,IAAI7K,IAAI,CAAb,EAAgBA,IAAIgI,OAAOjI,MAA3B,EAAmCC,GAAnC,EAAwC;UAClC6K,cAAL,CAAoB7C,OAAOhI,CAAP,CAApB,EAA+BqH,cAA/B;;SAEIwD,cAAL,GAAsB,IAAtB;;QAEID,cAAL,GAAsB,IAAtB;;;;;;;;;;;;mCASgBN,eAAe;;;OACzBtC,SACL,KAAK2C,cAAL,IAAuB,KAAKE,cAA5B,GACGxF,OAAOD,IAAP,CAAY,KAAKyF,cAAjB,CADH,GAEG,KAAKD,cAHT;QAIKD,cAAL,GAAsBL,aAAtB;OACItC,MAAJ,EAAY;SACNkD,gBAAL;WACOI,OAAP,CAAe;YAAS,OAAKC,UAAL,CAAgBvE,KAAhB,CAAT;KAAf;;;;;;;;;;;;;oCAUgBA,OAAO;OACpB,KAAK+D,UAAL,IAAmB,CAAC,KAAKA,UAAL,CAAgB/D,KAAhB,CAAxB,EAAgD;WACxC,KAAP;;OAEG,KAAK0D,UAAL,IAAmB,KAAKA,UAAL,CAAgB1D,KAAhB,CAAvB,EAA+C;WACvC,KAAP;;UAEM,CAAC,KAAK6D,cAAN,IAAwB,CAAC,KAAKA,cAAL,CAAoB7D,KAApB,CAAhC;;;;;;;;;;gCAOa;QACR8D,cAAL,CAAoBU,UAApB,CAA+B,KAAKD,UAAL,CAAgBvJ,IAAhB,CAAqB,IAArB,CAA/B;;;;;;;;;;;;oCASiBgF,OAAO;OACpB,KAAK2D,cAAT,EAAyB;SACnBE,cAAL,GAAsB,KAAKA,cAAL,IAAuB,EAA7C;SACKA,cAAL,CAAoB7D,KAApB,IAA6B,KAAKyE,YAAL,CAC5BzE,KAD4B,EAE5B,KAAK0E,aAAL,CAAmB1J,IAAnB,CAAwB,IAAxB,EAA8BgF,KAA9B,CAF4B,CAA7B;IAFD,MAMO;SACD4D,cAAL,GAAsB,KAAKA,cAAL,IAAuB,EAA7C;SACKA,cAAL,CAAoBtK,IAApB,CAAyB0G,KAAzB;;;;;EA7K6BxC;;ACPhC;;;;;;IAKMmH;;;;;;yBAIS;;;;;;;;;;;QASRC,aAAL,GAAqB,EAArB;;;;;;;;;;;;;wBAQY;qCAAN9G,IAAM;QAAA;;;QACP,IAAI9E,IAAI,CAAb,EAAgBA,IAAI2I,UAAU5I,MAA9B,EAAsCC,GAAtC,EAA2C;SACrC4L,aAAL,CAAmBtL,IAAnB,CAAwBwE,KAAK9E,CAAL,CAAxB;;;;;;;;;;;oCAQgB;QACZ4L,aAAL,GAAqB,IAArB;;;;;;;;;uCAMoB;QACf,IAAI5L,IAAI,CAAb,EAAgBA,IAAI,KAAK4L,aAAL,CAAmB7L,MAAvC,EAA+CC,GAA/C,EAAoD;SAC9C4L,aAAL,CAAmB5L,CAAnB,EAAsBqH,cAAtB;;;QAGIuE,aAAL,GAAqB,EAArB;;;;EA3CyBpH;;ACH3B;;;;;;IAKMqH;;;;;;;;;;;;kCAUO9E,OAAZ,EAAqBC,KAArB,EAA4BC,QAA5B,EAAsC6E,QAAtC,EAAgD;;;+IACzC/E,OADyC,EAChCC,KADgC,EACzBC,QADyB;;QAE1C8E,SAAL,GAAiBD,QAAjB;;;;;;;;;;;mCAMgB;OACVE,aAAarF,QAAQsF,GAAR,CAAY,KAAK/E,QAAjB,EAA2B,YAA3B,EAAyC,EAAzC,CAAnB;OACMsB,YAAY7B,QAAQsF,GAAR,CAAY,KAAK/E,QAAjB,EAA2B,WAA3B,EAAwC,EAAxC,CAAlB;OACM4E,WAAW,KAAKC,SAAtB;OACM9L,MAAMhB,SAAS6M,QAAT,IACTE,WAAW,KAAK7E,MAAhB,EAAwB+E,SADf,GAET1D,SAFH;OAGM5D,MAAM3F,SAAS6M,QAAT,IAAqBA,QAArB,GAAgC,KAAK3E,MAAjD;;SAEMgF,MAAN,CAAalM,IAAI2E,GAAJ,KAAY,EAAzB,EAA6B,KAAKwC,SAAlC;OACInH,IAAI2E,GAAJ,KAAY3E,IAAI2E,GAAJ,EAAS7E,MAAT,KAAoB,CAApC,EAAuC;WAC/BE,IAAI2E,GAAJ,CAAP;;;;;EA7BmCkC;;ACPtC;;;;;;IAKMsF;;;;;;;;;;;;yBAUOrF,OAAZ,EAAqBC,KAArB,EAA4BC,QAA5B,EAAsCoF,OAAtC,EAA+C;;;6HACxCtF,OADwC,EAC/BC,KAD+B,EACxBC,QADwB;;QAEzCqF,QAAL,GAAgBD,OAAhB;;;;;;;;;;;mCAMgB;QACXnF,QAAL,CAAcqF,mBAAd,CACC,KAAKpF,MADN,EAEC,KAAKC,SAFN,EAGC,KAAKkF,QAHN;;;;EAnB2BxF;;ACO7B,IAAM0F,iBAAiB,EAAvB;AACA,IAAMC,gBAAgB,EAAtB;AACA,AAAO,IAAMC,eAAe,EAArB;;AAEP,IAAMC,iBAAiB,0BAAvB;AACA,IAAMC,cAAc;OACb,IADa;QAEZ,IAFY;QAGZ,IAHY;UAIV,IAJU;OAKb,IALa;SAMX;CANT;;;;;;;AAcA,AAAO,SAASC,UAAT,CAAoBC,QAApB,EAA8BC,OAA9B,EAAuC;KACzC,CAAClO,SAASiO,QAAT,CAAD,IAAuB,CAAC7N,SAAS8N,OAAT,CAA5B,EAA+C;;;;KAI3C,CAACD,SAAS/M,MAAd,EAAsB;aACV,CAAC+M,QAAD,CAAX;;;MAGI,IAAI9M,IAAI,CAAb,EAAgBA,IAAI8M,SAAS/M,MAA7B,EAAqCC,GAArC,EAA0C;MACrC,eAAe8M,SAAS9M,CAAT,CAAnB,EAAgC;yBACT8M,SAAS9M,CAAT,CAAtB,EAAmC+M,OAAnC;GADD,MAEO;4BACmBD,SAAS9M,CAAT,CAAzB,EAAsC+M,OAAtC;;;;;;;;;;;AAWH,SAASC,qBAAT,CAA+BpG,OAA/B,EAAwCmG,OAAxC,EAAiD;SACxC/H,KAAR,CAAc,GAAd,EAAmBsG,OAAnB,CAA2B,UAAS2B,SAAT,EAAoB;MAC1CA,SAAJ,EAAe;WACNC,SAAR,CAAkBC,GAAlB,CAAsBF,SAAtB;;EAFF;;;;;;;;;AAaD,SAASG,wBAAT,CAAkCxG,OAAlC,EAA2CmG,OAA3C,EAAoD;KAC7CM,yBAAuBzG,QAAQqG,SAA/B,MAAN;KACIK,kBAAkB,EAAtB;;WAEUP,QAAQ/H,KAAR,CAAc,GAAd,CAAV;;MAEK,IAAIhF,IAAI,CAAb,EAAgBA,IAAI+M,QAAQhN,MAA5B,EAAoCC,GAApC,EAAyC;MAClCiN,YAAYF,QAAQ/M,CAAR,CAAlB;;MAEIqN,iBAAiBrQ,OAAjB,OAA6BiQ,SAA7B,YAA+C,CAAC,CAApD,EAAuD;4BAC/BA,SAAvB;;;;KAIEK,eAAJ,EAAqB;UACZL,SAAR,GAAoBrG,QAAQqG,SAAR,GAAoBK,eAAxC;;;;;;;;;;;AAWF,SAASC,mBAAT,CAA6B3G,OAA7B,EAAsC4G,SAAtC,EAAiDvG,QAAjD,EAA2D;WAChDN,QAAQsF,GAAR,CAAYrF,OAAZ,EAAqB,WAArB,EAAkC,EAAlC,CAAV,EAAiD4G,SAAjD,EAA4DvG,QAA5D;;;;;;;;;;;;AAYD,SAASwG,oBAAT,CAA8B7G,OAA9B,EAAuC4G,SAAvC,EAAkD1B,QAAlD,EAA4D7E,QAA5D,EAAsE;KAC/DyG,iBAAiB/G,QAAQsF,GAAR,CAAYrF,OAAZ,EAAqB,YAArB,EAAmC,EAAnC,CAAvB;WACU8G,eAAeF,SAAf,EAA0BtB,SAApC,EAA+CJ,QAA/C,EAAyD7E,QAAzD;;;;;;;;;;;AAWD,SAAS0G,SAAT,CAAmB1N,GAAnB,EAAwB2E,GAAxB,EAA6B6B,KAA7B,EAAoC;KAC/B,CAACxG,IAAI2E,GAAJ,CAAL,EAAe;MACVA,GAAJ,IAAW,EAAX;;KAEGA,GAAJ,EAAStE,IAAT,CAAcmG,KAAd;;;;;;;;;AASD,SAASmH,oBAAT,CAA8BhH,OAA9B,EAAuC4G,SAAvC,EAAkD;KAC7CE,iBAAiB/G,QAAQsF,GAAR,CAAYrF,OAAZ,EAAqB,YAArB,EAAmC,EAAnC,CAArB;KACI,CAAC8G,eAAeF,SAAf,CAAL,EAAgC;iBAChBA,SAAf,IAA4B;WACnBvC,GACPrE,OADO,EAEP4G,SAFO,EAGPK,oBAHO,EAIP,CAAC,CAACjB,YAAYY,SAAZ,CAJK,CADmB;cAOhB;GAPZ;;;;;;;;;;;AAmBF,AAAO,SAASM,OAAT,CAAiBlH,OAAjB,EAA0BkF,QAA1B,EAAoC;QACnClF,WAAW,CAACmH,MAAMnH,OAAN,EAAekF,QAAf,CAAnB,EAA6C;YAClClF,QAAQtC,UAAlB;;QAEMsC,OAAP;;;;;;;;;;;AAWD,AAAO,SAASoH,MAAT,CAAgBC,MAAhB,EAAwBC,KAAxB,EAA+B;KACjCjP,SAASiP,KAAT,CAAJ,EAAqB;UACZC,cAAcD,KAAd,CAAR;;KAEGE,eAAeF,KAAf,CAAJ,EAA2B;MACpBG,WAAWlO,MAAMO,SAAN,CAAgBgI,KAAhB,CAAsB9H,IAAtB,CAA2BsN,KAA3B,CAAjB;OACK,IAAIlO,IAAI,CAAb,EAAgBA,IAAIqO,SAAStO,MAA7B,EAAqCC,GAArC,EAA0C;UAClCiD,WAAP,CAAmBoL,SAASrO,CAAT,CAAnB;;EAHF,MAKO;SACCiD,WAAP,CAAmBiL,KAAnB;;QAEMA,KAAP;;;;;;;;AAQD,AAAO,SAASC,aAAT,CAAuBG,UAAvB,EAAmC;KACnCC,UAAU7L,SAASC,aAAT,CAAuB,KAAvB,CAAhB;SACQ6L,SAAR,YAA2BF,UAA3B;SACQ/J,WAAR,CAAoBgK,QAAQE,UAA5B;;KAEMC,WAAWhM,SAASiM,sBAAT,EAAjB;QACOJ,QAAQE,UAAf,EAA2B;WACjBxL,WAAT,CAAqBsL,QAAQE,UAA7B;;QAEMC,QAAP;;;;;;;;;AASD,AAAO,SAASE,QAAT,CAAkBC,QAAlB,EAA4BC,QAA5B,EAAsC;KACxCxQ,WAAWuQ,QAAX,CAAJ,EAA0B;;SAElBA,SAAS7L,eAAT,CAAyB4L,QAAzB,CAAkCE,QAAlC,CAAP;EAFD,MAGO;SACCD,SAASD,QAAT,CAAkBE,QAAlB,CAAP;;;;;;;;;;;;;;;;;;;;AAoBF,AAAO,SAASC,QAAT,CACNnI,OADM,EAEN4G,SAFM,EAGNwB,gBAHM,EAIN3N,QAJM,EAKNyG,eALM,EAML;KACKmH,eAAevC,aAAac,SAAb,CAArB;KACIyB,gBAAgBA,aAAaF,QAAjC,EAA2C;cAC9BE,aAAaC,aAAzB;aACWD,aAAapH,OAAb,CAAqB7F,IAArB,CAA0BiN,YAA1B,EAAwC5N,QAAxC,CAAX;;;KAGGyG,eAAJ,EAAqB;;aAETzG,SAASW,IAAT,EAAX;WACSmN,gBAAT,GAA4B,IAA5B;;;sBAGoBvI,OAArB,EAA8B4G,SAA9B;KACIvO,SAAS+P,gBAAT,CAAJ,EAAgC;uBACVpI,OAArB,EAA8B4G,SAA9B,EAAyCwB,gBAAzC,EAA2D3N,QAA3D;EADD,MAEO;sBACc2N,gBAApB,EAAsCxB,SAAtC,EAAiDnM,QAAjD;;;QAGM,IAAIwK,uBAAJ,CACN5M,SAAS+P,gBAAT,IAA6BpI,OAA7B,GAAuCoI,gBADjC,EAENxB,SAFM,EAGNnM,QAHM,EAINpC,SAAS+P,gBAAT,IAA6BA,gBAA7B,GAAgD,IAJ1C,CAAP;;;;;;;;;;;;AAiBD,SAASI,qBAAT,CAA+BC,IAA/B,EAAqC7B,SAArC,EAAgD8B,QAAhD,EAA0D;KACrDA,YAAY9B,cAAc,OAA1B,IAAqC8B,SAASC,MAAT,KAAoB,CAA7D,EAAgE;;;;SAIxD,KAAP;;;KAGKC,kBAAkB,CACvB,QADuB,EAEvB,OAFuB,EAGvB,QAHuB,EAIvB,UAJuB,EAKvB,UALuB,CAAxB;KAOIhC,cAAc,OAAd,IAAyBgC,gBAAgBxS,OAAhB,CAAwBqS,KAAKI,OAA7B,IAAwC,CAAC,CAAtE,EAAyE;SACjE,EAAEJ,KAAKK,QAAL,IAAiBzB,OAAOoB,IAAP,EAAa,oBAAb,CAAnB,CAAP;;QAEM,IAAP;;;;;;;;AAQD,AAAO,SAASjB,cAAT,CAAwBlQ,GAAxB,EAA6B;QAElCE,gBAAgBF,GAAhB,KACA,OAAOA,IAAI6B,MAAX,KAAsB,QADtB,IAEA,OAAO7B,IAAIyR,IAAX,KAAoB,UAHrB;;;;;;;AAWD;;;;;;AAQA,AAAO,SAASC,YAAT,CAAsBP,IAAtB,EAA4B;KAC9BA,QAAQA,KAAK/K,UAAjB,EAA6B;OACvBA,UAAL,CAAgBC,WAAhB,CAA4B8K,IAA5B;;;;;;;;;;;;;AAaF,SAASxB,oBAAT,CAA8B7G,KAA9B,EAAqC;yBACZA,KAAxB;KACI6I,MAAM,IAAV;KACMC,YAAY9I,MAAM+I,aAAxB;KACMC,SAAS,EAAf;;QAEOC,2BAA2BH,SAA3B,EAAsC9I,KAAtC,EAA6CgJ,MAA7C,CAAP;QACOE,kCAAkCF,MAAlC,EAA0ChJ,KAA1C,CAAP;;OAEMmJ,cAAN,GAAuB,IAAvB;OACMxD,cAAN,IAAwBmD,SAAxB;QACOD,GAAP;;;;;;;;;AASD;;AAQA,AA2BA;;;;;AAKA;;;;;;;;AAUA,AAAO,SAAS9B,KAAT,CAAenH,OAAf,EAAwBkF,QAAxB,EAAkC;KACpC,CAAClF,OAAD,IAAYA,QAAQrI,QAAR,KAAqB,CAArC,EAAwC;SAChC,KAAP;;;KAGK6R,IAAIC,QAAQ3P,SAAlB;KACM4P,IACLF,EAAEG,OAAF,IACAH,EAAEI,qBADF,IAEAJ,EAAEK,kBAFF,IAGAL,EAAEM,iBAHF,IAIAN,EAAEO,gBALH;KAMIL,CAAJ,EAAO;SACCA,EAAE1P,IAAF,CAAOgG,OAAP,EAAgBkF,QAAhB,CAAP;;;QAGM8E,eAAehK,OAAf,EAAwBkF,QAAxB,CAAP;;;;;;;;;;;AAWD,SAAS8E,cAAT,CAAwBhK,OAAxB,EAAiCkF,QAAjC,EAA2C;KACpCxH,aAAasC,QAAQtC,UAA3B;;KAEIA,UAAJ,EAAgB;MACTuM,QAAQvM,WAAWwM,gBAAX,CAA4BhF,QAA5B,CAAd;;OAEK,IAAI9L,IAAI,CAAb,EAAgBA,IAAI6Q,MAAM9Q,MAA1B,EAAkC,EAAEC,CAApC,EAAuC;OAClC6Q,MAAM7Q,CAAN,MAAa4G,OAAjB,EAA0B;WAClB,IAAP;;;;;QAKI,KAAP;;;;;;;;;;AAUD;;;;;;;AAeA,SAASmK,uBAAT,CAAiC/J,KAAjC,EAAwC;OACjCgK,eAAN,GAAwBC,gBAAxB;OACMC,wBAAN,GAAiCC,yBAAjC;;;;;;;;;;;;;;;;AAgBD,AAAO,SAASlG,EAAT,CAAYrE,OAAZ,EAAqB4G,SAArB,EAAgCnM,QAAhC,EAA0CgL,OAA1C,EAAmD;KACrDpN,SAAS2H,OAAT,CAAJ,EAAuB;SACfmI,SAASrM,QAAT,EAAmB8K,SAAnB,EAA8B5G,OAA9B,EAAuCvF,QAAvC,CAAP;;KAEK4N,eAAevC,aAAac,SAAb,CAArB;KACIyB,gBAAgBA,aAAajI,KAAjC,EAAwC;cAC3BiI,aAAaC,aAAzB;aACWD,aAAapH,OAAb,CAAqB7F,IAArB,CAA0BiN,YAA1B,EAAwC5N,QAAxC,CAAX;;SAEOmB,gBAAR,CAAyBgL,SAAzB,EAAoCnM,QAApC,EAA8CgL,OAA9C;QACO,IAAID,cAAJ,CAAmBxF,OAAnB,EAA4B4G,SAA5B,EAAuCnM,QAAvC,EAAiDgL,OAAjD,CAAP;;;;;;;;;;;;;AAaD,AAAO,SAAS+E,IAAT,CAAcxK,OAAd,EAAuB4G,SAAvB,EAAkCnM,QAAlC,EAA4C;KAC5CgQ,iBAAiBpG,GAAGrE,OAAH,EAAY4G,SAAZ,EAAuB,YAAW;iBACzCnG,cAAf;SACOhG,SAASiI,KAAT,CAAe,IAAf,EAAqBX,SAArB,CAAP,CAFwD;EAAlC,CAAvB;QAIO0I,cAAP;;;;;;;;;;AAUD,AAAO,SAASpD,MAAT,CAAgBrH,OAAhB,EAAyBkF,QAAzB,EAAmC;QAClCgC,QAAQlH,QAAQtC,UAAhB,EAA4BwH,QAA5B,CAAP;;;;;;;;;;AAUD;;;;;;;;AA2BA,AAAO,SAASwF,mBAAT,CAA6B9D,SAA7B,EAAwCyB,YAAxC,EAAsD;cAC/CzB,SAAb,IAA0ByB,YAA1B;;;;;;;AAOD,AAAO,SAASsC,cAAT,CAAwBlC,IAAxB,EAA8B;KAChCnB,cAAJ;QACQA,QAAQmB,KAAKZ,UAArB,EAAkC;OAC5BlK,WAAL,CAAiB2J,KAAjB;;;;;;;;;AASF,AAAO,SAASsD,aAAT,CAAuB1E,QAAvB,EAAiCC,OAAjC,EAA0C;KAC5C,CAAClO,SAASiO,QAAT,CAAD,IAAuB,CAAC7N,SAAS8N,OAAT,CAA5B,EAA+C;;;;KAI3C,CAACD,SAAS/M,MAAd,EAAsB;aACV,CAAC+M,QAAD,CAAX;;;MAGI,IAAI9M,IAAI,CAAb,EAAgBA,IAAI8M,SAAS/M,MAA7B,EAAqCC,GAArC,EAA0C;MACrC,eAAe8M,SAAS9M,CAAT,CAAnB,EAAgC;4BACN8M,SAAS9M,CAAT,CAAzB,EAAsC+M,OAAtC;GADD,MAEO;+BACsBD,SAAS9M,CAAT,CAA5B,EAAyC+M,OAAzC;;;;;;;;;;;AAWH,SAAS0E,wBAAT,CAAkC7K,OAAlC,EAA2CmG,OAA3C,EAAoD;SAC3C/H,KAAR,CAAc,GAAd,EAAmBsG,OAAnB,CAA2B,UAAS2B,SAAT,EAAoB;MAC1CA,SAAJ,EAAe;WACNC,SAAR,CAAkBf,MAAlB,CAAyBc,SAAzB;;EAFF;;;;;;;;;AAaD,SAASyE,2BAAT,CAAqC9K,OAArC,EAA8CmG,OAA9C,EAAuD;KAClDM,yBAAuBzG,QAAQqG,SAA/B,MAAJ;;WAEUF,QAAQ/H,KAAR,CAAc,GAAd,CAAV;;MAEK,IAAIhF,IAAI,CAAb,EAAgBA,IAAI+M,QAAQhN,MAA5B,EAAoCC,GAApC,EAAyC;qBACrBqN,iBAAiBrH,OAAjB,OAA6B+G,QAAQ/M,CAAR,CAA7B,QAA4C,GAA5C,CAAnB;;;SAGOiN,SAAR,GAAoBI,iBAAiBsE,IAAjB,EAApB;;;;;;;;AAQD;;;;;;AAWA,SAASR,yBAAT,GAAqC;KAC9BnK,QAAQ,IAAd,CADoC;OAE9B4K,OAAN,GAAgB,IAAhB;OACMC,gBAAN,GAAyB,IAAzB;OACMnR,SAAN,CAAgBwQ,wBAAhB,CAAyCtQ,IAAzC,CAA8CoG,KAA9C;;;;;;;AAOD,SAASiK,gBAAT,GAA4B;KACrBjK,QAAQ,IAAd,CAD2B;OAErB4K,OAAN,GAAgB,IAAhB;OACMlR,SAAN,CAAgBsQ,eAAhB,CAAgCpQ,IAAhC,CAAqCoG,KAArC;;;;;;;;;AASD,AAAO,SAAS8K,aAAT,CAAuBlL,OAAvB,EAAgC4G,SAAhC,EAA2C;KAC7Cd,aAAac,SAAb,CAAJ,EAA6B;SACrB,IAAP;;;KAGGvO,SAAS2H,OAAT,CAAJ,EAAuB;MAClB,CAAC4F,eAAe5F,OAAf,CAAL,EAA8B;kBACdA,OAAf,IAA0BlE,SAASC,aAAT,CAAuBiE,OAAvB,CAA1B;;YAES4F,eAAe5F,OAAf,CAAV;;;KAGKmL,MAAMnL,QAAQ6I,OAApB;KACI,CAAChD,cAAcsF,GAAd,CAAD,IAAuB,CAACtF,cAAcsF,GAAd,EAAmBzU,cAAnB,CAAkCkQ,SAAlC,CAA5B,EAA0E;gBAC3DuE,GAAd,IAAqBtF,cAAcsF,GAAd,KAAsB,EAA3C;gBACcA,GAAd,EAAmBvE,SAAnB,IAAgC,OAAOA,SAAP,IAAoB5G,OAApD;;QAEM6F,cAAcsF,GAAd,EAAmBvE,SAAnB,CAAP;;;;;;;;;;;AAWD,SAAS0C,iCAAT,CAA2CF,MAA3C,EAAmDhJ,KAAnD,EAA0D;KACrD6I,MAAM,IAAV;;MAEK,IAAI7P,IAAI,CAAb,EAAgBA,IAAIgQ,OAAOjQ,MAAX,IAAqB,CAACiH,MAAMgL,gBAA5C,EAA8DhS,GAA9D,EAAmE;QAC5DmQ,cAAN,GAAuBH,OAAOhQ,CAAP,EAAU4G,OAAjC;SACOoJ,OAAOhQ,CAAP,EAAUrD,EAAV,CAAaqK,KAAb,CAAP;;;QAGM6I,GAAP;;;;;;;;;;;;;;AAcD,SAASI,0BAAT,CAAoCH,SAApC,EAA+C9I,KAA/C,EAAsDiL,UAAtD,EAAkE;KAC7DpC,MAAM,IAAV;KACIqC,cAAclL,MAAMrC,MAAxB;KACMwN,QAAQrC,UAAUxL,UAAxB;;QAEO4N,eAAeA,gBAAgBC,KAA/B,IAAwC,CAACnL,MAAM4K,OAAtD,EAA+D;MAC1DxC,sBAAsB8C,WAAtB,EAAmClL,MAAMlI,IAAzC,EAA+CkI,KAA/C,CAAJ,EAA2D;SACpDmJ,cAAN,GAAuB+B,WAAvB;UACOE,yBAAyBF,WAAzB,EAAsClL,KAAtC,EAA6CiL,UAA7C,CAAP;UACOI,0BACNvC,SADM,EAENoC,WAFM,EAGNlL,KAHM,EAINiL,UAJM,CAAP;;gBAOaC,YAAY5N,UAA1B;;;QAGMuL,GAAP;;;;;;;;;;AAUD;;;;;;;;AA2BA;;AAYA,AA6CA;;;;;;;;;;;AAWA,SAASuC,wBAAT,CAAkCxL,OAAlC,EAA2CI,KAA3C,EAAkDiL,UAAlD,EAA8D;KACvDK,gBAAgBtL,MAAM2F,cAAN,CAAtB;KACI,CAACxO,MAAMmU,aAAN,CAAD,IAAyB,CAAC1D,SAAS0D,aAAT,EAAwB1L,OAAxB,CAA9B,EAAgE;MACzD4B,YAAY7B,QAAQsF,GAAR,CAAYrF,OAAZ,EAAqB,WAArB,EAAkC,EAAlC,EAAsCI,MAAMlI,IAA5C,CAAlB;SACOyT,kBAAkB/J,SAAlB,EAA6BxB,KAA7B,EAAoCJ,OAApC,EAA6CqL,UAA7C,CAAP;;QAEM,IAAP;;;;;;;;;;;AAWD;;;;;;;;;;;;;AAoBA,SAASM,iBAAT,CAA2B/J,SAA3B,EAAsCxB,KAAtC,EAA6CJ,OAA7C,EAAsDqL,UAAtD,EAAkE;KAC7DpC,MAAM,IAAV;aACYrH,aAAa,EAAzB;MACK,IAAIxI,IAAI,CAAb,EAAgBA,IAAIwI,UAAUzI,MAAd,IAAwB,CAACiH,MAAM6K,gBAA/C,EAAiE7R,GAAjE,EAAsE;MACjEwI,UAAUxI,CAAV,EAAamP,gBAAjB,EAAmC;cACvB7O,IAAX,CAAgB;oBAAA;QAEXkI,UAAUxI,CAAV;IAFL;GADD,MAKO;UACCwI,UAAUxI,CAAV,EAAagH,KAAb,CAAP;;;QAGK6I,GAAP;;;;;;;;;;;;;;AAcD,SAASwC,yBAAT,CAAmCvC,SAAnC,EAA8ClJ,OAA9C,EAAuDI,KAAvD,EAA8DiL,UAA9D,EAA0E;KACrEpC,MAAM,IAAV;KACM1T,OAAOwK,QAAQsF,GAAR,CAAY6D,SAAZ,EAAuB,YAAvB,EAAqC,EAArC,CAAb;KACM7G,MAAM9M,KAAK6K,MAAMlI,IAAX,EAAiBoN,SAA7B;KACMA,YAAY7G,OAAOD,IAAP,CAAY6D,GAAZ,CAAlB;MACK,IAAIjJ,IAAI,CAAb,EAAgBA,IAAIkM,UAAUnM,MAAd,IAAwB,CAACiH,MAAM6K,gBAA/C,EAAiE7R,GAAjE,EAAsE;MACjE+N,MAAMnH,OAAN,EAAesF,UAAUlM,CAAV,CAAf,CAAJ,EAAkC;OAC3BwI,YAAYS,IAAIiD,UAAUlM,CAAV,CAAJ,CAAlB;UACOuS,kBAAkB/J,SAAlB,EAA6BxB,KAA7B,EAAoCJ,OAApC,EAA6CqL,UAA7C,CAAP;;;QAGKpC,GAAP;;;AC/5BD;;;;;ACGA;;;;;;IAKM2C;;;;;;;;;;;;;;;;;;;+BASQxL,OAAOC,UAAU;OACzB,KAAK0D,cAAL,CAAoBnI,gBAAxB,EAA0C;QACrC,KAAKiQ,gBAAL,CAAsBzL,KAAtB,CAAJ,EAAkC;SAC3B0L,QAAQ1L,MAAMhK,OAAN,CAAc,GAAd,EAAmB,CAAnB,CAAd;SACMwQ,YAAYxG,MAAMjK,SAAN,CAAgB,CAAhB,EAAmB2V,KAAnB,CAAlB;SACM5G,WAAW9E,MAAMjK,SAAN,CAAgB2V,QAAQ,CAAxB,CAAjB;YACO3D,SACN,KAAKpE,cADC,EAEN6C,SAFM,EAGN1B,QAHM,EAIN7E,QAJM,CAAP,CAJiC;KAAlC,MAUO;YACCgE,GAAG,KAAKN,cAAR,EAAwB3D,KAAxB,EAA+BC,QAA/B,CAAP;;IAZF,MAcO;mJACoBD,KAA1B,EAAiCC,QAAjC;;;;;;;;;;;;;mCAUeD,OAAO;UAChBA,MAAM2L,MAAN,CAAa,CAAb,EAAgB,CAAhB,MAAuB,WAA9B;;;;;;;;;;;;uCASoB3L,OAAO;OACvB,CAAC,KAAK2D,cAAN,IAAwB,CAAC,KAAKA,cAAL,CAAoBnI,gBAAjD,EAAmE;WAC3D,IAAP;;UAGC,KAAKiQ,gBAAL,CAAsBzL,KAAtB,KAAgCA,MAAMhK,OAAN,CAAc,GAAd,EAAmB,CAAnB,MAA0B,CAAC,CAA5D,IACA8U,cAAc,KAAKnH,cAAnB,EAAmC3D,KAAnC,CAFD;;;;;;;;;;;;;oCAaiBA,OAAO;UAEvB4L,6IAAwB5L,KAAxB,KAAkC,KAAK6L,oBAAL,CAA0B7L,KAA1B,CADnC,CADwB;;;;EA9DSqD;;ACLnC;;;;IAGMyI;;;;;;;;;;;;;;4CAO4B;OAC5BA,SAASC,mBAAT,KAAiC9W,SAArC,EAAgD;aACtC8W,mBAAT,GAA+B;gBACnBD,SAASE,wBAAT,CAAkC,WAAlC,CADmB;iBAElBF,SAASE,wBAAT,CAAkC,YAAlC;KAFb;;UAKMF,SAASC,mBAAhB;;;;;;;;;;;2CAQ+BjU,MAAM;OAC/BmU,WAAW,CAAC,QAAD,EAAW,IAAX,EAAiB,GAAjB,EAAsB,EAAtB,CAAjB;OACMC,gBAAgBxN,OAAOyN,eAAP,CACrBrU,IADqB,EAErB,CAFqB,EAGrB,CAHqB,EAIrBA,KAAK/B,SAAL,CAAe,CAAf,EAAkB,CAAlB,EAAqBqW,WAArB,EAJqB,CAAtB;OAMMC,WAAW,CACbH,aADa,UAEbA,aAFa,UAGbA,aAHa,UAIbpU,IAJa,SAAjB;OAMI,CAACgU,SAASQ,iBAAd,EAAiC;aACvBA,iBAAT,GAA6B5Q,SAASC,aAAT,CAAuB,KAAvB,CAA7B;;QAEI,IAAI3C,IAAI,CAAb,EAAgBA,IAAIiT,SAASlT,MAA7B,EAAqCC,GAArC,EAA0C;QAExC8S,SAASQ,iBAAT,CAA2B1Q,KAA3B,CACCqQ,SAASjT,CAAT,IAAckT,aADf,MAEMjX,SAHP;MAIE;aACMgX,SAASjT,CAAT,EAAY8F,WAAZ,KAA4BuN,SAASrT,CAAT,CAAnC;;;UAGQlB,IAAV;;;;;;;;;;;;yCAS6B;OACzBgU,SAASS,gBAAT,KAA8BtX,SAAlC,EAA6C;QACtCuX,kBAAkB,2CAAxB;QACM5M,UAAUlE,SAASC,aAAT,CAAuB,KAAvB,CAAhB;WACOiE,OAAP,EAAgB4M,eAAhB;aACSD,gBAAT,GAA4BC,oBAAoB5M,QAAQ4H,SAAxD;;UAEMsE,SAASS,gBAAhB;;;;;;AAIFT,SAASQ,iBAAT,GAA6BrX,SAA7B;AACA6W,SAASC,mBAAT,GAA+B9W,SAA/B;AACA6W,SAASS,gBAAT,GAA4BtX,SAA5B;;ACzEA;;;;IAGMwX;;;;;;;;;;;;;;;sBAQMC,MAAMC,UAAU;OACpBvP,SAAS1B,SAASC,aAAT,CAAuB,QAAvB,CAAf;UACO+Q,IAAP,GAAcA,IAAd;OACIC,QAAJ,EAAc;aACJvP,MAAT;IADD,MAEO;aACGH,IAAT,CAAchB,WAAd,CAA0BmB,MAA1B;;gBAEYA,MAAb;UACOA,MAAP;;;;;;;;;;;;;;;0BAYctB,KAAK8Q,WAAWD,UAAU;OAClCvP,SAAS1B,SAASC,aAAT,CAAuB,QAAvB,CAAf;UACOG,GAAP,GAAaA,GAAb;;OAEMzB,WAAW,SAAXA,QAAW,GAAW;iBACd+C,MAAb;iBACawP,WAAb;IAFD;QAIKxP,MAAL,EAAa,MAAb,EAAqB/C,QAArB;QACK+C,MAAL,EAAa,OAAb,EAAsB/C,QAAtB;;OAEIsS,QAAJ,EAAc;aACJvP,MAAT;IADD,MAEO;aACGH,IAAT,CAAchB,WAAd,CAA0BmB,MAA1B;;;UAGMA,MAAP;;;;;;;;;;;;;;;4BAYgBA,QAAQwP,WAAWD,UAAU;OACvCtS,WAAW,SAAXA,QAAW,GAAW;iBACduS,WAAb;IADD;OAGIxP,OAAOtF,IAAP,IAAesF,OAAOtF,IAAP,KAAgB,iBAAnC,EAAsD;UAC/CqC,QAAN,CAAeE,QAAf;;;gBAGY+C,MAAb;OACIA,OAAOtB,GAAX,EAAgB;WACR2Q,WAAWI,OAAX,CAAmBzP,OAAOtB,GAA1B,EAA+B8Q,SAA/B,EAA0CD,QAA1C,CAAP;IADD,MAEO;UACAxS,QAAN,CAAeE,QAAf;WACOoS,WAAWrS,GAAX,CAAegD,OAAOsP,IAAtB,EAA4BC,QAA5B,CAAP;;;;;;;;;;;;;;;sCAYyB/M,SAASgN,WAAWD,UAAU;OAClDG,UAAUlN,QAAQkK,gBAAR,CAAyB,QAAzB,CAAhB;OACIgD,QAAQ/T,MAAZ,EAAoB;eACRgU,iBAAX,CAA6BD,OAA7B,EAAsC,CAAtC,EAAyCF,SAAzC,EAAoDD,QAApD;IADD,MAEO,IAAIC,SAAJ,EAAe;UACfzS,QAAN,CAAeyS,SAAf;;;;;;;;;;;;;;;;oCAauBE,SAASpB,OAAOkB,WAAWD,UAAU;cAClDK,SAAX,CACCF,QAAQnE,IAAR,CAAa+C,KAAb,CADD,EAEC,YAAW;QACNA,QAAQoB,QAAQ/T,MAAR,GAAiB,CAA7B,EAAgC;gBACpBgU,iBAAX,CACCD,OADD,EAECpB,QAAQ,CAFT,EAGCkB,SAHD,EAICD,QAJD,EAD+B;KAAhC,MAOO,IAAIC,SAAJ,EAAe;WACfzS,QAAN,CAAeyS,SAAf;;IAXH,EAcCD,QAdD;;;;;;ACzGF;;;;IAGMM;;;;;;;;;;;;;;;sBAQMP,MAAMC,UAAU;OACpB/Q,QAAQF,SAASC,aAAT,CAAuB,OAAvB,CAAd;SACM6L,SAAN,GAAkBkF,IAAlB;OACIC,QAAJ,EAAc;aACJ/Q,KAAT;IADD,MAEO;aACGqB,IAAT,CAAchB,WAAd,CAA0BL,KAA1B;;UAEMA,KAAP;;;;;;;;;;;;;;;0BAYcsR,MAAMN,WAAWD,UAAU;OACnCQ,OAAOzR,SAASC,aAAT,CAAuB,MAAvB,CAAb;QACKyR,GAAL,GAAW,YAAX;QACKF,IAAL,GAAYA,IAAZ;oBACiBG,QAAjB,CAA0BF,IAA1B,EAAgCP,SAAhC,EAA2CD,QAA3C;UACOQ,IAAP;;;;;;;;;;;;;;;2BAYevR,OAAOgR,WAAWD,UAAU;OACrCtS,WAAW,SAAXA,QAAW,GAAW;iBACduS,WAAb;IADD;OAGIhR,MAAMwR,GAAN,IAAaxR,MAAMwR,GAAN,KAAc,YAA/B,EAA6C;UACtCjT,QAAN,CAAeE,QAAf;;;;OAIGuB,MAAM6M,OAAN,KAAkB,OAAtB,EAA+B;UACxBtO,QAAN,CAAeE,QAAf;IADD,MAEO;SACDuB,KAAL,EAAY,MAAZ,EAAoBvB,QAApB;SACKuB,KAAL,EAAY,OAAZ,EAAqBvB,QAArB;;;OAGGsS,QAAJ,EAAc;aACJ/Q,KAAT;IADD,MAEO;aACGqB,IAAT,CAAchB,WAAd,CAA0BL,KAA1B;;;UAGMA,KAAP;;;;;;;;;;;;;;qCAWyBgE,SAASgN,WAAWD,UAAU;OACjDW,SAAS1N,QAAQkK,gBAAR,CAAyB,YAAzB,CAAf;OACIwD,OAAOvU,MAAP,KAAkB,CAAlB,IAAuB6T,SAA3B,EAAsC;UAC/BzS,QAAN,CAAeyS,SAAf;;;;OAIGW,YAAY,CAAhB;OACMlT,WAAW,SAAXA,QAAW,GAAW;QACvBuS,aAAa,EAAEW,SAAF,KAAgBD,OAAOvU,MAAxC,EAAgD;WACzCoB,QAAN,CAAeyS,SAAf;;IAFF;QAKK,IAAI5T,IAAI,CAAb,EAAgBA,IAAIsU,OAAOvU,MAA3B,EAAmCC,GAAnC,EAAwC;qBACtBqU,QAAjB,CAA0BC,OAAOtU,CAAP,CAA1B,EAAqCqB,QAArC,EAA+CsS,QAA/C;;;;;;;AC9FH;;;AAGA,SAASa,cAAT,GAA0B;KACnBC,gBAAgB;cACT,WADS;cAET,UAFS;gBAGP,aAHO;gBAIP;EAJf;QAMOrP,IAAP,CAAYqP,aAAZ,EAA2BnJ,OAA3B,CAAmC,UAASkC,SAAT,EAAoB;sBAClCA,SAApB,EAA+B;aACpB,IADoB;YAErB,iBAASnM,QAAT,EAAmB2F,KAAnB,EAA0B;QAC5B0N,UAAU1N,MAAM2N,aAAtB;QACMhQ,SAASqC,MAAMmJ,cAArB;;QAGC,CAACuE,OAAD,IACCA,YAAY/P,MAAZ,IAAsB,CAACiK,SAASjK,MAAT,EAAiB+P,OAAjB,CAFzB,EAGE;WACKE,UAAN,GAAmBpH,SAAnB;YACOnM,SAAS2F,KAAT,CAAP;;IAX4B;kBAcfyN,cAAcjH,SAAd;GAdhB;EADD;;KAmBMqH,oBAAoB;aACd,cADc;cAEb;EAFb;QAIOzP,IAAP,CAAYyP,iBAAZ,EAA+BvJ,OAA/B,CAAuC,UAASwJ,SAAT,EAAoB;MACpDtH,YAAYqH,kBAAkBC,SAAlB,CAAlB;sBACoBtH,SAApB,EAA+B;UACvB,IADuB;aAEpB,IAFoB;YAGrB,iBAASnM,QAAT,EAAmB2F,KAAnB,EAA0B;UAC5B4N,UAAN,GAAmBpH,SAAnB;WACOnM,SAAS2F,KAAT,CAAP;IAL6B;kBAOf8L,SAASiC,uBAAT,GAAmCD,SAAnC;GAPhB;EAFD;;;AAcD,IAAI,CAAC3V,cAAL,EAAqB;;;;ACrDrB,IAAI6V,UAAUA,WAAW,EAAzB;;AAEA,IAAI,OAAO3Y,MAAP,KAAkB,WAAtB,EAAmC;SAC1BA,MAAR,GAAiBA,MAAjB;;;AAGD,IAAI,OAAOqG,QAAP,KAAoB,WAAxB,EAAqC;SAC5BA,QAAR,GAAmBA,QAAnB;;;ACLD;;;;;AAIA,SAASuS,eAAT,CAAyBC,OAAzB,EAAkC;KAC7Bf,OAAOzR,SAASC,aAAT,CAAuB,GAAvB,CAAX;MACKuR,IAAL,GAAYgB,OAAZ;;KAEGf,KAAKxQ,QAAL,KAAkB,GAAlB,IAAyB,CAAC,IAAIwR,IAAJ,CAAShB,KAAKD,IAAd,CAA7B,EAAkD;QAC3C,IAAI9J,SAAJ,CAAiB8K,OAAjB,yBAAN;;;QAGM;QACAf,KAAK7N,IADL;YAEI6N,KAAKiB,QAFT;YAGIjB,KAAKkB,QAHT;YAIIlB,KAAKmB,QAAL,CAAc,CAAd,MAAqB,GAArB,GAA2BnB,KAAKmB,QAAhC,GAA2C,MAAMnB,KAAKmB,QAJ1D;QAKAnB,KAAKoB,IALL;YAMIpB,KAAKxQ,QANT;UAOEwQ,KAAKqB,MAPP;YAQIrB,KAAKsB;EARhB;;;ACTD;;;;;AAKA,SAASC,KAAT,CAAeR,OAAf,EAAwB;KACnBxW,WAAWiX,GAAX,KAAmBA,IAAI5V,MAA3B,EAAmC;MAC5B6V,MAAM,IAAID,GAAJ,CAAQT,OAAR,CAAZ;;;;;MAKIU,IAAIL,IAAJ,IAAYK,IAAI1B,IAAJ,CAASlX,OAAT,CAAiB4Y,IAAIL,IAArB,MAA+B,CAAC,CAAhD,EAAmD;SAC5C,IAAInL,SAAJ,CAAiB8K,OAAjB,yBAAN;;;SAGMU,GAAP;EAVD,MAWO;SACCX,gBAAgBC,OAAhB,CAAP;;;;ACnBF;;;AAGA,IAAIW,SAASxQ,OAAOwQ,MAApB;;;;;;;;IAOMC;;;qBACS;;;;;QAER1Q,IAAL,GAAYyQ,OAAO,IAAP,CAAZ;QACKE,MAAL,GAAcF,OAAO,IAAP,CAAd;;;;;;;;;;;;;;sBASGjZ,MAAM6J,OAAO;QACXrB,IAAL,CAAUxI,KAAKkJ,WAAL,EAAV,IAAgClJ,IAAhC;QACKmZ,MAAL,CAAYnZ,KAAKkJ,WAAL,EAAZ,IAAkC,KAAKiQ,MAAL,CAAYnZ,KAAKkJ,WAAL,EAAZ,KAAmC,EAArE;QACKiQ,MAAL,CAAYnZ,KAAKkJ,WAAL,EAAZ,EAAgCxF,IAAhC,CAAqCmG,KAArC;UACO,IAAP;;;;;;;;;;0BAOO;QACFrB,IAAL,GAAYyQ,OAAO,IAAP,CAAZ;QACKE,MAAL,GAAcF,OAAO,IAAP,CAAd;UACO,IAAP;;;;;;;;;;;;2BASQjZ,MAAM;UACPA,KAAKkJ,WAAL,MAAsB,KAAKiQ,MAAlC;;;;;;;;;oCAMiB;QACZA,MAAL,GAAc,IAAd;;;;;;;;;;;;;;;;;;;yBAuBGnZ,MAAM;OACLmZ,SAAS,KAAKA,MAAL,CAAYnZ,KAAKkJ,WAAL,EAAZ,CAAb;OACIiQ,MAAJ,EAAY;WACJA,OAAO,CAAP,CAAP;;;;;;;;;;;;yBASKnZ,MAAM;UACL,KAAKmZ,MAAL,CAAYnZ,KAAKkJ,WAAL,EAAZ,CAAP;;;;;;;;;;4BAOS;UACF,KAAKkQ,IAAL,OAAgB,CAAvB;;;;;;;;;;0BAOO;;;UACA3Q,OAAOD,IAAP,CAAY,KAAK2Q,MAAjB,EAAyB9M,GAAzB,CAA6B,UAACrE,GAAD;WAAS,OAAKQ,IAAL,CAAUR,GAAV,CAAT;IAA7B,CAAP;;;;;;;;;;;yBAQMhI,MAAM;UACL,KAAKwI,IAAL,CAAUxI,KAAKkJ,WAAL,EAAV,CAAP;UACO,KAAKiQ,MAAL,CAAYnZ,KAAKkJ,WAAL,EAAZ,CAAP;UACO,IAAP;;;;;;;;;;;;;yBAUGlJ,MAAM6J,OAAO;QACXrB,IAAL,CAAUxI,KAAKkJ,WAAL,EAAV,IAAgClJ,IAAhC;QACKmZ,MAAL,CAAYnZ,KAAKkJ,WAAL,EAAZ,IAAkC,CAACW,KAAD,CAAlC;UACO,IAAP;;;;;;;;;;yBAOM;UACC,KAAKwP,KAAL,GAAalW,MAApB;;;;;;;;;;6BAOU;UACHmW,KAAKC,SAAL,CAAe,KAAKJ,MAApB,CAAP;;;;6BApFiBxV,KAAK;OAClB0I,MAAM,IAAI6M,QAAJ,EAAV;OACI1Q,OAAOC,OAAOD,IAAP,CAAY7E,GAAZ,CAAX;QACK,IAAIP,IAAI,CAAb,EAAgBA,IAAIoF,KAAKrF,MAAzB,EAAiCC,GAAjC,EAAsC;QACjCoW,GAAJ,CAAQhR,KAAKpF,CAAL,CAAR,EAAiBO,IAAI6E,KAAKpF,CAAL,CAAJ,CAAjB;;UAEMiJ,GAAP;;;;EA1DqBzE;;ACVvB;;;;;;IAKM6R;mBAEO5P,KAAZ,EAAmB;;;;;;;OAKb6P,MAAL,GAAc7P,KAAd;;;;;;OAMK8P,OAAL,GAAe,IAAf;;;;;;OAMKC,SAAL,GAAiB,IAAjB;;;;;;;;;;;2BAOQtI,OAAO;0BACQA,KAAvB;SACMuI,SAAN,CAAgB,IAAhB;QACKD,SAAL,GAAiB,KAAKA,SAAL,IAAkB,EAAnC;QACKA,SAAL,CAAelW,IAAf,CAAoB4N,KAApB;;;;;;;;;;;2BAQQmB,MAAM;OACVqH,UAAUrH,KAAKsH,SAAL,EAAd;UACOD,OAAP,EAAgB;QACXA,YAAY,IAAhB,EAAsB;YACd,IAAP;;cAESA,QAAQC,SAAR,EAAV;;UAEM,KAAP;;;;;;;;;iCAMc;OACVC,YAAY,EAAhB;OACIvH,OAAO,KAAKsH,SAAL,EAAX;UACOtH,IAAP,EAAa;cACF/O,IAAV,CAAe+O,IAAf;WACOA,KAAKsH,SAAL,EAAP;;UAEMC,SAAP;;;;;;;;;;;;6BASUlE,OAAO;UACV,KAAKmE,WAAL,GAAmBnE,KAAnB,KAA6B,IAApC;;;;;;;;;gCAMa;UACN,KAAK8D,SAAL,IAAkBH,SAASS,WAAlC;;;;;;;;;kCAMe;UACR,KAAKD,WAAL,GAAmB9W,MAA1B;;;;;;;;;6BAMU;OACNgX,QAAQ,CAAZ;OACI1H,OAAO,IAAX;UACOA,KAAKsH,SAAL,EAAP,EAAyB;;WAEjBtH,KAAKsH,SAAL,EAAP;;UAEMI,KAAP;;;;;;;;;8BAMW;UACJ,KAAKR,OAAZ;;;;;;;;;;4BAOS;OACLS,OAAO,IAAX;UACOA,KAAKL,SAAL,EAAP,EAAyB;WACjBK,KAAKL,SAAL,EAAP;;UAEMK,IAAP;;;;;;;;;;6BAOU;UACH,KAAKV,MAAZ;;;;;;;;;2BAMQ;UACD,CAAC,KAAKW,aAAL,EAAR;;;;;;;;;;;8BAQW/I,OAAO;OACdtO,MAAMuM,MAAN,CAAa,KAAK0K,WAAL,EAAb,EAAiC3I,KAAjC,CAAJ,EAA6C;WACrCA,KAAP;;UAEM,IAAP;;;;;;;;;;;;;4BAUSD,QAAQ;QACZsI,OAAL,GAAetI,MAAf;;;;;;;;;;;;;;;;;;;;;;;;2BAqBQiJ,gBAAgBC,iBAAiB;OACrCD,cAAJ,EAAoB;mBACJ,IAAf;;QAEIL,WAAL,GAAmBvL,OAAnB,CAA2B,UAAC4C,KAAD;WAAWA,MAAMkJ,QAAN,CAAeF,cAAf,EAA+BC,eAA/B,CAAX;IAA3B;OACIA,eAAJ,EAAqB;oBACJ,IAAhB;;;;;;;;;;;;;AAUHd,SAASS,WAAT,GAAuB,EAAvB;;;;;;;AAOA,IAAMO,yBAAyB,SAAzBA,sBAAyB,CAASnJ,KAAT,EAAgB;KAC1CA,MAAMyI,SAAN,EAAJ,EAAuB;QAChB,IAAI5a,KAAJ,CAAU,+BAAV,CAAN;;CAFF;;ACxMA,IAAIub,WAAW5B,KAAf;;IAEM6B;;;;;;;;;;;;;;;;;gBAiBqB;MAAdrC,OAAc,uEAAJ,EAAI;;;OACpBU,GAAL,GAAW2B,IAAI7B,KAAJ,CAAU,KAAK8B,4BAAL,CAAkCtC,OAAlC,CAAV,CAAX;;;;;;;;;;;;;;4CAUyBuC,UAAU;;;YAC1BxB,KAAT,GAAiB3K,OAAjB,CAAyB,UAAC1O,IAAD,EAAU;aACzB8a,MAAT,CAAgB9a,IAAhB,EAAsB0O,OAAtB,CAA8B,UAAC7E,KAAD,EAAW;WACnCkR,iBAAL,CAAuB/a,IAAvB,EAA6B6J,KAA7B;KADD;IADD;UAKO,IAAP;;;;;;;;;;;;oCASiB7J,MAAM6J,OAAO;QACzBmR,uBAAL;OACIzZ,MAAMsI,KAAN,CAAJ,EAAkB;YACTvH,OAAOuH,KAAP,CAAR;;QAEIoR,KAAL,CAAW1K,GAAX,CAAevQ,IAAf,EAAqB6J,KAArB;UACO,IAAP;;;;;;;;;;;;qCASkB7J,MAAMmZ,QAAQ;;;UACzBzK,OAAP,CAAe,UAAC7E,KAAD;WAAW,OAAKkR,iBAAL,CAAuB/a,IAAvB,EAA6B6J,KAA7B,CAAX;IAAf;UACO,IAAP;;;;;;;;;;;4CAQyB;;;OACrB,KAAKoR,KAAT,EAAgB;;;QAGXA,KAAL,GAAa,IAAI/B,QAAJ,EAAb;OACIN,SAAS,KAAKI,GAAL,CAASJ,MAAtB;OACIA,MAAJ,EAAY;WACJzY,SAAP,CAAiB,CAAjB,EAAoBiI,KAApB,CAA0B,GAA1B,EAA+BsG,OAA/B,CAAuC,UAACwM,KAAD,EAAW;wBAC9BA,MAAM9S,KAAN,CAAY,GAAZ,CAD8B;;SAC5CJ,GAD4C;SACvC6B,KADuC;;SAE7CtI,MAAMsI,KAAN,CAAJ,EAAkB;cACT8Q,IAAIQ,SAAJ,CAActR,KAAd,CAAR;;YAEIkR,iBAAL,CAAuB/S,GAAvB,EAA4B6B,KAA5B;KALD;;;;;;;;;;;4BAcQ;UACF,KAAKmP,GAAL,CAAStP,IAAT,IAAiB,EAAxB;;;;;;;;;;4BAOS;OACL1C,OAAO,KAAKoU,WAAL,EAAX;OACIpU,IAAJ,EAAU;QACL2R,OAAO,KAAK0C,OAAL,EAAX;QACI1C,QAAQA,SAAS,IAArB,EAA2B;aAClB,MAAMA,IAAd;;;UAGK3R,IAAP;;;;;;;;;;gCAOa;OACTwR,WAAW,KAAKQ,GAAL,CAASR,QAAxB;OACIA,aAAamC,IAAIW,oBAArB,EAA2C;WACnC,EAAP;;UAEM9C,QAAP;;;;;;;;;;8BAOW;OACPxR,OAAO,KAAKuU,OAAL,EAAX;OACIvU,IAAJ,EAAU;WACF,KAAKwU,WAAL,KAAqB,IAArB,GAA4BxU,IAAnC;;UAEM,EAAP;;;;;;;;;;;;;;oCAWiBhH,MAAM;QAClBgb,uBAAL;UACO,KAAKC,KAAL,CAAW5L,GAAX,CAAerP,IAAf,CAAP;;;;;;;;;;;;;qCAUkBA,MAAM;QACnBgb,uBAAL;UACO,KAAKC,KAAL,CAAWH,MAAX,CAAkB9a,IAAlB,CAAP;;;;;;;;;;;sCAQmB;QACdgb,uBAAL;UACO,KAAKC,KAAL,CAAW5B,KAAX,EAAP;;;;;;;;;;;;;;;;gCAea;UACN,KAAKL,GAAL,CAASN,QAAhB;;;;;;;;;;4BAOS;UACF,KAAKM,GAAL,CAASL,IAAhB;;;;;;;;;;gCAOa;UACN,KAAKK,GAAL,CAASjS,QAAhB;;;;;;;;;;;8BAQW;;;OACP6R,SAAS,EAAb;OACI6C,cAAc,EAAlB;QACKC,iBAAL,GAAyBhN,OAAzB,CAAiC,UAAC1O,IAAD,EAAU;WACrC2b,kBAAL,CAAwB3b,IAAxB,EAA8B0O,OAA9B,CAAsC,UAAC7E,KAAD,EAAW;oBACjC7J,IAAf;SACIuB,MAAMsI,KAAN,CAAJ,EAAkB;qBACF,MAAM+R,mBAAmB/R,KAAnB,CAArB;;oBAEc,GAAf;KALD;IADD;iBASc4R,YAAY3P,KAAZ,CAAkB,CAAlB,EAAqB,CAAC,CAAtB,CAAd;OACI2P,WAAJ,EAAiB;cACN,MAAMA,WAAhB;;UAEM7C,MAAP;;;;;;;;;;;+BAQY5Y,MAAM;QACbgb,uBAAL;UACO,KAAKC,KAAL,CAAWjJ,QAAX,CAAoBhS,IAApB,CAAP;;;;;;;;;;+BAOY;QACP6b,iBAAL,CAAuBlB,IAAImB,YAA3B,EAAyChT,OAAOiT,eAAP,EAAzC;UACO,IAAP;;;;;;;;;;;;+CAS4BzD,SAAS;OACjCU,MAAMV,OAAV;OACIA,QAAQlY,OAAR,CAAgB,KAAhB,MAA2B,CAAC,CAA5B,IACHkY,QAAQlY,OAAR,CAAgB,aAAhB,MAAmC,CADpC,EACuC;;;UAEhCua,IAAIqB,gBAAV;QACI1D,QAAQ,CAAR,MAAe,GAAf,IAAsBA,QAAQ,CAAR,MAAe,GAAzC,EAA8C;YACtC,IAAP;;;YAGOA,QAAQ2D,MAAR,CAAe,CAAf,CAAR;UACM,GAAL;UACK,GAAL;UACK,GAAL;aACQtB,IAAIW,oBAAX;aACO,GAAP;aACOhD,OAAP;;UAEI,EAAL;UACK,GAAL;UACKA,QAAQ,CAAR,MAAe,GAAnB,EAAwB;cAChBqC,IAAIW,oBAAX;;aAEMhD,OAAP;;;aAGOA,OAAP;;;UAGIU,GAAP;;;;;;;;;;;;;;;;;kCAgBehZ,MAAM;QAChBgb,uBAAL;QACKC,KAAL,CAAW1L,MAAX,CAAkBvP,IAAlB;UACO,IAAP;;;;;;;;;;iCAOc;QACTkc,eAAL,CAAqBvB,IAAImB,YAAzB;UACO,IAAP;;;;;;;;;;;0BAQOpS,MAAM;QACRsP,GAAL,CAAStP,IAAT,GAAgBA,IAAhB;UACO,IAAP;;;;;;;;;;;8BAQW8O,UAAU;QAChBQ,GAAL,CAASR,QAAT,GAAoBA,QAApB;UACO,IAAP;;;;;;;;;;;;;oCAUiBxY,MAAM6J,OAAO;QACzBqS,eAAL,CAAqBlc,IAArB;QACK+a,iBAAL,CAAuB/a,IAAvB,EAA6B6J,KAA7B;UACO,IAAP;;;;;;;;;;;;;qCAUkB7J,MAAMmZ,QAAQ;;;QAC3B+C,eAAL,CAAqBlc,IAArB;UACO0O,OAAP,CAAe,UAAC7E,KAAD;WAAW,OAAKkR,iBAAL,CAAuB/a,IAAvB,EAA6B6J,KAA7B,CAAX;IAAf;UACO,IAAP;;;;;;;;;;;8BAQW6O,UAAU;QAChBM,GAAL,CAASN,QAAT,GAAoBA,QAApB;UACO,IAAP;;;;;;;;;;;0BAQOC,MAAM;QACRK,GAAL,CAASL,IAAT,GAAgBA,IAAhB;UACO,IAAP;;;;;;;;;;;;;;;;;;8BAiBW5R,UAAU;QAChBiS,GAAL,CAASjS,QAAT,GAAoBA,QAApB;OACI,KAAKiS,GAAL,CAASjS,QAAT,CAAkB,KAAKiS,GAAL,CAASjS,QAAT,CAAkB5D,MAAlB,GAA2B,CAA7C,MAAoD,GAAxD,EAA6D;SACvD6V,GAAL,CAASjS,QAAT,IAAqB,GAArB;;UAEM,IAAP;;;;;;;;;;6BAOU;OACNuQ,OAAO,EAAX;OACItQ,OAAO,KAAKuU,OAAL,EAAX;OACIvU,IAAJ,EAAU;YACD,KAAKwU,WAAL,KAAqB,IAA7B;;WAEOxU,OAAO,KAAKmV,WAAL,EAAP,GAA4B,KAAKC,SAAL,EAA5B,GAA+C,KAAKC,OAAL,EAAvD;UACO/E,IAAP;;;;;;;;;;;;+BA5OmB;UACZoD,QAAP;;;;2BAgHYpC,SAAS;UACdoC,SAASpC,OAAT,CAAP;;;;6BA8FiBgE,SAAS;cACfA,OAAX;;;;4BAoCgBC,UAAoB;qCAAPC,KAAO;SAAA;;;OAChCD,SAASN,MAAT,CAAgBM,SAASpZ,MAAT,GAAkB,CAAlC,MAAyC,GAA7C,EAAkD;eACtCoZ,SAASpc,SAAT,CAAmB,CAAnB,EAAsBoc,SAASpZ,MAAT,GAAkB,CAAxC,CAAX;;WAEOqZ,MAAMnQ,GAAN,CAAU;WAAQoQ,KAAKR,MAAL,CAAY,CAAZ,MAAmB,GAAnB,GAAyBQ,KAAKtc,SAAL,CAAe,CAAf,CAAzB,GAA6Csc,IAArD;IAAV,CAAR;UACO,CAACF,QAAD,EAAWnQ,MAAX,CAAkBoQ,KAAlB,EAAyBE,IAAzB,CAA8B,GAA9B,EAAmCtT,OAAnC,CAA2C,KAA3C,EAAkD,EAAlD,CAAP;;;;;;;;;;;;4BASgBnJ,KAAK;UACd0c,mBAAmB1c,IAAImJ,OAAJ,CAAY,KAAZ,EAAmB,GAAnB,CAAnB,CAAP;;;;;;;;;;;;;;AAWF,IAAMwT,WAAW,SAAXA,QAAW;QACf,OAAOnd,MAAP,KAAkB,WAAlB,IACAA,OAAOqH,QADP,IAEArH,OAAOqH,QAAP,CAAgBC,QAFhB,IAGAtH,OAAOqH,QAAP,CAAgBC,QAAhB,CAAyB3G,OAAzB,CAAiC,OAAjC,MAA8C,CAJ/B;CAAjB;;AAMAua,IAAIqB,gBAAJ,GAAuBY,aAAa,QAAb,GAAwB,OAA/C;;;;;;;AAOAjC,IAAIW,oBAAJ,GAA2B,aAAa9R,KAAKC,GAAL,EAAxC;;;;;;;AAOAkR,IAAImB,YAAJ,GAAmB,IAAnB;;AChdA;;;;;IAIMe;;;;;;;;;;;;;;qCAOqB5U,QAAQF,QAAQ;SACnCjE,SAAN,CAAgBgI,KAAhB,CAAsB9H,IAAtB,CAA2BiE,OAAO6U,UAAlC,EAA8CpO,OAA9C,CAAsD,UAACqO,SAAD;WAAehV,OAAOiV,YAAP,CAAoBD,UAAU/c,IAA9B,EAAoC+c,UAAUlT,KAA9C,CAAf;IAAtD;;;;;;;;;;;0CAQ8B;UACvB,KAAKoT,gCAAL,KAA0C7E,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB4C,IAAzE;;;;;;;;;;;qDAQyC;UAClC0O,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB4R,QAAxB,GAAmCN,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB8R,MAAlE;;;;;;;;;;;gCAQoBnG,MAAM;OACrByK,UADqB,GACK,CADL;OACTC,SADS,GACQ,CADR;;MAEvB;kBACY1K,KAAKyK,UAAnB;iBACazK,KAAK0K,SAAlB;WACO1K,KAAK2K,YAAZ;IAHD,QAIS3K,IAJT;UAKO;0BAAA;;IAAP;;;;;;;;;;;6BAWiBuG,KAAK;OAClBqE,MAAM,IAAI1C,GAAJ,CAAQ3B,GAAR,CAAV;UACOqE,IAAIlB,WAAJ,KAAoBkB,IAAIjB,SAAJ,EAApB,GAAsCiB,IAAIhB,OAAJ,EAA7C;;;;;;;;;;;wCAQ4BrD,KAAK;OAC7BqE,MAAM,IAAI1C,GAAJ,CAAQ3B,GAAR,CAAV;UACOqE,IAAIlB,WAAJ,KAAoBkB,IAAIjB,SAAJ,EAA3B;;;;;;;;;;;iDAQqCpD,KAAK;OACtCqE,MAAM,IAAI1C,GAAJ,CAAQ3B,GAAR,CAAV;UACOqE,IAAIlB,WAAJ,EAAP;;;;;;;;;;;;uCAS2BnD,KAAK;OAC5BA,GAAJ,EAAS;QACFsE,qBAAqB,KAAKL,gCAAL,EAA3B;;;WAGOJ,MAAMU,qBAAN,CAA4BvE,GAA5B,MAAqC,KAAKwE,UAAL,CAAgBF,kBAAhB,CAA5C;;UAEM,KAAP;;;;;;;;;;;4CAQgC;UACzB,CAAC,EAAElF,QAAQ3Y,MAAR,CAAege,OAAf,IAA0BrF,QAAQ3Y,MAAR,CAAege,OAAf,CAAuBC,SAAnD,CAAR;;;;;;;;;;;;2BASe1E,KAAK;OAChB;WACI,IAAI2B,GAAJ,CAAQ3B,GAAR,CAAP;IADD,CAEE,OAAO2E,GAAP,EAAY;YACLC,KAAR,CAAiBD,IAAI/W,OAArB,SAAgCoS,GAAhC;WACO,KAAP;;;;;;;;;;;;sCASyBvG,MAAM;SAC1B3O,SAAN,CAAgBgI,KAAhB,CAAsB9H,IAAtB,CAA2ByO,KAAKqK,UAAhC,EAA4CpO,OAA5C,CAAoD,UAACqO,SAAD;WAAetK,KAAKoL,eAAL,CAAqBd,UAAU/c,IAA/B,CAAf;IAApD;;;;;;;;;;6CAOiCkQ,UAAU;YAClCxB,OAAT,CAAiB,UAAC1E,OAAD;WAAagJ,aAAahJ,OAAb,CAAb;IAAjB;;;;;;;;;;;0CAQ8ByS,MAAM;OAChCtZ,SAASsZ,OAAOA,KAAKtZ,MAAZ,GAAqB,CAAlC;OACIA,SAAS,CAAT,IAAcsZ,KAAKtZ,SAAS,CAAd,MAAqB,GAAvC,EAA4C;WACpCsZ,KAAK1G,MAAL,CAAY,CAAZ,EAAe5S,SAAS,CAAxB,CAAP;;UAEMsZ,IAAP;;;;;;;;;;;2CAQ+BzS,SAAS;WAChCsN,IAAR,GAAetN,QAAQsN,IAAR,GAAe,KAAf,GAAuBtY,KAAKC,MAAL,EAAtC;UACO+K,OAAP;;;;;;;;;;;8BAQkB8T,UAAU;UACrBC,cAAP,CAAsB3F,QAAQtS,QAA9B,EAAwC,UAAxC,EAAoD;kBACrC,IADqC;SAE9C,kBAAW;YACRgY,QAAP;;IAHF;;;;;;AC3KF,qBAAe;WACJ,sBADI;eAEA,0BAFA;kBAGG,8BAHH;QAIP,YAJO;WAKJ,qBALI;UAML,oBANK;uBAOQ;CAPvB;;ACFA;;;;;;;;;;AAUA,AAKA;;;;;;;;AAQA,IAAIE,WAAW,SAAXA,QAAW,GAAW,EAA1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BAA,SAASla,SAAT,CAAmB1B,IAAnB,GAA0B,YAAW,EAArC;;;;;;;;;;AAWA4b,SAASC,mBAAT,GAA+B,gBAA/B;;;;;;;;;;;;AAaAD,SAASE,iBAAT,GAA6B,UAAS5d,IAAT,EAAe;OACrCwD,SAAL,CAAe1B,IAAf,GAAsB9B,KAAKwD,SAAL,CAAe1B,IAArC;OACK0B,SAAL,CAAeqa,cAAf,GAAgC,IAAhC;CAFF;;;;;;;AAWAH,SAASI,eAAT,GAA2B,UAASpd,SAAT,EAAiB;MACtC,CAACA,SAAL,EAAa;WACJ,KAAP;;MAEE;WACK,CAAC,CAACA,UAAOmd,cAAhB;GADF,CAEE,OAAOjZ,CAAP,EAAU;;WAEH,KAAP;;CARJ;;;;;;;;;;;;;;;AA0BA,IAAImZ,UAAU,SAAVA,OAAU,CAASte,EAAT,EAAa;MACrBmI,OAAO3E,MAAMO,SAAN,CAAgBgI,KAAhB,CAAsB9H,IAAtB,CAA2B+H,SAA3B,EAAsC,CAAtC,CAAX;SACO,YAAW;;;QAGZuS,UAAUpW,KAAK4D,KAAL,EAAd;YACQpI,IAAR,CAAagJ,KAAb,CAAmB4R,OAAnB,EAA4BvS,SAA5B;WACOhM,GAAG2M,KAAH,CAAS,IAAT,EAAe4R,OAAf,CAAP;GALF;CAFF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,IAAIC,qBAAqB,SAArBA,kBAAqB,CAASC,QAAT,EAAmBC,WAAnB,EAAgC;;;;;;OAMlDC,MAAL,GAAcH,mBAAmBI,MAAnB,CAA0BC,OAAxC;;;;;;;OAOKC,OAAL,GAAexf,SAAf;;;;;;OAMKsa,OAAL,GAAe,IAAf;;;;;;;OAOKmF,gBAAL,GAAwB,IAAxB;;;;;;OAMKC,UAAL,GAAkB,KAAlB;;MAEIR,mBAAmBS,yBAAnB,GAA+C,CAAnD,EAAsD;;;;;;;;;;;SAW/CC,qBAAL,GAA6B,CAA7B;GAXF,MAYO,IAAIV,mBAAmBS,yBAAnB,KAAiD,CAArD,EAAwD;;;;;;;;;SASxDE,sBAAL,GAA8B,KAA9B;;;MAGE;QACE1S,OAAO,IAAX;aACSxI,IAAT,CACEya,WADF,EACe,UAAS5U,KAAT,EAAgB;WACtBsV,QAAL,CAAcZ,mBAAmBI,MAAnB,CAA0BS,SAAxC,EAAmDvV,KAAnD;KAFJ,EAGK,UAASwV,MAAT,EAAiB;WACbF,QAAL,CAAcZ,mBAAmBI,MAAnB,CAA0BW,QAAxC,EAAkDD,MAAlD;KAJJ;GAFF,CAQE,OAAOna,CAAP,EAAU;SACLia,QAAL,CAAcZ,mBAAmBI,MAAnB,CAA0BW,QAAxC,EAAkDpa,CAAlD;;CAnEJ;;;;;;;;;;;AAgFAqZ,mBAAmBS,yBAAnB,GAA+C,CAA/C;;;;;;;;AASAT,mBAAmBI,MAAnB,GAA4B;;WAEjB,CAFiB;;;WAKjB,CALiB;;;aAQf,CARe;;;YAWhB;CAXZ;;;;;;;;;;;;;;AA2BAJ,mBAAmBgB,cAAnB,GAAoC,IAApC;;;;;;;;AASAhB,mBAAmBiB,OAAnB,GAA6B,UAASC,SAAT,EAAoB;SACxC,IAAIlB,kBAAJ,CAAuB,UAASiB,OAAT,EAAkB;YACpCC,SAAR;GADG,CAAP;CADF;;;;;;;AAYAlB,mBAAmBmB,MAAnB,GAA4B,UAASC,UAAT,EAAqB;SACxC,IAAIpB,kBAAJ,CAAuB,UAASiB,OAAT,EAAkBE,MAAlB,EAA0B;WAC7CC,UAAP;GADG,CAAP;CADF;;;;;;;;AAaApB,mBAAmBqB,IAAnB,GAA0B,UAASC,QAAT,EAAmB;SACpC,IAAItB,kBAAJ,CAAuB,UAASiB,OAAT,EAAkBE,MAAlB,EAA0B;QAChD,CAACG,SAAS1c,MAAd,EAAsB;cACZ9D,SAAR;;SAEG,IAAI+D,IAAI,CAAR,EAAW0c,OAAhB,EAA0BA,UAAUD,SAASzc,CAAT,CAApC,EAAkDA,GAAlD,EAAuD;cAC7ChB,IAAR,CAAaod,OAAb,EAAsBE,MAAtB;;GALC,CAAP;CADF;;;;;;;;;AAmBAnB,mBAAmBwB,GAAnB,GAAyB,UAASF,QAAT,EAAmB;SACnC,IAAItB,kBAAJ,CAAuB,UAASiB,OAAT,EAAkBE,MAAlB,EAA0B;QAChDM,YAAYH,SAAS1c,MAAzB;QACIgW,SAAS,EAAb;;QAEI,CAAC6G,SAAL,EAAgB;cACN7G,MAAR;;;;QAIE8G,YAAY,SAAZA,SAAY,CAASnK,KAAT,EAAgBjM,KAAhB,EAAuB;;aAE9BiM,KAAP,IAAgBjM,KAAhB;UACImW,cAAc,CAAlB,EAAqB;gBACX7G,MAAR;;KAJJ;;QAQI+G,WAAW,SAAXA,QAAW,CAASb,MAAT,EAAiB;aACvBA,MAAP;KADF;;SAIK,IAAIjc,IAAI,CAAR,EAAW0c,OAAhB,EAA0BA,UAAUD,SAASzc,CAAT,CAApC,EAAkDA,GAAlD,EAAuD;cAC7ChB,IAAR,CAAaic,QAAQ4B,SAAR,EAAmB7c,CAAnB,CAAb,EAAoC8c,QAApC;;GAtBC,CAAP;CADF;;;;;;;;;AAoCA3B,mBAAmB4B,cAAnB,GAAoC,UAASN,QAAT,EAAmB;SAC9C,IAAItB,kBAAJ,CAAuB,UAASiB,OAAT,EAAkBE,MAAlB,EAA0B;QAChDU,WAAWP,SAAS1c,MAAxB;QACIkd,UAAU,EAAd;;QAEI,CAACD,QAAL,EAAe;cACL/gB,SAAR;;;;QAIE4gB,YAAY,SAAZA,SAAY,CAASpW,KAAT,EAAgB;cACtBA,KAAR;KADF;;QAIIqW,WAAW,SAAXA,QAAW,CAASpK,KAAT,EAAgBuJ,MAAhB,EAAwB;;cAE7BvJ,KAAR,IAAiBuJ,MAAjB;UACIe,aAAa,CAAjB,EAAoB;eACXC,OAAP;;KAJJ;;SAQK,IAAIjd,IAAI,CAAR,EAAW0c,OAAhB,EAA0BA,UAAUD,SAASzc,CAAT,CAApC,EAAkDA,GAAlD,EAAuD;cAC7ChB,IAAR,CAAa6d,SAAb,EAAwB5B,QAAQ6B,QAAR,EAAkB9c,CAAlB,CAAxB;;GAtBC,CAAP;CADF;;;;;;;;;;;;;;;;;AA4CAmb,mBAAmBza,SAAnB,CAA6B1B,IAA7B,GAAoC,UAASke,eAAT,EAA0BC,cAA1B,EAA0C9B,WAA1C,EAAuD;SAClF,KAAK+B,gBAAL,CACL1e,WAAWwe,eAAX,IAA8BA,eAA9B,GAAgD,IAD3C,EAELxe,WAAWye,cAAX,IAA6BA,cAA7B,GAA8C,IAFzC,EAGL9B,WAHK,CAAP;CADF;AAMAT,SAASE,iBAAT,CAA2BK,kBAA3B;;;;;;;;;;;;;;;;;;;;;;;AAwBAA,mBAAmBza,SAAnB,CAA6B2c,UAA7B,GAA0C,UAASC,UAAT,EAAqBjC,WAArB,EAAkC;MACtEha,WAAW,SAAXA,QAAW,GAAW;QACpB;;iBAEST,IAAX,CAAgBya,WAAhB;KAFF,CAGE,OAAOd,GAAP,EAAY;yBACOgD,gBAAnB,CAAoC3c,IAApC,CAAyC,IAAzC,EAA+C2Z,GAA/C;;GALJ;;OASKiD,iBAAL,CAAuB;WACd,IADc;gBAETnc,QAFS;iBAGRA;GAHf;SAKO,IAAP;CAfF;;;;;;;;;;;;;;;AAgCA8Z,mBAAmBza,SAAnB,CAA6B+c,SAA7B,GAAyC,UAASC,UAAT,EAAqBrC,WAArB,EAAkC;SAClE,KAAK+B,gBAAL,CAAsB,IAAtB,EAA4BM,UAA5B,EAAwCrC,WAAxC,CAAP;CADF;;;;;AAOAF,mBAAmBza,SAAnB,CAA6Bid,KAA7B,GAAqCxC,mBAAmBza,SAAnB,CAA6B+c,SAAlE;;;;;;;;;;;;;;AAeAtC,mBAAmBza,SAAnB,CAA6Bkd,MAA7B,GAAsC,UAASC,WAAT,EAAsB;MACtD,KAAKvC,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BC,OAA9C,EAAuD;UAC/Cpa,GAAN,CAAU,YAAW;UACfmZ,MAAM,IAAIY,mBAAmB2C,iBAAvB,CAAyCD,WAAzC,CAAV;UACIE,qBAAJ,GAA4B,IAA5B;WACKC,eAAL,CAAqBzD,GAArB;KAHF,EAIG,IAJH;;CAFJ;;;;;;;;AAiBAY,mBAAmBza,SAAnB,CAA6Bsd,eAA7B,GAA+C,UAASzD,GAAT,EAAc;MACvD,KAAKe,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BC,OAA9C,EAAuD;QACjD,KAAKjF,OAAT,EAAkB;;WAEXA,OAAL,CAAa0H,YAAb,CAA0B,IAA1B,EAAgC1D,GAAhC;KAFF,MAGO;WACAwB,QAAL,CAAcZ,mBAAmBI,MAAnB,CAA0BW,QAAxC,EAAkD3B,GAAlD;;;CANN;;;;;;;;;;;;AAsBAY,mBAAmBza,SAAnB,CAA6Bud,YAA7B,GAA4C,UAASC,YAAT,EAAuB3D,GAAvB,EAA4B;MAClE,CAAC,KAAKmB,gBAAV,EAA4B;;;MAGxByC,aAAa,CAAjB;MACIC,aAAa,CAAC,CAAlB;;;;OAIK,IAAIpe,IAAI,CAAR,EAAWqe,KAAhB,EAAwBA,QAAQ,KAAK3C,gBAAL,CAAsB1b,CAAtB,CAAhC,EAA2DA,GAA3D,EAAgE;QAC1DkO,QAAQmQ,MAAMnQ,KAAlB;QACIA,KAAJ,EAAW;;UAELA,UAAUgQ,YAAd,EAA4B;qBACble,CAAb;;UAEEoe,cAAc,CAAd,IAAmBD,aAAa,CAApC,EAAuC;;;;;;;;MAQvCC,cAAc,CAAlB,EAAqB;QACf,KAAK9C,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BC,OAA1C,IAAqD2C,eAAe,CAAxE,EAA2E;WACpEH,eAAL,CAAqBzD,GAArB;KADF,MAEO;UACD+D,gBAAgB,KAAK5C,gBAAL,CAAsB/a,MAAtB,CAA6Byd,UAA7B,EAAyC,CAAzC,EAA4C,CAA5C,CAApB;WACKG,gBAAL,CACED,aADF,EACiBnD,mBAAmBI,MAAnB,CAA0BW,QAD3C,EACqD3B,GADrD;;;CA7BN;;;;;;;;;;;AA6CAY,mBAAmBza,SAAnB,CAA6B8c,iBAA7B,GAAiD,UAASc,aAAT,EAAwB;MACnE,CAAC,CAAC,KAAK5C,gBAAN,IAA0B,CAAC,KAAKA,gBAAL,CAAsB3b,MAAlD,MACD,KAAKub,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BS,SAA1C,IACD,KAAKV,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BW,QAFxC,CAAJ,EAEuD;SAChDsC,kBAAL;;MAEE,CAAC,KAAK9C,gBAAV,EAA4B;SACrBA,gBAAL,GAAwB,EAAxB;;OAEGA,gBAAL,CAAsBpb,IAAtB,CAA2Bge,aAA3B;CATF;;;;;;;;;;;;;;;;;;;;;AAgCAnD,mBAAmBza,SAAnB,CAA6B0c,gBAA7B,GAAgD,UAChDqB,WADgD,EACnCf,UADmC,EACvBrC,WADuB,EACV;;MAEhCiD,gBAAgB;WACX,IADW;iBAEL,IAFK;gBAGN;GAHd;;gBAMcpQ,KAAd,GAAsB,IAAIiN,kBAAJ,CAAuB,UAASiB,OAAT,EAAkBE,MAAlB,EAA0B;;kBAEvDmC,WAAd,GAA4BA,cAAc,UAAShY,KAAT,EAAgB;UACpD;YACEiY,SAASD,YAAY7d,IAAZ,CAAiBya,WAAjB,EAA8B5U,KAA9B,CAAb;gBACQiY,MAAR;OAFF,CAGE,OAAOnE,GAAP,EAAY;eACLA,GAAP;;KALwB,GAOxB6B,OAPJ;;;kBAUcsB,UAAd,GAA2BA,aAAa,UAASzB,MAAT,EAAiB;UACnD;YACEyC,SAAShB,WAAW9c,IAAX,CAAgBya,WAAhB,EAA6BY,MAA7B,CAAb;YACI,CAAC9d,MAAMugB,MAAN,CAAD,IAAkBzC,OAAO8B,qBAA7B,EAAoD;;iBAE3C9B,MAAP;SAFF,MAGO;kBACGyC,MAAR;;OANJ,CAQE,OAAOnE,GAAP,EAAY;eACLA,GAAP;;KAVuB,GAYvB+B,MAZJ;GAZoB,CAAtB;;gBA2BcpO,KAAd,CAAoBqI,OAApB,GAA8B,IAA9B;OACKiH,iBAAL;kDACoDc,aADpD;SAEOA,cAAcpQ,KAArB;CAvCF;;;;;;;;AAiDAiN,mBAAmBza,SAAnB,CAA6Bie,kBAA7B,GAAkD,UAASlY,KAAT,EAAgB;MAC5D,KAAK6U,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BqD,OAA9C,EAAuD;UAC/C,IAAI7iB,KAAJ,CAAU,oCAAV,CAAN;;OAEGuf,MAAL,GAAcH,mBAAmBI,MAAnB,CAA0BC,OAAxC;OACKO,QAAL,CAAcZ,mBAAmBI,MAAnB,CAA0BS,SAAxC,EAAmDvV,KAAnD;CALF;;;;;;;;AAeA0U,mBAAmBza,SAAnB,CAA6Bme,iBAA7B,GAAiD,UAAS5C,MAAT,EAAiB;MAC5D,KAAKX,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BqD,OAA9C,EAAuD;UAC/C,IAAI7iB,KAAJ,CAAU,oCAAV,CAAN;;OAEGuf,MAAL,GAAcH,mBAAmBI,MAAnB,CAA0BC,OAAxC;OACKO,QAAL,CAAcZ,mBAAmBI,MAAnB,CAA0BW,QAAxC,EAAkDD,MAAlD;CALF;;;;;;;;;;;;;;;;;;;AA0BAd,mBAAmBza,SAAnB,CAA6Bqb,QAA7B,GAAwC,UAAS+C,KAAT,EAAgB7Y,CAAhB,EAAmB;MACrD,KAAKqV,MAAL,KAAgBH,mBAAmBI,MAAnB,CAA0BC,OAA9C,EAAuD;;;;MAInD,SAASvV,CAAb,EAAgB;YACNkV,mBAAmBI,MAAnB,CAA0BW,QAAlC;QACI,IAAI9R,SAAJ,CAAc,6CAAd,CAAJ;GAFF,MAIO,IAAIwQ,SAASI,eAAT,CAAyB/U,CAAzB,CAAJ,EAAiC;gCACRA,CAA9B;SACKqV,MAAL,GAAcH,mBAAmBI,MAAnB,CAA0BqD,OAAxC;MACE5f,IAAF,CAAO,KAAK2f,kBAAZ,EAAgC,KAAKE,iBAArC,EAAwD,IAAxD;;GAHK,MAMA,IAAIhgB,SAASoH,CAAT,CAAJ,EAAiB;QAClB;UACEjH,OAAOiH,EAAEjH,IAAb;UACIN,WAAWM,IAAX,CAAJ,EAAsB;aACf+f,QAAL,CAAc9Y,CAAd,EAAiBjH,IAAjB;;;KAHJ,CAME,OAAO8C,CAAP,EAAU;cACFqZ,mBAAmBI,MAAnB,CAA0BW,QAAlC;UACIpa,CAAJ;;;;OAIC2Z,OAAL,GAAexV,CAAf;OACKqV,MAAL,GAAcwD,KAAd;OACKN,kBAAL;;MAEIM,UAAU3D,mBAAmBI,MAAnB,CAA0BW,QAApC,IAAgD,CAACjW,EAAE8X,qBAAvD,EAA8E;uBACzDiB,sBAAnB,CAA0C,IAA1C,EAAgD/Y,CAAhD;;CAjCJ;;;;;;;;;;;;;;;;AAoDAkV,mBAAmBza,SAAnB,CAA6Bqe,QAA7B,GAAwC,UAASE,QAAT,EAAmBjgB,IAAnB,EAAyB;OAC1Dsc,MAAL,GAAcH,mBAAmBI,MAAnB,CAA0BqD,OAAxC;MACIlC,UAAU,IAAd;MACIwC,SAAS,KAAb;;MAEI9C,UAAU,SAAVA,OAAU,CAAS3V,KAAT,EAAgB;QACxB,CAACyY,MAAL,EAAa;eACF,IAAT;cACQP,kBAAR,CAA2BlY,KAA3B;;GAHJ;;MAOI6V,SAAS,SAATA,MAAS,CAASL,MAAT,EAAiB;QACxB,CAACiD,MAAL,EAAa;eACF,IAAT;cACQL,iBAAR,CAA0B5C,MAA1B;;GAHJ;;MAOI;SACGrb,IAAL,CAAUqe,QAAV,EAAoB7C,OAApB,EAA6BE,MAA7B;GADF,CAEE,OAAOxa,CAAP,EAAU;WACHA,CAAP;;CAtBJ;;;;;;;;;;;;;;;;;;AA2CAqZ,mBAAmBza,SAAnB,CAA6B8d,kBAA7B,GAAkD,YAAW;MACvD,CAAC,KAAK7C,UAAV,EAAsB;SACfA,UAAL,GAAkB,IAAlB;UACMva,GAAN,CAAU,KAAK+d,iBAAf,EAAkC,IAAlC;;CAHJ;;;;;;;AAaAhE,mBAAmBza,SAAnB,CAA6Bye,iBAA7B,GAAiD,YAAW;SACnD,KAAKzD,gBAAL,IAAyB,KAAKA,gBAAL,CAAsB3b,MAAtD,EAA8D;QACxDqf,UAAU,KAAK1D,gBAAnB;SACKA,gBAAL,GAAwB,EAAxB;;SAEK,IAAI1b,IAAI,CAAb,EAAgBA,IAAIof,QAAQrf,MAA5B,EAAoCC,GAApC,EAAyC;WAClCue,gBAAL,CAAsBa,QAAQpf,CAAR,CAAtB,EAAkC,KAAKsb,MAAvC,EAA+C,KAAKG,OAApD;;;OAGCE,UAAL,GAAkB,KAAlB;CATF;;;;;;;;;;;;;AAwBAR,mBAAmBza,SAAnB,CAA6B6d,gBAA7B,GAAgD,UAChDD,aADgD,EACjCQ,KADiC,EAC1BJ,MAD0B,EAClB;MACxBI,UAAU3D,mBAAmBI,MAAnB,CAA0BS,SAAxC,EAAmD;kBACnCyC,WAAd,CAA0BC,MAA1B;GADF,MAEO;SACAW,yBAAL;kBACc3B,UAAd,CAAyBgB,MAAzB;;CANJ;;;;;;;;;AAkBAvD,mBAAmBza,SAAnB,CAA6B2e,yBAA7B,GAAyD,YAAW;MAC9DjP,CAAJ;MACI+K,mBAAmBS,yBAAnB,GAA+C,CAAnD,EAAsD;SAC/CxL,IAAI,IAAT,EAAeA,KAAKA,EAAEyL,qBAAtB,EAA6CzL,IAAIA,EAAEmG,OAAnD,EAA4D;mBAC7CnG,EAAEyL,qBAAf;QACEA,qBAAF,GAA0B,CAA1B;;GAHJ,MAKO,IAAIV,mBAAmBS,yBAAnB,KAAiD,CAArD,EAAwD;SACxDxL,IAAI,IAAT,EAAeA,KAAKA,EAAE0L,sBAAtB,EAA8C1L,IAAIA,EAAEmG,OAApD,EAA6D;QACzDuF,sBAAF,GAA2B,KAA3B;;;CATN;;;;;;;;;;;;;AA0BAX,mBAAmB6D,sBAAnB,GAA4C,UAAStC,OAAT,EAAkBT,MAAlB,EAA0B;MAChEd,mBAAmBS,yBAAnB,GAA+C,CAAnD,EAAsD;YAC5CC,qBAAR,GAAgCyD,WAAW,YAAW;yBACjC/B,gBAAnB,CAAoC3c,IAApC,CAAyC,IAAzC,EAA+Cqb,MAA/C;KAD8B,EAE7Bd,mBAAmBS,yBAFU,CAAhC;GADF,MAKO,IAAIT,mBAAmBS,yBAAnB,KAAiD,CAArD,EAAwD;YACrDE,sBAAR,GAAiC,IAAjC;UACM1a,GAAN,CAAU,YAAW;UACfsb,QAAQZ,sBAAZ,EAAoC;2BACfyB,gBAAnB,CAAoC3c,IAApC,CAAyC,IAAzC,EAA+Cqb,MAA/C;;KAFJ;;CARJ;;;;;;;;AAuBAd,mBAAmBoC,gBAAnB,GAAsCvc,MAAMC,cAA5C;;;;;;;;;;;;;;AAeAka,mBAAmBoE,4BAAnB,GAAkD,UAAS1X,OAAT,EAAkB;qBAC/C0V,gBAAnB,GAAsC1V,OAAtC;CADF;;;;;;;;;;AAcAsT,mBAAmB2C,iBAAnB;;;kBACcD,WAAZ,EAAyB;;;+GAChBA,WADgB;;QAGlBA,WAAJ,EAAiB;YACVra,OAAL,GAAeqa,WAAf;;;;;;EAL8C9hB,KAArD;;;AAWAof,mBAAmB2C,iBAAnB,CAAqCpd,SAArC,CAA+C9D,IAA/C,GAAsD,QAAtD;;ACp7BA;;;;;;;AAMA,SAAS4iB,QAAT,CAAkB7iB,EAAlB,EAAsB8iB,KAAtB,EAA6B;QACrB,SAASC,SAAT,GAAqB;MACvB5a,OAAO6D,SAAX;iBACe+W,SAAf;YACU5hB,EAAV,GAAewhB,WAAW,YAAW;MACjChW,KAAH,CAAS,IAAT,EAAexE,IAAf;GADc,EAEZ2a,KAFY,CAAf;EAHD;;;;;;AAYD,SAASE,cAAT,CAAwBD,SAAxB,EAAmC;cACrBA,UAAU5hB,EAAvB;;;AClBD,IAAM8hB,QAAQ,mFAAd;;;;;;;AAOA,SAASC,mBAAT,CAA6BtP,OAA7B,EAAsC;QAC9B;SACCA,QAAQ,CAAR,CADD;UAEEA,QAAQ,CAAR,CAFF;QAGAA,QAAQ,CAAR,CAHA;gBAIQA,QAAQ,CAAR,CAJR;kBAKUA,QAAQ,CAAR,CALV;YAMIA,QAAQ,CAAR;EANX;;;;;;;;AAeD,SAASuP,oBAAT,CAA8BC,MAA9B,EAAsC;KACjCC,QAAQ,EAAZ;MACK,IAAIhgB,IAAI,CAAb,EAAgBA,IAAI+f,OAAOhgB,MAA3B,EAAmCC,GAAnC,EAAwC;MACnCigB,OAAKhhB,QAAL,CAAc8gB,OAAO/f,CAAP,CAAd,CAAJ,EAA8B;YACpBkgB,OAAOH,OAAO/f,CAAP,CAAP,CAAT;GADD,MAEO;OACFqM,UAAU8T,yBAAyBJ,OAAO/f,CAAP,EAAUogB,OAAnC,CAAd;OACIL,OAAO/f,CAAP,EAAUqgB,MAAd,EAAsB;eACVF,yBAAyB,QAAQ9T,OAAjC,IAA4C,GAAvD;;aAES6T,OAAOH,OAAO/f,CAAP,EAAUsgB,MAAjB,WAA+BjU,OAA/B,OAAV;OACI0T,OAAO/f,CAAP,EAAUugB,QAAd,EAAwB;QACnB,CAACR,OAAO/f,CAAP,EAAUib,OAAf,EAAwB;eACbkF,yBAAyB9T,OAAzB,CAAV;;eAEU,GAAX;;YAEQA,OAAT;;;QAGK,IAAImU,MAAJ,CAAW,MAAMC,0BAA0BT,KAA1B,CAAN,GAAyC,GAApD,CAAP;;;;;;;;AAQD,SAASG,wBAAT,CAAkCC,OAAlC,EAA2C;gBAC7BA,OAAb;;;;;;;;AAQD,SAASF,MAAT,CAAgBrjB,GAAhB,EAAqB;QACbA,IAAImJ,OAAJ,CAAY,4BAAZ,EAA0C,MAA1C,CAAP;;;;;;;;AAQD,SAASya,yBAAT,CAAmCT,KAAnC,EAA0C;KACrC,MAAM7K,IAAN,CAAW6K,KAAX,CAAJ,EAAuB;WACb,GAAT;EADD,MAEO;WACG,MAAT;;QAEMA,KAAP;;;;;;;;;;AAUD,AAAO,SAAStK,OAAT,CAAegL,aAAf,EAA8B;KAChC,CAACT,OAAKhhB,QAAL,CAAcyhB,aAAd,CAAL,EAAmC;SAC3BA,aAAP;;;KAGKC,QAAQD,aAAd;KACIE,eAAe,CAAnB;KACMb,SAAS,EAAf;KACIc,WAAW,EAAf;KACInO,QAAQ,CAAZ;;KAEInC,UAAUqP,MAAMkB,IAAN,CAAWH,KAAX,CAAd;QACOpQ,OAAP,EAAgB;MACTpU,OAAO0jB,oBAAoBtP,OAApB,CAAb;;aAEWoQ,MAAMjY,KAAN,CAAYgK,KAAZ,EAAmBnC,QAAQmC,KAA3B,CAAX;UACQnC,QAAQmC,KAAR,GAAgBvW,KAAK4R,KAAL,CAAWhO,MAAnC;SACOO,IAAP,CAAYugB,QAAZ;;SAEOvgB,IAAP,CAAY;SACLnE,KAAKS,IAAL,GAAYT,KAAKS,IAAjB,GAAwB,KAAKgkB,cADxB;YAEFD,MAAMjO,KAAN,KAAgBiO,MAAMjO,KAAN,MAAiBvW,KAAKmkB,MAFpC;WAGHnkB,KAAKmkB,MAAL,IAAe,EAHZ;YAIFnkB,KAAK4kB,YAAL,IAAqB5kB,KAAK6kB,cAA1B,IAA4C,SAJ1C;WAKH7kB,KAAK8kB,QAAL,KAAkB,GAAlB,IAAyB9kB,KAAK8kB,QAAL,KAAkB,GALxC;aAMD9kB,KAAK8kB,QAAL,KAAkB,GAAlB,IAAyB9kB,KAAK8kB,QAAL,KAAkB;GANtD;;YASUrB,MAAMkB,IAAN,CAAWH,KAAX,CAAV;;;KAGGjO,QAAQiO,MAAM5gB,MAAlB,EAA0B;SAClBO,IAAP,CAAYqgB,MAAMhO,MAAN,CAAaD,KAAb,CAAZ;;QAEMqN,MAAP;;;;;;;;;;AAUD,AAAO,SAASmB,OAAT,CAAiBR,aAAjB,EAAgC;QAC/BZ,qBAAqBpK,QAAMgL,aAAN,CAArB,CAAP;;;;;;;;;;;AAWD,AAAO,SAASS,WAAT,CAAqBT,aAArB,EAAoCrH,IAApC,EAA0C;KAC1Cld,OAAO,EAAb;KACM4jB,SAASrK,QAAMgL,aAAN,CAAf;KACM3S,QAAQsL,KAAKtL,KAAL,CAAW+R,qBAAqBC,MAArB,CAAX,CAAd;;KAEI,CAAChS,KAAL,EAAY;SACJ,IAAP;;;KAGGqT,aAAa,CAAjB;MACK,IAAIphB,IAAI,CAAb,EAAgBA,IAAI+f,OAAOhgB,MAA3B,EAAmCC,GAAnC,EAAwC;MACnC,CAACigB,OAAKhhB,QAAL,CAAc8gB,OAAO/f,CAAP,CAAd,CAAL,EAA+B;OAC1ByG,QAAQsH,MAAMqT,YAAN,CAAZ;OACInB,OAAK9hB,KAAL,CAAWsI,KAAX,CAAJ,EAAuB;QAClBsZ,OAAO/f,CAAP,EAAUqgB,MAAd,EAAsB;aACb5Z,MAAMzB,KAAN,CAAY,GAAZ,CAAR;;SAEI+a,OAAO/f,CAAP,EAAUpD,IAAf,IAAuB6J,KAAvB;;;;QAIItK,IAAP;;;ICjKKklB;;;;;;;;gBAQOhI,IAAZ,EAAkBxR,OAAlB,EAA2B;;;MACtB,CAACzJ,gBAAgBib,IAAhB,CAAL,EAA4B;SACrB,IAAItd,KAAJ,CAAU,2BAAV,CAAN;;MAEG,CAAC2C,WAAWmJ,OAAX,CAAL,EAA0B;SACnB,IAAI9L,KAAJ,CAAU,kCAAV,CAAN;;;;;;;;;OASI8L,OAAL,GAAeA,OAAf;;;;;;;OAOKwR,IAAL,GAAYA,IAAZ;;;;;;;;;;;;qCAQkB;OACd,CAAC,KAAKiI,WAAV,EAAuB;QAClBvB,SAASrK,QAAM,KAAK2D,IAAX,CAAb;QACI2G,QAAQkB,QAAQnB,MAAR,CAAZ;SACKuB,WAAL,GAAmB;iBAAA;;KAAnB;;UAKM,KAAKA,WAAZ;;;;;;;;;;;;gCASajI,MAAM;OACfpa,SAAS,KAAKoa,IAAd,CAAJ,EAAyB;WACjB8H,YAAY,KAAKI,gBAAL,GAAwBxB,MAApC,EAA4C1G,IAA5C,CAAP;;UAEM,EAAP;;;;;;;;;;+BAOY;UACL,KAAKxR,OAAZ;;;;;;;;;;4BAOS;UACF,KAAKwR,IAAZ;;;;;;;;;;;8BAQW5S,OAAO;OACd4S,OAAO,KAAKA,IAAhB;;OAEI3a,WAAW2a,IAAX,CAAJ,EAAsB;WACdA,KAAK5S,KAAL,CAAP;;OAEGxH,SAASoa,IAAT,CAAJ,EAAoB;WACZ,KAAKkI,gBAAL,GAAwBvB,KAA/B;;OAEG3G,gBAAgBmH,MAApB,EAA4B;WACpB/Z,MAAM+O,MAAN,CAAa6D,IAAb,IAAqB,CAAC,CAA7B;;;UAGM,KAAP;;;;;;ICjGImI;;;;;;;sBAMS;;;;;;;;;;;QASRC,KAAL,GAAa,IAAb;;;;;;;;QAQKC,SAAL,GAAiB,KAAjB;;;;;;;;;;;;;2BAQQC,SAAS;OACb,KAAKD,SAAT,EAAoB;SACdD,KAAL,GAAaE,OAAb;;UAEM,IAAP;;;;;;;;;;+BAOY;QACPF,KAAL,GAAa,IAAb;UACO,IAAP;;;;;;;;;;oCAOiB;QACZG,UAAL;;;;;;;;;;;6BAQU;UACH,KAAKH,KAAZ;;;;;;;;;;gCAOa;UACN,KAAKC,SAAZ;;;;;;;;;;+BAOYA,WAAW;OACnB,CAACA,SAAL,EAAgB;SACVE,UAAL;;QAEIF,SAAL,GAAiBA,SAAjB;;;;EAhFsBld;;ICGlBqd;;;;;;;;;;mBASS;;;;;;;;;;QAQR/jB,EAAL,GAAU,MAAKgkB,OAAL,CAAankB,QAAb,CAAV;;;;;;QAMKokB,KAAL,GAAa,IAAb;;;;;;;;;QASKhf,KAAL,GAAa,IAAb;;;;;;;;;;;;6BAOU;WACFif,GAAR,CAAY,aAAa,IAAb,GAAoB,YAAhC;;;;;;;;;;;;;mCAUgB;WACRA,GAAR,CAAY,aAAa,IAAb,GAAoB,kBAAhC;;;;;;;;;;;;;;qCAWkB;WACVA,GAAR,CAAY,aAAa,IAAb,GAAoB,oBAAhC;;;;;;;;;;;0CAQuB3I,MAAM;UACtBA,IAAP;;;;;;;;;;;2CAQwByF,OAAO;UACxBA,KAAP;;;;;;;;;;;+BAQY;WACJkD,GAAR,CAAY,aAAa,IAAb,GAAoB,cAAhC;;;;;;;;;;;oCAQiB;;WAETA,GAAR,CAAY,aAAa,IAAb,GAAoB,WAAhC;;;;;;;;;;;;;kCAUeC,UAAU;UAClB7c,IAAP,CAAY6c,QAAZ,EAAsB3W,OAAtB,CAA8B,eAAO;QAChC2W,SAASC,GAAT,EAAcC,WAAlB,EAA+B;gBACnBC,mBAAX,CAA+BH,SAASC,GAAT,EAAcC,WAA7C;;IAFF;UAKOhH,mBAAmBiB,OAAnB,EAAP;;;;;;;;;;;;;mCAUgB;UACTjB,mBAAmBiB,OAAnB,EAAP;;;;;;;;;;;;;uBAUI6F,UAAU;;;WACND,GAAR,CAAY,aAAa,IAAb,GAAoB,QAAhC;;OAEIK,cAAc,EAAlB;;UAEOjd,IAAP,CAAY6c,QAAZ,EAAsB3W,OAAtB,CAA8B,eAAO;QAChCgX,UAAUL,SAASC,GAAT,CAAd;QACIK,WAAWD,QAAQE,IAAR,CAAa,OAAK1kB,EAAlB,CAAf;gBACYwC,IAAZ,CAAiBiiB,QAAjB;IAHD;;UAMOpH,mBAAmBwB,GAAnB,CAAuB0F,WAAvB,CAAP;;;;;;;;;;0BAOO;UACA,KAAKvkB,EAAZ;;;;;;;;;;6BAOU;UACH,KAAKikB,KAAZ;;;;;;;;;;;;;;;;sCAamB;WACXC,GAAR,CAAY,aAAa,IAAb,GAAoB,qBAAhC;;;;;;;;;;6BAOU;UACH,KAAKjf,KAAZ;;;;;;;;;;;;;;;yBAYM;WACEif,GAAR,CAAY,aAAa,IAAb,GAAoB,QAAhC;UACO7G,mBAAmBiB,OAAnB,EAAP;;;;;;;;;;;;0BASOte,IAAI;UACJ,YAAYA,EAAnB;;;;;;;;;;wBAOKA,IAAI;QACJA,EAAL,GAAUA,EAAV;;;;;;;;;;2BAOQikB,OAAO;QACVA,KAAL,GAAaA,KAAb;;;;;;;;;;2BAOQhf,OAAO;QACVA,KAAL,GAAaA,KAAb;;;;;;;;;6BAMU;UACH,KAAKjF,EAAZ;;;;EAjPmB0jB;;;;;;;;;AA2PrBK,OAAO7G,eAAP,GAAyB,UAASpd,SAAT,EAAiB;QAClCA,qBAAkBikB,MAAzB;CADD;;IC3PMY;;;;;;;;;kBAQO3kB,EAAZ,EAAgB;;;;;MAGX,CAACA,EAAL,EAAS;SACF,IAAI/B,KAAJ,CAAU,0EAAV,CAAN;;;;;;;;;QASIomB,WAAL,GAAmB,IAAnB;;;;;;;;QAQKO,YAAL,GAAoB,IAApB;;;;;;;;;QASK9b,OAAL,GAAe,IAAf;;;;;;;;QAQK9I,EAAL,GAAUA,EAAV;;;;;;;;QAQK6kB,YAAL,GAAoB,IAApB;;QAEKD,YAAL,GAAoB,MAAKE,QAAL,CAAcH,QAAQI,OAAtB,CAApB;QACKC,0BAAL;QACKX,WAAL,GAAmB,MAAKO,YAAxB;;;;;;;;;;;;;;;;;;6BAaUK,UAAUC,aAAa;OAC7B9U,QAAQ,KAAKwU,YAAjB;;OAEItkB,gBAAgB4kB,WAAhB,CAAJ,EAAkC;YACzB,KAAKJ,QAAL,CAAcG,QAAd,CAAR;QACI7U,KAAJ,EAAW;oBACKA,KAAf;KADD,MAEO;aACE,KAAK+U,WAAL,CAAiBF,QAAjB,CAAR;UACKG,UAAL,CAAgBhV,KAAhB,EAAuB,IAAvB;;WAEMA,KAAP,EAAc8U,WAAd;;;OAGGpc,UAAU,KAAKuc,UAAL,EAAd;;OAEIvc,WAAWsH,KAAf,EAAsB;WACdtH,OAAP,EAAgBsH,KAAhB;;;UAGMA,KAAP;;;;;;;;;;;8BAQW6U,UAAU;OACjB7U,QAAQ8G,QAAQtS,QAAR,CAAiBC,aAAjB,CAA+B,KAA/B,CAAZ;SACMiX,YAAN,CAAmB,IAAnB,EAAyB,KAAKkI,OAAL,CAAaiB,QAAb,CAAzB;UACO7U,KAAP;;;;;;;;;;;2BAQQ6U,UAAU;UACX/N,QAAQtS,QAAR,CAAiB0gB,cAAjB,CAAgC,KAAKtB,OAAL,CAAaiB,QAAb,CAAhC,CAAP;;;;;;;;;;;;+BASY;OACR,KAAKnc,OAAT,EAAkB;WACV,KAAKA,OAAZ;;QAEIA,OAAL,GAAeoO,QAAQtS,QAAR,CAAiB0gB,cAAjB,CAAgC,KAAKtlB,EAArC,CAAf;UACO,KAAK8I,OAAZ;;;;;;;;;;0BAOO;UACA,KAAK9I,EAAZ;;;;;;;;;;;oCAQiB;UACV,KAAK6kB,YAAZ;;;;;;;;;;;;0BASOI,UAAU;UACV,KAAKjlB,EAAL,GAAU,GAAV,GAAgBilB,QAAvB;;;;;;;;;;;;+CAS4B;OACxBnc,UAAU,KAAKuc,UAAL,EAAd;OACIvc,WAAW,CAAC,KAAK8b,YAArB,EAAmC;QAC9BhU,WAAWsG,QAAQtS,QAAR,CAAiBiM,sBAAjB,EAAf;WACO/H,QAAQ6H,UAAf,EAA2B;cACjBxL,WAAT,CAAqB2D,QAAQ6H,UAA7B;;SAEIiU,YAAL,GAAoB,KAAKW,UAAL,CAAgBZ,QAAQI,OAAxB,EAAiCnU,QAAjC,CAApB;SACKwU,UAAL,CAAgB,IAAhB,EAAsB,KAAKR,YAA3B;;;;;;;;;;;wBAQI5kB,IAAI;QACJA,EAAL,GAAUA,EAAV;;;;;;;;;;;kCAQe6kB,cAAc;QACxBA,YAAL,GAAoBA,YAApB;;;;;;;;;;;uBAQII,UAAU;OACVO,OAAO,KAAKnB,WAAhB;OACIoB,KAAK,KAAKX,QAAL,CAAcG,QAAd,CAAT;OACI,CAACQ,EAAL,EAAS;SACH,KAAKb,YAAV;;QAEIP,WAAL,GAAmBoB,EAAnB;UACO,KAAKL,UAAL,CAAgBI,IAAhB,EAAsBC,EAAtB,EAA0BlG,UAA1B,CAAqC,YAAM;QAC7CiG,QAAQA,SAASC,EAArB,EAAyB;kBACXD,IAAb;;IAFK,CAAP;;;;;;;;;;yBAWMP,UAAU;OACZ7U,QAAQ,KAAK0U,QAAL,CAAcG,QAAd,CAAZ;OACI7U,KAAJ,EAAW;iBACGA,KAAb;;;;;;;;;;6BAOS;UACH,KAAKpQ,EAAZ;;;;;;;;;;;;;6BAUUwlB,MAAMC,IAAI;OAChBZ,eAAe,KAAKA,YAAL,IAAqBF,QAAQe,iBAAhD;UACOrI,mBAAmBiB,OAAnB,CAA2BuG,aAAa/hB,IAAb,CAAkB,IAAlB,EAAwB0iB,IAAxB,EAA8BC,EAA9B,CAA3B,CAAP;;;;EA5OoB/e;;;;;;;;;;;;;;;;;;;;;;;AAoQtBie,QAAQI,OAAR,GAAkB,SAAlB;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BAJ,QAAQe,iBAAR,GAA4B,UAASF,IAAT,EAAeC,EAAf,EAAmB;KAC1CD,IAAJ,EAAU;OACJ1gB,KAAL,CAAWC,OAAX,GAAqB,MAArB;OACKqK,SAAL,CAAef,MAAf,CAAsB,SAAtB;;KAEGoX,EAAJ,EAAQ;KACJ3gB,KAAH,CAASC,OAAT,GAAmB,OAAnB;KACGqK,SAAH,CAAaC,GAAb,CAAiB,SAAjB;;CAPF;;ACvRA,IAAMsW,qBAAqB;YACf,WADe;gBAEX;CAFhB;;IAKMC;;;;;;;;gBAOS;;;;;;;;;;QAQRC,YAAL,GAAoB,IAApB;;;;;;;QAOKC,UAAL,GAAkB,IAAlB;;;;;;;;QAQKC,oBAAL,GAA4B,IAA5B;;;;;;;;QAQK1K,QAAL,GAAgB,EAAhB;;;;;;;;QAQK2K,yBAAL,GAAiCrK,MAAMI,gCAAN,EAAjC;;;;;;;;QAQKkK,oCAAL,GAA4C,IAA5C;;;;;;;;QAQKC,YAAL,GAAoBhP,QAAQtS,QAAR,CAAiBK,KAArC;;;;;;;;QAQKkhB,YAAL,GAAoB,2DAApB;;;;;;;;QAQKC,8BAAL,GAAsC,KAAtC;;;;;;;;QAQKC,YAAL,GAAoB,gDAApB;;;;;;;;QAQKC,eAAL,GAAuB,eAAvB;;;;;;;;;;;;;;;QAeKC,gCAAL,GAAyC,uBAAuBrP,QAAQ3Y,MAAR,CAAege,OAA/E;;;;;;;;;;;QAWKiK,kBAAL,GAA0Bb,mBAAmBc,SAA7C;;;;;;;;;QASKC,mBAAL,GAA2B,KAA3B;;;;;;;;QAQKC,eAAL,GAAuB,IAAvB;;;;;;;;;QASKC,kBAAL,GAA0B,CAA1B;;;;;;;;;QASKC,iBAAL,GAAyB,CAAzB;;;;;;;QAOKC,YAAL,GAAoB,IAApB;;;;;;;;QAQKC,MAAL,GAAc,EAAd;;;;;;;;QAQKC,wBAAL,GAAgC,EAAhC;;;;;;;;QAQKC,OAAL,GAAe,EAAf;;;;;;;;;;QAUKC,gBAAL,GAAwB,KAAxB;;;;;;;;QAQK/C,QAAL,GAAgB,EAAhB;;;;;;;;;;QAUKgD,oBAAL,GAA4B,IAA5B;;QAEKC,iBAAL,GAAyB,IAAIvZ,YAAJ,EAAzB;;QAEKuZ,iBAAL,CAAuB/X,GAAvB,CACClC,GAAG+J,QAAQ3Y,MAAX,EAAmB,QAAnB,EAA6BmjB,SAAS,MAAK2F,SAAL,CAAenjB,IAAf,OAAT,EAAoC,GAApC,CAA7B,CADD,EAECiJ,GAAG+J,QAAQ3Y,MAAX,EAAmB,MAAnB,EAA2B,MAAK+oB,OAAL,CAAapjB,IAAb,OAA3B,CAFD,EAGCiJ,GAAG+J,QAAQ3Y,MAAX,EAAmB,UAAnB,EAA+B,MAAKgpB,WAAL,CAAiBrjB,IAAjB,OAA/B,CAHD;;QAMKiJ,EAAL,CAAQ,eAAR,EAAyB,MAAKqa,gBAA9B;QACKra,EAAL,CAAQ,gBAAR,EAA0B,MAAKsa,iBAA/B;QACKta,EAAL,CAAQ,gBAAR,EAA0B,MAAKua,wBAA/B,EAAyD,IAAzD;QACKva,EAAL,CAAQ,cAAR,EAAwB,MAAKwa,sBAA7B;;QAEKC,eAAL,CAAqB,MAAKvB,YAA1B;QACKwB,eAAL,CAAqB,MAAK1B,YAA1B;;QAEK2B,0BAAL;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAsBSf,QAAQ;;;OACb,CAAC1kB,MAAMC,OAAN,CAAcykB,MAAd,CAAL,EAA4B;aAClB,CAACA,MAAD,CAAT;;UAEMvZ,OAAP,CAAe,UAACqV,KAAD,EAAW;QACrB,EAAEA,iBAAiBU,KAAnB,CAAJ,EAA+B;aACtB,IAAIA,KAAJ,CAAUV,MAAMtH,IAAhB,EAAsBsH,MAAM9Y,OAA5B,CAAR;;WAEIgd,MAAL,CAAYvkB,IAAZ,CAAiBqgB,KAAjB;IAJD;UAMO,IAAP;;;;;;;;;;;;;;8BAWWsB,UAAU;;;OACjB,CAAC9hB,MAAMC,OAAN,CAAc6hB,QAAd,CAAL,EAA8B;eAClB,CAACA,QAAD,CAAX;;YAEQ3W,OAAT,CAAiB,UAACgX,OAAD,EAAa;QACzBrjB,SAASqjB,OAAT,CAAJ,EAAuB;eACZ,IAAIG,OAAJ,CAAYH,OAAZ,CAAV;;WAEIL,QAAL,CAAcK,QAAQuD,KAAR,EAAd,IAAiCvD,OAAjC;IAJD;UAMO,IAAP;;;;;;;;;;;8BAQW1M,KAAK;OACVqE,MAAMR,MAAMqM,QAAN,CAAelQ,GAAf,CAAZ;;OAEI,CAACqE,GAAL,EAAU;WACF,KAAP;;;OAGKZ,OAAOI,MAAMW,UAAN,CAAiBxE,GAAjB,CAAb;;OAEI,CAAC,KAAKmQ,iBAAL,CAAuB9L,IAAI9B,OAAJ,EAAvB,CAAL,EAA4C;YACnC6J,GAAR,CAAY,sBAAZ;WACO,KAAP;;OAEG,CAAC,KAAKgE,eAAL,CAAqB3M,IAArB,CAAL,EAAiC;YACxB2I,GAAR,CAAY,uCAAZ;WACO,KAAP;;;OAGG/H,IAAIhB,OAAJ,MAAiBQ,MAAMwM,oBAAN,CAA2B5M,IAA3B,CAArB,EAAuD;WAC/C,KAAP;;OAEG,CAAC,KAAK6M,SAAL,CAAe7M,IAAf,CAAL,EAA2B;YAClB2I,GAAR,CAAY,kBAAkB3I,IAA9B;WACO,KAAP;;;UAGM,IAAP;;;;;;;;;;sCAOmB;;;UACZjU,IAAP,CAAY,KAAK2f,OAAjB,EAA0BzZ,OAA1B,CAAkC,UAAC+N,IAAD,EAAU;QACvCA,SAAS,OAAKuK,UAAlB,EAA8B;YACxBD,YAAL,CAAkB/B,UAAlB;KADD,MAEO,IAAI,EAAE,OAAK4C,mBAAL,IAA4B,OAAKC,eAAL,CAAqBpL,IAArB,KAA8BA,IAA5D,CAAJ,EAAuE;YACxE8M,YAAL,CAAkB9M,IAAlB;;IAJF;;;;;;;;;;;uCAcoBA,MAAMsH,OAAO;OAC7B,CAAC,KAAK8D,eAAN,IAAyBpL,SAAS,KAAKuK,UAA3C,EAAuD;YAC9C5B,GAAR,CAAY,4CAAZ;WACO,KAAK2B,YAAZ;;;OAGGyC,SAAS,KAAKrB,OAAL,CAAa1L,IAAb,CAAb;OACI,CAAC+M,MAAL,EAAa;QACRve,UAAU8Y,MAAM0F,UAAN,EAAd;QACIxe,YAAYga,MAAZ,IAAsBA,OAAO7G,eAAP,CAAuBnT,QAAQnH,SAA/B,CAA1B,EAAqE;cAC3D,IAAImH,OAAJ,EAAT;KADD,MAEO;cACGA,QAAQ8Y,KAAR,KAAkB,IAAIkB,MAAJ,EAA3B;;YAEOG,GAAR,CAAY,wBAAwB3I,IAAxB,GAA+B,KAA/B,GAAuC+M,MAAvC,GAAgD,GAA5D;;UAEMA,MAAP;;;;;;;;;oCAMiB;OACb,KAAKzC,YAAT,EAAuB;SACjBwC,YAAL,CAAkB,KAAKvC,UAAvB;;QAEI0C,iBAAL;QACKC,iBAAL,CAAuBlf,cAAvB;QACKmf,iBAAL,CAAuBnf,cAAvB;QACK6d,iBAAL,CAAuBuB,kBAAvB;;;;;;;;;;;;6BASU;UACH,KAAKC,QAAL,CAAcjN,MAAMkN,qBAAN,EAAd,EAA6C,IAA7C,CAAP;;;;;;;;;;;;8BASWtN,MAAMuN,oBAAoB;;;OACjCjG,QAAQ,KAAKuF,SAAL,CAAe7M,IAAf,CAAZ;OACI,CAACsH,KAAL,EAAY;SACN8D,eAAL,GAAuBtJ,mBAAmBmB,MAAnB,CAA0B,IAAInB,mBAAmB2C,iBAAvB,CAAyC,kBAAkBzE,IAA3D,CAA1B,CAAvB;WACO,KAAKoL,eAAZ;;;WAGOzC,GAAR,CAAY,kBAAkB3I,IAAlB,GAAyB,GAArC;;QAEKwN,oBAAL;QACKrC,mBAAL,GAA2B,IAA3B;;OAEIsC,aAAa,KAAKC,oBAAL,CAA0B1N,IAA1B,EAAgCsH,KAAhC,CAAjB;;UAEO,KAAKqG,uBAAL,GACLhoB,IADK,CACA;WAAM,OAAKioB,qBAAL,CAA2BH,UAA3B,CAAN;IADA,EAEL9nB,IAFK,CAEA;WAAM8nB,WAAWI,IAAX,CAAgB7N,IAAhB,CAAN;IAFA,EAGLra,IAHK,CAGA,YAAM;;;WAGNslB,kBAAL,GAA0Bb,mBAAmB0D,aAA7C;;QAEI,OAAKxD,YAAT,EAAuB;YACjBA,YAAL,CAAkByD,UAAlB;;WAEIC,uBAAL,CAA6BhO,IAA7B,EAAmCyN,UAAnC,EAA+CF,kBAA/C;WACKU,wBAAL,CACCR,UADD,EAEC,OAAK7E,QAFN,EAGC,OAAKsF,aAAL,CAAmB5G,KAAnB,EAA0BtH,IAA1B,CAHD;IAZK,EAkBLra,IAlBK,CAkBA;WAAM8nB,WAAWU,cAAX,CAA0B,OAAKvF,QAA/B,CAAN;IAlBA,EAmBLjjB,IAnBK,CAmBA;WAAM8nB,WAAWW,IAAX,CAAgB,OAAKxF,QAArB,CAAN;IAnBA,EAoBLjjB,IApBK,CAoBA;WAAM8nB,WAAWY,eAAX,CAA2B,OAAKzF,QAAhC,CAAN;IApBA,EAqBLjjB,IArBK,CAqBA;WAAM,OAAK2oB,+BAAL,EAAN;IArBA,EAsBL3oB,IAtBK,CAsBA;WAAM,OAAK4oB,gCAAL,EAAN;IAtBA,EAuBL5oB,IAvBK,CAuBA;WAAM,OAAK6oB,iBAAL,CAAuBxO,IAAvB,EAA6ByN,UAA7B,CAAN;IAvBA,EAwBL9nB,IAxBK,CAwBA;WAAM,OAAK4mB,0BAAL,EAAN;IAxBA,EAyBLjI,KAzBK,CAyBC,UAAC1B,MAAD,EAAY;WACbuI,mBAAL,GAA2B,KAA3B;WACKsD,oBAAL,CAA0BzO,IAA1B,EAAgCyN,UAAhC,EAA4C7K,MAA5C;UACMA,MAAN;IA5BK,EA8BLoB,UA9BK,CA8BM,YAAM;WACZiH,kBAAL,GAA0Bb,mBAAmBc,SAA7C;;QAEI,OAAKO,wBAAL,CAA8B/kB,MAAlC,EAA0C;SACnCgoB,sBAAsB,OAAKjD,wBAAL,CAA8BkD,KAA9B,EAA5B;YACKC,cAAL,CAAoBF,oBAAoB7T,IAAxC,EAA8C6T,mBAA9C;;IAnCI,CAAP;;;;;;;;;;;;gCA8CapH,OAAOtH,MAAM;UACnBsH,MAAM4G,aAAN,CAAoB,KAAKW,YAAL,CAAkB7O,IAAlB,CAApB,CAAP;;;;;;;;;;;;oCASiBA,MAAMyN,YAAY;cACxBqB,QAAX;;OAEI,KAAKxE,YAAL,IAAqB,CAAC,KAAKA,YAAL,CAAkByE,WAAlB,EAA1B,EAA2D;QACtD,KAAKzE,YAAL,KAAsBmD,UAA1B,EAAsC;UAChCX,YAAL,CAAkB,KAAKvC,UAAvB;;;;QAIGA,UAAL,GAAkBvK,IAAlB;QACKsK,YAAL,GAAoBmD,UAApB;QACKhD,yBAAL,GAAiCrK,MAAMI,gCAAN,EAAjC;QACKkL,OAAL,CAAa1L,IAAb,IAAqByN,UAArB;QACKtC,mBAAL,GAA2B,KAA3B;QACKC,eAAL,GAAuB,IAAvB;WACQ4D,mBAAR,GAA8B,IAA9B;WACQC,yBAAR,GAAoC,IAApC;WACQtG,GAAR,CAAY,iBAAZ;;;;;;;;;;;;;4BAUS3I,MAAM;UACR,KAAK6O,YAAL,CAAkB7O,IAAlB,CAAP;QACK,IAAIrZ,IAAI,CAAb,EAAgBA,IAAI,KAAK6kB,MAAL,CAAY9kB,MAAhC,EAAwCC,GAAxC,EAA6C;QACxC2gB,QAAQ,KAAKkE,MAAL,CAAY7kB,CAAZ,CAAZ;QACI2gB,MAAM4H,WAAN,CAAkBlP,IAAlB,CAAJ,EAA6B;YACrBsH,KAAP;;;;UAIK,IAAP;;;;;;;;;;4CAOyB;UAClB,KAAKkD,oBAAZ;;;;;;;;;;gCAOa;UACN,KAAK1K,QAAZ;;;;;;;;;;oCAOiB;UACV,KAAK6K,YAAZ;;;;;;;;;;oCAOiB;UACV,KAAKC,YAAZ;;;;;;;;;;sDAOmC;UAC5B,KAAKC,8BAAZ;;;;;;;;;;oCAOiB;UACV,KAAKC,YAAZ;;;;;;;;;;uCAOoB;UACb,KAAKC,eAAZ;;;;;;;;;;;;;+BAUY/K,MAAM;OACd,KAAKmP,iCAAL,EAAJ,EAA8C;WACtC/O,MAAMgP,8BAAN,CAAqCpP,IAArC,CAAP;WACOI,MAAMgP,8BAAN,CAAqCpP,KAAK1G,MAAL,CAAY,KAAKwG,QAAL,CAAcpZ,MAA1B,CAArC,CAAP;;;UAGM0Z,MAAMU,qBAAN,CAA4Bd,IAA5B,CAAP;UACOI,MAAMU,qBAAN,CAA4Bd,KAAK1G,MAAL,CAAY,KAAKwG,QAAL,CAAcpZ,MAA1B,CAA5B,CAAP;;;;;;;;;;4CAOyB;UAClB,KAAKklB,oBAAZ;;;;;;;;;;;;;uCAUoB5L,MAAMyN,YAAYtM,OAAO;;;WACrCwH,GAAR,CAAY,2BAA2B8E,UAA3B,GAAwC,KAAxC,GAAgDtM,MAAMkO,KAAtD,GAA8D,GAA1E;QACKvd,IAAL,CAAU,iBAAV,EAA6B;gBAAA;0BAAA;;IAA7B;OAKI,CAACsO,MAAMwM,oBAAN,CAA2B5M,IAA3B,CAAL,EAAuC;QAClC,KAAKmL,mBAAL,IAA4B,KAAKC,eAArC,EAAsD;UAChDA,eAAL,CAAqBpH,UAArB,CAAgC;aAAM,OAAK8I,YAAL,CAAkB9M,IAAlB,CAAN;MAAhC,EAA+D,IAA/D;KADD,MAEO;UACD8M,YAAL,CAAkB9M,IAAlB;;;;;;;;;;;;8BASS;UACJ,KAAKwL,MAAL,CAAY9kB,MAAZ,GAAqB,CAA5B;;;;;;;;;;;;;oCAUiB6D,MAAM;OACjB+kB,UAAU,IAAIpR,GAAJ,CAAQ3T,IAAR,CAAhB;OACMglB,kBAAkB,IAAIrR,GAAJ,CAAQvC,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwBE,IAAhC,CAAxB;;UAEO+kB,QAAQ1Q,OAAR,OAAsB2Q,gBAAgB3Q,OAAhB,EAAtB,IAAmD0Q,QAAQ3Q,WAAR,OAA0B4Q,gBAAgB5Q,WAAhB,EAApF;;;;;;;;;;;;kCASeqB,MAAM;UACdA,KAAKrc,OAAL,CAAa,KAAKmc,QAAlB,MAAgC,CAAvC;;;;;;;;;;;;+CAS4B;OACxB2F,QAAQ9J,QAAQ3Y,MAAR,CAAege,OAAf,CAAuByE,KAAnC;OACI,CAACA,KAAL,EAAY;;;;;;;;;;;OAWR+J,SAAS,KAAb;OACIC,2BAA2B,SAA3BA,wBAA2B,GAAW;YACjCpmB,QAAR,CAAiB6J,mBAAjB,CAAqC,QAArC,EAA+Cuc,wBAA/C,EAAyE,KAAzE;QACI,CAACD,MAAL,EAAa;aACJxsB,MAAR,CAAe0sB,QAAf,CAAwBjK,MAAMkK,UAA9B,EAA0ClK,MAAMmK,SAAhD;cACS,IAAT;;IAJF;SAOM9nB,QAAN,CAAe2nB,wBAAf;WACQpmB,QAAR,CAAiBF,gBAAjB,CAAkC,QAAlC,EAA4CsmB,wBAA5C,EAAsE,KAAtE;;;;;;;;;;wDAOqC;OACjC,KAAKzE,gCAAT,EAA2C;SACrC6E,wBAAL,GAAgClU,QAAQ3Y,MAAR,CAAege,OAAf,CAAuB8O,iBAAvD;YACQ9sB,MAAR,CAAege,OAAf,CAAuB8O,iBAAvB,GAA2C,QAA3C;;;;;;;;;;;;;2CAUuBjV,MAAMlN,OAAO;OACjC,KAAKwd,mBAAL,IAA4B,KAAKF,kBAAL,KAA4Bb,mBAAmB0D,aAA/E,EAA8F;SACxFrC,wBAAL,GAAgC,CAAClnB,OAAOwrB,KAAP,CAAa;eAAA;4BAEtB;KAFS,EAG9BpiB,KAH8B,CAAD,CAAhC;WAIO,IAAP;;UAEM,KAAP;;;;;;;;;;;iCAQckN,MAAMlN,OAAO;OACvB,CAAC,KAAKqiB,WAAL,CAAiBnV,IAAjB,CAAL,EAA6B;;;;OAIvBoV,wBAAwB,KAAKC,wBAAL,CAA8BrV,IAA9B,EAAoClN,KAApC,CAA9B;;OAEIsiB,qBAAJ,EAA2B;UACpBE,cAAN;;;;OAIGC,iBAAiB,KAArB;OACI;SACE/C,QAAL,CAAcjN,MAAMW,UAAN,CAAiBlG,IAAjB,CAAd,EAAsC,KAAtC,EAA6ClN,KAA7C;IADD,CAEE,OAAOuT,GAAP,EAAY;;qBAEI,IAAjB;;;OAGG,CAACkP,cAAD,IAAmB,CAACziB,MAAM0iB,qBAA9B,EAAqD;UAC9CF,cAAN;;;;;;;;;;;;;;;+CAY2B;;;OACxB,eAAe,OAAOntB,OAAOstB,cAAjC,EAAiD;WACzCC,eAAP,GAAyBvtB,OAAOstB,cAAhC;;WAEOA,cAAP,GAAwB,iBAAS;YAC3Bxe,IAAL,CAAU,cAAV,EAA0BnE,KAA1B;SACIA,SAASA,MAAMgL,gBAAnB,EAAqC;aAC7B,IAAP;;KAHF;;;WAQO2X,cAAP,CAAsBE,WAAtB,GAAoC,IAApC;;;;;;;;;;;;;wCAUoB/C,YAAY;;;UAC1B3L,mBAAmBiB,OAAnB,GACLpd,IADK,CACA,YAAM;WACJ8nB,WAAWgD,cAAX,EAAP;IAFK,EAIL9qB,IAJK,CAIA,mBAAW;QACZ+qB,OAAJ,EAAa;YACPtF,eAAL,GAAuBtJ,mBAAmBmB,MAAnB,CAA0B,IAAInB,mBAAmB2C,iBAAvB,CAAyC,0BAAzC,CAA1B,CAAvB;YACO,OAAK2G,eAAZ;;IAPI,CAAP;;;;;;;;;;;4CAiByB;;;UAClBtJ,mBAAmBiB,OAAnB,GACLpd,IADK,CACA,YAAM;QACP,OAAK2kB,YAAT,EAAuB;YACf,OAAKA,YAAL,CAAkBqG,gBAAlB,EAAP;;IAHI,EAMLhrB,IANK,CAMA,mBAAW;QACZ+qB,OAAJ,EAAa;YACPtF,eAAL,GAAuBtJ,mBAAmBmB,MAAnB,CAA0B,IAAInB,mBAAmB2C,iBAAvB,CAAyC,4BAAzC,CAA1B,CAAvB;YACO,OAAK2G,eAAZ;;IATI,CAAP;;;;;;;;;wDAiBqC;OAC/Bne,OAAO0O,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB4C,IAArC;OACIA,IAAJ,EAAU;QACL2jB,gBAAgBjV,QAAQtS,QAAR,CAAiB0gB,cAAjB,CAAgC9c,KAAKvJ,SAAL,CAAe,CAAf,CAAhC,CAApB;QACIktB,aAAJ,EAAmB;gCACcxQ,MAAMyQ,aAAN,CAAoBD,aAApB,CADd;SACXnQ,UADW,wBACXA,UADW;SACCC,SADD,wBACCA,SADD;;aAEV1d,MAAR,CAAe0sB,QAAf,CAAwBjP,UAAxB,EAAoCC,SAApC;;;;;;;;;;;;wDASmC;OACjC,KAAKsK,gCAAL,IAAyC,KAAK6E,wBAAlD,EAA4E;YACnE7sB,MAAR,CAAege,OAAf,CAAuB8O,iBAAvB,GAA2C,KAAKD,wBAAhD;;;;;;;;;;;;;;;gDAY4B7P,MAAMuL,cAActe,MAAM;OACnDse,iBAAiBnL,MAAMU,qBAAN,CAA4Bd,IAA5B,CAArB,EAAwD;WAChDuL,eAAete,IAAtB;;UAEMse,YAAP;;;;;;;;;;oDAOiC;OAC7Bte,OAAO0O,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB4C,IAAnC;OACI2jB,gBAAgBjV,QAAQtS,QAAR,CAAiB0gB,cAAjB,CAAgC9c,KAAKvJ,SAAL,CAAe,CAAf,CAAhC,CAApB;OACIktB,aAAJ,EAAmB;gCACcxQ,MAAMyQ,aAAN,CAAoBD,aAApB,CADd;QACXnQ,UADW,yBACXA,UADW;QACCC,SADD,yBACCA,SADD;;SAEboQ,qCAAL,CAA2CpQ,SAA3C,EAAsDD,UAAtD;;;;;;;;;;;;;;2BAWOT,MAAMuN,oBAAoBwD,WAAW;OACzC,CAAC3Q,MAAM4Q,uBAAN,EAAL,EAAsC;UAC/B,IAAItuB,KAAJ,CAAU,sEAAV,CAAN;;;OAGGquB,SAAJ,EAAe;YACN/B,mBAAR,GAA8B+B,UAAU/B,mBAAxC;YACQC,yBAAR,GAAoC8B,UAAU9B,yBAA9C;;;;;OAKGjP,SAAS,KAAKuK,UAAlB,EAA8B;yBACR,IAArB;;;QAGIzY,IAAL,CAAU,gBAAV,EAA4B;WACpBif,SADoB;UAErB/Q,IAFqB;oBAGX,CAAC,CAACuN;IAHnB;;UAMO,KAAKnC,eAAZ;;;;;;;;;;;;oCASiBzd,OAAO;OACpBgO,QAAQqT,mBAAZ,EAAiC;UAC1BiC,IAAN,GAAatV,QAAQqT,mBAArB;;;;;;;;;;;;;2CAUuBrhB,OAAO;OAC3B,KAAKyd,eAAT,EAA0B;QACrB,KAAKA,eAAL,CAAqBpL,IAArB,KAA8BrS,MAAMqS,IAApC,IAA4C,KAAKiL,kBAAL,KAA4Bb,mBAAmB0D,aAA/F,EAA8G;aACrGnF,GAAR,CAAY,YAAZ;;;;;QAKG7W,IAAL,CAAU,cAAV,EAA0BnE,KAA1B;;QAEKmE,IAAL,CAAU,eAAV,EAA2B;UACpBnE,MAAMsjB,IADc;UAEpBtjB,MAAMqS,IAFc;oBAGVrS,MAAMujB;IAHvB;;;;;;;;;;;;yCAasBvjB,OAAO;OACzBwjB,OAAOnuB,OAAOutB,eAAlB;OACIY,QAAQ,CAACA,KAAKX,WAAd,IAA6BW,MAAjC,EAAyC;UAClChB,cAAN;;;;;;;;;;;;;sCAUkBxiB,OAAO;OACtBA,MAAMyjB,MAAN,IAAgBzjB,MAAM0jB,OAAtB,IAAiC1jB,MAAM2jB,OAAvC,IAAkD3jB,MAAM4jB,QAAxD,IAAoE5jB,MAAMuI,MAA9E,EAAsF;YAC7EyS,GAAR,CAAY,iEAAZ;;;QAGIiG,cAAL,CAAoBjhB,MAAMmJ,cAAN,CAAqB+D,IAAzC,EAA+ClN,KAA/C;;;;;;;;;;;;uCASoBA,OAAO;OACvBsjB,OAAOtjB,MAAMmJ,cAAjB;OACIma,KAAKO,MAAL,KAAgB,KAApB,EAA2B;YAClB7I,GAAR,CAAY,0BAAZ;;;SAGKqG,mBAAN,GAA4BiC,IAA5B;OACMQ,iBAAiB,2DAAvB;OACI/c,MAAMiH,QAAQtS,QAAR,CAAiBqoB,aAAvB,EAAsCD,cAAtC,CAAJ,EAA2D;UACpDxC,yBAAN,GAAkCtT,QAAQtS,QAAR,CAAiBqoB,aAAnD;IADD,MAEO;UACAzC,yBAAN,GAAkCgC,KAAKU,aAAL,CAAmBF,cAAnB,CAAlC;;QAEI7C,cAAL,CAAoBqC,KAAKW,MAAzB,EAAiCjkB,KAAjC;;;;;;;;;;;;4BASS;;;QACJge,gBAAL,GAAwB,IAAxB;cACW,YAAM;;;YAGXA,gBAAL,GAAwB,KAAxB;IAHD,EAIG,CAJH;;QAMKkG,mCAAL;;;;;;;;;;;;;;;8BAYWlkB,OAAO;OACd,KAAKge,gBAAT,EAA2B;;;;;OAKvBvL,MAAMwM,oBAAN,CAA2B,KAAKnC,yBAAhC,CAAJ,EAAgE;SAC1DoH,mCAAL;;;;OAIGpM,QAAQ9X,MAAM8X,KAAlB;;OAEI,CAACA,KAAL,EAAY;QACP9J,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB4C,IAA5B,EAAkC;;;;;SAK7B,KAAKse,YAAL,IAAqB,CAACnL,MAAMwM,oBAAN,CAA2B,KAAKrB,YAAhC,CAA1B,EAAyE;WACnEuG,UAAL;;;;UAIID,mCAAL;KAVD,MAWO;UACDC,UAAL;;;;;OAKErM,MAAMsM,KAAV,EAAiB;YACRpJ,GAAR,CAAY,4BAA4BlD,MAAMzF,IAAlC,GAAyC,GAArD;SACKsL,iBAAL,GAAyB7F,MAAMmK,SAA/B;SACKvE,kBAAL,GAA0B5F,MAAMkK,UAAhC;QACI,CAAC,KAAK3E,gCAAV,EAA4C;UACtCgH,0BAAL;;SAEIja,IAAL,CAAU,aAAV,EAAyB,YAAM;SAC1B0N,MAAMpE,QAAV,EAAoB;YACb4Q,WAAN,CAAkBxM,MAAMpE,QAAxB;;KAFF;QAKMT,MAAM,IAAI1C,GAAJ,CAAQuH,MAAMzF,IAAd,CAAZ;QACIkS,WAAJ,CAAgBvW,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB0R,QAAxC;QACIoW,OAAJ,CAAYxW,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB6R,IAApC;QACM+T,wBAAwB,KAAKC,wBAAL,CAA8BtP,IAAInd,QAAJ,EAA9B,EAA8C,EAA9C,CAA9B;QACIwsB,qBAAJ,EAA2B;;;SAGtB5C,QAAL,CAAc5H,MAAMzF,IAApB,EAA0B,IAA1B;;;;;;;;;;;;8BASU;OACP,KAAK0K,oCAAT,EAA+C;SACzCoG,qCAAL,CAA2CnV,QAAQ3Y,MAAR,CAAeovB,WAA1D,EAAuEzW,QAAQ3Y,MAAR,CAAeqvB,WAAtF;;;;;;;;;;;;;mCAUe1kB,OAAO;;;QAClB2kB,mCAAL;QACK5H,oCAAL,GAA4C,KAA5C;cACW/O,QAAQtS,QAAR,CAAiBM,eAA5B,EAA6C,KAAKohB,eAAlD;;OAEIwH,qBAAqB;UAClB5kB,MAAMsjB,IADY;UAElBtjB,MAAMqS;IAFb;;QAKKoL,eAAL,GAAuB,KAAKoH,WAAL,CAAiB7kB,MAAMqS,IAAvB,EAA6BrS,MAAMujB,cAAnC,EACrB5M,KADqB,CACf,UAAC1B,MAAD,EAAY;uBACCzB,KAAnB,GAA2ByB,MAA3B;UACMA,MAAN;IAHqB,EAKrBoB,UALqB,CAKV,YAAM;QACb,CAAC,QAAKoH,eAAN,IAAyB,CAAC,QAAKK,wBAAL,CAA8B/kB,MAA5D,EAAoE;mBACrDiV,QAAQtS,QAAR,CAAiBM,eAA/B,EAAgD,QAAKohB,eAArD;aACK0H,mCAAL;aACK/H,oCAAL,GAA4C,IAA5C;;YAEI5Y,IAAL,CAAU,aAAV,EAAyBygB,kBAAzB;IAXqB,CAAvB;;QAcKnH,eAAL,CAAqBpL,IAArB,GAA4BrS,MAAMqS,IAAlC;;;;;;;;;;;2BAQQA,MAAM;;;OACVsH,QAAQ,KAAKuF,SAAL,CAAe7M,IAAf,CAAZ;OACI,CAACsH,KAAL,EAAY;WACJxF,mBAAmBmB,MAAnB,CAA0B,IAAInB,mBAAmB2C,iBAAvB,CAAyC,kBAAkBzE,IAA3D,CAA1B,CAAP;;;WAGO2I,GAAR,CAAY,kBAAkB3I,IAAlB,GAAyB,GAArC;;OAEIyN,aAAa,KAAKC,oBAAL,CAA0B1N,IAA1B,EAAgCsH,KAAhC,CAAjB;;UAEOmG,WAAWI,IAAX,CAAgB7N,IAAhB,EACLra,IADK,CACA;WAAM,QAAK+lB,OAAL,CAAa1L,IAAb,IAAqByN,UAA3B;IADA,EAELnJ,KAFK,CAEC,UAAC1B,MAAD,EAAY;YACb6L,oBAAL,CAA0BzO,IAA1B,EAAgCyN,UAAhC,EAA4C7K,MAA5C;UACMA,MAAN;IAJK,CAAP;;;;;;;;;;;;0CAcuB5C,MAAMyN,YAAYF,oBAAoB;OACzD7jB,QAAQ+jB,WAAWiF,QAAX,EAAZ;OACI,CAAC9sB,SAAS8D,KAAT,CAAL,EAAsB;YACb,KAAKipB,eAAL,EAAR;;OAEGpH,eAAekC,WAAWmF,uBAAX,CAAmC5S,IAAnC,CAAnB;OACM6S,eAAe;UACd9tB,gBAAgB4W,QAAQqT,mBAAxB,CADc;cAAA;8BAAA;gBAIR,CAJQ;eAKT,CALS;WAMb;IANR;OAQIzB,kBAAJ,EAAwB;iBACVqC,SAAb,GAAyB,KAAKtE,iBAA9B;iBACaqE,UAAb,GAA0B,KAAKtE,kBAA/B;;OAEKpe,OAAO,IAAIiR,GAAJ,CAAQ8B,IAAR,EAAcJ,OAAd,EAAb;kBACe,KAAKkT,6BAAL,CAAmC9S,IAAnC,EAAyCuL,YAAzC,EAAuDte,IAAvD,CAAf;QACK8lB,cAAL,CAAoBrpB,KAApB,EAA2B6hB,YAA3B,EAAyCkC,WAAWuF,wBAAX,CAAoCH,YAApC,CAAzC,EAA4FtF,kBAA5F;QACKhC,YAAL,GAAoBA,YAApB;;;;;;;;;;;;2CASwBkC,YAAY7E,UAAUqK,QAAQ;UAC/ClnB,IAAP,CAAY6c,QAAZ,EAAsB3W,OAAtB,CAA8B,UAACxN,EAAD,EAAQ;QACjCyuB,iBAAiBzF,WAAW0F,iBAAX,CAA6B1uB,EAA7B,EAAiCwuB,MAAjC,CAArB;aACSxuB,EAAT,EAAaulB,UAAb,CAAwByD,WAAWjB,KAAX,EAAxB,EAA4C0G,cAA5C;YACQvK,GAAR,CAAY,aAAa8E,WAAWjB,KAAX,EAAb,GAAkC,2BAAlC,GACX,GADW,GACL5D,SAASnkB,EAAT,CADK,GACU,KADV,IACmBM,gBAAgBmuB,cAAhB,IAAkC,KAAlC,GAA0C,OAD7D,IACwE,GADpF;IAHD;;;;;;;;;+BAWY;WACJlwB,MAAR,CAAeqH,QAAf,CAAwB+oB,MAAxB;;;;;;;;;;;8BAQW9L,OAAO;UACX/gB,MAAMuM,MAAN,CAAa,KAAK0Y,MAAlB,EAA0BlE,KAA1B,CAAP;;;;;;;;;;+BAOYtH,MAAM;;;OACd+M,SAAS,KAAKrB,OAAL,CAAa1L,IAAb,CAAb;OACI+M,MAAJ,EAAY;WACJhhB,IAAP,CAAY,KAAK6c,QAAjB,EAA2B3W,OAA3B,CAAmC,UAACohB,SAAD;YAAe,QAAKzK,QAAL,CAAcyK,SAAd,EAAyBvgB,MAAzB,CAAgCia,OAAOP,KAAP,EAAhC,CAAf;KAAnC;WACO8G,OAAP;WACO,KAAK5H,OAAL,CAAa1L,IAAb,CAAP;;;;;;;;;;;;wDASoC4P,WAAWD,YAAY;OACxDlK,QAAQ9J,QAAQ3Y,MAAR,CAAege,OAAf,CAAuByE,KAAnC;OACIA,SAASA,MAAMsM,KAAnB,EAA0B;eACa,CAACnC,SAAD,EAAYD,UAAZ,CADb;UAClBC,SADkB;UACDD,UADC;;YAEjB3sB,MAAR,CAAege,OAAf,CAAuBuS,YAAvB,CAAoC9N,KAApC,EAA2C,IAA3C,EAAiD,IAAjD;;;;;;;;;;;0CAQsB+E,sBAAsB;QACxCA,oBAAL,GAA4BA,oBAA5B;;;;;;;;;;8BAOW1K,UAAU;QAChBA,QAAL,GAAgBM,MAAMoT,uBAAN,CAA8B1T,QAA9B,CAAhB;;;;;;;;;;kCAOe6K,cAAc;QACxBA,YAAL,GAAoBA,YAApB;;;;;;;;;;kCAOeC,cAAc;QACxBA,YAAL,GAAoBA,YAApB;OACI,KAAKsC,iBAAT,EAA4B;SACtBA,iBAAL,CAAuBlf,cAAvB;;QAEIkf,iBAAL,GAAyBxX,SAASrM,QAAT,EAAmB,QAAnB,EAA6B,KAAKuhB,YAAlC,EAAgD,KAAK6I,oBAAL,CAA0B9qB,IAA1B,CAA+B,IAA/B,CAAhD,EAAsF,KAAK6hB,oBAA3F,CAAzB;;;;;;;;;;oDAOiCK,gCAAgC;QAC5DA,8BAAL,GAAsCA,8BAAtC;;;;;;;;;;kCAOeC,cAAc;QACxBA,YAAL,GAAoBA,YAApB;OACI,KAAKqC,iBAAT,EAA4B;SACtBA,iBAAL,CAAuBnf,cAAvB;;QAEImf,iBAAL,GAAyBzX,SAASrM,QAAT,EAAmB,OAAnB,EAA4B,KAAKyhB,YAAjC,EAA+C,KAAK4I,mBAAL,CAAyB/qB,IAAzB,CAA8B,IAA9B,CAA/C,EAAoF,KAAK6hB,oBAAzF,CAAzB;;;;;;;;;;qCAOkBO,iBAAiB;QAC9BA,eAAL,GAAuBA,eAAvB;;;;;;;;;;0CAOuBa,sBAAsB;QACxCA,oBAAL,GAA4BA,oBAA5B;;;;;;;;;;yCAOsB;OAClB,KAAKR,eAAT,EAA0B;SACpBA,eAAL,CAAqB7G,MAArB,CAA4B,2BAA5B;;QAEI6G,eAAL,GAAuB,IAAvB;;;;;;;;;;;;;qDAUkC;;;OAC9B3F,QAAQ9J,QAAQ3Y,MAAR,CAAege,OAAf,CAAuByE,KAAnC;OACI,CAACA,KAAL,EAAY;;;;OAIRmK,YAAYnK,MAAMmK,SAAtB;OACID,aAAalK,MAAMkK,UAAvB;;OAEIgE,OAAO,SAAPA,IAAO,GAAM;QACZ,QAAK/H,oBAAT,EAA+B;aACtB5oB,MAAR,CAAe0sB,QAAf,CAAwBC,UAAxB,EAAoCC,SAApC;;IAFF;;UAMO,IAAI9N,kBAAJ,CAAuB,UAACiB,OAAD;WAAa4Q,SAAShsB,MAAMG,QAAN,CAAe;YAAM6rB,SAAS5Q,SAAf;KAAf,CAAtB;IAAvB,CAAP;;;;;;;;;;;;;;iCAWcrZ,OAAOsW,MAAMyF,OAAO8H,oBAAoB;OAChDlM,WAAW1F,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwBwQ,IAAzC;;OAEI4K,KAAJ,EAAW;UACJpE,QAAN,GAAiBA,QAAjB;;;OAGGkM,kBAAJ,EAAwB;YACfvqB,MAAR,CAAege,OAAf,CAAuBuS,YAAvB,CAAoC9N,KAApC,EAA2C/b,KAA3C,EAAkDsW,IAAlD;IADD,MAEO;YACEhd,MAAR,CAAege,OAAf,CAAuBC,SAAvB,CAAiCwE,KAAjC,EAAwC/b,KAAxC,EAA+CsW,IAA/C;;;SAGKiS,WAAN,CAAkB5Q,QAAlB;;OAEIuS,YAAYjY,QAAQtS,QAAR,CAAiBsoB,aAAjB,CAA+B,OAA/B,CAAhB;OACIiC,SAAJ,EAAe;cACJze,SAAV,GAAsBzL,KAAtB;IADD,MAEO;YACEL,QAAR,CAAiBK,KAAjB,GAAyBA,KAAzB;;;;;EA3yCeyE;;ICbZ0lB;;;;;;;;;;;;;;;;;;uCAWuBC,YAAY;OACnCC,UAAU,EAAd;OACI,CAACD,UAAL,EAAiB;WACTC,OAAP;;OAEGC,QAAQF,WAAWnoB,KAAX,CAAiB,MAAjB,CAAZ;QACK,IAAIhF,IAAI,CAAb,EAAgBA,IAAIqtB,MAAMttB,MAA1B,EAAkCC,GAAlC,EAAuC;QAClC0S,QAAQ2a,MAAMrtB,CAAN,EAAShD,OAAT,CAAiB,IAAjB,CAAZ;QACI0V,QAAQ,CAAZ,EAAe;SACV9V,OAAOywB,MAAMrtB,CAAN,EAASjD,SAAT,CAAmB,CAAnB,EAAsB2V,KAAtB,CAAX;SACIjM,QAAQ4mB,MAAMrtB,CAAN,EAASjD,SAAT,CAAmB2V,QAAQ,CAA3B,CAAZ;aACQpS,IAAR,CAAa;YACN1D,IADM;aAEL6J;MAFR;;;UAMK2mB,OAAP;;;;;;;;;;;;;;;;;;;0BAgBcxX,KAAKiV,QAAQyC,MAAMC,aAAaC,YAAYC,aAAaC,UAAUC,qBAAqB;SAChG/X,OAAO,EAAb;YACSiV,UAAU,KAAnB;;OAEI+C,UAAU,IAAIC,cAAJ,EAAd;OACIC,qBAAqB,CAAzB;;OAEIpR,UAAU,IAAIqR,kBAAJ,CAAY,UAAS3R,OAAT,EAAkBE,MAAlB,EAA0B;YAC3C0R,MAAR,GAAiB,YAAW;SACvBJ,QAAQK,OAAZ,EAAqB;cACZC,OAAR;;;aAGON,OAAR;KALD;YAOQvpB,kBAAR,GAA6B,YAAW;SACnCypB,sBAAsBA,qBAAqB,CAA3C,IAAgD,MAAMF,QAAQO,UAAlE,EAA8E;cACrEC,qBAAR,GAAgC,IAAhC;;0BAEoBR,QAAQO,UAA7B;KAJD;YAMQD,OAAR,GAAkB,YAAW;SACxB1qB,UAAU,eAAd;SACIoqB,QAAQQ,qBAAZ,EAAmC;gBACxB,gCAAV;;SAEG5T,QAAQ,IAAIze,KAAJ,CAAUyH,OAAV,CAAZ;WACMoqB,OAAN,GAAgBA,OAAhB;YACOpT,KAAP;KAPD;IAda,EAuBXiD,SAvBW,CAuBD,UAASxB,MAAT,EAAiB;YACrBoS,KAAR;UACMpS,MAAN;IAzBa,EA0BXoB,UA1BW,CA0BA,YAAW;iBACXiR,OAAb;IA3Ba,CAAd;;SA8BM,IAAI/W,GAAJ,CAAQ3B,GAAR,CAAN;;OAEI4X,UAAJ,EAAgB;QACXe,yBAAJ,CAA8Bf,UAA9B,EAA0C1wB,QAA1C;;;SAGK8Y,IAAI9Y,QAAJ,EAAN;;WAEQuG,IAAR,CAAawnB,MAAb,EAAqBjV,GAArB,EAA0B,CAAC8X,QAA3B;;OAEIC,mBAAJ,EAAyB;YAChBa,eAAR,GAA0B,IAA1B;;;OAGGjB,WAAJ,EAAiB;gBACJtX,KAAZ,GAAoB3K,OAApB,CAA4B,UAAS1O,IAAT,EAAe;aAClC6xB,gBAAR,CAAyB7xB,IAAzB,EAA+B2wB,YAAY7V,MAAZ,CAAmB9a,IAAnB,EAAyB0c,IAAzB,CAA8B,IAA9B,CAA/B;KADD;;;WAKOoV,IAAR,CAAavwB,MAAMmvB,IAAN,IAAcA,IAAd,GAAqB,IAAlC;;OAEIlvB,gBAAgBqvB,WAAhB,CAAJ,EAAkC;QAC7Ba,UAAUhP,WAAW,YAAW;aAC3B1B,MAAR,CAAe,iBAAf;KADa,EAEX6P,WAFW,CAAd;;;UAKM/Q,OAAP;;;;;;ACjHF;;;;;IAIMiS;;;;;;;;;;;AAQNA,OAAOC,cAAP,GAAwB,qBAAxB;;;;;;;AAOAD,OAAOE,aAAP,GAAuB,eAAvB;;;;;;;AAOAF,OAAOG,eAAP,GAAyB,iBAAzB;;;;;;;AAOAH,OAAOI,6BAAP,GAAuC,gCAAvC;;AC/BA;;;;;;;;IAOMC;;;;;;;;;;;;;;;;uCASuB;OACvBC,YAAYD,GAAGha,OAAH,CAAW3Y,MAAX,IAAqB2yB,GAAGha,OAAH,CAAW3Y,MAAX,CAAkB4yB,SAAvD;OACIA,SAAJ,EAAe;QACVC,YAAYD,UAAUC,SAA1B;QACIA,SAAJ,EAAe;YACPA,SAAP;;;UAGK,EAAP;;;;;;;;;;;;;;sCAW0B;OACtBD,YAAYD,GAAGha,OAAH,CAAW3Y,MAAX,IAAqB2yB,GAAGha,OAAH,CAAW3Y,MAAX,CAAkB4yB,SAAvD;OACIA,SAAJ,EAAe;QACVE,WAAWF,UAAUE,QAAzB;QACIA,QAAJ,EAAc;YACNA,QAAP;;;UAGK,EAAP;;;;;;;;;;;;;gCAUoBtyB,KAAK;UAClBmyB,GAAGG,QAAH,CAAYnyB,OAAZ,CAAoBH,GAApB,MAA6B,CAAC,CAArC;;;;;;;;;;;;;iCAUqBA,KAAK;UACnBmyB,GAAGE,SAAH,CAAalyB,OAAb,CAAqBH,GAArB,MAA8B,CAAC,CAAtC;;;;;;;;;;;;kCASmD;OAA/BqyB,SAA+B,uEAAnB,EAAmB;OAAfC,QAAe,uEAAJ,EAAI;;;;;;;MAMhDD,SAAH,GAAeA,SAAf;;;;;;;MAOGC,QAAH,GAAcA,QAAd;;;;;;;MAOGC,KAAH,GAAWJ,GAAGK,aAAH,CAAiB,KAAjB,CAAX;;;;;;;MAOGC,KAAH,GAAWN,GAAGK,aAAH,CAAiB,KAAjB,CAAX;;;;;;;MAOGE,OAAH,GAAaP,GAAGQ,cAAH,CAAkB,OAAlB,KAA8BR,GAAGQ,cAAH,CAAkB,KAAlB,CAA3C;;;;;;;MAOGC,IAAH,GAAUT,GAAGQ,cAAH,CAAkB,SAAlB,KAAgCR,GAAGQ,cAAH,CAAkB,MAAlB,CAA1C;;;;;;;MAOGE,MAAH,GAAYV,GAAGQ,cAAH,CAAkB,MAAlB,CAAZ;;;;;;;MAOGG,UAAH,GAAgBX,GAAGS,IAAH,IAAWT,GAAGU,MAA9B;;;;;;;MAOGE,QAAH,GACC,CAACZ,GAAGQ,cAAH,CAAkB,QAAlB,KAA+BR,GAAGQ,cAAH,CAAkB,OAAlB,CAAhC,KACA,CAACR,GAAGO,OADJ,IAEA,CAACP,GAAGU,MAHL;;;;;;;MAUGG,QAAH,GACCb,GAAGQ,cAAH,CAAkB,QAAlB,KACA,EAAER,GAAGY,QAAH,IAAeZ,GAAGO,OAAlB,IAA6BP,GAAGU,MAAlC,CAFD;;;;;;;MASGI,SAAH,GAAed,GAAGQ,cAAH,CAAkB,SAAlB,CAAf;;;;;;;;;;;;;AASFnqB,OAAOsV,cAAP,CAAsBqU,EAAtB,EAA0B,SAA1B,EAAqC;WAC1B,IAD0B;QAE7B;UACE7vB,iBAAiB,IAAjB,GAAwB9C;;CAHlC;;AAOA2yB,GAAGe,aAAH,CAAiBf,GAAGgB,kBAAH,EAAjB,EAA0ChB,GAAGiB,iBAAH,EAA1C;;IClKMC;;;;;;;;;0BAQS;;;;;;;;;QAORxO,SAAL,GAAiB,IAAjB;;;;;;;;;;;QAWKyO,WAAL,GAAmB;aACR,MADQ;uBAEE;GAFrB;;;;;;;;QAWKC,UAAL,GAAkBF,cAAcG,GAAhC;;;;;;;;QAQKzC,OAAL,GAAe,IAAf;;;;;;;;QAQKU,OAAL,GAAe,KAAf;;;;;;;;;;;;;gDAQ6BgC,QAAQ;OACjC,CAAC,KAAKC,yBAAL,CAA+BD,MAA/B,CAAL,EAA6C;QACxC9V,QAAQ,IAAIze,KAAJ,CAAU4yB,OAAOC,cAAjB,CAAZ;UACM4B,aAAN,GAAsB,IAAtB;UACMC,UAAN,GAAmBH,MAAnB;UACM9V,KAAN;;;;;;;;;;0CAOsBnB,MAAM;OACzBuL,eAAe,KAAK8L,cAAL,EAAnB;OACI9L,gBAAgBA,iBAAiBvL,IAArC,EAA2C;WACnCuL,YAAP;;UAEMvL,IAAP;;;;;;;;;2CAMwByF,OAAO;;;;OAI3BA,MAAMsM,KAAN,IAAetM,MAAMwL,IAArB,IAA6BxL,MAAM8F,YAAN,KAAuB9F,MAAMzF,IAA9D,EAAoE;WAC5D,IAAP;;UAEMyF,KAAP;;;;;;;;;;;;iCASczF,MAAM;OAChBY,MAAM,IAAI1C,GAAJ,CAAQ8B,IAAR,CAAV;;OAEIkS,WAAJ,CAAgBvW,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB0R,QAAxC;OACIub,WAAJ,CAAgB3b,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwBC,QAAxC;;OAEIqR,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB6R,IAA5B,EAAkC;QAC7BiW,OAAJ,CAAYxW,QAAQ3Y,MAAR,CAAeqH,QAAf,CAAwB6R,IAApC;;;OAGGyZ,GAAGW,UAAH,IAAiB,KAAKS,UAAL,KAAoBF,cAAcG,GAAvD,EAA4D;WACpDpW,IAAI2W,UAAJ,GAAiB9zB,QAAjB,EAAP;;;UAGMmd,IAAInd,QAAJ,EAAP;;;;;;;;;;mCAOgB;UACT,KAAKqzB,WAAZ;;;;;;;;;;kCAOe;UACR,KAAKC,UAAZ;;;;;;;;;;mCAOgB;OACZxC,UAAU,KAAKiD,UAAL,EAAd;OACIjD,OAAJ,EAAa;QACRkD,cAAclD,QAAQkD,WAA1B;QACIC,cAAc,KAAKC,kCAAL,CAAwCpD,OAAxC,CAAlB;QACImD,WAAJ,EAAiB;mBACFA,WAAd;;QAEG/B,GAAGW,UAAH,IAAiB,KAAKS,UAAL,KAAoBF,cAAcG,GAAvD,EAA4D;mBAC7C,IAAI9Y,GAAJ,CAAQuZ,WAAR,EAAqBG,YAArB,GAAoCn0B,QAApC,EAAd;;WAEM2c,MAAMW,UAAN,CAAiB0W,WAAjB,CAAP;;UAEM,IAAP;;;;;;;;;;+BAOY;UACL,KAAKlD,OAAZ;;;;;;;;;;+BAOY;UACL,KAAKU,OAAZ;;;;;;;;;;;4CAQyBmC,YAAY;UAC9BA,cAAc,GAAd,IAAqBA,cAAc,GAA1C;;;;;;;;;uBAMIpX,MAAM;;;OACJoI,QAAQ,KAAKyP,QAAL,EAAd;OACI9yB,gBAAgBqjB,KAAhB,CAAJ,EAA4B;WACpBtG,mBAAmBiB,OAAnB,CAA2BqF,KAA3B,CAAP;;OAEG6L,OAAO,IAAX;OACI8C,aAAa,KAAKA,UAAtB;OACMhD,UAAU,IAAItX,QAAJ,EAAhB;UACO1Q,IAAP,CAAY,KAAK+qB,WAAjB,EAA8B7kB,OAA9B,CAAsC;WAAU8hB,QAAQjgB,GAAR,CAAYgkB,MAAZ,EAAoB,OAAKhB,WAAL,CAAiBgB,MAAjB,CAApB,CAAV;IAAtC;OACInc,QAAQqT,mBAAZ,EAAiC;SAC3B+I,oBAAL;WACO,IAAIC,QAAJ,CAAarc,QAAQqT,mBAArB,CAAP;SACKiJ,6BAAL,CAAmChE,IAAnC;iBACa4C,cAAcqB,IAA3B;QACIvC,GAAGW,UAAP,EAAmB;aACVxiB,GAAR,CAAY,eAAZ,EAA6B,KAA7B;;;OAGI2jB,cAAc,KAAKU,cAAL,CAAoBnY,IAApB,CAApB;UACO6T,KACLU,OADK,CACGkD,WADH,EACgBV,UADhB,EAC4B9C,IAD5B,EACkCF,OADlC,EAC2C,IAD3C,EACiD,KAAKkB,OADtD,EAELtvB,IAFK,CAEA,eAAO;WACPyyB,uBAAL;WACKC,UAAL,CAAgBC,GAAhB;WACKC,6BAAL,CAAmCD,IAAIrB,MAAvC;QACIF,eAAeF,cAAcG,GAA7B,IAAoC,OAAKjI,WAAL,EAAxC,EAA4D;YACtDyJ,QAAL,CAAcF,IAAIG,YAAlB;;QAEGhB,WAAJ,GAAkBA,WAAlB;WACOa,IAAIG,YAAX;IAVK,EAYLnU,KAZK,CAYC,UAAC1B,MAAD,EAAY;WACbwV,uBAAL;YACQxV,OAAOzY,OAAf;UACMmrB,OAAOG,eAAZ;aACQR,OAAP,GAAiB,IAAjB;;UAEIK,OAAOE,aAAZ;aACQkD,YAAP,GAAsB,IAAtB;;UAEIpD,OAAOI,6BAAZ;aACQgD,YAAP,GAAsB,IAAtB;aACOC,2BAAP,GAAqC,IAArC;;;UAGI/V,MAAN;IA1BK,CAAP;;;;;;;;;;;;gDAoC6BqR,MAAM;OAC7B/d,SAASyF,QAAQsT,yBAAvB;OACI/Y,UAAUA,OAAO3S,IAArB,EAA2B;SACrBoR,MAAL,CAAYuB,OAAO3S,IAAnB,EAAyB2S,OAAO9I,KAAhC;;;;;;;;;;;;;;;;;;qDAeiCmnB,SAAS;OACvCmD,cAAcnD,QAAQqE,WAA1B;OACIlB,WAAJ,EAAiB;WACTA,WAAP;;UAEMnD,QAAQsE,iBAAR,CAA0BhC,cAAciC,oBAAxC,CAAP;;;;;;;;;;;;;;yCAWsB;OAClBnd,QAAQqT,mBAAR,IAA+B2G,GAAGa,QAAtC,EAAgD;QAC3CuC,SAASpd,QAAQqT,mBAAR,CAA4BvX,gBAA5B,CAA6C,oCAA7C,CAAb;SACK,IAAI4B,QAAQ,CAAjB,EAAoBA,QAAQ0f,OAAOryB,MAAnC,EAA2C2S,OAA3C,EAAoD;SAC/C2f,QAAQD,OAAO1f,KAAP,CAAZ;SACI2f,MAAMC,KAAN,CAAYvyB,MAAZ,GAAqB,CAAzB,EAA4B;;;WAGtB6Z,YAAN,CAAmB,2BAAnB,EAAgD,MAAhD;WACMA,YAAN,CAAmB,UAAnB,EAA+B,EAA/B;;;;;;;;;;;;;;;4CAYuB;OACrB5E,QAAQqT,mBAAR,IAA+B2G,GAAGa,QAAtC,EAAgD;QAC3CuC,SAASpd,QAAQqT,mBAAR,CAA4BvX,gBAA5B,CAA6C,+CAA7C,CAAb;SACK,IAAI4B,QAAQ,CAAjB,EAAoBA,QAAQ0f,OAAOryB,MAAnC,EAA2C2S,OAA3C,EAAoD;SAC7C2f,QAAQD,OAAO1f,KAAP,CAAd;WACM+H,eAAN,CAAsB,2BAAtB;WACMA,eAAN,CAAsB,UAAtB;;;;;;;;;;;;iCASY0V,aAAa;QACtBA,WAAL,GAAmBA,WAAnB;;;;;;;;;;gCAOaC,YAAY;QACpBA,UAAL,GAAkBA,WAAWtqB,WAAX,EAAlB;;;;;;;;;;6BAOU8nB,SAAS;QACdA,OAAL,GAAeA,OAAf;;;;;;;;;;6BAOUU,SAAS;QACdA,OAAL,GAAeA,OAAf;;;;EA3U0BzM;;;;;;;;;;AAsV5BqO,cAAcG,GAAd,GAAoB,KAApB;;;;;;;;AAQAH,cAAcqB,IAAd,GAAqB,MAArB;;;;;;;;AAQArB,cAAciC,oBAAd,GAAqC,eAArC;;ICvWMI;;;;;;;;;uBAQS;;;;;;;;;;;;QAURC,gBAAL,GAAwB,MAAxB;;;;;;;;;QASKC,aAAL,GAAqB,OAArB;;;;;;;;;;;6BAMU;;QAELC,sBAAL;QACKC,aAAL,GAAqB,IAArB;;;;;;;;;;;oDAQiCrkB,YAAY;OACzC,CAAC,KAAKskB,eAAV,EAA2B;SACrBA,eAAL,GAAuB5d,QAAQtS,QAAR,CAAiBC,aAAjB,CAA+B,MAA/B,CAAvB;;;QAGIkwB,8BAAL,CAAoCvkB,UAApC,EAAgD,KAAKskB,eAArD;;QAEKA,eAAL,CAAqBpkB,SAArB,GAAiCF,UAAjC;;;;;;;;;;;;2CASwBwkB,UAAU;OAC9BC,mBAAmBhlB,MAAM+kB,QAAN,EAAgBP,WAAWrmB,SAAX,CAAqB8mB,eAArC,CAAvB;OACID,gBAAJ,EAAsB;SAChBJ,aAAL,CAAmBryB,IAAnB,CAAwBwyB,QAAxB;;OAEGA,SAASh1B,EAAb,EAAiB;QACZm1B,aAAaje,QAAQtS,QAAR,CAAiB0gB,cAAjB,CAAgC0P,SAASh1B,EAAzC,CAAjB;QACIm1B,UAAJ,EAAgB;gBACJ3uB,UAAX,CAAsB4uB,YAAtB,CAAmCJ,QAAnC,EAA6CG,WAAWE,WAAxD;;;;WAIMzwB,QAAR,CAAiBuB,IAAjB,CAAsBhB,WAAtB,CAAkC6vB,QAAlC;;;;;;;;;;sDAOmC;OAC/BM,cAAc,KAAKR,eAAL,CAAqB5H,aAArB,CAAmC,MAAnC,CAAlB;OACI,CAAChW,QAAQtS,QAAR,CAAiB4qB,IAAjB,CAAsBxvB,EAA3B,EAA+B;YACtB4E,QAAR,CAAiB4qB,IAAjB,CAAsBxvB,EAAtB,GAA2B,mBAAmBH,QAA9C;;OAEGy1B,WAAJ,EAAiB;gBACJt1B,EAAZ,GAAiBkX,QAAQtS,QAAR,CAAiB4qB,IAAjB,CAAsBxvB,EAAvC;;;;;;;;;;iDAO6B6jB,SAAStS,MAAM;aACnCsS,QAAQ3b,OAAR,CAAgB,cAAhB,EAAgC,QAAhC,CAAV;aACU2b,QAAQ3b,OAAR,CAAgB,eAAhB,EAAiC,SAAjC,CAAV;OACIqtB,oBAAJ;OACIrE,GAAGS,IAAP,EAAa;QACN6D,WAAWte,QAAQtS,QAAR,CAAiB6wB,WAAjB,GAA+BC,wBAA/B,CAAwD7R,OAAxD,CAAjB;kBACc2R,SAAStI,aAAT,CAAuB,OAAvB,CAAd;IAFD,MAGO;SACDxc,SAAL,GAAiBmT,OAAjB;kBACctS,KAAK2b,aAAL,CAAmB,OAAnB,CAAd;;;OAGGqI,WAAJ,EAAiB;UACVI,mBAAN,CAA0BpkB,IAA1B;UACMqkB,kBAAN,CAAyBL,WAAzB,EAAsChkB,IAAtC;;;;;;;;;;oCAOgB;QACZskB,oBAAL;;;;;;;;;;yCAOsB;OAClB,KAAKhB,aAAT,EAAwB;UACjBiB,0BAAN,CAAiC,KAAKjB,aAAtC;;;;;;;;;;kCAOc1Q,UAAU;;;OACrB4R,yBAAyB,KAAKC,yBAAL,CAC5BrgB,WAAW2O,mBADiB,EACImQ,WAAWrmB,SAAX,CAAqB4H,OADzB,EAE5Bye,WAAWrmB,SAAX,CAAqB6nB,gBAFO,EAEWxB,WAAWrmB,SAAX,CAAqB8nB,gBAFhC,CAA7B;;UAIOH,uBAAuB70B,IAAvB,CAA4B;sIAA4BijB,QAA5B;IAA5B,CAAP;;;;;;;;;iCAMcA,UAAU;;;QACnB0Q,aAAL,GAAqB,EAArB;OACIsB,wBAAwB,KAAKH,yBAAL,CAC3B7f,iBAAiBigB,kBADU,EACU3B,WAAWrmB,SAAX,CAAqBoI,MAD/B,EAE3Bie,WAAWrmB,SAAX,CAAqB8mB,eAFM,EAEWT,WAAWrmB,SAAX,CAAqBioB,eAFhC,EAG3B,KAAKC,wBAAL,CAA8BpyB,IAA9B,CAAmC,IAAnC,CAH2B,CAA5B;;UAKOiyB,sBAAsBj1B,IAAtB,CAA2B;qIAA2BijB,QAA3B;IAA3B,CAAP;;;;;;;;;;qCAOkB;;;OACZoS,qBAAqB,KAAKC,wBAAL,CAA8B/B,WAAWrmB,SAAX,CAAqBqoB,OAAnD,CAA3B;OACMC,sBAAsB,KAAKC,iBAAL,CAAuBlC,WAAWrmB,SAAX,CAAqBqoB,OAA5C,CAA5B;;UAEO,IAAIpZ,kBAAJ,CAAuB,UAACiB,OAAD,EAAa;UACpCwX,0BAAN,CAAiCY,mBAAjC;WACKE,oBAAL,CAA0BL,kBAA1B,EAA8Cr1B,IAA9C,CAAmD;YAAMod,SAAN;KAAnD;IAFM,CAAP;;;;;;;;;;;;;;;;;;;;;4CAqByBuY,aAAa7oB,UAAU8oB,mBAAmBC,mBAAmBC,sBAAsB;;;OACxGC,UAAU,KAAKT,wBAAL,CAA8BxoB,QAA9B,CAAd;OACIkpB,mBAAmB,KAAKP,iBAAL,CAAuBG,iBAAvB,CAAvB;OACIK,kBAAkB,KAAKR,iBAAL,CAAuBI,iBAAvB,CAAtB;;;mBAGgBvpB,OAAhB,CAAwB,UAAC4pB,QAAD,EAAc;QACjCC,cAAc,OAAKC,eAAL,CAAqBF,QAArB,CAAlB;QACIC,WAAJ,EAAiB;gBACLE,uBAAX,CAAmCF,WAAnC,IAAkD,IAAlD;;IAHF;;OAOIG,OAAOnnB,eAAX;WACQ7C,OAAR,CAAgB,UAAC4pB,QAAD,EAAc;QACzBC,cAAc,OAAKC,eAAL,CAAqBF,QAArB,CAAlB;;QAEI,CAAC3C,WAAW8C,uBAAX,CAAmCF,WAAnC,CAAL,EAAsD;UAChDlyB,WAAL,CAAiBiyB,QAAjB;;;QAGGC,eAAepnB,MAAMmnB,QAAN,EAAgBL,iBAAhB,CAAnB,EAAuD;gBAC3CQ,uBAAX,CAAmCF,WAAnC,IAAkD,IAAlD;;IARF;;UAYO,IAAIha,kBAAJ,CAAuB,UAACiB,OAAD,EAAa;gBAC9BkZ,IAAZ,EAAkB,YAAM;WACjB1B,0BAAN,CAAiCoB,gBAAjC;;KADD,EAGGF,oBAHH;IADM,CAAP;;;;;;;;;uBAWI7S,UAAU;;;UACPrP,4GAAWqP,QAAX,EAAqBjjB,IAArB,CAA0B,YAAM;UAChCy0B,mBAAN,CAA0Bze,QAAQtS,QAAR,CAAiBM,eAA3C;UACM0wB,kBAAN,CAAyB,OAAKd,eAA9B,EAA+C5d,QAAQtS,QAAR,CAAiBM,eAAhE;WACKuyB,gBAAL;WACKC,eAAL;IAJM,CAAP;;;;oCAQiB;OACXC,mBAAmB,KAAKhB,iBAAL,CAAuB,MAAvB,CAAzB;OACMiB,2BAA2B,KAAK3T,KAAtC;OACI0T,gBAAJ,EAAsB;UACf7B,0BAAN,CAAiC6B,gBAAjC;QACIC,wBAAJ,EAA8B;8BACJpqB,OAAzB,CAAiC,UAACqqB,IAAD;aAAU3gB,QAAQtS,QAAR,CAAiBuB,IAAjB,CAAsBhB,WAAtB,CAAkC0yB,IAAlC,CAAV;MAAjC;;;;;;;;;;;;;;kCAWaT,UAAU;UAClBA,SAASp3B,EAAT,IAAeo3B,SAAShhB,IAAxB,IAAgCghB,SAASpyB,GAAzC,IAAgD,EAAvD;;;;;;;;;oCAMiB4pB,WAAW;OACxBpK,UAAU,KAAKsQ,eAAL,CAAqB5H,aAArB,CAAmC,MAAM0B,SAAzC,CAAd;OACIpK,OAAJ,EAAa;QACRI,eAAeJ,QAAQ0I,aAAR,CAAsB,MAAM0B,SAAN,GAAkB,GAAlB,GAAwBjK,QAAQI,OAAtD,CAAnB;QACIH,YAAJ,EAAkB;YACVA,aAAalU,SAApB;;WAEM8T,QAAQ9T,SAAf,CALY;;;;;;;;;;;qCAaK;UACX,KAAKikB,aAAZ;;;;;;;;;uBAMIpZ,MAAM;;;UACHzG,4GAAWyG,IAAX,EACLra,IADK,CACA,mBAAW;WACX42B,iCAAL,CAAuCjU,OAAvC;WACKkU,+BAAL;WACKC,kCAAL;WACKC,iCAAL;QACI/G,GAAGS,IAAP,EAAa;YACPuG,+BAAL;;WAEMrU,OAAP;IATK,CAAP;;;;;;;;;;;oDAkBiC;;;OAC7BqT,mBAAmB,KAAKV,wBAAL,CAA8B/B,WAAWrmB,SAAX,CAAqB8mB,eAAnD,CAAvB;oBACiB1nB,OAAjB,CAAyB,UAAC1I,KAAD;WAAW,OAAKqzB,0BAAL,CAAgCrzB,KAAhC,CAAX;IAAzB;;;;;;;;;;6CAO0BA,OAAO;OAC7BA,MAAMsR,IAAV,EAAgB;QACX4e,WAAW9d,QAAQtS,QAAR,CAAiBC,aAAjB,CAA+BC,MAAM6M,OAArC,CAAf;UACMyE,IAAN,GAAa,IAAIqD,GAAJ,CAAQ3U,MAAMsR,IAAd,EAAoB0c,UAApB,GAAiC9zB,QAAjC,EAAb;UACM42B,kBAAN,CAAyB9wB,KAAzB,EAAgCkwB,QAAhC;UACMxuB,UAAN,CAAiB4xB,YAAjB,CAA8BpD,QAA9B,EAAwClwB,KAAxC;UACM8M,QAAN,GAAiB,IAAjB;;;;;;;;;;;;;uCAUmB5C,UAAU;UACvB,IAAIqO,kBAAJ,CAAuB,UAACiB,OAAD,EAAa;aACjC9Q,OAAT,CAAiB,UAAC1E,OAAD;YAAalE,SAASuB,IAAT,CAAchB,WAAd,CAC7B+rB,GAAGS,IAAH,GAAU7oB,OAAV,GAAoB6S,MAAM0c,wBAAN,CAA+BvvB,OAA/B,CADS,CAAb;KAAjB;;IADM,CAAP;;;;;;;;;;;2CAawBkF,UAAU;UAC3B3L,MAAMO,SAAN,CAAgBgI,KAAhB,CAAsB9H,IAAtB,CAA2B,KAAKgyB,eAAL,CAAqB9hB,gBAArB,CAAsChF,QAAtC,CAA3B,CAAP;;;;;;;;;;;oCAQiBA,UAAU;UACpB3L,MAAMO,SAAN,CAAgBgI,KAAhB,CAAsB9H,IAAtB,CAA2BoU,QAAQtS,QAAR,CAAiBoO,gBAAjB,CAAkChF,QAAlC,CAA3B,CAAP;;;;;;;;;2CAMwB;QACnB8mB,eAAL,GAAuB,IAAvB;;;;;;;;;oDAMiC;OAC3B7vB,QAAQ,KAAK6vB,eAAL,CAAqB5H,aAArB,CAAmC,KAAKyH,aAAxC,CAAd;OACI1vB,KAAJ,EAAW;SACLqzB,QAAL,CAAcrzB,MAAMszB,WAAN,CAAkB1kB,IAAlB,EAAd;;;;;uDAImC;OAC9BoQ,QAAQ,KAAKuS,wBAAL,CAA8B,KAAK9B,gBAAnC,CAAd;OACIzQ,KAAJ,EAAW;SACLuU,QAAL,CAAcvU,KAAd;;;;;;;;;;;mCAQe0Q,eAAe;QAC1BA,aAAL,GAAqBA,aAArB;;;;EApXuBvC;;;;;;;AA4XzB,IAAMqG,gBAAgB,sGAAtB;;;;;;;;AAQAhE,WAAWrmB,SAAX,GAAuB;UACb,iGADa;UAEb,0BAFa;mBAGJ,sCAHI;mBAIJ,sCAJI;4DAKmCqqB,aALnC;6FAMoEA,aANpE;6FAOoEA;CAP3F;;;;;;;;AAgBAhE,WAAW8C,uBAAX,GAAqC,EAArC;;ICvZMmB;;;;;;;oCAMS;;;;;;;;;;QAQRC,GAAL,GAAW,IAAX;;;;;;;;;QASKC,WAAL,GAAmB,IAAnB;;;;;;;;;;;2BAMQ;OACJ,CAACj4B,UAAU,KAAKi4B,WAAf,CAAL,EAAkC;UAC3B,IAAI36B,KAAJ,CAAU,+CACf,uDADe,GAEf,oCAFK,CAAN;;;OAKG,CAAC,KAAK26B,WAAL,CAAiBC,YAAjB,CAA8BC,eAAexL,KAA7C,CAAL,EAA0D;YACjDpJ,GAAR,CAAY,qDACX,gEADW,GAEX,gDAFD;;;;OAMG,KAAKyU,GAAT,EAAc;UACP,IAAI16B,KAAJ,CAAU,oCAAV,CAAN;;;WAGOimB,GAAR,CAAY,wCAAZ;;QAEKyU,GAAL,GAAW,IAAI/S,KAAJ,EAAX;QACKmT,eAAL;QACKC,iBAAL;QACKC,iBAAL;QACKC,qBAAL;QACKC,wBAAL;QACKC,6BAAL;QACKC,cAAL;;;;;;;;;;oCAOiB;OACb,KAAKV,GAAT,EAAc;SACRA,GAAL,CAAS9J,OAAT;;;;;;;;;;;2BAQO;UACD,KAAK8J,GAAZ;;;;;;;;;;mCAOgB;UACT,KAAKC,WAAZ;;;;;;;;;oCAMiB;;;OACbU,iBAAiB,yBAArB;QACKC,wBAAL,CAA8BD,cAA9B,EAA8C9rB,OAA9C,CAAsD,UAAC6I,IAAD;WAAU,OAAKmjB,oBAAL,CAA0BnjB,IAA1B,CAAV;IAAtD;OACI,CAAC,KAAKsiB,GAAL,CAASc,SAAT,EAAL,EAA2B;SACrBd,GAAL,CAASe,SAAT,CAAmB,IAAInW,KAAJ,CAAU,IAAV,EAAgBkR,UAAhB,CAAnB;YACQvQ,GAAR,CAAY,mDAAZ;;;;;;;;;;sCAOkB;;;OACfyV,mBAAmB,MAAMb,eAAetU,OAArB,GAA+B,GAAtD;QACK+U,wBAAL,CAA8BI,gBAA9B,EAAgDnsB,OAAhD,CAAwD,UAACosB,cAAD,EAAoB;WACtEC,gCAAL,CAAsCD,cAAtC;WACKjB,GAAL,CAASmB,WAAT,CAAqBF,eAAe55B,EAApC;IAFD;;;;;;;;;mCASgB;OACZ,KAAK44B,WAAL,CAAiBC,YAAjB,CAA8BC,eAAeiB,QAA7C,CAAJ,EAA4D;SACtDpB,GAAL,CAASoB,QAAT;;;;;;;;;;;;uCASmB1jB,MAAM;OACtBwM,QAAQ,IAAIU,KAAJ,CAAU,KAAKyW,wBAAL,CAA8B3jB,IAA9B,CAAV,EAA+C,KAAK4jB,2BAAL,CAAiC5jB,IAAjC,CAA/C,CAAZ;QACKsiB,GAAL,CAASe,SAAT,CAAmB7W,KAAnB;WACQqB,GAAR,CAAY,yBAAyBrB,MAAMqX,OAAN,EAArC;;;;;;;;;;;8CAQ2B7jB,MAAM;OAC7BtM,UAAUsM,KAAK8jB,YAAL,CAAkB,MAAlB,CAAd;OACI75B,gBAAgByJ,OAAhB,CAAJ,EAA8B;cACnBjK,OAAOs6B,eAAP,CAAuBrwB,OAAvB,CAAV;;UAEMA,OAAP;;;;;;;;;;;2CAQwBsM,MAAM;OAC1BkF,OAAOlF,KAAK8jB,YAAL,CAAkB,MAAlB,CAAX;OACI75B,gBAAgBib,IAAhB,CAAJ,EAA2B;QACtBA,KAAKrc,OAAL,CAAa,QAAb,MAA2B,CAA/B,EAAkC;YAC1B,IAAIwjB,MAAJ,CAAWnH,KAAKtc,SAAL,CAAe,CAAf,CAAX,CAAP;;;UAGKsc,IAAP;;;;;;;;;sCAMmB;OACfF,WAAW,KAAKud,WAAL,CAAiBuB,YAAjB,CAA8BrB,eAAezd,QAA7C,CAAf;OACI/a,gBAAgB+a,QAAhB,CAAJ,EAA+B;SACzBsd,GAAL,CAAS0B,WAAT,CAAqBhf,QAArB;YACQ6I,GAAR,CAAY,6BAA6B7I,QAAzC;;;;;;;;;;;0CAQsB;OACnBgL,eAAe,KAAKuS,WAAL,CAAiBuB,YAAjB,CAA8BrB,eAAezS,YAA7C,CAAnB;OACI/lB,gBAAgB+lB,YAAhB,CAAJ,EAAmC;SAC7BsS,GAAL,CAAS/Q,eAAT,CAAyBvB,YAAzB;YACQnC,GAAR,CAAY,iCAAiCmC,YAA7C;;;;;;;;;;;6CAQyB;OACtBC,kBAAkB,KAAKsS,WAAL,CAAiBuB,YAAjB,CAA8BrB,eAAexS,eAA7C,CAAtB;OACIhmB,gBAAgBgmB,eAAhB,CAAJ,EAAsC;SAChCqS,GAAL,CAAS2B,kBAAT,CAA4BhU,eAA5B;YACQpC,GAAR,CAAY,qCAAqCoC,eAAjD;;;;;;;;;;;kDAQ8B;OAC3Ba,uBAAuB,KAAKyR,WAAL,CAAiBuB,YAAjB,CAA8BrB,eAAe3R,oBAA7C,CAA3B;OACI7mB,gBAAgB6mB,oBAAhB,CAAJ,EAA2C;QACtCA,yBAAyB,OAA7B,EAAsC;UAChCwR,GAAL,CAAS4B,uBAAT,CAAiC,KAAjC;KADD,MAEO;UACD5B,GAAL,CAAS4B,uBAAT,CAAiC,IAAjC;;YAEOrW,GAAR,CAAY,0CAA0CiD,oBAAtD;;;;;;;;;;;;2CASuBnZ,UAAU;UAC3B3L,MAAMO,SAAN,CAAgBgI,KAAhB,CAAsB9H,IAAtB,CAA2BoU,QAAQtS,QAAR,CAAiBoO,gBAAjB,CAAkChF,QAAlC,CAA3B,CAAP;;;;;;;;;;;;mDASgClF,SAAS;OACrC,CAACA,QAAQ9I,EAAT,IAAe8I,YAAYoO,QAAQtS,QAAR,CAAiB4qB,IAAhD,EAAsD;YAC7CxvB,EAAR,GAAa,mBAAmBH,QAAhC;;;;;;;;;;;iCAQa+4B,aAAa;QACtBA,WAAL,GAAmBA,WAAnB;;;;EAzOoClyB;;ACJtC;;;;AAIA,IAAI8zB,uBAAuB,IAAI9B,uBAAJ,EAA3B;;AAEAxhB,QAAQtS,QAAR,CAAiBF,gBAAjB,CAAkC,kBAAlC,EAAsD,YAAW;uBAC3C+1B,cAArB,CAAoCvjB,QAAQtS,QAAR,CAAiB4qB,IAArD;uBACqBkL,MAArB;CAFD;;ACXA;;;;AAIA,IAAMC,UAAU,gBAAhB;;;;;;;;;;;;;;;;;;;;","preExistingComment":"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvY29yZU5hbWVkLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9jb3JlLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9hcnJheS9hcnJheS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvYXN5bmMvYXN5bmMuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2Rpc3Bvc2FibGUvRGlzcG9zYWJsZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvb2JqZWN0L29iamVjdC5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvc3RyaW5nL3N0cmluZy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2RvbURhdGEuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZXZlbnRzL3NyYy9FdmVudEhhbmRsZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50RW1pdHRlci5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1ldmVudHMvc3JjL0V2ZW50RW1pdHRlclByb3h5LmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRIYW5kbGVyLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGUuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9Eb21FdmVudEhhbmRsZS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2RvbU5hbWVkLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZG9tLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvRG9tRXZlbnRFbWl0dGVyUHJveHkuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9mZWF0dXJlcy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2dsb2JhbEV2YWwuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9nbG9iYWxFdmFsU3R5bGVzLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZXZlbnRzLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL2dsb2JhbHMvZ2xvYmFscy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC11cmkvc3JjL3BhcnNlRnJvbUFuY2hvci5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC11cmkvc3JjL3BhcnNlLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXN0cnVjdHMvc3JjL011bHRpTWFwLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXN0cnVjdHMvc3JjL1RyZWVOb2RlLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXVyaS9zcmMvVXJpLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL3V0aWxzL3V0aWxzLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL2FwcC9kYXRhQXR0cmlidXRlcy5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1wcm9taXNlL3NyYy9wcm9taXNlL1Byb21pc2UuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZGVib3VuY2Uvc3JjL2RlYm91bmNlLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXBhdGgtcGFyc2VyL3NyYy9wYXRoUGFyc2VyLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL3JvdXRlL1JvdXRlLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL2NhY2hlYWJsZS9DYWNoZWFibGUuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9zcmMvc2NyZWVuL1NjcmVlbi5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9zdXJmYWNlL1N1cmZhY2UuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9zcmMvYXBwL0FwcC5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1hamF4L3NyYy9BamF4LmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL2Vycm9ycy9lcnJvcnMuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtdXNlcmFnZW50L3NyYy9VQS5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9zY3JlZW4vUmVxdWVzdFNjcmVlbi5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9zY3JlZW4vSHRtbFNjcmVlbi5qcyIsIi9Vc2Vycy9kaWVnb25hc2NpbWVudG8vd29ya3NwYWNlL3Nlbm5hLmpzL3NyYy9hcHAvQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXIuanMiLCIvVXNlcnMvZGllZ29uYXNjaW1lbnRvL3dvcmtzcGFjZS9zZW5uYS5qcy9zcmMvYXBwL2RhdGFBdHRyaWJ1dGVIYW5kbGVyLmpzIiwiL1VzZXJzL2RpZWdvbmFzY2ltZW50by93b3Jrc3BhY2Uvc2VubmEuanMvc3JjL2FwcC92ZXJzaW9uLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBBIGNvbGxlY3Rpb24gb2YgY29yZSB1dGlsaXR5IGZ1bmN0aW9ucy5cbiAqIEBjb25zdFxuICovXG5cbmxldCBjb21wYXRpYmlsaXR5TW9kZURhdGFfO1xuXG4vKipcbiAqIENvdW50ZXIgZm9yIHVuaXF1ZSBpZC5cbiAqIEB0eXBlIHtOdW1iZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG5sZXQgdW5pcXVlSWRDb3VudGVyXyA9IDE7XG5cbi8qKlxuICogVW5pcXVlIGlkIHByb3BlcnR5IHByZWZpeC5cbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAcHJvdGVjdGVkXG4gKi9cbmV4cG9ydCBjb25zdCBVSURfUFJPUEVSVFkgPSBgY29yZV8keyhNYXRoLnJhbmRvbSgpICogMWU5KSA+Pj4gMH1gO1xuXG4vKipcbiAqIFdoZW4gZGVmaW5pbmcgYSBjbGFzcyBGb28gd2l0aCBhbiBhYnN0cmFjdCBtZXRob2QgYmFyKCksIHlvdSBjYW4gZG86XG4gKiBGb28ucHJvdG90eXBlLmJhciA9IGFic3RyYWN0TWV0aG9kXG4gKlxuICogTm93IGlmIGEgc3ViY2xhc3Mgb2YgRm9vIGZhaWxzIHRvIG92ZXJyaWRlIGJhcigpLCBhbiBlcnJvciB3aWxsIGJlIHRocm93blxuICogd2hlbiBiYXIoKSBpcyBpbnZva2VkLlxuICpcbiAqIEB0eXBlIHshRnVuY3Rpb259XG4gKiBAdGhyb3dzIHtFcnJvcn0gd2hlbiBpbnZva2VkIHRvIGluZGljYXRlIHRoZSBtZXRob2Qgc2hvdWxkIGJlIG92ZXJyaWRkZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhYnN0cmFjdE1ldGhvZCgpIHtcblx0dGhyb3cgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgYWJzdHJhY3QgbWV0aG9kJyk7XG59XG5cbi8qKlxuICogRGlzYWJsZXMgTWV0YWwuanMncyBjb21wYXRpYmlsaXR5IG1vZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNhYmxlQ29tcGF0aWJpbGl0eU1vZGUoKSB7XG5cdGNvbXBhdGliaWxpdHlNb2RlRGF0YV8gPSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRW5hYmxlcyBNZXRhbC5qcydzIGNvbXBhdGliaWxpdHkgbW9kZSB3aXRoIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgZnJvbSByY1xuICogYW5kIDEueCB2ZXJzaW9uczpcbiAqICAgICAtIFVzaW5nIFwia2V5XCIgdG8gcmVmZXJlbmNlIGNvbXBvbmVudCBpbnN0YW5jZXMuIEluIHRoZSBjdXJyZW50IHZlcnNpb25cbiAqICAgICAgIHRoaXMgc2hvdWxkIGJlIGRvbmUgdmlhIFwicmVmXCIgaW5zdGVhZC4gVGhpcyBhbGxvd3Mgb2xkIGNvZGUgc3RpbGxcbiAqICAgICAgIHVzaW5nIFwia2V5XCIgdG8ga2VlcCB3b3JraW5nIGxpa2UgYmVmb3JlLiBOT1RFOiB0aGlzIG1heSBjYXVzZVxuICogICAgICAgcHJvYmxlbXMsIHNpbmNlIFwia2V5XCIgaXMgbWVhbnQgdG8gYmUgdXNlZCBkaWZmZXJlbnRseS4gT25seSB1c2UgdGhpc1xuICogICAgICAgaWYgaXQncyBub3QgcG9zc2libGUgdG8gdXBncmFkZSB0aGUgY29kZSB0byB1c2UgXCJyZWZcIiBpbnN0ZWFkLlxuICogQHBhcmFtIHtPYmplY3Q9fSBkYXRhIE9wdGlvbmFsIG9iamVjdCB3aXRoIGRhdGEgdG8gc3BlY2lmeSBtb3JlXG4gKiAgICAgZGV0YWlscywgc3VjaCBhczpcbiAqICAgICAgICAgLSByZW5kZXJlcnMge0FycmF5fSB0aGUgdGVtcGxhdGUgcmVuZGVyZXJzIHRoYXQgc2hvdWxkIGJlIGluXG4gKiAgICAgICAgICAgY29tcGF0aWJpbGl0eSBtb2RlLCBlaXRoZXIgdGhlaXIgY29uc3RydWN0b3JzIG9yIHN0cmluZ3NcbiAqICAgICAgICAgICByZXByZXNlbnRpbmcgdGhlbSAoZS5nLiAnc295JyBvciAnanN4JykuIEJ5IGRlZmF1bHQsIGFsbCB0aGUgb25lc1xuICogICAgICAgICAgIHRoYXQgZXh0ZW5kIGZyb20gSW5jcmVtZW50YWxEb21SZW5kZXJlci5cbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmFibGVDb21wYXRpYmlsaXR5TW9kZShkYXRhID0ge30pIHtcblx0Y29tcGF0aWJpbGl0eU1vZGVEYXRhXyA9IGRhdGE7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZGF0YSB1c2VkIGZvciBjb21wYXRpYmlsaXR5IG1vZGUsIG9yIG5vdGhpbmcgaWYgaXQgaGFzbid0IGJlZW5cbiAqIGVuYWJsZWQuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb21wYXRpYmlsaXR5TW9kZURhdGEoKSB7XG5cdC8vIENvbXBhdGliaWxpdHkgbW9kZSBjYW4gYmUgc2V0IHZpYSB0aGUgX19NRVRBTF9DT01QQVRJQklMSVRZX18gZ2xvYmFsIHZhci5cblx0aWYgKGNvbXBhdGliaWxpdHlNb2RlRGF0YV8gPT09IHVuZGVmaW5lZCkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuX19NRVRBTF9DT01QQVRJQklMSVRZX18pIHtcblx0XHRcdGVuYWJsZUNvbXBhdGliaWxpdHlNb2RlKHdpbmRvdy5fX01FVEFMX0NPTVBBVElCSUxJVFlfXyk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBjb21wYXRpYmlsaXR5TW9kZURhdGFfO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGlmIGl0J3MgdHJ1dGh5LCBvciB0aGUgc2Vjb25kIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7Kn0gYVxuICogQHBhcmFtIHsqfSBiXG4gKiBAcmV0dXJuIHsqfVxuICogQHByb3RlY3RlZFxuICovXG5mdW5jdGlvbiBnZXRGaXJzdFRydXRoeV8oYSwgYikge1xuXHRyZXR1cm4gYSB8fCBiO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGdpdmVuIGZ1bmN0aW9uLiBJZiB0aGUgY3VycmVudCBicm93c2VyIGRvZXNuJ3RcbiAqIHN1cHBvcnQgdGhlIGBuYW1lYCBwcm9wZXJ0eSwgdGhpcyB3aWxsIGNhbGN1bGF0ZSBpdCBmcm9tIHRoZSBmdW5jdGlvbidzXG4gKiBjb250ZW50IHN0cmluZy5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGZuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoZm4pIHtcblx0aWYgKCFmbi5uYW1lKSB7XG5cdFx0Y29uc3Qgc3RyID0gZm4udG9TdHJpbmcoKTtcblx0XHRmbi5uYW1lID0gc3RyLnN1YnN0cmluZyg5LCBzdHIuaW5kZXhPZignKCcpKTtcblx0fVxuXHRyZXR1cm4gZm4ubmFtZTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHN0YXRpYyBwcm9wZXJ0eSBpbiB0aGUgZ2l2ZW4gY2xhc3MuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gKiBpbmhlcml0ZWQgZnJvbSBhbmNlc3RvcnMgYXMgZXhwZWN0ZWQsIHVubGVzcyBhIGN1c3RvbSBtZXJnZSBmdW5jdGlvbiBpcyBnaXZlbixcbiAqIHdoaWNoIGNhbiBjaGFuZ2UgaG93IHRoZSBzdXBlciBjbGFzc2VzJyB2YWx1ZSBmb3IgdGhhdCBwcm9wZXJ0eSB3aWxsIGJlIG1lcmdlZFxuICogdG9nZXRoZXIuXG4gKiBUaGUgZmluYWwgbWVyZ2VkIHZhbHVlIHdpbGwgYmUgc3RvcmVkIGluIGFub3RoZXIgcHJvcGVydHksIHNvIHRoYXQgaXQgd29uJ3RcbiAqIGJlIHJlY2FsY3VsYXRlZCBldmVuIGlmIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG11bHRpcGxlIHRpbWVzLlxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gY3RvciBDbGFzcyBjb25zdHJ1Y3Rvci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWUgUHJvcGVydHkgbmFtZSB0byBiZSBtZXJnZWQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosICopOio9fSBtZXJnZUZuIEZ1bmN0aW9uIHRoYXQgcmVjZWl2ZXMgdGhlIG1lcmdlZFxuICogICAgIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBzbyBmYXIgYW5kIHRoZSBuZXh0IHZhbHVlIHRvIGJlIG1lcmdlZCB0byBpdC5cbiAqICAgICBTaG91bGQgcmV0dXJuIHRoZXNlIHR3byBtZXJnZWQgdG9nZXRoZXIuIElmIG5vdCBwYXNzZWQgdGhlIGZpbmFsIHByb3BlcnR5XG4gKiAgICAgd2lsbCBiZSB0aGUgZmlyc3QgdHJ1dGh5IHZhbHVlIGFtb25nIGFuY2VzdG9ycy5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0YXRpY1Byb3BlcnR5KFxuXHRjdG9yLFxuXHRwcm9wZXJ0eU5hbWUsXG5cdG1lcmdlRm4gPSBnZXRGaXJzdFRydXRoeV9cbikge1xuXHRjb25zdCBtZXJnZWROYW1lID0gcHJvcGVydHlOYW1lICsgJ19NRVJHRUQnO1xuXHRpZiAoIWN0b3IuaGFzT3duUHJvcGVydHkobWVyZ2VkTmFtZSkpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRsZXQgbWVyZ2VkID0gY3Rvci5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpXG5cdFx0XHQ/IGN0b3JbcHJvcGVydHlOYW1lXVxuXHRcdFx0OiBudWxsO1xuXHRcdGlmIChjdG9yLl9fcHJvdG9fXyAmJiAhY3Rvci5fX3Byb3RvX18uaXNQcm90b3R5cGVPZihGdW5jdGlvbikpIHtcblx0XHRcdG1lcmdlZCA9IG1lcmdlRm4oXG5cdFx0XHRcdG1lcmdlZCxcblx0XHRcdFx0Z2V0U3RhdGljUHJvcGVydHkoY3Rvci5fX3Byb3RvX18sIHByb3BlcnR5TmFtZSwgbWVyZ2VGbilcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGN0b3JbbWVyZ2VkTmFtZV0gPSBtZXJnZWQ7XG5cdH1cblx0cmV0dXJuIGN0b3JbbWVyZ2VkTmFtZV07XG59XG5cbi8qKlxuICogR2V0cyBhbiB1bmlxdWUgaWQuIElmIGBvYmplY3RgIGFyZ3VtZW50IGlzIHBhc3NlZCwgdGhlIG9iamVjdCBpc1xuICogbXV0YXRlZCB3aXRoIGFuIHVuaXF1ZSBpZC4gQ29uc2VjdXRpdmUgY2FsbHMgd2l0aCB0aGUgc2FtZSBvYmplY3RcbiAqIHJlZmVyZW5jZSB3b24ndCBtdXRhdGUgdGhlIG9iamVjdCBhZ2FpbiwgaW5zdGVhZCB0aGUgY3VycmVudCBvYmplY3QgdWlkXG4gKiByZXR1cm5zLiBTZWUge0BsaW5rIFVJRF9QUk9QRVJUWX0uXG4gKiBAcGFyYW0ge09iamVjdD19IG9iamVjdCBPcHRpb25hbCBvYmplY3QgdG8gYmUgbXV0YXRlZCB3aXRoIHRoZSB1aWQuIElmXG4gKiAgICAgbm90IHNwZWNpZmllZCB0aGlzIG1ldGhvZCBvbmx5IHJldHVybnMgdGhlIHVpZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vSW5oZXJpdGFuY2UgT3B0aW9uYWwgZmxhZyBpbmRpY2F0aW5nIGlmIHRoaXNcbiAqICAgICBvYmplY3QncyB1aWQgcHJvcGVydHkgY2FuIGJlIGluaGVyaXRlZCBmcm9tIHBhcmVudHMgb3Igbm90LlxuICogQHRocm93cyB7RXJyb3J9IHdoZW4gaW52b2tlZCB0byBpbmRpY2F0ZSB0aGUgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuLlxuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VWlkKG9iamVjdCwgbm9Jbmhlcml0YW5jZSkge1xuXHRpZiAob2JqZWN0KSB7XG5cdFx0bGV0IGlkID0gb2JqZWN0W1VJRF9QUk9QRVJUWV07XG5cdFx0aWYgKG5vSW5oZXJpdGFuY2UgJiYgIW9iamVjdC5oYXNPd25Qcm9wZXJ0eShVSURfUFJPUEVSVFkpKSB7XG5cdFx0XHRpZCA9IG51bGw7XG5cdFx0fVxuXHRcdHJldHVybiBpZCB8fCAob2JqZWN0W1VJRF9QUk9QRVJUWV0gPSB1bmlxdWVJZENvdW50ZXJfKyspO1xuXHR9XG5cdHJldHVybiB1bmlxdWVJZENvdW50ZXJfKys7XG59XG5cbi8qKlxuICogVGhlIGlkZW50aXR5IGZ1bmN0aW9uLiBSZXR1cm5zIGl0cyBmaXJzdCBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kj19IHJldHVyblZhbHVlIFRoZSBzaW5nbGUgdmFsdWUgdGhhdCB3aWxsIGJlIHJldHVybmVkLlxuICogQHJldHVybiB7P30gVGhlIGZpcnN0IGFyZ3VtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHlGdW5jdGlvbihyZXR1cm5WYWx1ZSkge1xuXHRyZXR1cm4gcmV0dXJuVmFsdWU7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBib29sZWFuLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYm9vbGVhbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbih2YWwpIHtcblx0cmV0dXJuIHR5cGVvZiB2YWwgPT09ICdib29sZWFuJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBub3QgdW5kZWZpbmVkLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmKHZhbCkge1xuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIG5vdCB1bmRlZmluZWQgb3IgbnVsbC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEZWZBbmROb3ROdWxsKHZhbCkge1xuXHRyZXR1cm4gaXNEZWYodmFsKSAmJiAhaXNOdWxsKHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgZG9jdW1lbnQuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRG9jdW1lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSA5O1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIGRvY3VtZW50LWZyYWdtZW50LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RvY3VtZW50RnJhZ21lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSAxMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBkb20gZWxlbWVudC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbGVtZW50KHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC5ub2RlVHlwZSA9PT0gMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIGZ1bmN0aW9uLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsKSB7XG5cdHJldHVybiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBudWxsLlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bGwodmFsKSB7XG5cdHJldHVybiB2YWwgPT09IG51bGw7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBhIG51bWJlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtYmVyKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ251bWJlcic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgd2luZG93LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1dpbmRvdyh2YWwpIHtcblx0cmV0dXJuIHZhbCAhPT0gbnVsbCAmJiB2YWwgPT09IHZhbC53aW5kb3c7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gb2JqZWN0LiBUaGlzIGluY2x1ZGVzIGFycmF5c1xuICogYW5kIGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGFuIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbCkge1xuXHRjb25zdCB0eXBlID0gdHlwZW9mIHZhbDtcblx0cmV0dXJuICh0eXBlID09PSAnb2JqZWN0JyAmJiB2YWwgIT09IG51bGwpIHx8IHR5cGUgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgUHJvbWlzZS5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQcm9taXNlKHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWwudGhlbiA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgfHwgdmFsIGluc3RhbmNlb2YgU3RyaW5nO1xufVxuXG4vKipcbiAqIFNldHMgdG8gdHJ1ZSBpZiBydW5uaW5nIGluc2lkZSBOb2RlLmpzIGVudmlyb25tZW50IHdpdGggZXh0cmEgY2hlY2sgZm9yXG4gKiBgcHJvY2Vzcy5icm93c2VyYCB0byBza2lwIEthcm1hIHJ1bm5lciBlbnZpcm9ubWVudC4gS2FybWEgZW52aXJvbm1lbnQgaGFzXG4gKiBgcHJvY2Vzc2AgZGVmaW5lZCBldmVuIHRob3VnaCBpdCBydW5zIG9uIHRoZSBicm93c2VyLlxuICogQHBhcmFtIHs/T2JqZWN0fSBvcHRpb25zIENvbnRhaW5zIGBjaGVja0VudmAgcHJvcGVydHkgd2hpY2ggaWYgdHJ1ZSwgY2hlY2tzXG4gKiB0aGUgTk9ERV9FTlYgdmFyaWFibGUuIElmIE5PREVfRU5WIGVxdWFscyAndGVzdCcsIHRoZSBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2VydmVyU2lkZShvcHRpb25zID0ge2NoZWNrRW52OiB0cnVlfSkge1xuXHRsZXQgc2VydmVyU2lkZSA9IHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiAhcHJvY2Vzcy5icm93c2VyO1xuXHRpZiAoc2VydmVyU2lkZSAmJiBvcHRpb25zLmNoZWNrRW52KSB7XG5cdFx0c2VydmVyU2lkZSA9XG5cdFx0XHR0eXBlb2YgcHJvY2Vzcy5lbnYgIT09ICd1bmRlZmluZWQnICYmXG5cdFx0XHRwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnO1xuXHR9XG5cdHJldHVybiBzZXJ2ZXJTaWRlO1xufVxuXG4vKipcbiAqIE51bGwgZnVuY3Rpb24gdXNlZCBmb3IgZGVmYXVsdCB2YWx1ZXMgb2YgY2FsbGJhY2tzLCBldGMuXG4gKiBAcmV0dXJuIHt2b2lkfSBOb3RoaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVsbEZ1bmN0aW9uKCkge31cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gVGhpcyBmaWxlIGV4aXN0cyBqdXN0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgbWFraW5nIHN1cmUgdGhhdCBvbGRcbi8vIGRlZmF1bHQgaW1wb3J0cyBmb3IgdGhpcyBmaWxlIHN0aWxsIHdvcmsuIEl0J3MgYmVzdCB0byB1c2UgdGhlIG5hbWVkIGV4cG9ydHNcbi8vIGZvciBlYWNoIGZ1bmN0aW9uIGluc3RlYWQgdGhvdWdoLCBzaW5jZSB0aGF0IGFsbG93cyBidW5kbGVycyBsaWtlIFJvbGx1cCB0b1xuLy8gcmVkdWNlIHRoZSBidW5kbGUgc2l6ZSBieSByZW1vdmluZyB1bnVzZWQgY29kZS5cbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnLi9jb3JlTmFtZWQnO1xuXG5leHBvcnQgZGVmYXVsdCBjb3JlO1xuZXhwb3J0IHtjb3JlfTtcbmV4cG9ydCAqIGZyb20gJy4vY29yZU5hbWVkJztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBhcnJheSBvcGVyYXRpb25zXG4gKi9cbmNsYXNzIGFycmF5IHtcblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJyYXlzIGhhdmUgdGhlIHNhbWUgY29udGVudC5cblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjFcblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBlcXVhbChhcnIxLCBhcnIyKSB7XG5cdFx0aWYgKGFycjEgPT09IGFycjIpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRpZiAoYXJyMS5sZW5ndGggIT09IGFycjIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycjFbaV0gIT09IGFycjJbaV0pIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZ2l2ZW4gYXJyYXkgdGhhdCBpc24ndCB1bmRlZmluZWQuXG5cdCAqIEBwYXJhbSB7IUFycmF5fSBhcnJcblx0ICogQHJldHVybiB7Kn1cblx0ICovXG5cdHN0YXRpYyBmaXJzdERlZmluZWRWYWx1ZShhcnIpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycltpXSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBhcnJbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRyYW5zZm9ybXMgdGhlIGlucHV0IG5lc3RlZCBhcnJheSB0byBiZWNvbWUgZmxhdC5cblx0ICogQHBhcmFtIHtBcnJheS48KnxBcnJheS48Kj4+fSBhcnIgTmVzdGVkIGFycmF5IHRvIGZsYXR0ZW4uXG5cdCAqIEBwYXJhbSB7QXJyYXkuPCo+PX0gb3V0cHV0IE9wdGlvbmFsIG91dHB1dCBhcnJheS5cblx0ICogQHJldHVybiB7QXJyYXkuPCo+fSBGbGF0IGFycmF5LlxuXHQgKi9cblx0c3RhdGljIGZsYXR0ZW4oYXJyLCBvdXRwdXQgPSBbXSkge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoQXJyYXkuaXNBcnJheShhcnJbaV0pKSB7XG5cdFx0XHRcdGFycmF5LmZsYXR0ZW4oYXJyW2ldLCBvdXRwdXQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3V0cHV0LnB1c2goYXJyW2ldKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGEgcGFydGljdWxhciB2YWx1ZSBmcm9tIGFuIGFycmF5LlxuXHQgKiBAcGFyYW0ge0FycmF5LjxUPn0gYXJyIEFycmF5IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge1R9IG9iaiBPYmplY3QgdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqIEB0ZW1wbGF0ZSBUXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlKGFyciwgb2JqKSB7XG5cdFx0Y29uc3QgaSA9IGFyci5pbmRleE9mKG9iaik7XG5cdFx0bGV0IHJ2O1xuXHRcdGlmICgocnYgPSBpID49IDApKSB7XG5cdFx0XHRhcnJheS5yZW1vdmVBdChhcnIsIGkpO1xuXHRcdH1cblx0XHRyZXR1cm4gcnY7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBmcm9tIGFuIGFycmF5IHRoZSBlbGVtZW50IGF0IGluZGV4IGlcblx0ICogQHBhcmFtIHtBcnJheX0gYXJyIEFycmF5IG9yIGFycmF5IGxpa2Ugb2JqZWN0IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gaSBUaGUgaW5kZXggdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlQXQoYXJyLCBpKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zcGxpY2UuY2FsbChhcnIsIGksIDEpLmxlbmd0aCA9PT0gMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTbGljZXMgdGhlIGdpdmVuIGFycmF5LCBqdXN0IGxpa2UgQXJyYXkucHJvdG90eXBlLnNsaWNlLCBidXQgdGhpc1xuXHQgKiBpcyBmYXN0ZXIgYW5kIHdvcmtpbmcgb24gYWxsIGFycmF5LWxpa2Ugb2JqZWN0cyAobGlrZSBhcmd1bWVudHMpLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGFyciBBcnJheS1saWtlIG9iamVjdCB0byBzbGljZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBpbmRleCB0aGF0IHNob3VsZCBzdGFydCB0aGUgc2xpY2UuXG5cdCAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIFRoZSBpbmRleCB3aGVyZSB0aGUgc2xpY2Ugc2hvdWxkIGVuZCwgbm90XG5cdCAqICAgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIGFycmF5LiBJZiBub3QgZ2l2ZW4sIGFsbCBlbGVtZW50cyBhZnRlciB0aGVcblx0ICogICBzdGFydCBpbmRleCB3aWxsIGJlIGluY2x1ZGVkLlxuXHQgKiBAcmV0dXJuIHshQXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc2xpY2UoYXJyLCBzdGFydCwgZW5kID0gYXJyLmxlbmd0aCkge1xuXHRcdGNvbnN0IHNsaWNlZCA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG5cdFx0XHRzbGljZWQucHVzaChhcnJbaV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gc2xpY2VkO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGFycmF5O1xuIiwiLyogIVxuICogUG9seWZpbGwgZnJvbSBHb29nbGUncyBDbG9zdXJlIExpYnJhcnkuXG4gKiBDb3B5cmlnaHQgMjAxMyBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2lzU2VydmVyU2lkZX0gZnJvbSAnLi4vY29yZU5hbWVkJztcblxuY29uc3QgYXN5bmMgPSB7fTtcblxuLyoqXG4gKiBUaHJvdyBhbiBpdGVtIHdpdGhvdXQgaW50ZXJydXB0aW5nIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LiAgRm9yXG4gKiBleGFtcGxlLCBpZiBwcm9jZXNzaW5nIGEgZ3JvdXAgb2YgaXRlbXMgaW4gYSBsb29wLCBzb21ldGltZXMgaXQgaXMgdXNlZnVsXG4gKiB0byByZXBvcnQgYW4gZXJyb3Igd2hpbGUgc3RpbGwgYWxsb3dpbmcgdGhlIHJlc3Qgb2YgdGhlIGJhdGNoIHRvIGJlXG4gKiBwcm9jZXNzZWQuXG4gKiBAcGFyYW0geyp9IGV4Y2VwdGlvblxuICovXG5hc3luYy50aHJvd0V4Y2VwdGlvbiA9IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuXHQvLyBFYWNoIHRocm93IG5lZWRzIHRvIGJlIGluIGl0cyBvd24gY29udGV4dC5cblx0YXN5bmMubmV4dFRpY2soZnVuY3Rpb24oKSB7XG5cdFx0dGhyb3cgZXhjZXB0aW9uO1xuXHR9KTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrIGp1c3QgYmVmb3JlIHRoZSBjdXJyZW50IGNhbGxzdGFjayB1bndpbmRzLCBvciBhc1xuICogc29vbiBhcyBwb3NzaWJsZSBhZnRlciB0aGUgY3VycmVudCBKUyBleGVjdXRpb24gY29udGV4dC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpUSElTKX0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7VEhJUz19IGNvbnRleHQgT2JqZWN0IHRvIHVzZSBhcyB0aGUgXCJ0aGlzIHZhbHVlXCIgd2hlbiBjYWxsaW5nXG4gKiAgICAgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uLlxuICogQHRlbXBsYXRlIFRISVNcbiAqL1xuYXN5bmMucnVuID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0aWYgKCFhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXykge1xuXHRcdC8vIE5vdGhpbmcgaXMgY3VycmVudGx5IHNjaGVkdWxlZCwgc2NoZWR1bGUgaXQgbm93LlxuXHRcdGFzeW5jLm5leHRUaWNrKGFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlKTtcblx0XHRhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IHRydWU7XG5cdH1cblxuXHRhc3luYy5ydW4ud29ya1F1ZXVlXy5wdXNoKG5ldyBhc3luYy5ydW4uV29ya0l0ZW1fKGNhbGxiYWNrLCBjb250ZXh0KSk7XG59O1xuXG4vKiogQHByaXZhdGUge2Jvb2xlYW59ICovXG5hc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IGZhbHNlO1xuXG4vKiogQHByaXZhdGUgeyFBcnJheS48IWFzeW5jLnJ1bi5Xb3JrSXRlbV8+fSAqL1xuYXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblxuLyoqXG4gKiBSdW4gYW55IHBlbmRpbmcgYXN5bmMucnVuIHdvcmsgaXRlbXMuIFRoaXMgZnVuY3Rpb24gaXMgbm90IGludGVuZGVkXG4gKiBmb3IgZ2VuZXJhbCB1c2UsIGJ1dCBmb3IgdXNlIGJ5IGVudHJ5IHBvaW50IGhhbmRsZXJzIHRvIHJ1biBpdGVtcyBhaGVhZCBvZlxuICogYXN5bmMubmV4dFRpY2suXG4gKi9cbmFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlID0gZnVuY3Rpb24oKSB7XG5cdC8vIE5PVEU6IGFkZGl0aW9uYWwgd29yayBxdWV1ZSBpdGVtcyBtYXkgYmUgcHVzaGVkIHdoaWxlIHByb2Nlc3NpbmcuXG5cdHdoaWxlIChhc3luYy5ydW4ud29ya1F1ZXVlXy5sZW5ndGgpIHtcblx0XHQvLyBEb24ndCBsZXQgdGhlIHdvcmsgcXVldWUgZ3JvdyBpbmRlZmluaXRlbHkuXG5cdFx0Y29uc3Qgd29ya0l0ZW1zID0gYXN5bmMucnVuLndvcmtRdWV1ZV87XG5cdFx0YXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHdvcmtJdGVtcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgd29ya0l0ZW0gPSB3b3JrSXRlbXNbaV07XG5cdFx0XHR0cnkge1xuXHRcdFx0XHR3b3JrSXRlbS5mbi5jYWxsKHdvcmtJdGVtLnNjb3BlKTtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0YXN5bmMudGhyb3dFeGNlcHRpb24oZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gVGhlcmUgYXJlIG5vIG1vcmUgd29yayBpdGVtcywgcmVzZXQgdGhlIHdvcmsgcXVldWUuXG5cdGFzeW5jLnJ1bi53b3JrUXVldWVTY2hlZHVsZWRfID0gZmFsc2U7XG59O1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICogQGZpbmFsXG4gKiBAc3RydWN0XG4gKiBAcHJpdmF0ZVxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gZm5cbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx8dW5kZWZpbmVkfSBzY29wZVxuICovXG5hc3luYy5ydW4uV29ya0l0ZW1fID0gZnVuY3Rpb24oZm4sIHNjb3BlKSB7XG5cdC8qKiBAY29uc3QgKi9cblx0dGhpcy5mbiA9IGZuO1xuXHQvKiogQGNvbnN0ICovXG5cdHRoaXMuc2NvcGUgPSBzY29wZTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrcyBhcyBzb29uIGFzIHBvc3NpYmxlIGFmdGVyIHRoZSBjdXJyZW50IEpTXG4gKiBleGVjdXRpb24gY29udGV4dC4gc2V0VGltZW91dCjigKYsIDApIGFsd2F5cyB0YWtlcyBhdCBsZWFzdCA1bXMgZm9yIGxlZ2FjeVxuICogcmVhc29ucy5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpTQ09QRSl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhc1xuICogICAgIHBvc3NpYmxlLlxuICogQHBhcmFtIHtTQ09QRT19IGNvbnRleHQgT2JqZWN0IGluIHdob3NlIHNjb3BlIHRvIGNhbGwgdGhlIGxpc3RlbmVyLlxuICogQHRlbXBsYXRlIFNDT1BFXG4gKi9cbmFzeW5jLm5leHRUaWNrID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0bGV0IGNiID0gY2FsbGJhY2s7XG5cdGlmIChjb250ZXh0KSB7XG5cdFx0Y2IgPSBjYWxsYmFjay5iaW5kKGNvbnRleHQpO1xuXHR9XG5cdGNiID0gYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyhjYik7XG5cdC8vIExvb2sgZm9yIGFuZCBjYWNoZSB0aGUgY3VzdG9tIGZhbGxiYWNrIHZlcnNpb24gb2Ygc2V0SW1tZWRpYXRlLlxuXHRpZiAoIWFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8pIHtcblx0XHRpZiAoXG5cdFx0XHR0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHRpc1NlcnZlclNpZGUoe2NoZWNrRW52OiBmYWxzZX0pXG5cdFx0KSB7XG5cdFx0XHRhc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfID0gc2V0SW1tZWRpYXRlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRcdGFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8gPSBhc3luYy5uZXh0VGljay5nZXRTZXRJbW1lZGlhdGVFbXVsYXRvcl8oKTtcblx0XHR9XG5cdH1cblx0YXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyhjYik7XG59O1xuXG4vKipcbiAqIENhY2hlIGZvciB0aGUgc2V0SW1tZWRpYXRlIGltcGxlbWVudGF0aW9uLlxuICogQHR5cGUge2Z1bmN0aW9uKGZ1bmN0aW9uKCkpfVxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyA9IG51bGw7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB0aGUgYmVzdCBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbiB0byBydW4gYSBmdW5jdGlvbiBhcyBzb29uIGFzXG4gKiB0aGUgSlMgZXZlbnQgbG9vcCBpcyBpZGxlLlxuICogQHJldHVybiB7ZnVuY3Rpb24oZnVuY3Rpb24oKSl9IFRoZSBcInNldEltbWVkaWF0ZVwiIGltcGxlbWVudGF0aW9uLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfID0gZnVuY3Rpb24oKSB7XG5cdC8vIENyZWF0ZSBhIHByaXZhdGUgbWVzc2FnZSBjaGFubmVsIGFuZCB1c2UgaXQgdG8gcG9zdE1lc3NhZ2UgZW1wdHkgbWVzc2FnZXNcblx0Ly8gdG8gb3Vyc2VsdmVzLlxuXHRsZXQgQ2hhbm5lbDtcblxuXHQvLyBWZXJpZnkgaWYgdmFyaWFibGUgaXMgZGVmaW5lZCBvbiB0aGUgY3VycmVudCBydW50aW1lIChpLmUuLCBub2RlLCBicm93c2VyKS5cblx0Ly8gQ2FuJ3QgdXNlIHR5cGVvZiBlbmNsb3NlZCBpbiBhIGZ1bmN0aW9uIChzdWNoIGFzIGNvcmUuaXNGdW5jdGlvbikgb3IgYW5cblx0Ly8gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBhbiBlbnZpcm9ubWVudFxuXHQvLyB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdW5kZWZpbmVkLlxuXHRpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0Q2hhbm5lbCA9IE1lc3NhZ2VDaGFubmVsO1xuXHR9XG5cblx0Ly8gSWYgTWVzc2FnZUNoYW5uZWwgaXMgbm90IGF2YWlsYWJsZSBhbmQgd2UgYXJlIGluIGEgYnJvd3NlciwgaW1wbGVtZW50XG5cdC8vIGFuIGlmcmFtZSBiYXNlZCBwb2x5ZmlsbCBpbiBicm93c2VycyB0aGF0IGhhdmUgcG9zdE1lc3NhZ2UgYW5kXG5cdC8vIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIuIFRoZSBsYXR0ZXIgZXhjbHVkZXMgSUU4IGJlY2F1c2UgaXQgaGFzIGFcblx0Ly8gc3luY2hyb25vdXMgcG9zdE1lc3NhZ2UgaW1wbGVtZW50YXRpb24uXG5cdGlmIChcblx0XHR0eXBlb2YgQ2hhbm5lbCA9PT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuXHRcdHdpbmRvdy5wb3N0TWVzc2FnZSAmJlxuXHRcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG5cdCkge1xuXHRcdC8qKiBAY29uc3RydWN0b3IgKi9cblx0XHRDaGFubmVsID0gZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBNYWtlIGFuIGVtcHR5LCBpbnZpc2libGUgaWZyYW1lLlxuXHRcdFx0Y29uc3QgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG5cdFx0XHRpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdGlmcmFtZS5zcmMgPSAnJztcblx0XHRcdGlmcmFtZS50aXRsZSA9ICcnO1xuXHRcdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKGlmcmFtZSk7XG5cdFx0XHRjb25zdCB3aW4gPSBpZnJhbWUuY29udGVudFdpbmRvdztcblx0XHRcdGNvbnN0IGRvYyA9IHdpbi5kb2N1bWVudDtcblx0XHRcdGRvYy5vcGVuKCk7XG5cdFx0XHRkb2Mud3JpdGUoJycpO1xuXHRcdFx0ZG9jLmNsb3NlKCk7XG5cdFx0XHRjb25zdCBtZXNzYWdlID0gJ2NhbGxJbW1lZGlhdGUnICsgTWF0aC5yYW5kb20oKTtcblx0XHRcdGNvbnN0IG9yaWdpbiA9IHdpbi5sb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyB3aW4ubG9jYXRpb24uaG9zdDtcblx0XHRcdGNvbnN0IG9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0Ly8gVmFsaWRhdGUgb3JpZ2luIGFuZCBtZXNzYWdlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSB3YXNcblx0XHRcdFx0Ly8gaW50ZW5kZWQgZm9yIHVzLlxuXHRcdFx0XHRpZiAoZS5vcmlnaW4gIT09IG9yaWdpbiAmJiBlLmRhdGEgIT09IG1lc3NhZ2UpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5wb3J0MS5vbm1lc3NhZ2UoKTtcblx0XHRcdH0uYmluZCh0aGlzKTtcblx0XHRcdHdpbi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25tZXNzYWdlLCBmYWxzZSk7XG5cdFx0XHR0aGlzLnBvcnQxID0ge307XG5cdFx0XHR0aGlzLnBvcnQyID0ge1xuXHRcdFx0XHRwb3N0TWVzc2FnZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0d2luLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIG9yaWdpbik7XG5cdFx0XHRcdH0sXG5cdFx0XHR9O1xuXHRcdH07XG5cdH1cblx0aWYgKHR5cGVvZiBDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuXHRcdGNvbnN0IGNoYW5uZWwgPSBuZXcgQ2hhbm5lbCgpO1xuXHRcdC8vIFVzZSBhIGZpZm8gbGlua2VkIGxpc3QgdG8gY2FsbCBjYWxsYmFja3MgaW4gdGhlIHJpZ2h0IG9yZGVyLlxuXHRcdGxldCBoZWFkID0ge307XG5cdFx0bGV0IHRhaWwgPSBoZWFkO1xuXHRcdGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRoZWFkID0gaGVhZC5uZXh0O1xuXHRcdFx0Y29uc3QgY2IgPSBoZWFkLmNiO1xuXHRcdFx0aGVhZC5jYiA9IG51bGw7XG5cdFx0XHRjYigpO1xuXHRcdH07XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0XHR0YWlsLm5leHQgPSB7XG5cdFx0XHRcdGNiOiBjYixcblx0XHRcdH07XG5cdFx0XHR0YWlsID0gdGFpbC5uZXh0O1xuXHRcdFx0Y2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcblx0XHR9O1xuXHR9XG5cdC8vIEltcGxlbWVudGF0aW9uIGZvciBJRTYtODogU2NyaXB0IGVsZW1lbnRzIGZpcmUgYW4gYXN5bmNocm9ub3VzXG5cdC8vIG9ucmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aGVuIGluc2VydGVkIGludG8gdGhlIERPTS5cblx0aWYgKFxuXHRcdHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHQnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKVxuXHQpIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oY2IpIHtcblx0XHRcdGxldCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRcdHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0Ly8gQ2xlYW4gdXAgYW5kIGNhbGwgdGhlIGNhbGxiYWNrLlxuXHRcdFx0XHRzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcblx0XHRcdFx0c2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcblx0XHRcdFx0c2NyaXB0ID0gbnVsbDtcblx0XHRcdFx0Y2IoKTtcblx0XHRcdFx0Y2IgPSBudWxsO1xuXHRcdFx0fTtcblx0XHRcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH07XG5cdH1cblx0Ly8gRmFsbCBiYWNrIHRvIHNldFRpbWVvdXQgd2l0aCAwLiBJbiBicm93c2VycyB0aGlzIGNyZWF0ZXMgYSBkZWxheSBvZiA1bXNcblx0Ly8gb3IgbW9yZS5cblx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0c2V0VGltZW91dChjYiwgMCk7XG5cdH07XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGlzIG92ZXJyaWRlZCB0byBwcm90ZWN0IGNhbGxiYWNrcyB3aXRoIGVudHJ5IHBvaW50XG4gKiBtb25pdG9yIGlmIHRoZSBhcHBsaWNhdGlvbiBtb25pdG9ycyBlbnRyeSBwb2ludHMuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhcyBwb3NzaWJsZS5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKCl9IFRoZSB3cmFwcGVkIGNhbGxiYWNrLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG5cdHJldHVybiBjYWxsYmFjaztcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIERpc3Bvc2FibGUgdXRpbGl0eS4gV2hlbiBpbmhlcml0ZWQgcHJvdmlkZXMgdGhlIGBkaXNwb3NlYCBmdW5jdGlvbiB0byBpdHNcbiAqIHN1YmNsYXNzLCB3aGljaCBpcyByZXNwb25zaWJsZSBmb3IgZGlzcG9zaW5nIG9mIGFueSBvYmplY3QgcmVmZXJlbmNlc1xuICogd2hlbiBhbiBpbnN0YW5jZSB3b24ndCBiZSB1c2VkIGFueW1vcmUuIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlXG4gKiBgZGlzcG9zZUludGVybmFsYCB0byBpbXBsZW1lbnQgYW55IHNwZWNpZmljIGRpc3Bvc2luZyBsb2dpYy5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5jbGFzcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIERpc3Bvc2FibGUgY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdC8qKlxuXHRcdCAqIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGluc3RhbmNlIGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZGlzcG9zZWRfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLiBDYWxscyBgZGlzcG9zZUludGVybmFsYC5cblx0ICovXG5cdGRpc3Bvc2UoKSB7XG5cdFx0aWYgKCF0aGlzLmRpc3Bvc2VkXykge1xuXHRcdFx0dGhpcy5kaXNwb3NlSW50ZXJuYWwoKTtcblx0XHRcdHRoaXMuZGlzcG9zZWRfID0gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gaW1wbGVtZW50IGFueSBzcGVjaWZpY1xuXHQgKiBkaXNwb3NpbmcgbG9naWMgKGxpa2UgY2xlYXJpbmcgcmVmZXJlbmNlcyBhbmQgY2FsbGluZyBgZGlzcG9zZWAgb24gb3RoZXJcblx0ICogZGlzcG9zYWJsZXMpLlxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge31cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoaXMgaW5zdGFuY2UgaGFzIGFscmVhZHkgYmVlbiBkaXNwb3NlZC5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzRGlzcG9zZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZGlzcG9zZWRfO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERpc3Bvc2FibGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3Igb2JqZWN0IG9wZXJhdGlvbnNcbiAqL1xuY2xhc3Mgb2JqZWN0IHtcblx0LyoqXG5cdCAqIENvcGllcyBhbGwgdGhlIG1lbWJlcnMgb2YgYSBzb3VyY2Ugb2JqZWN0IHRvIGEgdGFyZ2V0IG9iamVjdC5cblx0ICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUYXJnZXQgb2JqZWN0LlxuXHQgKiBAcGFyYW0gey4uLk9iamVjdH0gdmFyX2FyZ3MgVGhlIG9iamVjdHMgZnJvbSB3aGljaCB2YWx1ZXMgd2lsbCBiZSBjb3BpZWQuXG5cdCAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyB0aGUgdGFyZ2V0IG9iamVjdCByZWZlcmVuY2UuXG5cdCAqL1xuXHRzdGF0aWMgbWl4aW4odGFyZ2V0LCAuLi5hcmdzKSB7XG5cdFx0bGV0IGtleTtcblx0XHRsZXQgc291cmNlO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0c291cmNlID0gYXJnc1tpXTtcblx0XHRcdC8vIFBvc3NpYmxlIHByb3RvdHlwZSBjaGFpbiBsZWFrLCBicmVha3MgMSBtZXRhbC1kb20gYW5kXG5cdFx0XHQvLyAxIG1ldGFsLWluY3JlbWVudGFsLWRvbSB0ZXN0IGlmIGd1YXJkLWZvci1pbiBydWxlIGlzIGFkZHJlc3NlZFxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cdFx0XHRmb3IgKGtleSBpbiBzb3VyY2UpIHtcblx0XHRcdFx0dGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRhcmdldDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGFuIG9iamVjdCBiYXNlZCBvbiBpdHMgZnVsbHkgcXVhbGlmaWVkIGV4dGVybmFsIG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZS5cblx0ICogQHBhcmFtIHtvYmplY3Q9fSBzY29wZSBUaGUgb2JqZWN0IHdpdGhpbiB3aGljaCB0byBsb29rOyBkZWZhdWx0IGlzXG5cdCAqICAgICA8Y29kZT53aW5kb3c8L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHs/fSBUaGUgdmFsdWUgKG9iamVjdCBvciBwcmltaXRpdmUpIG9yLCBpZiBub3QgZm91bmQsIHVuZGVmaW5lZC5cblx0ICovXG5cdHN0YXRpYyBnZXRPYmplY3RCeU5hbWUobmFtZSwgc2NvcGUgPSB3aW5kb3cpIHtcblx0XHRjb25zdCBwYXJ0cyA9IG5hbWUuc3BsaXQoJy4nKTtcblx0XHRyZXR1cm4gcGFydHMucmVkdWNlKChwYXJ0LCBrZXkpID0+IHBhcnRba2V5XSwgc2NvcGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUga2V5cyBhcyB0aGUgZ2l2ZW4gb25lLCBidXQgd2l0aFxuXHQgKiB0aGVpciB2YWx1ZXMgc2V0IHRvIHRoZSByZXR1cm4gdmFsdWVzIG9mIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24uXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gb2JqXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKHN0cmluZywgKil9IGZuXG5cdCAqIEByZXR1cm4geyFPYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgbWFwKG9iaiwgZm4pIHtcblx0XHRjb25zdCBtYXBwZWRPYmogPSB7fTtcblx0XHRjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG1hcHBlZE9ialtrZXlzW2ldXSA9IGZuKGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXBwZWRPYmo7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSB0d28gZ2l2ZW4gb2JqZWN0cyBhcmUgZXF1YWwuIFRoaXMgaXMgZG9uZSB2aWEgYSBzaGFsbG93XG5cdCAqIGNoZWNrLCBpbmNsdWRpbmcgb25seSB0aGUga2V5cyBkaXJlY3RseSBjb250YWluZWQgYnkgdGhlIDIgb2JqZWN0cy5cblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajFcblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBzaGFsbG93RXF1YWwob2JqMSwgb2JqMikge1xuXHRcdGlmIChvYmoxID09PSBvYmoyKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBrZXlzMSA9IE9iamVjdC5rZXlzKG9iajEpO1xuXHRcdGNvbnN0IGtleXMyID0gT2JqZWN0LmtleXMob2JqMik7XG5cdFx0aWYgKGtleXMxLmxlbmd0aCAhPT0ga2V5czIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKG9iajFba2V5czFbaV1dICE9PSBvYmoyW2tleXMxW2ldXSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9iamVjdDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBzdHJpbmcgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBzdHJpbmcge1xuXHQvKipcblx0ICogQ29tcGFyZXMgdGhlIGdpdmVuIHN0cmluZ3Mgd2l0aG91dCB0YWtpbmcgdGhlIGNhc2UgaW50byBhY2NvdW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHN0cjFcblx0ICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdHIyXG5cdCAqIEByZXR1cm4ge251bWJlcn0gRWl0aGVyIC0xLCAwIG9yIDEsIGFjY29yZGluZyB0byBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzXG5cdCAqICAgICBcInNtYWxsZXJcIiwgZXF1YWwgb3IgXCJiaWdnZXJcIiB0aGFuIHRoZSBzZWNvbmQgZ2l2ZW4gc3RyaW5nLlxuXHQgKi9cblx0c3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbXBhcmUoc3RyMSwgc3RyMikge1xuXHRcdGNvbnN0IHRlc3QxID0gU3RyaW5nKHN0cjEpLnRvTG93ZXJDYXNlKCk7XG5cdFx0Y29uc3QgdGVzdDIgPSBTdHJpbmcoc3RyMikudG9Mb3dlckNhc2UoKTtcblxuXHRcdGlmICh0ZXN0MSA8IHRlc3QyKSB7XG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0fSBlbHNlIGlmICh0ZXN0MSA9PT0gdGVzdDIpIHtcblx0XHRcdHJldHVybiAwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgYnJlYWtpbmcgc3BhY2VzIGZyb20gdGhlIGxlZnQgYW5kIHJpZ2h0IG9mIHRoZSBzdHJpbmcgYW5kXG5cdCAqIGNvbGxhcHNlcyB0aGUgc2VxdWVuY2VzIG9mIGJyZWFraW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlIGludG8gc2luZ2xlIHNwYWNlcy5cblx0ICogVGhlIG9yaWdpbmFsIGFuZCB0aGUgcmVzdWx0IHN0cmluZ3MgcmVuZGVyIHRoZSBzYW1lIHdheSBpbiBIVE1MLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIEEgc3RyaW5nIGluIHdoaWNoIHRvIGNvbGxhcHNlIHNwYWNlcy5cblx0ICogQHJldHVybiB7c3RyaW5nfSBDb3B5IG9mIHRoZSBzdHJpbmcgd2l0aCBub3JtYWxpemVkIGJyZWFraW5nIHNwYWNlcy5cblx0ICovXG5cdHN0YXRpYyBjb2xsYXBzZUJyZWFraW5nU3BhY2VzKHN0cikge1xuXHRcdHJldHVybiBzdHJcblx0XHRcdC5yZXBsYWNlKC9bXFx0XFxyXFxuIF0rL2csICcgJylcblx0XHRcdC5yZXBsYWNlKC9eW1xcdFxcclxcbiBdK3xbXFx0XFxyXFxuIF0rJC9nLCAnJyk7XG5cdH1cblxuXHQvKipcblx0ICogRXNjYXBlcyBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcgdGhhdCBhcmUgbm90IHNhZmUgdG8gdXNlIGluIGEgUmVnRXhwLlxuXHQgKiBAcGFyYW0geyp9IHN0ciBUaGUgc3RyaW5nIHRvIGVzY2FwZS4gSWYgbm90IGEgc3RyaW5nLCBpdCB3aWxsIGJlIGNhc3RlZFxuXHQgKiAgICAgdG8gb25lLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEEgUmVnRXhwIHNhZmUsIGVzY2FwZWQgY29weSBvZiB7QGNvZGUgc30uXG5cdCAqL1xuXHRzdGF0aWMgZXNjYXBlUmVnZXgoc3RyKSB7XG5cdFx0cmV0dXJuIFN0cmluZyhzdHIpXG5cdFx0XHQucmVwbGFjZSgvKFstKClbXFxde30rPyouJF58LDojPCFcXFxcXSkvZywgJ1xcXFwkMScpXG5cdFx0XHQucmVwbGFjZSgvXFx4MDgvZywgJ1xcXFx4MDgnKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhdCBsZWFzdCA2NC1iaXRzIG9mIHJhbmRvbW5lc3MuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQSByYW5kb20gc3RyaW5nLCBlLmcuIHNuMXM3dmI0Z2NpYy5cblx0ICovXG5cdHN0YXRpYyBnZXRSYW5kb21TdHJpbmcoKSB7XG5cdFx0Y29uc3QgeCA9IDIxNDc0ODM2NDg7XG5cdFx0cmV0dXJuIChcblx0XHRcdE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHgpLnRvU3RyaW5nKDM2KSArXG5cdFx0XHRNYXRoLmFicyhNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB4KSBeIERhdGUubm93KCkpLnRvU3RyaW5nKDM2KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FsY3VsYXRlcyB0aGUgaGFzaGNvZGUgZm9yIGEgc3RyaW5nLiBUaGUgaGFzaGNvZGUgdmFsdWUgaXMgY29tcHV0ZWQgYnlcblx0ICogdGhlIHN1bSBhbGdvcml0aG06IHNbMF0qMzFeKG4tMSkgKyBzWzFdKjMxXihuLTIpICsgLi4uICsgc1tuLTFdLiBBIG5pY2Vcblx0ICogcHJvcGVydHkgb2YgdXNpbmcgMzEgcHJpbWUgaXMgdGhhdCB0aGUgbXVsdGlwbGljYXRpb24gY2FuIGJlIHJlcGxhY2VkIGJ5XG5cdCAqIGEgc2hpZnQgYW5kIGEgc3VidHJhY3Rpb24gZm9yIGJldHRlciBwZXJmb3JtYW5jZTogMzEqaSA9PSAoaTw8NSktaS5cblx0ICogTW9kZXJuIFZNcyBkbyB0aGlzIHNvcnQgb2Ygb3B0aW1pemF0aW9uIGF1dG9tYXRpY2FsbHkuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB2YWwgVGFyZ2V0IHN0cmluZy5cblx0ICogQHJldHVybiB7TnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgaGFzaGNvZGUuXG5cdCAqL1xuXHRzdGF0aWMgaGFzaENvZGUodmFsKSB7XG5cdFx0bGV0IGhhc2ggPSAwO1xuXHRcdGZvciAobGV0IGkgPSAwLCBsZW4gPSB2YWwubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGhhc2ggPSAzMSAqIGhhc2ggKyB2YWwuY2hhckNvZGVBdChpKTtcblx0XHRcdGhhc2ggJT0gMHgxMDAwMDAwMDA7XG5cdFx0fVxuXHRcdHJldHVybiBoYXNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlcGxhY2VzIGludGVydmFsIGludG8gdGhlIHN0cmluZyB3aXRoIHNwZWNpZmllZCB2YWx1ZSwgZS5nLlxuXHQgKiBgcmVwbGFjZUludGVydmFsKFwiYWJjZGVcIiwgMSwgNCwgXCJcIilgIHJldHVybnMgXCJhZVwiLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBpbnB1dCBzdHJpbmcuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydCBTdGFydCBpbnRlcnZhbCBwb3NpdGlvbiB0byBiZSByZXBsYWNlZC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IGVuZCBFbmQgaW50ZXJ2YWwgcG9zaXRpb24gdG8gYmUgcmVwbGFjZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdGhhdCByZXBsYWNlcyB0aGUgc3BlY2lmaWVkIGludGVydmFsLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgcmVwbGFjZUludGVydmFsKHN0ciwgc3RhcnQsIGVuZCwgdmFsdWUpIHtcblx0XHRyZXR1cm4gc3RyLnN1YnN0cmluZygwLCBzdGFydCkgKyB2YWx1ZSArIHN0ci5zdWJzdHJpbmcoZW5kKTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBzdHJpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7aXNEZWZ9IGZyb20gJ21ldGFsJztcblxuY29uc3QgTUVUQUxfREFUQSA9ICdfX21ldGFsX2RhdGFfXyc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3IgZG9tIGRhdGEgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBkb21EYXRhIHtcblx0LyoqXG5cdCAqIEdldHMgTWV0YWwuanMncyBkYXRhIGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuXHQgKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgT3B0aW9uYWwgcHJvcGVydHkgZnJvbSB0aGUgZGF0YSB0byBiZSByZXR1cm5lZC5cblx0ICogQHBhcmFtIHsqPX0gaW5pdGlhbFZhbHVlIE9wdGlvbmFsIHZhbHVlIHRvIHRoZSBzZXQgdGhlIHJlcXVlc3RlZCBwcm9wZXJ0eVxuXHQgKiAgICAgdG8gaWYgaXQgZG9lc24ndCBleGlzdCB5ZXQgaW4gdGhlIGRhdGEuXG5cdCAqIEByZXR1cm4geyFPYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgZ2V0KGVsZW1lbnQsIG5hbWUsIGluaXRpYWxWYWx1ZSkge1xuXHRcdGlmICghZWxlbWVudFtNRVRBTF9EQVRBXSkge1xuXHRcdFx0ZWxlbWVudFtNRVRBTF9EQVRBXSA9IHt9O1xuXHRcdH1cblx0XHRpZiAoIW5hbWUpIHtcblx0XHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdO1xuXHRcdH1cblx0XHRpZiAoIWlzRGVmKGVsZW1lbnRbTUVUQUxfREFUQV1bbmFtZV0pICYmIGlzRGVmKGluaXRpYWxWYWx1ZSkpIHtcblx0XHRcdGVsZW1lbnRbTUVUQUxfREFUQV1bbmFtZV0gPSBpbml0aWFsVmFsdWU7XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBoYXMgZGF0YSBzdG9yZWQgaW4gaXQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBoYXMoZWxlbWVudCkge1xuXHRcdHJldHVybiAhIWVsZW1lbnRbTUVUQUxfREFUQV07XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBNZXRhbC5qcydzIGRhdGEgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBmcm9tIHRoZSBkYXRhIHRvIGJlIHNldC5cblx0ICogQHBhcmFtIHsqPX0gdmFsdWUgVmFsdWUgdG8gYmUgc2V0IG9uIHRoZSBlbGVtZW50LlxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fCp9XG5cdCAqL1xuXHRzdGF0aWMgc2V0KGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG5cdFx0aWYgKCFlbGVtZW50W01FVEFMX0RBVEFdKSB7XG5cdFx0XHRlbGVtZW50W01FVEFMX0RBVEFdID0ge307XG5cdFx0fVxuXHRcdGlmICghbmFtZSB8fCAhaXNEZWYodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gZWxlbWVudFtNRVRBTF9EQVRBXTtcblx0XHR9XG5cdFx0ZWxlbWVudFtNRVRBTF9EQVRBXVtuYW1lXSA9IHZhbHVlO1xuXHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRvbURhdGE7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlIHV0aWxpdHkuIEhvbGRzIGluZm9ybWF0aW9uIGFib3V0IGFuIGV2ZW50IHN1YnNjcmlwdGlvbiwgYW5kXG4gKiBhbGxvd3MgcmVtb3ZpbmcgdGhlbSBlYXNpbHkuXG4gKiBFdmVudEhhbmRsZSBpcyBhIERpc3Bvc2FibGUsIGJ1dCBpdCdzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhlXG4gKiBFdmVudEVtaXR0ZXIgdGhhdCBjcmVhdGVkIGl0IGlzIG5vdCB0aGUgb25lIHJlc3BvbnNpYmxlIGZvciBkaXNwb3NpbmcgaXQuXG4gKiBUaGF0IHJlc3BvbnNpYmlsaXR5IGlzIGZvciB0aGUgY29kZSB0aGF0IGhvbGRzIGEgcmVmZXJlbmNlIHRvIGl0LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBFdmVudEhhbmRsZSBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IGVtaXR0ZXIgRW1pdHRlciB0aGUgZXZlbnQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdGhhdCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgRXZlbnRFbWl0dGVyIGluc3RhbmNlIHRoYXQgdGhlIGV2ZW50IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZW1pdHRlcl8gPSBlbWl0dGVyO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRoYXQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudF8gPSBldmVudDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0XHQgKiBAdHlwZSB7RnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubGlzdGVuZXJfID0gbGlzdGVuZXI7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0dGhpcy5lbWl0dGVyXyA9IG51bGw7XG5cdFx0dGhpcy5saXN0ZW5lcl8gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIHN1YnNjcmlwdGlvbiBmcm9tIHRoZSBlbWl0dGVyLlxuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0aWYgKCF0aGlzLmVtaXR0ZXJfLmlzRGlzcG9zZWQoKSkge1xuXHRcdFx0dGhpcy5lbWl0dGVyXy5yZW1vdmVMaXN0ZW5lcih0aGlzLmV2ZW50XywgdGhpcy5saXN0ZW5lcl8pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudEhhbmRsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcnJheSwgRGlzcG9zYWJsZSwgaXNGdW5jdGlvbiwgaXNTdHJpbmd9IGZyb20gJ21ldGFsJztcbmltcG9ydCBFdmVudEhhbmRsZSBmcm9tICcuL0V2ZW50SGFuZGxlJztcblxuY29uc3Qgc2luZ2xlQXJyYXlfID0gWzBdO1xuXG4vKipcbiAqIEV2ZW50RW1pdHRlciB1dGlsaXR5LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50RW1pdHRlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRFbWl0dGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgZXZlbnQgbGlzdGVuZXJzIHNjb3BlZCBieSBldmVudCB0eXBlLlxuXHRcdCAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAhQXJyYXk8IWZ1bmN0aW9uKCk+Pn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhhbmRsZXJzIHRoYXQgYXJlIHRyaWdnZXJlZCB3aGVuIGFuIGV2ZW50IGlzIGxpc3RlbmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtBcnJheX1cblx0XHQgKi9cblx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIENvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZCBiZSBzZW50XG5cdFx0ICogYXMgYSBwYXJhbSBvZiBsaXN0ZW5lcnMgd2hlbiBlbWl0dGluZyBldmVudHMuIElmIHNldCB0byB0cnVlLCB0aGUgZmFjYWRlXG5cdFx0ICogd2lsbCBiZSBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoZSBsaXN0ZW5lci5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zaG91bGRVc2VGYWNhZGVfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGhhbmRsZXIgdG8gZ2l2ZW4gaG9sZGVyIHZhcmlhYmxlLiBJZiB0aGUgaG9sZGVyIGRvZXNuJ3QgaGF2ZSBhXG5cdCAqIHZhbHVlIHlldCwgaXQgd2lsbCByZWNlaXZlIHRoZSBoYW5kbGVyIGRpcmVjdGx5LiBJZiB0aGUgaG9sZGVyIGlzIGFuIGFycmF5LFxuXHQgKiB0aGUgdmFsdWUgd2lsbCBqdXN0IGJlIGFkZGVkIHRvIGl0LiBPdGhlcndpc2UsIHRoZSBob2xkZXIgd2lsbCBiZSBzZXQgdG8gYVxuXHQgKiBuZXcgYXJyYXkgY29udGFpbmluZyBpdHMgcHJldmlvdXMgdmFsdWUgcGx1cyB0aGUgbmV3IGhhbmRsZXIuXG5cdCAqIEBwYXJhbSB7Kn0gaG9sZGVyXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl8T2JqZWN0fSBoYW5kbGVyXG5cdCAqIEByZXR1cm4geyp9IFRoZSBob2xkZXIncyBuZXcgdmFsdWUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGFkZEhhbmRsZXJfKGhvbGRlciwgaGFuZGxlcikge1xuXHRcdGlmICghaG9sZGVyKSB7XG5cdFx0XHRob2xkZXIgPSBoYW5kbGVyO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIUFycmF5LmlzQXJyYXkoaG9sZGVyKSkge1xuXHRcdFx0XHRob2xkZXIgPSBbaG9sZGVyXTtcblx0XHRcdH1cblx0XHRcdGhvbGRlci5wdXNoKGhhbmRsZXIpO1xuXHRcdH1cblx0XHRyZXR1cm4gaG9sZGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG5cdCAqL1xuXHRhZGRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcikge1xuXHRcdHRoaXMudmFsaWRhdGVMaXN0ZW5lcl8obGlzdGVuZXIpO1xuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50c1tpXSwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBFdmVudEhhbmRsZSh0aGlzLCBldmVudCwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIGEgc2luZ2xlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9uPX0gb3JpZ2luIFRoZSBvcmlnaW5hbCBmdW5jdGlvbiB0aGF0IHdhcyBhZGRlZCBhcyBhXG5cdCAqICAgbGlzdGVuZXIsIGlmIHRoZXJlIGlzIGFueS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lciwgZGVmYXVsdExpc3RlbmVyLCBvcmlnaW4pIHtcblx0XHR0aGlzLnJ1bkxpc3RlbmVySGFuZGxlcnNfKGV2ZW50KTtcblx0XHRpZiAoZGVmYXVsdExpc3RlbmVyIHx8IG9yaWdpbikge1xuXHRcdFx0bGlzdGVuZXIgPSB7XG5cdFx0XHRcdGRlZmF1bHQ6IGRlZmF1bHRMaXN0ZW5lcixcblx0XHRcdFx0Zm46IGxpc3RlbmVyLFxuXHRcdFx0XHRvcmlnaW46IG9yaWdpbixcblx0XHRcdH07XG5cdFx0fVxuXHRcdHRoaXMuZXZlbnRzXyA9IHRoaXMuZXZlbnRzXyB8fCB7fTtcblx0XHR0aGlzLmV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRIYW5kbGVyXyh0aGlzLmV2ZW50c19bZXZlbnRdLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGZhY2FkZSBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7T2JqZWN0fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRidWlsZEZhY2FkZV8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy5nZXRTaG91bGRVc2VGYWNhZGUoKSkge1xuXHRcdFx0Y29uc3QgZmFjYWRlID0ge1xuXHRcdFx0XHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0ZmFjYWRlLnByZXZlbnRlZERlZmF1bHQgPSB0cnVlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0YXJnZXQ6IHRoaXMsXG5cdFx0XHRcdHR5cGU6IGV2ZW50LFxuXHRcdFx0fTtcblx0XHRcdHJldHVybiBmYWNhZGU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeGVjdXRlIGVhY2ggb2YgdGhlIGxpc3RlbmVycyBpbiBvcmRlciB3aXRoIHRoZSBzdXBwbGllZCBhcmd1bWVudHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyp9IG9wdF9hcmdzIFthcmcxXSwgW2FyZzJdLCBbLi4uXVxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgZXZlbnQgaGFkIGxpc3RlbmVycywgZmFsc2Ugb3RoZXJ3aXNlLlxuXHQgKi9cblx0ZW1pdChldmVudCkge1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCk7XG5cdFx0aWYgKGxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRjb25zdCBhcmdzID0gYXJyYXkuc2xpY2UoYXJndW1lbnRzLCAxKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdHRoaXMucnVuTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGFyZ3MsIHRoaXMuYnVpbGRGYWNhZGVfKGV2ZW50KSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbGlzdGVuZXIgb2JqZWN0cyBmb3IgdGhlIGdpdmVuIGV2ZW50LCBpZiB0aGVyZSBhcmUgYW55LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRnZXRSYXdMaXN0ZW5lcnNfKGV2ZW50KSB7XG5cdFx0Y29uc3QgZGlyZWN0TGlzdGVuZXJzID0gdG9BcnJheSh0aGlzLmV2ZW50c18gJiYgdGhpcy5ldmVudHNfW2V2ZW50XSk7XG5cdFx0cmV0dXJuIGRpcmVjdExpc3RlbmVycy5jb25jYXQoXG5cdFx0XHR0b0FycmF5KHRoaXMuZXZlbnRzXyAmJiB0aGlzLmV2ZW50c19bJyonXSlcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Z2V0U2hvdWxkVXNlRmFjYWRlKCkge1xuXHRcdHJldHVybiB0aGlzLnNob3VsZFVzZUZhY2FkZV87XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgbGlzdGVuZXJzLlxuXHQgKi9cblx0bGlzdGVuZXJzKGV2ZW50KSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCkubWFwKFxuXHRcdFx0bGlzdGVuZXIgPT4gKGxpc3RlbmVyLmZuID8gbGlzdGVuZXIuZm4gOiBsaXN0ZW5lcilcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIGZpeGVkIG51bWJlciBvZiB0aW1lcyBmb3IgdGhlXG5cdCAqIGV2ZW50cy4gQWZ0ZXIgZWFjaCBldmVudCBpcyB0cmlnZ2VyZWQgdGhlIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZXMsIHRoZVxuXHQgKiBsaXN0ZW5lciBpcyByZW1vdmVkIGZvciBpdC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cblx0ICovXG5cdG1hbnkoZXZlbnQsIGFtb3VudCwgbGlzdGVuZXIpIHtcblx0XHRjb25zdCBldmVudHMgPSB0aGlzLnRvRXZlbnRzQXJyYXlfKGV2ZW50KTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5tYW55XyhldmVudHNbaV0sIGFtb3VudCwgbGlzdGVuZXIpO1xuXHRcdH1cblxuXHRcdHJldHVybiBuZXcgRXZlbnRIYW5kbGUodGhpcywgZXZlbnQsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgYSBmaXhlZCBudW1iZXIgb2YgdGltZXMgZm9yIGEgc2luZ2xlXG5cdCAqIGV2ZW50LiBBZnRlciB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWVzLCB0aGVcblx0ICogbGlzdGVuZXIgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG1hbnlfKGV2ZW50LCBhbW91bnQsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3Qgc2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoYW1vdW50IDw9IDApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKlxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGhhbmRsZXJJbnRlcm5hbCgpIHtcblx0XHRcdGlmICgtLWFtb3VudCA9PT0gMCkge1xuXHRcdFx0XHRzZWxmLnJlbW92ZUxpc3RlbmVyKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwpO1xuXHRcdFx0fVxuXHRcdFx0bGlzdGVuZXIuYXBwbHkoc2VsZiwgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdH1cblxuXHRcdHNlbGYuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwsIGZhbHNlLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGEgbGlzdGVuZXIgb2JqZWN0IG1hdGNoZXMgdGhlIGdpdmVuIGxpc3RlbmVyIGZ1bmN0aW9uLiBUbyBtYXRjaCxcblx0ICogaXQgbmVlZHMgdG8gZWl0aGVyIHBvaW50IHRvIHRoYXQgbGlzdGVuZXIgb3IgaGF2ZSBpdCBhcyBpdHMgb3JpZ2luLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGxpc3RlbmVyT2JqXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXRjaGVzTGlzdGVuZXJfKGxpc3RlbmVyT2JqLCBsaXN0ZW5lcikge1xuXHRcdGNvbnN0IGZuID0gbGlzdGVuZXJPYmouZm4gfHwgbGlzdGVuZXJPYmo7XG5cdFx0cmV0dXJuIChcblx0XHRcdGZuID09PSBsaXN0ZW5lciB8fFxuXHRcdFx0KGxpc3RlbmVyT2JqLm9yaWdpbiAmJiBsaXN0ZW5lck9iai5vcmlnaW4gPT09IGxpc3RlbmVyKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudFxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IU9iamVjdH0gUmV0dXJucyBlbWl0dGVyLCBzbyBjYWxscyBjYW4gYmUgY2hhaW5lZC5cblx0ICovXG5cdG9mZihldmVudCwgbGlzdGVuZXIpIHtcblx0XHR0aGlzLnZhbGlkYXRlTGlzdGVuZXJfKGxpc3RlbmVyKTtcblx0XHRpZiAoIXRoaXMuZXZlbnRzXykge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRzX1tldmVudHNbaV1dID0gdGhpcy5yZW1vdmVNYXRjaGluZ0xpc3RlbmVyT2Jqc18oXG5cdFx0XHRcdHRvQXJyYXkodGhpcy5ldmVudHNfW2V2ZW50c1tpXV0pLFxuXHRcdFx0XHRsaXN0ZW5lclxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50cy5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgaGFuZGxlciB0aGF0IGdldHMgdHJpZ2dlcmVkIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8gb24gdGhpc1xuXHQgKiBpbnN0YW5jZS5cblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gaGFuZGxlclxuXHQgKi9cblx0b25MaXN0ZW5lcihoYW5kbGVyKSB7XG5cdFx0dGhpcy5saXN0ZW5lckhhbmRsZXJzXyA9IHRoaXMuYWRkSGFuZGxlcl8oXG5cdFx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfLFxuXHRcdFx0aGFuZGxlclxuXHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudHMuIFRoaXMgbGlzdGVuZXIgaXMgaW52b2tlZCBvbmx5IHRoZVxuXHQgKiBuZXh0IHRpbWUgZWFjaCBldmVudCBpcyBmaXJlZCwgYWZ0ZXIgd2hpY2ggaXQgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b25jZShldmVudHMsIGxpc3RlbmVyKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFueShldmVudHMsIDEsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnRzLiBJdCdzIG5vdCBhIGdvb2Rcblx0ICogaWRlYSB0byByZW1vdmUgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZCBlbHNld2hlcmUgaW4gdGhlIGNvZGUsXG5cdCAqIGVzcGVjaWFsbHkgd2hlbiBpdCdzIG9uIGFuIGVtaXR0ZXIgdGhhdCB5b3UgZGlkbid0IGNyZWF0ZS5cblx0ICogQHBhcmFtIHsoQXJyYXl8c3RyaW5nKT19IGV2ZW50XG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnQpIHtcblx0XHRpZiAodGhpcy5ldmVudHNfKSB7XG5cdFx0XHRpZiAoZXZlbnQpIHtcblx0XHRcdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5ldmVudHNfW2V2ZW50c1tpXV0gPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmV2ZW50c18gPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lciBvYmplY3RzIGZyb20gdGhlIGdpdmVuIGFycmF5IHRoYXQgbWF0Y2ggdGhlIGdpdmVuXG5cdCAqIGxpc3RlbmVyIGZ1bmN0aW9uLlxuXHQgKiBAcGFyYW0ge0FycmF5LjxPYmplY3Q+fSBsaXN0ZW5lck9ianNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4ge0FycmF5LjxPYmplY3Q+fE9iamVjdH0gVGhlIG5ldyBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoaXMgZXZlbnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZU1hdGNoaW5nTGlzdGVuZXJPYmpzXyhsaXN0ZW5lck9ianMsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3QgZmluYWxMaXN0ZW5lcnMgPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVyT2Jqcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKCF0aGlzLm1hdGNoZXNMaXN0ZW5lcl8obGlzdGVuZXJPYmpzW2ldLCBsaXN0ZW5lcikpIHtcblx0XHRcdFx0ZmluYWxMaXN0ZW5lcnMucHVzaChsaXN0ZW5lck9ianNbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmluYWxMaXN0ZW5lcnMubGVuZ3RoID4gMCA/IGZpbmFsTGlzdGVuZXJzIDogbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGhhbmRsZXJzIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRydW5MaXN0ZW5lckhhbmRsZXJzXyhldmVudCkge1xuXHRcdGxldCBoYW5kbGVycyA9IHRoaXMubGlzdGVuZXJIYW5kbGVyc187XG5cdFx0aWYgKGhhbmRsZXJzKSB7XG5cdFx0XHRoYW5kbGVycyA9IHRvQXJyYXkoaGFuZGxlcnMpO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBoYW5kbGVycy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRoYW5kbGVyc1tpXShldmVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGdpdmVuIGxpc3RlbmVycy5cblx0ICogQHBhcmFtIHshQXJyYXl9IGxpc3RlbmVyc1xuXHQgKiBAcGFyYW0geyFBcnJheX0gYXJnc1xuXHQgKiBAcGFyYW0ge09iamVjdH0gZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJ1bkxpc3RlbmVyc18obGlzdGVuZXJzLCBhcmdzLCBmYWNhZGUpIHtcblx0XHRpZiAoZmFjYWRlKSB7XG5cdFx0XHRhcmdzLnB1c2goZmFjYWRlKTtcblx0XHR9XG5cblx0XHRjb25zdCBkZWZhdWx0TGlzdGVuZXJzID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldLmZuIHx8IGxpc3RlbmVyc1tpXTtcblx0XHRcdGlmIChsaXN0ZW5lcnNbaV0uZGVmYXVsdCkge1xuXHRcdFx0XHRkZWZhdWx0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICghZmFjYWRlIHx8ICFmYWNhZGUucHJldmVudGVkRGVmYXVsdCkge1xuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBkZWZhdWx0TGlzdGVuZXJzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdGRlZmF1bHRMaXN0ZW5lcnNbal0uYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFVzZUZhY2FkZVxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fSBSZXR1cm5zIGVtaXR0ZXIsIHNvIGNhbGxzIGNhbiBiZSBjaGFpbmVkLlxuXHQgKi9cblx0c2V0U2hvdWxkVXNlRmFjYWRlKHNob3VsZFVzZUZhY2FkZSkge1xuXHRcdHRoaXMuc2hvdWxkVXNlRmFjYWRlXyA9IHNob3VsZFVzZUZhY2FkZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyB0aGUgcGFyYW1ldGVyIHRvIGFuIGFycmF5IGlmIG9ubHkgb25lIGV2ZW50IGlzIGdpdmVuLiBSZXVzZXMgdGhlXG5cdCAqIHNhbWUgYXJyYXkgZWFjaCB0aW1lIHRoaXMgY29udmVyc2lvbiBpcyBkb25lLCB0byBhdm9pZCB1c2luZyBtb3JlIG1lbW9yeVxuXHQgKiB0aGFuIG5lY2Vzc2FyeS5cblx0ICogQHBhcmFtICB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0b0V2ZW50c0FycmF5XyhldmVudHMpIHtcblx0XHRpZiAoaXNTdHJpbmcoZXZlbnRzKSkge1xuXHRcdFx0c2luZ2xlQXJyYXlfWzBdID0gZXZlbnRzO1xuXHRcdFx0ZXZlbnRzID0gc2luZ2xlQXJyYXlfO1xuXHRcdH1cblx0XHRyZXR1cm4gZXZlbnRzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbGlzdGVuZXIgaXMgdmFsaWQsIHRocm93aW5nIGFuIGV4Y2VwdGlvbiB3aGVuIGl0J3Mgbm90LlxuXHQgKiBAcGFyYW0gIHsqfSBsaXN0ZW5lclxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR2YWxpZGF0ZUxpc3RlbmVyXyhsaXN0ZW5lcikge1xuXHRcdGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIENvbnZlcnRzIHRvIGFuIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gdmFsXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdG9BcnJheSh2YWwpIHtcblx0dmFsID0gdmFsIHx8IFtdO1xuXHRyZXR1cm4gQXJyYXkuaXNBcnJheSh2YWwpID8gdmFsIDogW3ZhbF07XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50RW1pdHRlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtEaXNwb3NhYmxlfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogRXZlbnRFbWl0dGVyUHJveHkgdXRpbGl0eS4gSXQncyByZXNwb25zaWJsZSBmb3IgbGlua2luZyB0d28gRXZlbnRFbWl0dGVyXG4gKiBpbnN0YW5jZXMgdG9nZXRoZXIsIGVtaXR0aW5nIGV2ZW50cyBmcm9tIHRoZSBmaXJzdCBlbWl0dGVyIHRocm91Z2ggdGhlXG4gKiBzZWNvbmQgb25lLiBUaGF0IG1lYW5zIHRoYXQgbGlzdGVuaW5nIHRvIGEgc3VwcG9ydGVkIGV2ZW50IG9uIHRoZSB0YXJnZXRcbiAqIGVtaXR0ZXIgd2lsbCBtZWFuIGxpc3RlbmluZyB0byBpdCBvbiB0aGUgb3JpZ2luIGVtaXR0ZXIgYXMgd2VsbC5cbiAqIEBleHRlbmRzIHtEaXNwb3NhYmxlfVxuICovXG5jbGFzcyBFdmVudEVtaXR0ZXJQcm94eSBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXIgRXZlbnRzIG9yaWdpbmF0ZWQgb24gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYmUgZmlyZWQgZm9yIHRoZSB0YXJnZXQgZW1pdHRlcidzIGxpc3RlbmVycyBhcyB3ZWxsLlxuXHQgKiBAcGFyYW0ge0V2ZW50RW1pdHRlcn0gdGFyZ2V0RW1pdHRlciBFdmVudCBsaXN0ZW5lcnMgYXR0YWNoZWQgdG8gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYWxzbyBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgZXZlbnQgaXMgZmlyZWQgYnkgdGhlIG9yaWdpbiBlbWl0dGVyLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gYmxhY2tsaXN0IE9wdGlvbmFsIGJsYWNrbGlzdCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlXG5cdCAqIHByb3hpZWQuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB3aGl0ZWxpc3Rcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9yaWdpbkVtaXR0ZXIsIHRhcmdldEVtaXR0ZXIsIGJsYWNrbGlzdCwgd2hpdGVsaXN0KSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ibGFja2xpc3RfID0gYmxhY2tsaXN0O1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG9yaWdpbiBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIncyBldmVudHMgd2lsbCBiZSBwcm94aWVkIHRocm91Z2ggdGhlXG5cdFx0ICogdGFyZ2V0IGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBBIGxpc3Qgb2YgZXZlbnRzIHRoYXQgYXJlIHBlbmRpbmcgdG8gYmUgbGlzdGVuZWQgYnkgYW4gYWN0dWFsIG9yaWdpblxuXHRcdCAqIGVtaXR0ZXIuIEV2ZW50cyBhcmUgc3RvcmVkIGhlcmUgd2hlbiB0aGUgb3JpZ2luIGRvZXNuJ3QgZXhpc3QsIHNvIHRoZXlcblx0XHQgKiBjYW4gYmUgc2V0IG9uIGEgbmV3IG9yaWdpbiB3aGVuIG9uZSBpcyBzZXQuXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBlbmRpbmdFdmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGEgbWFwIG9mIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gZW1pdHRlciB0aGF0IGFyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdDxzdHJpbmcsICFFdmVudEhhbmRsZT59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucHJveGllZEV2ZW50c18gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIHRhcmdldCBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIgd2lsbCBlbWl0IGFsbCBldmVudHMgdGhhdCBjb21lIGZyb21cblx0XHQgKiB0aGUgb3JpZ2luIGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy50YXJnZXRFbWl0dGVyXyA9IHRhcmdldEVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBNYXAgb2YgZXZlbnRzIHRoYXQgc2hvdWxkIGJlIHByb3hpZWQuIElmIHdoaXRlbGlzdCBpcyBzZXQgYmxhY2tsaXN0IGlzIGlnbm9yZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy53aGl0ZWxpc3RfID0gd2hpdGVsaXN0O1xuXG5cdFx0dGhpcy5zdGFydFByb3h5XygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIGdpdmVuIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IFRoZSBsaXN0ZW5lZCBldmVudCdzIGhhbmRsZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHJldHVybiB0aGlzLm9yaWdpbkVtaXR0ZXJfLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyc18oKTtcblx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfID0gbnVsbDtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbWl0cyB0aGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUgb24gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRlbWl0T25UYXJnZXRfKC4uLmFyZ3MpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLmVtaXQoLi4uYXJncyk7XG5cdH1cblxuXHQvKipcblx0ICogUHJveGllcyB0aGUgZ2l2ZW4gZXZlbnQgZnJvbSB0aGUgb3JpZ2luIHRvIHRoZSB0YXJnZXQgZW1pdHRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqL1xuXHRwcm94eUV2ZW50KGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuc2hvdWxkUHJveHlFdmVudF8oZXZlbnQpKSB7XG5cdFx0XHR0aGlzLnRyeVRvQWRkTGlzdGVuZXJfKGV2ZW50KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgcHJveHkgbGlzdGVuZXIgZm9yIGFsbCBldmVudHMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZUxpc3RlbmVyc18oKSB7XG5cdFx0aWYgKHRoaXMucHJveGllZEV2ZW50c18pIHtcblx0XHRcdGNvbnN0IGV2ZW50cyA9IE9iamVjdC5rZXlzKHRoaXMucHJveGllZEV2ZW50c18pO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0dGhpcy5wcm94aWVkRXZlbnRzX1tldmVudHNbaV1dLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR9XG5cdFx0dGhpcy5wZW5kaW5nRXZlbnRzXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQ2hhbmdlcyB0aGUgb3JpZ2luIGVtaXR0ZXIuIFRoaXMgYXV0b21hdGljYWxseSBkZXRhY2hlcyBhbnkgZXZlbnRzIHRoYXRcblx0ICogd2VyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQgZnJvbSB0aGUgcHJldmlvdXMgZW1pdHRlciwgYW5kIHN0YXJ0cyBwcm94eWluZ1xuXHQgKiB0aGVtIG9uIHRoZSBuZXcgZW1pdHRlciBpbnN0ZWFkLlxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXJcblx0ICovXG5cdHNldE9yaWdpbkVtaXR0ZXIob3JpZ2luRW1pdHRlcikge1xuXHRcdGNvbnN0IGV2ZW50cyA9XG5cdFx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfICYmIHRoaXMucHJveGllZEV2ZW50c19cblx0XHRcdFx0PyBPYmplY3Qua2V5cyh0aGlzLnByb3hpZWRFdmVudHNfKVxuXHRcdFx0XHQ6IHRoaXMucGVuZGluZ0V2ZW50c187XG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cdFx0aWYgKGV2ZW50cykge1xuXHRcdFx0dGhpcy5yZW1vdmVMaXN0ZW5lcnNfKCk7XG5cdFx0XHRldmVudHMuZm9yRWFjaChldmVudCA9PiB0aGlzLnByb3h5RXZlbnQoZXZlbnQpKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBzaG91bGQgYmUgcHJveGllZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHNob3VsZFByb3h5RXZlbnRfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMud2hpdGVsaXN0XyAmJiAhdGhpcy53aGl0ZWxpc3RfW2V2ZW50XSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAodGhpcy5ibGFja2xpc3RfICYmIHRoaXMuYmxhY2tsaXN0X1tldmVudF0pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuICF0aGlzLnByb3hpZWRFdmVudHNfIHx8ICF0aGlzLnByb3hpZWRFdmVudHNfW2V2ZW50XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgcHJveHlpbmcgYWxsIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gdG8gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzdGFydFByb3h5XygpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLm9uTGlzdGVuZXIodGhpcy5wcm94eUV2ZW50LmJpbmQodGhpcykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgb3JpZ2luIGVtaXR0ZXIsIGlmIGl0IGV4aXN0cy4gT3RoZXJ3aXNlLCBzdG9yZXNcblx0ICogdGhlIHBlbmRpbmcgbGlzdGVuZXIgc28gaXQgY2FuIGJlIHVzZWQgb24gYSBmdXR1cmUgb3JpZ2luIGVtaXR0ZXIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0cnlUb0FkZExpc3RlbmVyXyhldmVudCkge1xuXHRcdGlmICh0aGlzLm9yaWdpbkVtaXR0ZXJfKSB7XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gdGhpcy5wcm94aWVkRXZlbnRzXyB8fCB7fTtcblx0XHRcdHRoaXMucHJveGllZEV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRMaXN0ZW5lcl8oXG5cdFx0XHRcdGV2ZW50LFxuXHRcdFx0XHR0aGlzLmVtaXRPblRhcmdldF8uYmluZCh0aGlzLCBldmVudClcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucGVuZGluZ0V2ZW50c18gPSB0aGlzLnBlbmRpbmdFdmVudHNfIHx8IFtdO1xuXHRcdFx0dGhpcy5wZW5kaW5nRXZlbnRzXy5wdXNoKGV2ZW50KTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRFbWl0dGVyUHJveHk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlciB1dGlsaXR5LiBJdCdzIHVzZWZ1bCBmb3IgZWFzaWx5IHJlbW92aW5nIGEgZ3JvdXAgb2ZcbiAqIGxpc3RlbmVycyBmcm9tIGRpZmZlcmVudCBFdmVudEVtaXR0ZXIgaW5zdGFuY2VzLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRIYW5kbGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogQW4gYXJyYXkgdGhhdCBob2xkcyB0aGUgYWRkZWQgZXZlbnQgaGFuZGxlcywgc28gdGhlIGxpc3RlbmVycyBjYW4gYmVcblx0XHQgKiByZW1vdmVkIGxhdGVyLlxuXHRcdCAqIEB0eXBlIHtBcnJheS48RXZlbnRIYW5kbGU+fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGV2ZW50IGhhbmRsZXMgdG8gYmUgcmVtb3ZlZCBsYXRlciB0aHJvdWdoIHRoZSBgcmVtb3ZlQWxsTGlzdGVuZXJzYFxuXHQgKiBtZXRob2QuXG5cdCAqIEBwYXJhbSB7Li4uKCFFdmVudEhhbmRsZSl9IHZhcl9hcmdzXG5cdCAqL1xuXHRhZGQoLi4uYXJncykge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmV2ZW50SGFuZGxlc18ucHVzaChhcmdzW2ldKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyB0aGF0IGhhdmUgYmVlbiBhZGRlZCB0aHJvdWdoIHRoZSBgYWRkYCBtZXRob2QuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmV2ZW50SGFuZGxlc18ubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRIYW5kbGVzX1tpXS5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdH1cblxuXHRcdHRoaXMuZXZlbnRIYW5kbGVzXyA9IFtdO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50SGFuZGxlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcnJheSwgaXNTdHJpbmd9IGZyb20gJ21ldGFsJztcbmltcG9ydCBkb21EYXRhIGZyb20gJy4vZG9tRGF0YSc7XG5pbXBvcnQge0V2ZW50SGFuZGxlfSBmcm9tICdtZXRhbC1ldmVudHMnO1xuXG4vKipcbiAqIFRoaXMgaXMgYSBzcGVjaWFsIEV2ZW50SGFuZGxlLCB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciBkb20gZGVsZWdhdGVkIGV2ZW50c1xuICogKG9ubHkgdGhlIG9uZXMgdGhhdCByZWNlaXZlIGEgdGFyZ2V0IGVsZW1lbnQsIG5vdCBhIHNlbGVjdG9yIHN0cmluZykuXG4gKiBAZXh0ZW5kcyB7RXZlbnRIYW5kbGV9XG4gKi9cbmNsYXNzIERvbURlbGVnYXRlZEV2ZW50SGFuZGxlIGV4dGVuZHMgRXZlbnRIYW5kbGUge1xuXHQvKipcblx0ICogVGhlIGNvbnN0cnVjdG9yIGZvciBgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGVgLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZW1pdHRlciBFbGVtZW50IHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZz19IHNlbGVjdG9yIEFuIG9wdGlvbmFsIHNlbGVjdG9yIHVzZWQgd2hlbiBkZWxlZ2F0aW5nXG5cdCAqICAgICB0aGUgZXZlbnQuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoZW1pdHRlciwgZXZlbnQsIGxpc3RlbmVyLCBzZWxlY3Rvcikge1xuXHRcdHN1cGVyKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lcik7XG5cdFx0dGhpcy5zZWxlY3Rvcl8gPSBzZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0Y29uc3QgZGVsZWdhdGluZyA9IGRvbURhdGEuZ2V0KHRoaXMuZW1pdHRlcl8sICdkZWxlZ2F0aW5nJywge30pO1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IGRvbURhdGEuZ2V0KHRoaXMuZW1pdHRlcl8sICdsaXN0ZW5lcnMnLCB7fSk7XG5cdFx0Y29uc3Qgc2VsZWN0b3IgPSB0aGlzLnNlbGVjdG9yXztcblx0XHRjb25zdCBhcnIgPSBpc1N0cmluZyhzZWxlY3Rvcilcblx0XHRcdD8gZGVsZWdhdGluZ1t0aGlzLmV2ZW50X10uc2VsZWN0b3JzXG5cdFx0XHQ6IGxpc3RlbmVycztcblx0XHRjb25zdCBrZXkgPSBpc1N0cmluZyhzZWxlY3RvcikgPyBzZWxlY3RvciA6IHRoaXMuZXZlbnRfO1xuXG5cdFx0YXJyYXkucmVtb3ZlKGFycltrZXldIHx8IFtdLCB0aGlzLmxpc3RlbmVyXyk7XG5cdFx0aWYgKGFycltrZXldICYmIGFycltrZXldLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0ZGVsZXRlIGFycltrZXldO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtFdmVudEhhbmRsZX0gZnJvbSAnbWV0YWwtZXZlbnRzJztcblxuLyoqXG4gKiBUaGlzIGlzIGEgc3BlY2lhbCBFdmVudEhhbmRsZSwgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgZG9tIGV2ZW50cywgaW5zdGVhZFxuICogb2YgRXZlbnRFbWl0dGVyIGV2ZW50cy5cbiAqIEBleHRlbmRzIHtFdmVudEhhbmRsZX1cbiAqL1xuY2xhc3MgRG9tRXZlbnRIYW5kbGUgZXh0ZW5kcyBFdmVudEhhbmRsZSB7XG5cdC8qKlxuXHQgKiBUaGUgY29uc3RydWN0b3IgZm9yIGBEb21FdmVudEhhbmRsZWAuXG5cdCAqIEBwYXJhbSB7IUV2ZW50RW1pdHRlcn0gZW1pdHRlciBFbWl0dGVyIHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGNhcHR1cmUgRmxhZyBpbmRpY2F0aW5nIGlmIGxpc3RlbmVyIHNob3VsZCBiZSB0cmlnZ2VyZWRcblx0ICogICBkdXJpbmcgY2FwdHVyZSBwaGFzZSwgaW5zdGVhZCBvZiBkdXJpbmcgdGhlIGJ1YmJsaW5nIHBoYXNlLiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIsIGNhcHR1cmUpIHtcblx0XHRzdXBlcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIpO1xuXHRcdHRoaXMuY2FwdHVyZV8gPSBjYXB0dXJlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHR0aGlzLmVtaXR0ZXJfLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG5cdFx0XHR0aGlzLmV2ZW50Xyxcblx0XHRcdHRoaXMubGlzdGVuZXJfLFxuXHRcdFx0dGhpcy5jYXB0dXJlX1xuXHRcdCk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRG9tRXZlbnRIYW5kbGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7XG5cdGlzRGVmLFxuXHRpc0RlZkFuZE5vdE51bGwsXG5cdGlzRG9jdW1lbnQsXG5cdGlzRG9jdW1lbnRGcmFnbWVudCxcblx0aXNFbGVtZW50LFxuXHRpc09iamVjdCxcblx0aXNTdHJpbmcsXG5cdG9iamVjdCxcbn0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IGRvbURhdGEgZnJvbSAnLi9kb21EYXRhJztcbmltcG9ydCBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZSBmcm9tICcuL0RvbURlbGVnYXRlZEV2ZW50SGFuZGxlJztcbmltcG9ydCBEb21FdmVudEhhbmRsZSBmcm9tICcuL0RvbUV2ZW50SGFuZGxlJztcblxuY29uc3QgZWxlbWVudHNCeVRhZ18gPSB7fTtcbmNvbnN0IHN1cHBvcnRDYWNoZV8gPSB7fTtcbmV4cG9ydCBjb25zdCBjdXN0b21FdmVudHMgPSB7fTtcblxuY29uc3QgTEFTVF9DT05UQUlORVIgPSAnX19tZXRhbF9sYXN0X2NvbnRhaW5lcl9fJztcbmNvbnN0IFVTRV9DQVBUVVJFID0ge1xuXHRibHVyOiB0cnVlLFxuXHRlcnJvcjogdHJ1ZSxcblx0Zm9jdXM6IHRydWUsXG5cdGludmFsaWQ6IHRydWUsXG5cdGxvYWQ6IHRydWUsXG5cdHNjcm9sbDogdHJ1ZSxcbn07XG5cbi8qKlxuICogQWRkcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIHRvIGFuIGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fCFOb2RlbGlzdH0gZWxlbWVudHMgVGhlIGVsZW1lbnQgb3IgZWxlbWVudHMgdG8gYWRkIENTUyBjbGFzc2VzIHRvLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gYWRkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkQ2xhc3NlcyhlbGVtZW50cywgY2xhc3Nlcykge1xuXHRpZiAoIWlzT2JqZWN0KGVsZW1lbnRzKSB8fCAhaXNTdHJpbmcoY2xhc3NlcykpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuXHRcdGVsZW1lbnRzID0gW2VsZW1lbnRzXTtcblx0fVxuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoJ2NsYXNzTGlzdCcgaW4gZWxlbWVudHNbaV0pIHtcblx0XHRcdGFkZENsYXNzZXNXaXRoTmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFkZENsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIHRvIGFuIGVsZW1lbnQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBhZGQgQ1NTIGNsYXNzZXMgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byBhZGQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRpZiAoY2xhc3NOYW1lKSB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcblx0XHR9XG5cdH0pO1xufVxuXG4vKipcbiAqIEFkZHMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyB0byBhbiBlbGVtZW50IHdpdGhvdXQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBhZGQgQ1NTIGNsYXNzZXMgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byBhZGQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRDbGFzc2VzV2l0aG91dE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjb25zdCBlbGVtZW50Q2xhc3NOYW1lID0gYCAke2VsZW1lbnQuY2xhc3NOYW1lfSBgO1xuXHRsZXQgY2xhc3Nlc1RvQXBwZW5kID0gJyc7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRjb25zdCBjbGFzc05hbWUgPSBjbGFzc2VzW2ldO1xuXG5cdFx0aWYgKGVsZW1lbnRDbGFzc05hbWUuaW5kZXhPZihgICR7Y2xhc3NOYW1lfSBgKSA9PT0gLTEpIHtcblx0XHRcdGNsYXNzZXNUb0FwcGVuZCArPSBgICR7Y2xhc3NOYW1lfWA7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGNsYXNzZXNUb0FwcGVuZCkge1xuXHRcdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWUgKyBjbGFzc2VzVG9BcHBlbmQ7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIGFuIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBnaXZlbiBlbGVtZW50LCB0byBiZSB0cmlnZ2VyZWQgdmlhIGRlbGVnYXRlLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gbGlzdGVuZXJcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGFkZEVsZW1lbnRMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBsaXN0ZW5lcikge1xuXHRhZGRUb0Fycl8oZG9tRGF0YS5nZXQoZWxlbWVudCwgJ2xpc3RlbmVycycsIHt9KSwgZXZlbnROYW1lLCBsaXN0ZW5lcik7XG59XG5cbi8qKlxuICogQWRkcyBhbiBldmVudCBsaXN0ZW5lciB0byB0aGUgZ2l2ZW4gZWxlbWVudCwgdG8gYmUgdHJpZ2dlcmVkIHZpYSBkZWxlZ2F0ZVxuICogc2VsZWN0b3JzLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYWRkU2VsZWN0b3JMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3RvciwgbGlzdGVuZXIpIHtcblx0Y29uc3QgZGVsZWdhdGluZ0RhdGEgPSBkb21EYXRhLmdldChlbGVtZW50LCAnZGVsZWdhdGluZycsIHt9KTtcblx0YWRkVG9BcnJfKGRlbGVnYXRpbmdEYXRhW2V2ZW50TmFtZV0uc2VsZWN0b3JzLCBzZWxlY3RvciwgbGlzdGVuZXIpO1xufVxuXG4vKipcbiAqIEFkZHMgYSB2YWx1ZSB0byBhbiBhcnJheSBpbnNpZGUgYW4gb2JqZWN0LCBjcmVhdGluZyBpdCBmaXJzdCBpZiBpdCBkb2Vzbid0XG4gKiB5ZXQgZXhpc3QuXG4gKiBAcGFyYW0geyFBcnJheX0gYXJyXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRUb0Fycl8oYXJyLCBrZXksIHZhbHVlKSB7XG5cdGlmICghYXJyW2tleV0pIHtcblx0XHRhcnJba2V5XSA9IFtdO1xuXHR9XG5cdGFycltrZXldLnB1c2godmFsdWUpO1xufVxuXG4vKipcbiAqIEF0dGFjaGVzIGEgZGVsZWdhdGUgbGlzdGVuZXIsIHVubGVzcyB0aGVyZSdzIGFscmVhZHkgb25lIGF0dGFjaGVkLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYXR0YWNoRGVsZWdhdGVFdmVudF8oZWxlbWVudCwgZXZlbnROYW1lKSB7XG5cdGxldCBkZWxlZ2F0aW5nRGF0YSA9IGRvbURhdGEuZ2V0KGVsZW1lbnQsICdkZWxlZ2F0aW5nJywge30pO1xuXHRpZiAoIWRlbGVnYXRpbmdEYXRhW2V2ZW50TmFtZV0pIHtcblx0XHRkZWxlZ2F0aW5nRGF0YVtldmVudE5hbWVdID0ge1xuXHRcdFx0aGFuZGxlOiBvbihcblx0XHRcdFx0ZWxlbWVudCxcblx0XHRcdFx0ZXZlbnROYW1lLFxuXHRcdFx0XHRoYW5kbGVEZWxlZ2F0ZUV2ZW50Xyxcblx0XHRcdFx0ISFVU0VfQ0FQVFVSRVtldmVudE5hbWVdXG5cdFx0XHQpLFxuXHRcdFx0c2VsZWN0b3JzOiB7fSxcblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogR2V0cyB0aGUgY2xvc2VzdCBlbGVtZW50IHVwIHRoZSB0cmVlIGZyb20gdGhlIGdpdmVuIGVsZW1lbnQgKGluY2x1ZGluZ1xuICogaXRzZWxmKSB0aGF0IG1hdGNoZXMgdGhlIHNwZWNpZmllZCBzZWxlY3Rvciwgb3IgbnVsbCBpZiBub25lIG1hdGNoLlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZXN0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XG5cdHdoaWxlIChlbGVtZW50ICYmICFtYXRjaChlbGVtZW50LCBzZWxlY3RvcikpIHtcblx0XHRlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXHR9XG5cdHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIEFwcGVuZHMgYSBjaGlsZCBub2RlIHdpdGggdGV4dCBvciBvdGhlciBub2RlcyB0byBhIHBhcmVudCBub2RlLiBJZlxuICogY2hpbGQgaXMgYSBIVE1MIHN0cmluZyBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIGEgZG9jdW1lbnRcbiAqIGZyYWdtZW50IGJlZm9yZSBhcHBlbmRpbmcgaXQgdG8gdGhlIHBhcmVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IHBhcmVudCBUaGUgbm9kZSB0byBhcHBlbmQgbm9kZXMgdG8uXG4gKiBAcGFyYW0geyEoRWxlbWVudHxOb2RlTGlzdHxzdHJpbmcpfSBjaGlsZCBUaGUgdGhpbmcgdG8gYXBwZW5kIHRvIHRoZSBwYXJlbnQuXG4gKiBAcmV0dXJuIHshRWxlbWVudH0gVGhlIGFwcGVuZGVkIGNoaWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kKHBhcmVudCwgY2hpbGQpIHtcblx0aWYgKGlzU3RyaW5nKGNoaWxkKSkge1xuXHRcdGNoaWxkID0gYnVpbGRGcmFnbWVudChjaGlsZCk7XG5cdH1cblx0aWYgKGlzTm9kZUxpc3RMaWtlKGNoaWxkKSkge1xuXHRcdGNvbnN0IGNoaWxkQXJyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoY2hpbGQpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRBcnIubGVuZ3RoOyBpKyspIHtcblx0XHRcdHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZEFycltpXSk7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG5cdH1cblx0cmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAqIEhlbHBlciBmb3IgY29udmVydGluZyBhIEhUTUwgc3RyaW5nIGludG8gYSBkb2N1bWVudCBmcmFnbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sU3RyaW5nIFRoZSBIVE1MIHN0cmluZyB0byBjb252ZXJ0LlxuICogQHJldHVybiB7IUVsZW1lbnR9IFRoZSByZXN1bHRpbmcgZG9jdW1lbnQgZnJhZ21lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEZyYWdtZW50KGh0bWxTdHJpbmcpIHtcblx0Y29uc3QgdGVtcERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHR0ZW1wRGl2LmlubmVySFRNTCA9IGA8YnI+JHtodG1sU3RyaW5nfWA7XG5cdHRlbXBEaXYucmVtb3ZlQ2hpbGQodGVtcERpdi5maXJzdENoaWxkKTtcblxuXHRjb25zdCBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblx0d2hpbGUgKHRlbXBEaXYuZmlyc3RDaGlsZCkge1xuXHRcdGZyYWdtZW50LmFwcGVuZENoaWxkKHRlbXBEaXYuZmlyc3RDaGlsZCk7XG5cdH1cblx0cmV0dXJuIGZyYWdtZW50O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZmlyc3QgZWxlbWVudCBjb250YWlucyB0aGUgc2Vjb25kIG9uZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQxXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50MlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zKGVsZW1lbnQxLCBlbGVtZW50Mikge1xuXHRpZiAoaXNEb2N1bWVudChlbGVtZW50MSkpIHtcblx0XHQvLyBkb2N1bWVudC5jb250YWlucyBpcyBub3QgZGVmaW5lZCBvbiBJRTksIHNvIGNhbGwgaXQgb24gZG9jdW1lbnRFbGVtZW50IGluc3RlYWQuXG5cdFx0cmV0dXJuIGVsZW1lbnQxLmRvY3VtZW50RWxlbWVudC5jb250YWlucyhlbGVtZW50Mik7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGVsZW1lbnQxLmNvbnRhaW5zKGVsZW1lbnQyKTtcblx0fVxufVxuXG4vKipcbiAqIExpc3RlbnMgdG8gdGhlIHNwZWNpZmllZCBldmVudCBvbiB0aGUgZ2l2ZW4gRE9NIGVsZW1lbnQsIGJ1dCBvbmx5IGNhbGxzIHRoZVxuICogZ2l2ZW4gY2FsbGJhY2sgbGlzdGVuZXIgd2hlbiBpdCdzIHRyaWdnZXJlZCBieSBlbGVtZW50cyB0aGF0IG1hdGNoIHRoZVxuICogZ2l2ZW4gc2VsZWN0b3Igb3IgdGFyZ2V0IGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBET00gZWxlbWVudCB0aGUgZXZlbnQgc2hvdWxkIGJlIGxpc3RlbmVkIG9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIHRvLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IHNlbGVjdG9yT3JUYXJnZXQgRWl0aGVyIGFuIGVsZW1lbnQgb3IgY3NzIHNlbGVjdG9yXG4gKiAgICAgdGhhdCBzaG91bGQgbWF0Y2ggdGhlIGV2ZW50IGZvciB0aGUgbGlzdGVuZXIgdG8gYmUgdHJpZ2dlcmVkLlxuICogQHBhcmFtIHshZnVuY3Rpb24oIU9iamVjdCl9IGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudFxuICogICAgIGlzIHRyaWdnZXJlZC4gSXQgd2lsbCByZWNlaXZlIHRoZSBub3JtYWxpemVkIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IGRlZmF1bHRMaXN0ZW5lciBPcHRpb25hbCBmbGFnIGluZGljYXRpbmcgaWYgdGhpcyBpcyBhIGRlZmF1bHRcbiAqICAgICBsaXN0ZW5lci4gVGhhdCBtZWFucyB0aGF0IGl0IHdvdWxkIG9ubHkgYmUgZXhlY3V0ZWQgYWZ0ZXIgYWxsIG5vblxuICogICAgIGRlZmF1bHQgbGlzdGVuZXJzLCBhbmQgb25seSBpZiB0aGUgZXZlbnQgaXNuJ3QgcHJldmVudGVkIHZpYVxuICogICAgIGBwcmV2ZW50RGVmYXVsdGAuXG4gKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxlZ2F0ZShcblx0ZWxlbWVudCxcblx0ZXZlbnROYW1lLFxuXHRzZWxlY3Rvck9yVGFyZ2V0LFxuXHRjYWxsYmFjayxcblx0ZGVmYXVsdExpc3RlbmVyXG4pIHtcblx0Y29uc3QgY3VzdG9tQ29uZmlnID0gY3VzdG9tRXZlbnRzW2V2ZW50TmFtZV07XG5cdGlmIChjdXN0b21Db25maWcgJiYgY3VzdG9tQ29uZmlnLmRlbGVnYXRlKSB7XG5cdFx0ZXZlbnROYW1lID0gY3VzdG9tQ29uZmlnLm9yaWdpbmFsRXZlbnQ7XG5cdFx0Y2FsbGJhY2sgPSBjdXN0b21Db25maWcuaGFuZGxlci5iaW5kKGN1c3RvbUNvbmZpZywgY2FsbGJhY2spO1xuXHR9XG5cblx0aWYgKGRlZmF1bHRMaXN0ZW5lcikge1xuXHRcdC8vIFdyYXAgY2FsbGJhY2sgc28gd2UgZG9uJ3Qgc2V0IHByb3BlcnR5IGRpcmVjdGx5IG9uIGl0LlxuXHRcdGNhbGxiYWNrID0gY2FsbGJhY2suYmluZCgpO1xuXHRcdGNhbGxiYWNrLmRlZmF1bHRMaXN0ZW5lcl8gPSB0cnVlO1xuXHR9XG5cblx0YXR0YWNoRGVsZWdhdGVFdmVudF8oZWxlbWVudCwgZXZlbnROYW1lKTtcblx0aWYgKGlzU3RyaW5nKHNlbGVjdG9yT3JUYXJnZXQpKSB7XG5cdFx0YWRkU2VsZWN0b3JMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3Rvck9yVGFyZ2V0LCBjYWxsYmFjayk7XG5cdH0gZWxzZSB7XG5cdFx0YWRkRWxlbWVudExpc3RlbmVyXyhzZWxlY3Rvck9yVGFyZ2V0LCBldmVudE5hbWUsIGNhbGxiYWNrKTtcblx0fVxuXG5cdHJldHVybiBuZXcgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGUoXG5cdFx0aXNTdHJpbmcoc2VsZWN0b3JPclRhcmdldCkgPyBlbGVtZW50IDogc2VsZWN0b3JPclRhcmdldCxcblx0XHRldmVudE5hbWUsXG5cdFx0Y2FsbGJhY2ssXG5cdFx0aXNTdHJpbmcoc2VsZWN0b3JPclRhcmdldCkgPyBzZWxlY3Rvck9yVGFyZ2V0IDogbnVsbFxuXHQpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIGlmIHRoZSBlbGVtZW50IGlzIGFibGUgdG8gdHJpZ2dlciB0aGUgQ2xpY2sgZXZlbnQsXG4gKiBzaW11bGF0aW5nIGJyb3dzZXJzIGJlaGF2aW91ciwgYXZvaWRpbmcgZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGNhbGxlZCBieSB0cmlnZ2VyRXZlbnQgbWV0aG9kLlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gYmUgY2hlY2tlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUuXG4gKiBAcGFyYW0ge09iamVjdD19IGV2ZW50T2JqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNBYmxlVG9JbnRlcmFjdFdpdGhfKG5vZGUsIGV2ZW50TmFtZSwgZXZlbnRPYmopIHtcblx0aWYgKGV2ZW50T2JqICYmIGV2ZW50TmFtZSA9PT0gJ2NsaWNrJyAmJiBldmVudE9iai5idXR0b24gPT09IDIpIHtcblx0XHQvLyBGaXJlZm94IHRyaWdnZXJzIFwiY2xpY2tcIiBldmVudHMgb24gdGhlIGRvY3VtZW50IGZvciByaWdodCBjbGlja3MuIFRoaXNcblx0XHQvLyBjYXVzZXMgb3VyIGRlbGVnYXRlIGxvZ2ljIHRvIHRyaWdnZXIgaXQgZm9yIHJlZ3VsYXIgZWxlbWVudHMgdG9vLCB3aGljaFxuXHRcdC8vIHNob3VsZG4ndCBoYXBwZW4uIElnbm9yaW5nIHRoZW0gaGVyZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRjb25zdCBtYXRjaGVzU2VsZWN0b3IgPSBbXG5cdFx0J0JVVFRPTicsXG5cdFx0J0lOUFVUJyxcblx0XHQnU0VMRUNUJyxcblx0XHQnVEVYVEFSRUEnLFxuXHRcdCdGSUVMRFNFVCcsXG5cdF07XG5cdGlmIChldmVudE5hbWUgPT09ICdjbGljaycgJiYgbWF0Y2hlc1NlbGVjdG9yLmluZGV4T2Yobm9kZS50YWdOYW1lKSA+IC0xKSB7XG5cdFx0cmV0dXJuICEobm9kZS5kaXNhYmxlZCB8fCBwYXJlbnQobm9kZSwgJ2ZpZWxkc2V0W2Rpc2FibGVkXScpKTtcblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIE5vZGVMaXN0IG9yIGxpa2Ugb25lLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgbGlrZSBhIE5vZGVMaXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb2RlTGlzdExpa2UodmFsKSB7XG5cdHJldHVybiAoXG5cdFx0aXNEZWZBbmROb3ROdWxsKHZhbCkgJiZcblx0XHR0eXBlb2YgdmFsLmxlbmd0aCA9PT0gJ251bWJlcicgJiZcblx0XHR0eXBlb2YgdmFsLml0ZW0gPT09ICdmdW5jdGlvbidcblx0KTtcbn1cblxuLyoqXG4gKiBJbnNlcnRzIG5vZGUgaW4gZG9jdW1lbnQgYXMgbGFzdCBlbGVtZW50LlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gcmVtb3ZlIGNoaWxkcmVuIGZyb20uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnRlckRvY3VtZW50KG5vZGUpIHtcblx0bm9kZSAmJiBhcHBlbmQoZG9jdW1lbnQuYm9keSwgbm9kZSk7XG59XG5cbi8qKlxuICogUmVtb3ZlcyBub2RlIGZyb20gZG9jdW1lbnQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgRWxlbWVudCB0byByZW1vdmUgY2hpbGRyZW4gZnJvbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4aXREb2N1bWVudChub2RlKSB7XG5cdGlmIChub2RlICYmIG5vZGUucGFyZW50Tm9kZSkge1xuXHRcdG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcblx0fVxufVxuXG4vKipcbiAqIFRoaXMgaXMgY2FsbGVkIHdoZW4gYW4gZXZlbnQgaXMgdHJpZ2dlcmVkIGJ5IGEgZGVsZWdhdGUgbGlzdGVuZXIuIEFsbFxuICogbWF0Y2hpbmcgbGlzdGVuZXJzIG9mIHRoaXMgZXZlbnQgdHlwZSBmcm9tIGB0YXJnZXRgIHRvIGBjdXJyZW50VGFyZ2V0YCB3aWxsXG4gKiBiZSB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHBheWxvYWQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGhhbmRsZURlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdG5vcm1hbGl6ZURlbGVnYXRlRXZlbnRfKGV2ZW50KTtcblx0bGV0IHJldCA9IHRydWU7XG5cdGNvbnN0IGNvbnRhaW5lciA9IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XG5cdGNvbnN0IGRlZkZucyA9IFtdO1xuXG5cdHJldCAmPSB0cmlnZ2VyRGVsZWdhdGVkTGlzdGVuZXJzXyhjb250YWluZXIsIGV2ZW50LCBkZWZGbnMpO1xuXHRyZXQgJj0gdHJpZ2dlckRlZmF1bHREZWxlZ2F0ZWRMaXN0ZW5lcnNfKGRlZkZucywgZXZlbnQpO1xuXG5cdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gbnVsbDtcblx0ZXZlbnRbTEFTVF9DT05UQUlORVJdID0gY29udGFpbmVyO1xuXHRyZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBoYXMgdGhlIHJlcXVlc3RlZCBjc3MgY2xhc3MuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lKSB7XG5cdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XG5cdFx0cmV0dXJuIGhhc0NsYXNzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3NOYW1lKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gaGFzQ2xhc3NXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc05hbWUpO1xuXHR9XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgcmVxdWVzdGVkIGNzcyBjbGFzcyB1c2luZyBjbGFzc0xpc3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gaGFzQ2xhc3NXaXRoTmF0aXZlXyhlbGVtZW50LCBjbGFzc05hbWUpIHtcblx0cmV0dXJuIChcblx0XHRjbGFzc05hbWUuaW5kZXhPZignICcpID09PSAtMSAmJiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpXG5cdCk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgcmVxdWVzdGVkIGNzcyBjbGFzcyB3aXRob3V0IHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBoYXNDbGFzc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuXHRyZXR1cm4gKFxuXHRcdGAgJHtlbGVtZW50LmNsYXNzTmFtZX0gYC5pbmRleE9mKGAgJHtjbGFzc05hbWV9IGApID49IDAgJiZcblx0XHRjbGFzc05hbWUuc3BsaXQoJyAnKS5sZW5ndGggPT09IDFcblx0KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgZW1wdHkgb3Igbm90LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkoZWxlbWVudCkge1xuXHRyZXR1cm4gZWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMDtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IG1hdGNoZXMgYSBnaXZlbiBzZWxlY3Rvci5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0aWYgKCFlbGVtZW50IHx8IGVsZW1lbnQubm9kZVR5cGUgIT09IDEpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRjb25zdCBwID0gRWxlbWVudC5wcm90b3R5cGU7XG5cdGNvbnN0IG0gPVxuXHRcdHAubWF0Y2hlcyB8fFxuXHRcdHAud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0cC5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRwLm1zTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0cC5vTWF0Y2hlc1NlbGVjdG9yO1xuXHRpZiAobSkge1xuXHRcdHJldHVybiBtLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpO1xuXHR9XG5cblx0cmV0dXJuIG1hdGNoRmFsbGJhY2tfKGVsZW1lbnQsIHNlbGVjdG9yKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IG1hdGNoZXMgYSBnaXZlbiBzZWxlY3RvciwgdXNpbmcgYW4gaW50ZXJuYWwgaW1wbGVtZW50YXRpb25cbiAqIGluc3RlYWQgb2YgY2FsbGluZyBleGlzdGluZyBqYXZhc2NyaXB0IGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gbWF0Y2hGYWxsYmFja18oZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0Y29uc3QgcGFyZW50Tm9kZSA9IGVsZW1lbnQucGFyZW50Tm9kZTtcblxuXHRpZiAocGFyZW50Tm9kZSkge1xuXHRcdGNvbnN0IG5vZGVzID0gcGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyArK2kpIHtcblx0XHRcdGlmIChub2Rlc1tpXSA9PT0gZWxlbWVudCkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbmV4dCBzaWJsaW5nIG9mIHRoZSBnaXZlbiBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkXG4gKiBzZWxlY3Rvciwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHs/c3RyaW5nfSBzZWxlY3RvclxuICogQHJldHVybiB7RWxlbWVudHxudWxsfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbmV4dChlbGVtZW50LCBzZWxlY3Rvcikge1xuXHRkbyB7XG5cdFx0ZWxlbWVudCA9IGVsZW1lbnQubmV4dFNpYmxpbmc7XG5cdFx0aWYgKGVsZW1lbnQgJiYgbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpKSB7XG5cdFx0XHRyZXR1cm4gZWxlbWVudDtcblx0XHR9XG5cdH0gd2hpbGUgKGVsZW1lbnQpO1xuXHRyZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIHRoZSBldmVudCBwYXlsb2FkIGZvciBkZWxlZ2F0ZSBsaXN0ZW5lcnMuXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZURlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdGV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IHN0b3BQcm9wYWdhdGlvbl87XG5cdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9IHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbl87XG59XG5cbi8qKlxuICogTGlzdGVucyB0byB0aGUgc3BlY2lmaWVkIGV2ZW50IG9uIHRoZSBnaXZlbiBET00gZWxlbWVudC4gVGhpcyBmdW5jdGlvbiBub3JtYWxpemVzXG4gKiBET00gZXZlbnQgcGF5bG9hZHMgYW5kIGZ1bmN0aW9ucyBzbyB0aGV5J2xsIHdvcmsgdGhlIHNhbWUgd2F5IG9uIGFsbCBzdXBwb3J0ZWRcbiAqIGJyb3dzZXJzLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IGVsZW1lbnQgVGhlIERPTSBlbGVtZW50IHRvIGxpc3RlbiB0byB0aGUgZXZlbnQgb24sIG9yXG4gKiAgIGEgc2VsZWN0b3IgdGhhdCBzaG91bGQgYmUgZGVsZWdhdGVkIG9uIHRoZSBlbnRpcmUgZG9jdW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gdG8uXG4gKiBAcGFyYW0geyFmdW5jdGlvbighT2JqZWN0KX0gY2FsbGJhY2sgRnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzXG4gKiAgIHRyaWdnZXJlZC4gSXQgd2lsbCByZWNlaXZlIHRoZSBub3JtYWxpemVkIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2FwdHVyZSBGbGFnIGluZGljYXRpbmcgaWYgbGlzdGVuZXIgc2hvdWxkIGJlIHRyaWdnZXJlZFxuICogICBkdXJpbmcgY2FwdHVyZSBwaGFzZSwgaW5zdGVhZCBvZiBkdXJpbmcgdGhlIGJ1YmJsaW5nIHBoYXNlLiBEZWZhdWx0cyB0byBmYWxzZS5cbiAqIEByZXR1cm4geyFEb21FdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpIHtcblx0aWYgKGlzU3RyaW5nKGVsZW1lbnQpKSB7XG5cdFx0cmV0dXJuIGRlbGVnYXRlKGRvY3VtZW50LCBldmVudE5hbWUsIGVsZW1lbnQsIGNhbGxiYWNrKTtcblx0fVxuXHRjb25zdCBjdXN0b21Db25maWcgPSBjdXN0b21FdmVudHNbZXZlbnROYW1lXTtcblx0aWYgKGN1c3RvbUNvbmZpZyAmJiBjdXN0b21Db25maWcuZXZlbnQpIHtcblx0XHRldmVudE5hbWUgPSBjdXN0b21Db25maWcub3JpZ2luYWxFdmVudDtcblx0XHRjYWxsYmFjayA9IGN1c3RvbUNvbmZpZy5oYW5kbGVyLmJpbmQoY3VzdG9tQ29uZmlnLCBjYWxsYmFjayk7XG5cdH1cblx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xuXHRyZXR1cm4gbmV3IERvbUV2ZW50SGFuZGxlKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xufVxuXG4vKipcbiAqIExpc3RlbnMgdG8gdGhlIHNwZWNpZmllZCBldmVudCBvbiB0aGUgZ2l2ZW4gRE9NIGVsZW1lbnQgb25jZS4gVGhpc1xuICogZnVuY3Rpb24gbm9ybWFsaXplcyBET00gZXZlbnQgcGF5bG9hZHMgYW5kIGZ1bmN0aW9ucyBzbyB0aGV5J2xsIHdvcmsgdGhlXG4gKiBzYW1lIHdheSBvbiBhbGwgc3VwcG9ydGVkIGJyb3dzZXJzLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgRE9NIGVsZW1lbnQgdG8gbGlzdGVuIHRvIHRoZSBldmVudCBvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiB0by5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCFPYmplY3QpfSBjYWxsYmFjayBGdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnRcbiAqICAgaXMgdHJpZ2dlcmVkLiBJdCB3aWxsIHJlY2VpdmUgdGhlIG5vcm1hbGl6ZWQgZXZlbnQgb2JqZWN0LlxuICogQHJldHVybiB7IURvbUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb25jZShlbGVtZW50LCBldmVudE5hbWUsIGNhbGxiYWNrKSB7XG5cdGNvbnN0IGRvbUV2ZW50SGFuZGxlID0gb24oZWxlbWVudCwgZXZlbnROYW1lLCBmdW5jdGlvbigpIHtcblx0XHRkb21FdmVudEhhbmRsZS5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdHJldHVybiBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdH0pO1xuXHRyZXR1cm4gZG9tRXZlbnRIYW5kbGU7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgZmlyc3QgcGFyZW50IGZyb20gdGhlIGdpdmVuIGVsZW1lbnQgdGhhdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWRcbiAqIHNlbGVjdG9yLCBvciBudWxsIGlmIG5vbmUgbWF0Y2guXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJlbnQoZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0cmV0dXJuIGNsb3Nlc3QoZWxlbWVudC5wYXJlbnROb2RlLCBzZWxlY3Rvcik7XG59XG5cbi8qKlxuICogSW5zZXJ0cyBhIG5vZGUgYmVmb3JlIGZpcnN0IGNoaWxkIG9mIHRoZSBwYXJlbnQuIElmIGNoaWxkIGlzIGEgSFRNTCBzdHJpbmdcbiAqIGl0IHdpbGwgYmUgY29udmVydGVkIHRvIGRvY3VtZW50IGZyYWdtZW50IGJlZm9yZSBwcmVwZW5kaW5nIGl0IHRvIHRoZSBwYXJlbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBwYXJlbnQgVGhlIG5vZGUgdG8gcHJlcGVuZCB0by5cbiAqIEBwYXJhbSB7IShFbGVtZW50fE5vZGVMaXN0fHN0cmluZyl9IGNoaWxkIFRoZSB0aGluZyB0byBwcmVwZW5kIHRvIHRoZSBwYXJlbnQuXG4gKiBAcmV0dXJuIHshRWxlbWVudH0gVGhlIHByZXBlbmRlZCBjaGlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZXBlbmQocGFyZW50LCBjaGlsZCkge1xuXHRpZiAoaXNTdHJpbmcoY2hpbGQpKSB7XG5cdFx0Y2hpbGQgPSBidWlsZEZyYWdtZW50KGNoaWxkKTtcblx0fVxuXG5cdGlmICghaXNOb2RlTGlzdExpa2UoY2hpbGQpICYmICFpc0RlZkFuZE5vdE51bGwocGFyZW50LmZpcnN0Q2hpbGQpKSB7XG5cdFx0cmV0dXJuIGFwcGVuZChwYXJlbnQsIGNoaWxkKTtcblx0fVxuXG5cdGlmIChpc05vZGVMaXN0TGlrZShjaGlsZCkpIHtcblx0XHRjb25zdCBjaGlsZEFyciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGNoaWxkKTtcblx0XHRmb3IgKGxldCBpID0gY2hpbGRBcnIubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0XHRcdHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGRBcnJbaV0sIHBhcmVudC5maXJzdENoaWxkKTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgcGFyZW50LmZpcnN0Q2hpbGQpO1xuXHR9XG5cblx0cmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGN1c3RvbSBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGN1c3RvbSBldmVudC5cbiAqIEBwYXJhbSB7IU9iamVjdH0gY3VzdG9tQ29uZmlnIEFuIG9iamVjdCB3aXRoIGluZm9ybWF0aW9uIGFib3V0IGhvdyB0aGUgZXZlbnRcbiAqICAgc2hvdWxkIGJlIGhhbmRsZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckN1c3RvbUV2ZW50KGV2ZW50TmFtZSwgY3VzdG9tQ29uZmlnKSB7XG5cdGN1c3RvbUV2ZW50c1tldmVudE5hbWVdID0gY3VzdG9tQ29uZmlnO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgYWxsIHRoZSBjaGlsZCBub2RlcyBvbiBhIERPTSBub2RlLlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gcmVtb3ZlIGNoaWxkcmVuIGZyb20uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDaGlsZHJlbihub2RlKSB7XG5cdGxldCBjaGlsZDtcblx0d2hpbGUgKChjaGlsZCA9IG5vZGUuZmlyc3RDaGlsZCkpIHtcblx0XHRub2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcblx0fVxufVxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fCFOb2RlTGlzdH0gZWxlbWVudHMgVGhlIGVsZW1lbnQgb3IgZWxlbWVudHMgdG8gcmVtb3ZlIENTUyBjbGFzc2VzIGZyb20uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byByZW1vdmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDbGFzc2VzKGVsZW1lbnRzLCBjbGFzc2VzKSB7XG5cdGlmICghaXNPYmplY3QoZWxlbWVudHMpIHx8ICFpc1N0cmluZyhjbGFzc2VzKSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGlmICghZWxlbWVudHMubGVuZ3RoKSB7XG5cdFx0ZWxlbWVudHMgPSBbZWxlbWVudHNdO1xuXHR9XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50c1tpXSkge1xuXHRcdFx0cmVtb3ZlQ2xhc3Nlc1dpdGhOYXRpdmVfKGVsZW1lbnRzW2ldLCBjbGFzc2VzKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmVtb3ZlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnRzW2ldLCBjbGFzc2VzKTtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSByZXF1ZXN0ZWQgQ1NTIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50IHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gcmVtb3ZlIENTUyBjbGFzc2VzIGZyb20uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byByZW1vdmUuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiByZW1vdmVDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRpZiAoY2xhc3NOYW1lKSB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKTtcblx0XHR9XG5cdH0pO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQgd2l0aG91dCB1c2luZyBjbGFzc0xpc3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIHJlbW92ZSBDU1MgY2xhc3NlcyBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gcmVtb3ZlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0bGV0IGVsZW1lbnRDbGFzc05hbWUgPSBgICR7ZWxlbWVudC5jbGFzc05hbWV9IGA7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRlbGVtZW50Q2xhc3NOYW1lID0gZWxlbWVudENsYXNzTmFtZS5yZXBsYWNlKGAgJHtjbGFzc2VzW2ldfSBgLCAnICcpO1xuXHR9XG5cblx0ZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50Q2xhc3NOYW1lLnRyaW0oKTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlcyB0aGUgZmlyc3QgZWxlbWVudCB3aXRoIHRoZSBzZWNvbmQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQxXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlKGVsZW1lbnQxLCBlbGVtZW50Mikge1xuXHRpZiAoZWxlbWVudDEgJiYgZWxlbWVudDIgJiYgZWxlbWVudDEgIT09IGVsZW1lbnQyICYmIGVsZW1lbnQxLnBhcmVudE5vZGUpIHtcblx0XHRlbGVtZW50MS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50MiwgZWxlbWVudDEpO1xuXHRcdGVsZW1lbnQxLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudDEpO1xuXHR9XG59XG5cbi8qKlxuICogVGhlIGZ1bmN0aW9uIHRoYXQgcmVwbGFjZXMgYHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbl9gIGZvciBldmVudHMuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25fKCkge1xuXHRjb25zdCBldmVudCA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0ZXZlbnQuc3RvcHBlZCA9IHRydWU7XG5cdGV2ZW50LnN0b3BwZWRJbW1lZGlhdGUgPSB0cnVlO1xuXHRFdmVudC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uLmNhbGwoZXZlbnQpO1xufVxuXG4vKipcbiAqIFRoZSBmdW5jdGlvbiB0aGF0IHJlcGxhY2VzIGBzdG9wUHJvcGFnYXRpb25gIGZvciBldmVudHMuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzdG9wUHJvcGFnYXRpb25fKCkge1xuXHRjb25zdCBldmVudCA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0ZXZlbnQuc3RvcHBlZCA9IHRydWU7XG5cdEV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24uY2FsbChldmVudCk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IHN1cHBvcnRzIHRoZSBnaXZlbiBldmVudCB0eXBlLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IGVsZW1lbnQgVGhlIERPTSBlbGVtZW50IG9yIGVsZW1lbnQgdGFnIG5hbWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBjaGVjay5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdXBwb3J0c0V2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSkge1xuXHRpZiAoY3VzdG9tRXZlbnRzW2V2ZW50TmFtZV0pIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdGlmIChpc1N0cmluZyhlbGVtZW50KSkge1xuXHRcdGlmICghZWxlbWVudHNCeVRhZ19bZWxlbWVudF0pIHtcblx0XHRcdGVsZW1lbnRzQnlUYWdfW2VsZW1lbnRdID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChlbGVtZW50KTtcblx0XHR9XG5cdFx0ZWxlbWVudCA9IGVsZW1lbnRzQnlUYWdfW2VsZW1lbnRdO1xuXHR9XG5cblx0Y29uc3QgdGFnID0gZWxlbWVudC50YWdOYW1lO1xuXHRpZiAoIXN1cHBvcnRDYWNoZV9bdGFnXSB8fCAhc3VwcG9ydENhY2hlX1t0YWddLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcblx0XHRzdXBwb3J0Q2FjaGVfW3RhZ10gPSBzdXBwb3J0Q2FjaGVfW3RhZ10gfHwge307XG5cdFx0c3VwcG9ydENhY2hlX1t0YWddW2V2ZW50TmFtZV0gPSAnb24nICsgZXZlbnROYW1lIGluIGVsZW1lbnQ7XG5cdH1cblx0cmV0dXJuIHN1cHBvcnRDYWNoZV9bdGFnXVtldmVudE5hbWVdO1xufVxuXG4vKipcbiAqIFRoaXMgdHJpZ2dlcnMgYWxsIGRlZmF1bHQgbWF0Y2hlZCBkZWxlZ2F0ZWQgbGlzdGVuZXJzIG9mIGEgZ2l2ZW4gZXZlbnQgdHlwZS5cbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogQHBhcmFtIHshRXZlbnR9IGV2ZW50XG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJEZWZhdWx0RGVsZWdhdGVkTGlzdGVuZXJzXyhkZWZGbnMsIGV2ZW50KSB7XG5cdGxldCByZXQgPSB0cnVlO1xuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgZGVmRm5zLmxlbmd0aCAmJiAhZXZlbnQuZGVmYXVsdFByZXZlbnRlZDsgaSsrKSB7XG5cdFx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSBkZWZGbnNbaV0uZWxlbWVudDtcblx0XHRyZXQgJj0gZGVmRm5zW2ldLmZuKGV2ZW50KTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogVGhpcyB0cmlnZ2VycyBhbGwgbWF0Y2hlZCBkZWxlZ2F0ZWQgbGlzdGVuZXJzIG9mIGEgZ2l2ZW4gZXZlbnQgdHlwZSB3aGVuIGl0c1xuICogZGVsZWdhdGVkIHRhcmdldCBpcyBhYmxlIHRvIGludGVyYWN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gY29udGFpbmVyXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZhdWx0Rm5zIEFycmF5IHRvIGNvbGxlY3QgZGVmYXVsdCBsaXN0ZW5lcnMgaW4sIGluc3RlYWRcbiAqICAgICBvZiBydW5uaW5nIHRoZW0uXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJEZWxlZ2F0ZWRMaXN0ZW5lcnNfKGNvbnRhaW5lciwgZXZlbnQsIGRlZmF1bHRGbnMpIHtcblx0bGV0IHJldCA9IHRydWU7XG5cdGxldCBjdXJyRWxlbWVudCA9IGV2ZW50LnRhcmdldDtcblx0Y29uc3QgbGltaXQgPSBjb250YWluZXIucGFyZW50Tm9kZTtcblxuXHR3aGlsZSAoY3VyckVsZW1lbnQgJiYgY3VyckVsZW1lbnQgIT09IGxpbWl0ICYmICFldmVudC5zdG9wcGVkKSB7XG5cdFx0aWYgKGlzQWJsZVRvSW50ZXJhY3RXaXRoXyhjdXJyRWxlbWVudCwgZXZlbnQudHlwZSwgZXZlbnQpKSB7XG5cdFx0XHRldmVudC5kZWxlZ2F0ZVRhcmdldCA9IGN1cnJFbGVtZW50O1xuXHRcdFx0cmV0ICY9IHRyaWdnZXJFbGVtZW50TGlzdGVuZXJzXyhjdXJyRWxlbWVudCwgZXZlbnQsIGRlZmF1bHRGbnMpO1xuXHRcdFx0cmV0ICY9IHRyaWdnZXJTZWxlY3Rvckxpc3RlbmVyc18oXG5cdFx0XHRcdGNvbnRhaW5lcixcblx0XHRcdFx0Y3VyckVsZW1lbnQsXG5cdFx0XHRcdGV2ZW50LFxuXHRcdFx0XHRkZWZhdWx0Rm5zXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRjdXJyRWxlbWVudCA9IGN1cnJFbGVtZW50LnBhcmVudE5vZGU7XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBhcmd1bWVudCB0byBhIERPTSBlbGVtZW50LiBTdHJpbmdzIGFyZSBhc3N1bWVkIHRvXG4gKiBiZSBzZWxlY3RvcnMsIGFuZCBzbyBhIG1hdGNoZWQgZWxlbWVudCB3aWxsIGJlIHJldHVybmVkLiBJZiB0aGUgYXJnXG4gKiBpcyBhbHJlYWR5IGEgRE9NIGVsZW1lbnQgaXQgd2lsbCBiZSB0aGUgcmV0dXJuIHZhbHVlLlxuICogQHBhcmFtIHtzdHJpbmd8RWxlbWVudHxEb2N1bWVudH0gc2VsZWN0b3JPckVsZW1lbnRcbiAqIEByZXR1cm4ge0VsZW1lbnR9IFRoZSBjb252ZXJ0ZWQgZWxlbWVudCwgb3IgbnVsbCBpZiBub25lIHdhcyBmb3VuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRWxlbWVudChzZWxlY3Rvck9yRWxlbWVudCkge1xuXHRpZiAoXG5cdFx0aXNFbGVtZW50KHNlbGVjdG9yT3JFbGVtZW50KSB8fFxuXHRcdGlzRG9jdW1lbnQoc2VsZWN0b3JPckVsZW1lbnQpIHx8XG5cdFx0aXNEb2N1bWVudEZyYWdtZW50KHNlbGVjdG9yT3JFbGVtZW50KVxuXHQpIHtcblx0XHRyZXR1cm4gc2VsZWN0b3JPckVsZW1lbnQ7XG5cdH0gZWxzZSBpZiAoaXNTdHJpbmcoc2VsZWN0b3JPckVsZW1lbnQpKSB7XG5cdFx0aWYgKFxuXHRcdFx0c2VsZWN0b3JPckVsZW1lbnRbMF0gPT09ICcjJyAmJlxuXHRcdFx0c2VsZWN0b3JPckVsZW1lbnQuaW5kZXhPZignICcpID09PSAtMVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHNlbGVjdG9yT3JFbGVtZW50LnN1YnN0cigxKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yT3JFbGVtZW50KTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIG9yIHJlbW92ZXMgb25lIG9yIG1vcmUgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQuIElmIGFueSBvZiB0aGUgY2xhc3Nlc1xuICogaXMgcHJlc2VudCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQsIG9yIGFkZGVkIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgd2hpY2ggY2xhc3NlcyB3aWxsIGJlIHRvZ2dsZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBUaGUgY2xhc3NlcyB3aGljaCBoYXZlIHRvIGFkZGVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvZ2dsZUNsYXNzZXMoZWxlbWVudCwgY2xhc3Nlcykge1xuXHRpZiAoIWlzT2JqZWN0KGVsZW1lbnQpIHx8ICFpc1N0cmluZyhjbGFzc2VzKSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XG5cdFx0dG9nZ2xlQ2xhc3Nlc1dpdGhOYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpO1xuXHR9IGVsc2Uge1xuXHRcdHRvZ2dsZUNsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc2VzKTtcblx0fVxufVxuXG4vKipcbiAqIEFkZHMgb3IgcmVtb3ZlcyBvbmUgb3IgbW9yZSBjbGFzc2VzIGZyb20gYW4gZWxlbWVudCB1c2luZyBjbGFzc0xpc3QuXG4gKiBJZiBhbnkgb2YgdGhlIGNsYXNzZXMgaXMgcHJlc2VudCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQsXG4gKiBvciBhZGRlZCBvdGhlcndpc2UuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHdoaWNoIGNsYXNzZXMgd2lsbCBiZSB0b2dnbGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgVGhlIGNsYXNzZXMgd2hpY2ggaGF2ZSB0byBhZGRlZCBvciByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoY2xhc3NOYW1lKTtcblx0fSk7XG59XG5cbi8qKlxuICogQWRkcyBvciByZW1vdmVzIG9uZSBvciBtb3JlIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50IHdpdGhvdXQgdXNpbmcgY2xhc3NMaXN0LlxuICogSWYgYW55IG9mIHRoZSBjbGFzc2VzIGlzIHByZXNlbnQsIGl0IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBlbGVtZW50LFxuICogb3IgYWRkZWQgb3RoZXJ3aXNlLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB3aGljaCBjbGFzc2VzIHdpbGwgYmUgdG9nZ2xlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc2VzIFRoZSBjbGFzc2VzIHdoaWNoIGhhdmUgdG8gYWRkZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBlbGVtZW50LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0bGV0IGVsZW1lbnRDbGFzc05hbWUgPSBgICR7ZWxlbWVudC5jbGFzc05hbWV9IGA7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRjb25zdCBjbGFzc05hbWUgPSBgICR7Y2xhc3Nlc1tpXX0gYDtcblx0XHRjb25zdCBjbGFzc0luZGV4ID0gZWxlbWVudENsYXNzTmFtZS5pbmRleE9mKGNsYXNzTmFtZSk7XG5cblx0XHRpZiAoY2xhc3NJbmRleCA9PT0gLTEpIHtcblx0XHRcdGVsZW1lbnRDbGFzc05hbWUgPSBgJHtlbGVtZW50Q2xhc3NOYW1lfSR7Y2xhc3Nlc1tpXX0gYDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3QgYmVmb3JlID0gZWxlbWVudENsYXNzTmFtZS5zdWJzdHJpbmcoMCwgY2xhc3NJbmRleCk7XG5cdFx0XHRjb25zdCBhZnRlciA9IGVsZW1lbnRDbGFzc05hbWUuc3Vic3RyaW5nKFxuXHRcdFx0XHRjbGFzc0luZGV4ICsgY2xhc3NOYW1lLmxlbmd0aFxuXHRcdFx0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdFx0ZWxlbWVudENsYXNzTmFtZSA9IGAke2JlZm9yZX0gJHthZnRlcn1gO1xuXHRcdH1cblx0fVxuXG5cdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudENsYXNzTmFtZS50cmltKCk7XG59XG5cbi8qKlxuICogVHJpZ2dlcnMgYWxsIGxpc3RlbmVycyBmb3IgdGhlIGdpdmVuIGV2ZW50IHR5cGUgdGhhdCBhcmUgc3RvcmVkIGluIHRoZVxuICogc3BlY2lmaWVkIGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZhdWx0Rm5zIEFycmF5IHRvIGNvbGxlY3QgZGVmYXVsdCBsaXN0ZW5lcnMgaW4sIGluc3RlYWRcbiAqICAgICBvZiBydW5uaW5nIHRoZW0uXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJFbGVtZW50TGlzdGVuZXJzXyhlbGVtZW50LCBldmVudCwgZGVmYXVsdEZucykge1xuXHRjb25zdCBsYXN0Q29udGFpbmVyID0gZXZlbnRbTEFTVF9DT05UQUlORVJdO1xuXHRpZiAoIWlzRGVmKGxhc3RDb250YWluZXIpIHx8ICFjb250YWlucyhsYXN0Q29udGFpbmVyLCBlbGVtZW50KSkge1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IGRvbURhdGEuZ2V0KGVsZW1lbnQsICdsaXN0ZW5lcnMnLCB7fSlbZXZlbnQudHlwZV07XG5cdFx0cmV0dXJuIHRyaWdnZXJMaXN0ZW5lcnNfKGxpc3RlbmVycywgZXZlbnQsIGVsZW1lbnQsIGRlZmF1bHRGbnMpO1xuXHR9XG5cdHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIFRyaWdnZXJzIHRoZSBzcGVjaWZpZWQgZXZlbnQgb24gdGhlIGdpdmVuIGVsZW1lbnQuXG4gKiBOT1RFOiBUaGlzIHNob3VsZCBtb3N0bHkgYmUgdXNlZCBmb3IgdGVzdGluZywgbm90IG9uIHJlYWwgY29kZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIG5vZGUgdGhhdCBzaG91bGQgdHJpZ2dlciB0aGUgZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBiZSB0cmlnZ3JlZC5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gZXZlbnRPYmogQW4gb2JqZWN0IHdpdGggZGF0YSB0aGF0IHNob3VsZCBiZSBvbiB0aGVcbiAqICAgdHJpZ2dlcmVkIGV2ZW50J3MgcGF5bG9hZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXJFdmVudChlbGVtZW50LCBldmVudE5hbWUsIGV2ZW50T2JqKSB7XG5cdGlmIChpc0FibGVUb0ludGVyYWN0V2l0aF8oZWxlbWVudCwgZXZlbnROYW1lLCBldmVudE9iaikpIHtcblx0XHRjb25zdCBwYXlsb2FkID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKTtcblx0XHRwYXlsb2FkLmluaXRFdmVudChldmVudE5hbWUsIHRydWUsIHRydWUpO1xuXHRcdG9iamVjdC5taXhpbihwYXlsb2FkLCBldmVudE9iaik7XG5cdFx0ZWxlbWVudC5kaXNwYXRjaEV2ZW50KHBheWxvYWQpO1xuXHR9XG59XG5cbi8qKlxuICogVHJpZ2dlcnMgdGhlIGdpdmVuIGxpc3RlbmVycyBhcnJheS5cbiAqIEBwYXJhbSB7QXJyYXk8IWZ1bmN0aW9uKCk+fSBsaXN0ZW5lcnNcbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHshQXJyYXl9IGRlZmF1bHRGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogICAgIG9mIHJ1bm5pbmcgdGhlbS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlckxpc3RlbmVyc18obGlzdGVuZXJzLCBldmVudCwgZWxlbWVudCwgZGVmYXVsdEZucykge1xuXHRsZXQgcmV0ID0gdHJ1ZTtcblx0bGlzdGVuZXJzID0gbGlzdGVuZXJzIHx8IFtdO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGggJiYgIWV2ZW50LnN0b3BwZWRJbW1lZGlhdGU7IGkrKykge1xuXHRcdGlmIChsaXN0ZW5lcnNbaV0uZGVmYXVsdExpc3RlbmVyXykge1xuXHRcdFx0ZGVmYXVsdEZucy5wdXNoKHtcblx0XHRcdFx0ZWxlbWVudCxcblx0XHRcdFx0Zm46IGxpc3RlbmVyc1tpXSxcblx0XHRcdH0pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXQgJj0gbGlzdGVuZXJzW2ldKGV2ZW50KTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBUcmlnZ2VycyBhbGwgc2VsZWN0b3IgbGlzdGVuZXJzIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBjb250YWluZXJcbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHBhcmFtIHshQXJyYXl9IGRlZmF1bHRGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogICAgIG9mIHJ1bm5pbmcgdGhlbS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlclNlbGVjdG9yTGlzdGVuZXJzXyhjb250YWluZXIsIGVsZW1lbnQsIGV2ZW50LCBkZWZhdWx0Rm5zKSB7XG5cdGxldCByZXQgPSB0cnVlO1xuXHRjb25zdCBkYXRhID0gZG9tRGF0YS5nZXQoY29udGFpbmVyLCAnZGVsZWdhdGluZycsIHt9KTtcblx0Y29uc3QgbWFwID0gZGF0YVtldmVudC50eXBlXS5zZWxlY3RvcnM7XG5cdGNvbnN0IHNlbGVjdG9ycyA9IE9iamVjdC5rZXlzKG1hcCk7XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0b3JzLmxlbmd0aCAmJiAhZXZlbnQuc3RvcHBlZEltbWVkaWF0ZTsgaSsrKSB7XG5cdFx0aWYgKG1hdGNoKGVsZW1lbnQsIHNlbGVjdG9yc1tpXSkpIHtcblx0XHRcdGNvbnN0IGxpc3RlbmVycyA9IG1hcFtzZWxlY3RvcnNbaV1dO1xuXHRcdFx0cmV0ICY9IHRyaWdnZXJMaXN0ZW5lcnNfKGxpc3RlbmVycywgZXZlbnQsIGVsZW1lbnQsIGRlZmF1bHRGbnMpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gcmV0O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBUaGlzIGZpbGUgZXhpc3RzIGp1c3QgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBtYWtpbmcgc3VyZSB0aGF0IG9sZFxuLy8gZGVmYXVsdCBpbXBvcnRzIGZvciB0aGlzIGZpbGUgc3RpbGwgd29yay4gSXQncyBiZXN0IHRvIHVzZSB0aGUgbmFtZWQgZXhwb3J0c1xuLy8gZm9yIGVhY2ggZnVuY3Rpb24gaW5zdGVhZCB0aG91Z2gsIHNpbmNlIHRoYXQgYWxsb3dzIGJ1bmRsZXJzIGxpa2UgUm9sbHVwIHRvXG4vLyByZWR1Y2UgdGhlIGJ1bmRsZSBzaXplIGJ5IHJlbW92aW5nIHVudXNlZCBjb2RlLlxuaW1wb3J0ICogYXMgZG9tIGZyb20gJy4vZG9tTmFtZWQnO1xuXG5leHBvcnQgZGVmYXVsdCBkb207XG5leHBvcnQge2RvbX07XG5leHBvcnQgKiBmcm9tICcuL2RvbU5hbWVkJztcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtkZWxlZ2F0ZSwgb24sIHN1cHBvcnRzRXZlbnR9IGZyb20gJy4vZG9tJztcbmltcG9ydCB7RXZlbnRFbWl0dGVyUHJveHl9IGZyb20gJ21ldGFsLWV2ZW50cyc7XG5cbi8qKlxuICogRG9tRXZlbnRFbWl0dGVyUHJveHkgdXRpbGl0eS4gSXQgZXh0ZW5kcyBgRXZlbnRFbWl0dGVyUHJveHlgIHRvIGFsc28gYWNjZXB0XG4gKiBkb20gZWxlbWVudHMgYXMgb3JpZ2luIGVtaXR0ZXJzLlxuICogQGV4dGVuZHMge0V2ZW50RW1pdHRlclByb3h5fVxuICovXG5jbGFzcyBEb21FdmVudEVtaXR0ZXJQcm94eSBleHRlbmRzIEV2ZW50RW1pdHRlclByb3h5IHtcblx0LyoqXG5cdCAqIEFkZHMgdGhlIGdpdmVuIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IFRoZSBsaXN0ZW5lZCBldmVudCdzIGhhbmRsZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGFkZExpc3RlbmVyXyhldmVudCwgbGlzdGVuZXIpIHtcblx0XHRpZiAodGhpcy5vcmlnaW5FbWl0dGVyXy5hZGRFdmVudExpc3RlbmVyKSB7XG5cdFx0XHRpZiAodGhpcy5pc0RlbGVnYXRlRXZlbnRfKGV2ZW50KSkge1xuXHRcdFx0XHRjb25zdCBpbmRleCA9IGV2ZW50LmluZGV4T2YoJzonLCA5KTtcblx0XHRcdFx0Y29uc3QgZXZlbnROYW1lID0gZXZlbnQuc3Vic3RyaW5nKDksIGluZGV4KTtcblx0XHRcdFx0Y29uc3Qgc2VsZWN0b3IgPSBldmVudC5zdWJzdHJpbmcoaW5kZXggKyAxKTtcblx0XHRcdFx0cmV0dXJuIGRlbGVnYXRlKFxuXHRcdFx0XHRcdHRoaXMub3JpZ2luRW1pdHRlcl8sXG5cdFx0XHRcdFx0ZXZlbnROYW1lLFxuXHRcdFx0XHRcdHNlbGVjdG9yLFxuXHRcdFx0XHRcdGxpc3RlbmVyXG5cdFx0XHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBvbih0aGlzLm9yaWdpbkVtaXR0ZXJfLCBldmVudCwgbGlzdGVuZXIpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gc3VwZXIuYWRkTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lcik7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXZlbnQgaXMgb2YgdGhlIGRlbGVnYXRlIHR5cGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRpc0RlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdFx0cmV0dXJuIGV2ZW50LnN1YnN0cigwLCA5KSA9PT0gJ2RlbGVnYXRlOic7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBpcyBzdXBwb3J0ZWQgYnkgdGhlIG9yaWdpbiBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHByb3RlY3RlZFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0aXNTdXBwb3J0ZWREb21FdmVudF8oZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMub3JpZ2luRW1pdHRlcl8gfHwgIXRoaXMub3JpZ2luRW1pdHRlcl8uYWRkRXZlbnRMaXN0ZW5lcikge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAoXG5cdFx0XHQodGhpcy5pc0RlbGVnYXRlRXZlbnRfKGV2ZW50KSAmJiBldmVudC5pbmRleE9mKCc6JywgOSkgIT09IC0xKSB8fFxuXHRcdFx0c3VwcG9ydHNFdmVudCh0aGlzLm9yaWdpbkVtaXR0ZXJfLCBldmVudClcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXZlbnQgc2hvdWxkIGJlIHByb3hpZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0c2hvdWxkUHJveHlFdmVudF8oZXZlbnQpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0c3VwZXIuc2hvdWxkUHJveHlFdmVudF8oZXZlbnQpICYmIHRoaXMuaXNTdXBwb3J0ZWREb21FdmVudF8oZXZlbnQpXG5cdFx0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERvbUV2ZW50RW1pdHRlclByb3h5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2FwcGVuZH0gZnJvbSAnLi9kb20nO1xuaW1wb3J0IHtzdHJpbmd9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBDbGFzcyB3aXRoIHN0YXRpYyBtZXRob2RzIHJlc3BvbnNpYmxlIGZvciBkb2luZyBicm93c2VyIGZlYXR1cmUgY2hlY2tzLlxuICovXG5jbGFzcyBmZWF0dXJlcyB7XG5cdC8qKlxuXHQgKiBTb21lIGJyb3dzZXJzIHN0aWxsIHN1cHBvcnRzIHByZWZpeGVkIGFuaW1hdGlvbiBldmVudHMuIFRoaXMgbWV0aG9kIGNhblxuXHQgKiBiZSB1c2VkIHRvIHJldHJpZXZlIHRoZSBjdXJyZW50IGJyb3dzZXIgZXZlbnQgbmFtZSBmb3IgYm90aCwgYW5pbWF0aW9uXG5cdCAqIGFuZCB0cmFuc2l0aW9uLlxuXHQgKiBAcmV0dXJuIHtvYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgY2hlY2tBbmltYXRpb25FdmVudE5hbWUoKSB7XG5cdFx0aWYgKGZlYXR1cmVzLmFuaW1hdGlvbkV2ZW50TmFtZV8gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0ZmVhdHVyZXMuYW5pbWF0aW9uRXZlbnROYW1lXyA9IHtcblx0XHRcdFx0YW5pbWF0aW9uOiBmZWF0dXJlcy5jaGVja0FuaW1hdGlvbkV2ZW50TmFtZV8oJ2FuaW1hdGlvbicpLFxuXHRcdFx0XHR0cmFuc2l0aW9uOiBmZWF0dXJlcy5jaGVja0FuaW1hdGlvbkV2ZW50TmFtZV8oJ3RyYW5zaXRpb24nKSxcblx0XHRcdH07XG5cdFx0fVxuXHRcdHJldHVybiBmZWF0dXJlcy5hbmltYXRpb25FdmVudE5hbWVfO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZSB0byB0ZXN0OiBhbmltYXRpb24sIHRyYW5zaXRpb24uXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQnJvd3NlciBldmVudCBuYW1lLlxuXHQgKi9cblx0c3RhdGljIGNoZWNrQW5pbWF0aW9uRXZlbnROYW1lXyh0eXBlKSB7XG5cdFx0Y29uc3QgcHJlZml4ZXMgPSBbJ1dlYmtpdCcsICdNUycsICdPJywgJyddO1xuXHRcdGNvbnN0IHR5cGVUaXRsZUNhc2UgPSBzdHJpbmcucmVwbGFjZUludGVydmFsKFxuXHRcdFx0dHlwZSxcblx0XHRcdDAsXG5cdFx0XHQxLFxuXHRcdFx0dHlwZS5zdWJzdHJpbmcoMCwgMSkudG9VcHBlckNhc2UoKVxuXHRcdCk7XG5cdFx0Y29uc3Qgc3VmZml4ZXMgPSBbXG5cdFx0XHRgJHt0eXBlVGl0bGVDYXNlfUVuZGAsXG5cdFx0XHRgJHt0eXBlVGl0bGVDYXNlfUVuZGAsXG5cdFx0XHRgJHt0eXBlVGl0bGVDYXNlfUVuZGAsXG5cdFx0XHRgJHt0eXBlfWVuZGAsXG5cdFx0XTtcblx0XHRpZiAoIWZlYXR1cmVzLmFuaW1hdGlvbkVsZW1lbnRfKSB7XG5cdFx0XHRmZWF0dXJlcy5hbmltYXRpb25FbGVtZW50XyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdH1cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdGZlYXR1cmVzLmFuaW1hdGlvbkVsZW1lbnRfLnN0eWxlW1xuXHRcdFx0XHRcdHByZWZpeGVzW2ldICsgdHlwZVRpdGxlQ2FzZVxuXHRcdFx0XHRdICE9PSB1bmRlZmluZWQgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiBwcmVmaXhlc1tpXS50b0xvd2VyQ2FzZSgpICsgc3VmZml4ZXNbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBgJHt0eXBlfWVuZGA7XG5cdH1cblxuXHQvKipcblx0ICogU29tZSBicm93c2VycyAobGlrZSBJRTkpIGNoYW5nZSB0aGUgb3JkZXIgb2YgZWxlbWVudCBhdHRyaWJ1dGVzLCB3aGVuIGh0bWxcblx0ICogaXMgcmVuZGVyZWQuIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNoZWNrIGlmIHRoaXMgYmVoYXZpb3IgaGFwcGVucyBvblxuXHQgKiB0aGUgY3VycmVudCBicm93c2VyLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGNoZWNrQXR0ck9yZGVyQ2hhbmdlKCkge1xuXHRcdGlmIChmZWF0dXJlcy5hdHRyT3JkZXJDaGFuZ2VfID09PSB1bmRlZmluZWQpIHtcblx0XHRcdGNvbnN0IG9yaWdpbmFsQ29udGVudCA9ICc8ZGl2IGRhdGEtY29tcG9uZW50PVwiXCIgZGF0YS1yZWY9XCJcIj48L2Rpdj4nO1xuXHRcdFx0Y29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0YXBwZW5kKGVsZW1lbnQsIG9yaWdpbmFsQ29udGVudCk7XG5cdFx0XHRmZWF0dXJlcy5hdHRyT3JkZXJDaGFuZ2VfID0gb3JpZ2luYWxDb250ZW50ICE9PSBlbGVtZW50LmlubmVySFRNTDtcblx0XHR9XG5cdFx0cmV0dXJuIGZlYXR1cmVzLmF0dHJPcmRlckNoYW5nZV87XG5cdH1cbn1cblxuZmVhdHVyZXMuYW5pbWF0aW9uRWxlbWVudF8gPSB1bmRlZmluZWQ7XG5mZWF0dXJlcy5hbmltYXRpb25FdmVudE5hbWVfID0gdW5kZWZpbmVkO1xuZmVhdHVyZXMuYXR0ck9yZGVyQ2hhbmdlXyA9IHVuZGVmaW5lZDtcblxuZXhwb3J0IGRlZmF1bHQgZmVhdHVyZXM7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXN5bmN9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7ZXhpdERvY3VtZW50LCBvbmNlfSBmcm9tICcuL2RvbSc7XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIHJ1bm5pbmcgamF2YXNjcmlwdCBjb2RlIGluIHRoZSBnbG9iYWwgc2NvcGUuXG4gKi9cbmNsYXNzIGdsb2JhbEV2YWwge1xuXHQvKipcblx0ICogRXZhbHVhdGVzIHRoZSBnaXZlbiBzdHJpbmcgaW4gdGhlIGdsb2JhbCBzY29wZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc2NyaXB0XG5cdCAqL1xuXHRzdGF0aWMgcnVuKHRleHQsIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cdFx0c2NyaXB0LnRleHQgPSB0ZXh0O1xuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc2NyaXB0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH1cblx0XHRleGl0RG9jdW1lbnQoc2NyaXB0KTtcblx0XHRyZXR1cm4gc2NyaXB0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gamF2YXNjcmlwdCBmaWxlIGluIHRoZSBnbG9iYWwgc2NvcGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgVGhlIGZpbGUncyBwYXRoLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc2NyaXB0XG5cdCAqL1xuXHRzdGF0aWMgcnVuRmlsZShzcmMsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRzY3JpcHQuc3JjID0gc3JjO1xuXG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGV4aXREb2N1bWVudChzY3JpcHQpO1xuXHRcdFx0ZGVmYXVsdEZuICYmIGRlZmF1bHRGbigpO1xuXHRcdH07XG5cdFx0b25jZShzY3JpcHQsICdsb2FkJywgY2FsbGJhY2spO1xuXHRcdG9uY2Uoc2NyaXB0LCAnZXJyb3InLCBjYWxsYmFjayk7XG5cblx0XHRpZiAoYXBwZW5kRm4pIHtcblx0XHRcdGFwcGVuZEZuKHNjcmlwdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc2NyaXB0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgY29kZSByZWZlcmVuY2VkIGJ5IHRoZSBnaXZlbiBzY3JpcHQgZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gc2NyaXB0XG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWRcblx0ICogICB3aGVuIHRoZSBzY3JpcHQgaGFzIGJlZW4gcnVuLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzY3JpcHRcblx0ICovXG5cdHN0YXRpYyBydW5TY3JpcHQoc2NyaXB0LCBkZWZhdWx0Rm4sIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGRlZmF1bHRGbiAmJiBkZWZhdWx0Rm4oKTtcblx0XHR9O1xuXHRcdGlmIChzY3JpcHQudHlwZSAmJiBzY3JpcHQudHlwZSAhPT0gJ3RleHQvamF2YXNjcmlwdCcpIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGNhbGxiYWNrKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZXhpdERvY3VtZW50KHNjcmlwdCk7XG5cdFx0aWYgKHNjcmlwdC5zcmMpIHtcblx0XHRcdHJldHVybiBnbG9iYWxFdmFsLnJ1bkZpbGUoc2NyaXB0LnNyYywgZGVmYXVsdEZuLCBhcHBlbmRGbik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGNhbGxiYWNrKTtcblx0XHRcdHJldHVybiBnbG9iYWxFdmFsLnJ1bihzY3JpcHQudGV4dCwgYXBwZW5kRm4pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgYW55IHNjcmlwdCB0YWdzIHByZXNlbnQgaW4gdGhlIGdpdmVuIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiAgIHdoZW4gdGhlIHNjcmlwdCBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU2NyaXB0c0luRWxlbWVudChlbGVtZW50LCBkZWZhdWx0Rm4sIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc2NyaXB0cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnc2NyaXB0Jyk7XG5cdFx0aWYgKHNjcmlwdHMubGVuZ3RoKSB7XG5cdFx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdHNJbk9yZGVyKHNjcmlwdHMsIDAsIGRlZmF1bHRGbiwgYXBwZW5kRm4pO1xuXHRcdH0gZWxzZSBpZiAoZGVmYXVsdEZuKSB7XG5cdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSdW5zIHRoZSBnaXZlbiBzY3JpcHRzIGVsZW1lbnRzIGluIHRoZSBvcmRlciB0aGF0IHRoZXkgYXBwZWFyLlxuXHQgKiBAcGFyYW0geyFOb2RlTGlzdH0gc2NyaXB0c1xuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiAgIHdoZW4gdGhlIHNjcmlwdCBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU2NyaXB0c0luT3JkZXIoc2NyaXB0cywgaW5kZXgsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdChcblx0XHRcdHNjcmlwdHMuaXRlbShpbmRleCksXG5cdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKGluZGV4IDwgc2NyaXB0cy5sZW5ndGggLSAxKSB7XG5cdFx0XHRcdFx0Z2xvYmFsRXZhbC5ydW5TY3JpcHRzSW5PcmRlcihcblx0XHRcdFx0XHRcdHNjcmlwdHMsXG5cdFx0XHRcdFx0XHRpbmRleCArIDEsXG5cdFx0XHRcdFx0XHRkZWZhdWx0Rm4sXG5cdFx0XHRcdFx0XHRhcHBlbmRGblxuXHRcdFx0XHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdFx0fSBlbHNlIGlmIChkZWZhdWx0Rm4pIHtcblx0XHRcdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0YXBwZW5kRm5cblx0XHQpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGdsb2JhbEV2YWw7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXN5bmN9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7b25jZX0gZnJvbSAnLi9kb20nO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zIGZvciBydW5uaW5nIHN0eWxlcy5cbiAqL1xuY2xhc3MgZ2xvYmFsRXZhbFN0eWxlcyB7XG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdGhlIGdpdmVuIHN0eWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzdHlsZVxuXHQgKi9cblx0c3RhdGljIHJ1bih0ZXh0LCBhcHBlbmRGbikge1xuXHRcdGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblx0XHRzdHlsZS5pbm5lckhUTUwgPSB0ZXh0O1xuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc3R5bGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblx0XHR9XG5cdFx0cmV0dXJuIHN0eWxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gc3R5bGUgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgVGhlIGZpbGUncyBwYXRoLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc3R5bGVzIGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc3R5bGVcblx0ICovXG5cdHN0YXRpYyBydW5GaWxlKGhyZWYsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGluaycpO1xuXHRcdGxpbmsucmVsID0gJ3N0eWxlc2hlZXQnO1xuXHRcdGxpbmsuaHJlZiA9IGhyZWY7XG5cdFx0Z2xvYmFsRXZhbFN0eWxlcy5ydW5TdHlsZShsaW5rLCBkZWZhdWx0Rm4sIGFwcGVuZEZuKTtcblx0XHRyZXR1cm4gbGluaztcblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdGhlIGNvZGUgcmVmZXJlbmNlZCBieSB0aGUgZ2l2ZW4gc3R5bGUvbGluayBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBzdHlsZVxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogIEByZXR1cm4ge0VsZW1lbnR9IHN0eWxlXG5cdCAqL1xuXHRzdGF0aWMgcnVuU3R5bGUoc3R5bGUsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGVmYXVsdEZuICYmIGRlZmF1bHRGbigpO1xuXHRcdH07XG5cdFx0aWYgKHN0eWxlLnJlbCAmJiBzdHlsZS5yZWwgIT09ICdzdHlsZXNoZWV0Jykge1xuXHRcdFx0YXN5bmMubmV4dFRpY2soY2FsbGJhY2spO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChzdHlsZS50YWdOYW1lID09PSAnU1RZTEUnKSB7XG5cdFx0XHRhc3luYy5uZXh0VGljayhjYWxsYmFjayk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG9uY2Uoc3R5bGUsICdsb2FkJywgY2FsbGJhY2spO1xuXHRcdFx0b25jZShzdHlsZSwgJ2Vycm9yJywgY2FsbGJhY2spO1xuXHRcdH1cblxuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc3R5bGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc3R5bGU7XG5cdH1cblxuXHQvKipcblx0ICogRXZhbHVhdGVzIGFueSBzdHlsZSBwcmVzZW50IGluIHRoZSBnaXZlbiBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGVcblx0ICogICBzdHlsZSBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU3R5bGVzSW5FbGVtZW50KGVsZW1lbnQsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBzdHlsZXMgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3N0eWxlLGxpbmsnKTtcblx0XHRpZiAoc3R5bGVzLmxlbmd0aCA9PT0gMCAmJiBkZWZhdWx0Rm4pIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGRlZmF1bHRGbik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0bGV0IGxvYWRDb3VudCA9IDA7XG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmIChkZWZhdWx0Rm4gJiYgKytsb2FkQ291bnQgPT09IHN0eWxlcy5sZW5ndGgpIHtcblx0XHRcdFx0YXN5bmMubmV4dFRpY2soZGVmYXVsdEZuKTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRnbG9iYWxFdmFsU3R5bGVzLnJ1blN0eWxlKHN0eWxlc1tpXSwgY2FsbGJhY2ssIGFwcGVuZEZuKTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZ2xvYmFsRXZhbFN0eWxlcztcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtpc1NlcnZlclNpZGV9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7cmVnaXN0ZXJDdXN0b21FdmVudCwgY29udGFpbnN9IGZyb20gJy4vZG9tJztcbmltcG9ydCBmZWF0dXJlcyBmcm9tICcuL2ZlYXR1cmVzJztcblxuLyoqXG4gKiBSZWdpc3RlciBjdXN0b20gZXZlbnRzIGZvciBldmVudCBkZWxlZ2F0aW9uLlxuICovXG5mdW5jdGlvbiByZWdpc3RlckV2ZW50cygpIHtcblx0Y29uc3QgbW91c2VFdmVudE1hcCA9IHtcblx0XHRtb3VzZWVudGVyOiAnbW91c2VvdmVyJyxcblx0XHRtb3VzZWxlYXZlOiAnbW91c2VvdXQnLFxuXHRcdHBvaW50ZXJlbnRlcjogJ3BvaW50ZXJvdmVyJyxcblx0XHRwb2ludGVybGVhdmU6ICdwb2ludGVyb3V0Jyxcblx0fTtcblx0T2JqZWN0LmtleXMobW91c2VFdmVudE1hcCkuZm9yRWFjaChmdW5jdGlvbihldmVudE5hbWUpIHtcblx0XHRyZWdpc3RlckN1c3RvbUV2ZW50KGV2ZW50TmFtZSwge1xuXHRcdFx0ZGVsZWdhdGU6IHRydWUsXG5cdFx0XHRoYW5kbGVyOiBmdW5jdGlvbihjYWxsYmFjaywgZXZlbnQpIHtcblx0XHRcdFx0Y29uc3QgcmVsYXRlZCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7XG5cdFx0XHRcdGNvbnN0IHRhcmdldCA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0O1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdCFyZWxhdGVkIHx8XG5cdFx0XHRcdFx0KHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhY29udGFpbnModGFyZ2V0LCByZWxhdGVkKSlcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0ZXZlbnQuY3VzdG9tVHlwZSA9IGV2ZW50TmFtZTtcblx0XHRcdFx0XHRyZXR1cm4gY2FsbGJhY2soZXZlbnQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0b3JpZ2luYWxFdmVudDogbW91c2VFdmVudE1hcFtldmVudE5hbWVdLFxuXHRcdH0pO1xuXHR9KTtcblxuXHRjb25zdCBhbmltYXRpb25FdmVudE1hcCA9IHtcblx0XHRhbmltYXRpb246ICdhbmltYXRpb25lbmQnLFxuXHRcdHRyYW5zaXRpb246ICd0cmFuc2l0aW9uZW5kJyxcblx0fTtcblx0T2JqZWN0LmtleXMoYW5pbWF0aW9uRXZlbnRNYXApLmZvckVhY2goZnVuY3Rpb24oZXZlbnRUeXBlKSB7XG5cdFx0Y29uc3QgZXZlbnROYW1lID0gYW5pbWF0aW9uRXZlbnRNYXBbZXZlbnRUeXBlXTtcblx0XHRyZWdpc3RlckN1c3RvbUV2ZW50KGV2ZW50TmFtZSwge1xuXHRcdFx0ZXZlbnQ6IHRydWUsXG5cdFx0XHRkZWxlZ2F0ZTogdHJ1ZSxcblx0XHRcdGhhbmRsZXI6IGZ1bmN0aW9uKGNhbGxiYWNrLCBldmVudCkge1xuXHRcdFx0XHRldmVudC5jdXN0b21UeXBlID0gZXZlbnROYW1lO1xuXHRcdFx0XHRyZXR1cm4gY2FsbGJhY2soZXZlbnQpO1xuXHRcdFx0fSxcblx0XHRcdG9yaWdpbmFsRXZlbnQ6IGZlYXR1cmVzLmNoZWNrQW5pbWF0aW9uRXZlbnROYW1lKClbZXZlbnRUeXBlXSxcblx0XHR9KTtcblx0fSk7XG59XG5cbmlmICghaXNTZXJ2ZXJTaWRlKCkpIHtcblx0cmVnaXN0ZXJFdmVudHMoKTtcbn1cbiIsInZhciBnbG9iYWxzID0gZ2xvYmFscyB8fCB7fTtcblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG5cdGdsb2JhbHMud2luZG93ID0gd2luZG93O1xufVxuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuXHRnbG9iYWxzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGdsb2JhbHM7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuICogQHBhcmFtIHsqPX0gb3B0X3VyaSBPcHRpb25hbCBzdHJpbmcgVVJJIHRvIHBhcnNlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlRnJvbUFuY2hvcihvcHRfdXJpKSB7XG5cdHZhciBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXHRsaW5rLmhyZWYgPSBvcHRfdXJpO1xuXG5cdGlmKGxpbmsucHJvdG9jb2wgPT09ICc6JyB8fCAhLzovLnRlc3QobGluay5ocmVmKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7b3B0X3VyaX0gaXMgbm90IGEgdmFsaWQgVVJMYCk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdGhhc2g6IGxpbmsuaGFzaCxcblx0XHRob3N0bmFtZTogbGluay5ob3N0bmFtZSxcblx0XHRwYXNzd29yZDogbGluay5wYXNzd29yZCxcblx0XHRwYXRobmFtZTogbGluay5wYXRobmFtZVswXSA9PT0gJy8nID8gbGluay5wYXRobmFtZSA6ICcvJyArIGxpbmsucGF0aG5hbWUsXG5cdFx0cG9ydDogbGluay5wb3J0LFxuXHRcdHByb3RvY29sOiBsaW5rLnByb3RvY29sLFxuXHRcdHNlYXJjaDogbGluay5zZWFyY2gsXG5cdFx0dXNlcm5hbWU6IGxpbmsudXNlcm5hbWVcblx0fTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgcGFyc2VGcm9tQW5jaG9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHBhcnNlRnJvbUFuY2hvciBmcm9tICcuL3BhcnNlRnJvbUFuY2hvcic7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LiBUaGUgVVJMIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZFxuICogd2hlbiBwcmVzZW50LCBvdGhlcndpc2Ugd2UnbGwgZmFsbCBiYWNrIHRvIHRoZSBhbmNob3Igbm9kZSBlbGVtZW50LlxuICogQHBhcmFtIHsqPX0gb3B0X3VyaSBPcHRpb25hbCBzdHJpbmcgVVJJIHRvIHBhcnNlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlKG9wdF91cmkpIHtcblx0aWYgKGlzRnVuY3Rpb24oVVJMKSAmJiBVUkwubGVuZ3RoKSB7XG5cdFx0Y29uc3QgdXJsID0gbmV3IFVSTChvcHRfdXJpKTtcblxuXHRcdC8vIFNhZmFyaSBCcm93c2VycyB3aWxsIGNhcCBwb3J0IHRvIHRoZSBtYXggMTYtYml0IHVuc2lnbmVkIGludGVnZXIgKDY1NTM1KSBpbnN0ZWFkXG5cdFx0Ly8gb2YgdGhyb3dpbmcgYSBUeXBlRXJyb3IgYXMgcGVyIHNwZWMuIEl0IHdpbGwgc3RpbGwga2VlcCB0aGUgcG9ydCBudW1iZXIgaW4gdGhlXG5cdFx0Ly8gaHJlZiBhdHRyaWJ1dGUsIHNvIHdlIGNhbiB1c2UgdGhpcyBtaXNtYXRjaCB0byByYWlzZSB0aGUgZXhwZWN0ZWQgZXhjZXB0aW9uLlxuXHRcdGlmICh1cmwucG9ydCAmJiB1cmwuaHJlZi5pbmRleE9mKHVybC5wb3J0KSA9PT0gLTEpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7b3B0X3VyaX0gaXMgbm90IGEgdmFsaWQgVVJMYCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVybDtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gcGFyc2VGcm9tQW5jaG9yKG9wdF91cmkpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHBhcnNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBEaXNwb3NhYmxlIH0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEEgY2FjaGVkIHJlZmVyZW5jZSB0byB0aGUgY3JlYXRlIGZ1bmN0aW9uLlxuICovXG52YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTtcblxuLyoqXG4gKiBDYXNlIGluc2Vuc2l0aXZlIHN0cmluZyBNdWx0aW1hcCBpbXBsZW1lbnRhdGlvbi4gQWxsb3dzIG11bHRpcGxlIHZhbHVlcyBmb3JcbiAqIHRoZSBzYW1lIGtleSBuYW1lLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIE11bHRpTWFwIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cdFx0dGhpcy5rZXlzID0gY3JlYXRlKG51bGwpO1xuXHRcdHRoaXMudmFsdWVzID0gY3JlYXRlKG51bGwpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdmFsdWUgdG8gYSBrZXkgbmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHBhcmFtIHsqfSB2YWx1ZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRhZGQobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IG5hbWU7XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IHRoaXMudmFsdWVzW25hbWUudG9Mb3dlckNhc2UoKV0gfHwgW107XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXS5wdXNoKHZhbHVlKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhcnMgbWFwIG5hbWVzIGFuZCB2YWx1ZXMuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGNsZWFyKCkge1xuXHRcdHRoaXMua2V5cyA9IGNyZWF0ZShudWxsKTtcblx0XHR0aGlzLnZhbHVlcyA9IGNyZWF0ZShudWxsKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgbWFwIGNvbnRhaW5zIGEgdmFsdWUgdG8gdGhlIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRjb250YWlucyhuYW1lKSB7XG5cdFx0cmV0dXJuIG5hbWUudG9Mb3dlckNhc2UoKSBpbiB0aGlzLnZhbHVlcztcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMudmFsdWVzID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgYE11bHRpTWFwYCBpbnN0YW5jZSBmcm9tIHRoZSBnaXZlbiBvYmplY3QuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gb2JqXG5cdCAqIEByZXR1cm4geyFNdWx0aU1hcH1cblx0ICovXG5cdHN0YXRpYyBmcm9tT2JqZWN0KG9iaikge1xuXHRcdHZhciBtYXAgPSBuZXcgTXVsdGlNYXAoKTtcblx0XHR2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRtYXAuc2V0KGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXA7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZmlyc3QgYWRkZWQgdmFsdWUgZnJvbSBhIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcmV0dXJuIHsqfVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRnZXQobmFtZSkge1xuXHRcdHZhciB2YWx1ZXMgPSB0aGlzLnZhbHVlc1tuYW1lLnRvTG93ZXJDYXNlKCldO1xuXHRcdGlmICh2YWx1ZXMpIHtcblx0XHRcdHJldHVybiB2YWx1ZXNbMF07XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYWxsIHZhbHVlcyBmcm9tIGEga2V5IG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG5cdCAqIEByZXR1cm4ge0FycmF5LjwqPn1cblx0ICovXG5cdGdldEFsbChuYW1lKSB7XG5cdFx0cmV0dXJuIHRoaXMudmFsdWVzW25hbWUudG9Mb3dlckNhc2UoKV07XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIGlmIHRoZSBtYXAgaXMgZW1wdHksIGZhbHNlIG90aGVyd2lzZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzRW1wdHkoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2l6ZSgpID09PSAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYXJyYXkgb2Yga2V5IG5hbWVzLlxuXHQgKiBAcmV0dXJuIHtBcnJheS48c3RyaW5nPn1cblx0ICovXG5cdG5hbWVzKCkge1xuXHRcdHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnZhbHVlcykubWFwKChrZXkpID0+IHRoaXMua2V5c1trZXldKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCB2YWx1ZXMgZnJvbSBhIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRyZW1vdmUobmFtZSkge1xuXHRcdGRlbGV0ZSB0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcblx0XHRkZWxldGUgdGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIGtleSBuYW1lLiBSZWxldmFudCB0byByZXBsYWNlIHRoZSBjdXJyZW50IHZhbHVlcyB3aXRoXG5cdCAqIGEgbmV3IG9uZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHBhcmFtIHsqfSB2YWx1ZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXQobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IG5hbWU7XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IFt2YWx1ZV07XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgbWFwIGtleSBuYW1lcy5cblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0c2l6ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5uYW1lcygpLmxlbmd0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBwYXJzZWQgdmFsdWVzIGFzIGEgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy52YWx1ZXMpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE11bHRpTWFwO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBhcnJheSB9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBHZW5lcmljIHRyZWUgbm9kZSBkYXRhIHN0cnVjdHVyZSB3aXRoIGFyYml0cmFyeSBudW1iZXIgb2YgY2hpbGQgbm9kZXMuXG4gKiBAcGFyYW0ge1Z9IHZhbHVlIFZhbHVlLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmNsYXNzIFRyZWVOb2RlIHtcblxuXHRjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuXHRcdC8qKlxuXHRcdCAqIFRoZSB2YWx1ZS5cblx0XHQgKiBAcHJpdmF0ZSB7Vn1cblx0XHQgKi9cblx0XHR0aGlzLnZhbHVlXyA9IHZhbHVlO1xuXG5cdFx0LyoqXG5cdFx0ICogUmVmZXJlbmNlIHRvIHRoZSBwYXJlbnQgbm9kZSBvciBudWxsIGlmIGl0IGhhcyBubyBwYXJlbnQuXG5cdFx0ICogQHByaXZhdGUge1RyZWVOb2RlfVxuXHRcdCAqL1xuXHRcdHRoaXMucGFyZW50XyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBDaGlsZCBub2RlcyBvciBudWxsIGluIGNhc2Ugb2YgbGVhZiBub2RlLlxuXHRcdCAqIEBwcml2YXRlIHtBcnJheTwhVHJlZU5vZGU+fVxuXHRcdCAqL1xuXHRcdHRoaXMuY2hpbGRyZW5fID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBBcHBlbmRzIGEgY2hpbGQgbm9kZSB0byB0aGlzIG5vZGUuXG5cdCAqIEBwYXJhbSB7IVRyZWVOb2RlfSBjaGlsZCBPcnBoYW4gY2hpbGQgbm9kZS5cblx0ICovXG5cdGFkZENoaWxkKGNoaWxkKSB7XG5cdFx0YXNzZXJ0Q2hpbGRIYXNOb1BhcmVudChjaGlsZCk7XG5cdFx0Y2hpbGQuc2V0UGFyZW50KHRoaXMpO1xuXHRcdHRoaXMuY2hpbGRyZW5fID0gdGhpcy5jaGlsZHJlbl8gfHwgW107XG5cdFx0dGhpcy5jaGlsZHJlbl8ucHVzaChjaGlsZCk7XG5cdH1cblxuXHQvKipcblx0ICogVGVsbHMgd2hldGhlciB0aGlzIG5vZGUgaXMgdGhlIGFuY2VzdG9yIG9mIHRoZSBnaXZlbiBub2RlLlxuXHQgKiBAcGFyYW0geyFUcmVlTm9kZX0gbm9kZSBBIG5vZGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhpcyBub2RlIGlzIHRoZSBhbmNlc3RvciBvZiB7QGNvZGUgbm9kZX0uXG5cdCAqL1xuXHRjb250YWlucyhub2RlKSB7XG5cdFx0bGV0IGN1cnJlbnQgPSBub2RlLmdldFBhcmVudCgpO1xuXHRcdHdoaWxlIChjdXJyZW50KSB7XG5cdFx0XHRpZiAoY3VycmVudCA9PT0gdGhpcykge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdGN1cnJlbnQgPSBjdXJyZW50LmdldFBhcmVudCgpO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7IUFycmF5PFRyZWVOb2RlPn0gQWxsIGFuY2VzdG9yIG5vZGVzIGluIGJvdHRvbS11cCBvcmRlci5cblx0ICovXG5cdGdldEFuY2VzdG9ycygpIHtcblx0XHRsZXQgYW5jZXN0b3JzID0gW107XG5cdFx0bGV0IG5vZGUgPSB0aGlzLmdldFBhcmVudCgpO1xuXHRcdHdoaWxlIChub2RlKSB7XG5cdFx0XHRhbmNlc3RvcnMucHVzaChub2RlKTtcblx0XHRcdG5vZGUgPSBub2RlLmdldFBhcmVudCgpO1xuXHRcdH1cblx0XHRyZXR1cm4gYW5jZXN0b3JzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNoaWxkIG5vZGUgb2YgdGhpcyBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IENoaWxkIGluZGV4LlxuXHQgKiBAcmV0dXJuIHs/VHJlZU5vZGV9IFRoZSBub2RlIGF0IHRoZSBnaXZlbiBpbmRleFxuXHQgKiBvciBudWxsIGlmIG5vdCBmb3VuZC5cblx0ICovXG5cdGdldENoaWxkQXQoaW5kZXgpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRDaGlsZHJlbigpW2luZGV4XSB8fCBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4gez9BcnJheTwhVHJlZU5vZGU+fSBDaGlsZCBub2RlcyBvciBudWxsIGluIGNhc2Ugb2YgbGVhZiBub2RlLlxuXHQgKi9cblx0Z2V0Q2hpbGRyZW4oKSB7XG5cdFx0cmV0dXJuIHRoaXMuY2hpbGRyZW5fIHx8IFRyZWVOb2RlLkVNUFRZX0FSUkFZO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBjaGlsZHJlbi5cblx0ICovXG5cdGdldENoaWxkQ291bnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0Q2hpbGRyZW4oKS5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGFuY2VzdG9ycyBvZiB0aGUgbm9kZS5cblx0ICovXG5cdGdldERlcHRoKCkge1xuXHRcdGxldCBkZXB0aCA9IDA7XG5cdFx0bGV0IG5vZGUgPSB0aGlzO1xuXHRcdHdoaWxlIChub2RlLmdldFBhcmVudCgpKSB7XG5cdFx0XHRkZXB0aCsrO1xuXHRcdFx0bm9kZSA9IG5vZGUuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiBkZXB0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHs/VHJlZU5vZGV9IFBhcmVudCBub2RlIG9yIG51bGwgaWYgaXQgaGFzIG5vIHBhcmVudC5cblx0ICovXG5cdGdldFBhcmVudCgpIHtcblx0XHRyZXR1cm4gdGhpcy5wYXJlbnRfO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4geyFUcmVlTm9kZX0gVGhlIHJvb3Qgb2YgdGhlIHRyZWUgc3RydWN0dXJlLCBpLmUuIHRoZSBmYXJ0aGVzdFxuXHQgKiBhbmNlc3RvciBvZiB0aGUgbm9kZSBvciB0aGUgbm9kZSBpdHNlbGYgaWYgaXQgaGFzIG5vIHBhcmVudHMuXG5cdCAqL1xuXHRnZXRSb290KCkge1xuXHRcdGxldCByb290ID0gdGhpcztcblx0XHR3aGlsZSAocm9vdC5nZXRQYXJlbnQoKSkge1xuXHRcdFx0cm9vdCA9IHJvb3QuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiByb290O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHZhbHVlLlxuXHQgKiBAcmV0dXJuIHtWfSBUaGUgdmFsdWUuXG5cdCAqL1xuXHRnZXRWYWx1ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy52YWx1ZV87XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBpcyBhIGxlYWYgbm9kZS5cblx0ICovXG5cdGlzTGVhZigpIHtcblx0XHRyZXR1cm4gIXRoaXMuZ2V0Q2hpbGRDb3VudCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGdpdmVuIGNoaWxkIG5vZGUgb2YgdGhpcyBub2RlLlxuXHQgKiBAcGFyYW0ge1RyZWVOb2RlfSBjaGlsZCBUaGUgbm9kZSB0byByZW1vdmUuXG5cdCAqIEByZXR1cm4ge1RyZWVOb2RlfSBUaGUgcmVtb3ZlZCBub2RlIGlmIGFueSwgbnVsbCBvdGhlcndpc2UuXG5cdCAqL1xuXHRyZW1vdmVDaGlsZChjaGlsZCkge1xuXHRcdGlmIChhcnJheS5yZW1vdmUodGhpcy5nZXRDaGlsZHJlbigpLCBjaGlsZCkpIHtcblx0XHRcdHJldHVybiBjaGlsZDtcblx0XHR9XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgcGFyZW50IG5vZGUgb2YgdGhpcyBub2RlLiBUaGUgY2FsbGVycyBtdXN0IGVuc3VyZSB0aGF0IHRoZVxuXHQgKiBwYXJlbnQgbm9kZSBhbmQgb25seSB0aGF0IGhhcyB0aGlzIG5vZGUgYW1vbmcgaXRzIGNoaWxkcmVuLlxuXHQgKiBAcGFyYW0ge1RyZWVOb2RlfSBwYXJlbnQgVGhlIHBhcmVudCB0byBzZXQuIElmIG51bGwsIHRoZSBub2RlIHdpbGwgYmVcblx0ICogZGV0YWNoZWQgZnJvbSB0aGUgdHJlZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0c2V0UGFyZW50KHBhcmVudCkge1xuXHRcdHRoaXMucGFyZW50XyA9IHBhcmVudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUcmF2ZXJzZXMgdGhlIHN1YnRyZWUuIFRoZSBmaXJzdCBjYWxsYmFjayBzdGFydHMgd2l0aCB0aGlzIG5vZGUsXG5cdCAqIGFuZCB2aXNpdHMgdGhlIGRlc2NlbmRhbnQgbm9kZXMgZGVwdGgtZmlyc3QsIGluIHByZW9yZGVyLlxuXHQgKiBUaGUgc2Vjb25kIGNhbGxiYWNrLCBzdGFydHMgd2l0aCBkZWVwZXN0IGNoaWxkIHRoZW4gdmlzaXRzXG5cdCAqIHRoZSBhbmNlc3RvciBub2RlcyBkZXB0aC1maXJzdCwgaW4gcG9zdG9yZGVyLiBFLmcuXG5cdCAqXG5cdCAqICBcdCBBXG5cdCAqICAgIC8gXFxcblx0ICogICBCICAgQ1xuXHQgKiAgLyAgIC8gXFxcblx0ICogRCAgIEUgICBGXG5cdCAqXG5cdCAqIHByZW9yZGVyIC0+IFsnQScsICdCJywgJ0QnLCAnQycsICdFJywgJ0YnXVxuXHQgKiBwb3N0b3JkZXIgLT4gWydEJywgJ0InLCAnRScsICdGJywgJ0MnLCAnQSddXG5cdCAqXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb249fSBvcHRfcHJlb3JkZXJGbiBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSB3aGVuIHZpc2l0aW5nIGEgbm9kZS5cblx0ICogQHBhcmFtIHtmdW5jdGlvbj19IG9wdF9wb3N0b3JkZXJGbiBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSBiZWZvcmUgbGVhdmluZyBhIG5vZGUuXG5cdCAqL1xuXHR0cmF2ZXJzZShvcHRfcHJlb3JkZXJGbiwgb3B0X3Bvc3RvcmRlckZuKSB7XG5cdFx0aWYgKG9wdF9wcmVvcmRlckZuKSB7XG5cdFx0XHRvcHRfcHJlb3JkZXJGbih0aGlzKTtcblx0XHR9XG5cdFx0dGhpcy5nZXRDaGlsZHJlbigpLmZvckVhY2goKGNoaWxkKSA9PiBjaGlsZC50cmF2ZXJzZShvcHRfcHJlb3JkZXJGbiwgb3B0X3Bvc3RvcmRlckZuKSk7XG5cdFx0aWYgKG9wdF9wb3N0b3JkZXJGbikge1xuXHRcdFx0b3B0X3Bvc3RvcmRlckZuKHRoaXMpO1xuXHRcdH1cblx0fVxuXG59XG5cbi8qKlxuICogQ29uc3RhbnQgZm9yIGVtcHR5IGFycmF5IHRvIGF2b2lkIHVubmVjZXNzYXJ5IGFsbG9jYXRpb25zLlxuICogQHByaXZhdGVcbiAqL1xuVHJlZU5vZGUuRU1QVFlfQVJSQVkgPSBbXTtcblxuLyoqXG4gKiBBc3NlcnRzIHRoYXQgY2hpbGQgaGFzIG5vIHBhcmVudC5cbiAqIEBwYXJhbSB7VHJlZU5vZGV9IGNoaWxkIEEgY2hpbGQuXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBhc3NlcnRDaGlsZEhhc05vUGFyZW50ID0gZnVuY3Rpb24oY2hpbGQpIHtcblx0aWYgKGNoaWxkLmdldFBhcmVudCgpKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgYWRkIGNoaWxkIHdpdGggcGFyZW50LicpO1xuXHR9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBUcmVlTm9kZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgaXNEZWYsIHN0cmluZyB9IGZyb20gJ21ldGFsJztcbmltcG9ydCBwYXJzZSBmcm9tICcuL3BhcnNlJztcbmltcG9ydCB7IE11bHRpTWFwIH0gZnJvbSAnbWV0YWwtc3RydWN0cyc7XG5cbnZhciBwYXJzZUZuXyA9IHBhcnNlO1xuXG5jbGFzcyBVcmkge1xuXG5cdC8qKlxuXHQgKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHNldHRlcnMgYW5kIGdldHRlcnMgZm9yIHRoZSBwYXJ0cyBvZiB0aGUgVVJJLlxuXHQgKiBUaGUgZm9sbG93aW5nIGZpZ3VyZSBkaXNwbGF5cyBhbiBleGFtcGxlIFVSSXMgYW5kIHRoZWlyIGNvbXBvbmVudCBwYXJ0cy5cblx0ICpcblx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aFxuXHQgKlx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIzilIDilIDilIDilLTilIDilIDilIDilIDilJBcblx0ICpcdCAgYWJjOi8vZXhhbXBsZS5jb206MTIzL3BhdGgvZGF0YT9rZXk9dmFsdWUjZnJhZ2lkMVxuXHQgKlx0ICDilJTilKzilJggICDilJTilIDilIDilIDilIDilKzilIDilIDilIDilIDilJgg4pSU4pSs4pSYICAgICAgICAgICDilJTilIDilIDilIDilKzilIDilIDilIDilJgg4pSU4pSA4pSA4pSs4pSA4pSA4pSYXG5cdCAqIHByb3RvY29sICBob3N0bmFtZSAgcG9ydCAgICAgICAgICAgIHNlYXJjaCAgICBoYXNoXG5cdCAqICAgICAgICAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuXHQgKiAgICAgICAgICAgICAgICBob3N0XG5cdCAqXG5cdCAqIEBwYXJhbSB7Kj19IG9wdF91cmkgT3B0aW9uYWwgc3RyaW5nIFVSSSB0byBwYXJzZVxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9wdF91cmkgPSAnJykge1xuXHRcdHRoaXMudXJsID0gVXJpLnBhcnNlKHRoaXMubWF5YmVBZGRQcm90b2NvbEFuZEhvc3RuYW1lXyhvcHRfdXJpKSk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBwYXJhbWV0ZXJzIHRvIHVyaSBmcm9tIGEgPGNvZGU+TXVsdGlNYXA8L2NvZGU+IGFzIHNvdXJjZS5cblx0ICogQHBhcmFtIHtNdWx0aU1hcH0gbXVsdGltYXAgVGhlIDxjb2RlPk11bHRpTWFwPC9jb2RlPiBjb250YWluaW5nIHRoZVxuXHQgKiAgIHBhcmFtZXRlcnMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkUGFyYW1ldGVyc0Zyb21NdWx0aU1hcChtdWx0aW1hcCkge1xuXHRcdG11bHRpbWFwLm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuXHRcdFx0bXVsdGltYXAuZ2V0QWxsKG5hbWUpLmZvckVhY2goKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB0aGUgdmFsdWUgb2YgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlcnMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHBhcmFtZXRlciB0byBzZXQuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZS4gV2lsbCBiZSBleHBsaWNpdGx5IGNhc3RlZCB0byBTdHJpbmcuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFBhcmFtZXRlclZhbHVlKG5hbWUsIHZhbHVlKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdGlmIChpc0RlZih2YWx1ZSkpIHtcblx0XHRcdHZhbHVlID0gU3RyaW5nKHZhbHVlKTtcblx0XHR9XG5cdFx0dGhpcy5xdWVyeS5hZGQobmFtZSwgdmFsdWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIHZhbHVlcyBvZiB0aGUgbmFtZWQgcXVlcnkgcGFyYW1ldGVyLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFBhcmFtZXRlclZhbHVlcyhuYW1lLCB2YWx1ZXMpIHtcblx0XHR2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBFbnN1cmVzIHF1ZXJ5IGludGVybmFsIG1hcCBpcyBpbml0aWFsaXplZCBhbmQgc3luY2VkIHdpdGggaW5pdGlhbCB2YWx1ZVxuXHQgKiBleHRyYWN0ZWQgZnJvbSBVUkkgc2VhcmNoIHBhcnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCkge1xuXHRcdGlmICh0aGlzLnF1ZXJ5KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMucXVlcnkgPSBuZXcgTXVsdGlNYXAoKTtcblx0XHR2YXIgc2VhcmNoID0gdGhpcy51cmwuc2VhcmNoO1xuXHRcdGlmIChzZWFyY2gpIHtcblx0XHRcdHNlYXJjaC5zdWJzdHJpbmcoMSkuc3BsaXQoJyYnKS5mb3JFYWNoKChwYXJhbSkgPT4ge1xuXHRcdFx0XHR2YXIgW2tleSwgdmFsdWVdID0gcGFyYW0uc3BsaXQoJz0nKTtcblx0XHRcdFx0aWYgKGlzRGVmKHZhbHVlKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gVXJpLnVybERlY29kZSh2YWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShrZXksIHZhbHVlKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBoYXNoIHBhcnQgb2YgdXJpLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRIYXNoKCkge1xuXHRcdHJldHVybiB0aGlzLnVybC5oYXNoIHx8ICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGhvc3QgcGFydCBvZiB1cmkuIEUuZy4gPGNvZGU+W2hvc3RuYW1lXTpbcG9ydF08L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRIb3N0KCkge1xuXHRcdHZhciBob3N0ID0gdGhpcy5nZXRIb3N0bmFtZSgpO1xuXHRcdGlmIChob3N0KSB7XG5cdFx0XHR2YXIgcG9ydCA9IHRoaXMuZ2V0UG9ydCgpO1xuXHRcdFx0aWYgKHBvcnQgJiYgcG9ydCAhPT0gJzgwJykge1xuXHRcdFx0XHRob3N0ICs9ICc6JyArIHBvcnQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBob3N0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGhvc3RuYW1lIHBhcnQgb2YgdXJpIHdpdGhvdXQgcHJvdG9jb2wgYW5kIHBvcnQuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldEhvc3RuYW1lKCkge1xuXHRcdHZhciBob3N0bmFtZSA9IHRoaXMudXJsLmhvc3RuYW1lO1xuXHRcdGlmIChob3N0bmFtZSA9PT0gVXJpLkhPU1ROQU1FX1BMQUNFSE9MREVSKSB7XG5cdFx0XHRyZXR1cm4gJyc7XG5cdFx0fVxuXHRcdHJldHVybiBob3N0bmFtZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBvcmlnaW4gcGFydCBvZiB1cmkuIEUuZy4gPGNvZGU+aHR0cDovL1tob3N0bmFtZV06W3BvcnRdPC9jb2RlPi5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0T3JpZ2luKCkge1xuXHRcdHZhciBob3N0ID0gdGhpcy5nZXRIb3N0KCk7XG5cdFx0aWYgKGhvc3QpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldFByb3RvY29sKCkgKyAnLy8nICsgaG9zdDtcblx0XHR9XG5cdFx0cmV0dXJuICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGZpcnN0IHZhbHVlIGZvciBhIGdpdmVuIHBhcmFtZXRlciBvciB1bmRlZmluZWQgaWYgdGhlIGdpdmVuXG5cdCAqIHBhcmFtZXRlciBuYW1lIGRvZXMgbm90IGFwcGVhciBpbiB0aGUgcXVlcnkgc3RyaW5nLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1OYW1lIFVuZXNjYXBlZCBwYXJhbWV0ZXIgbmFtZS5cblx0ICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gVGhlIGZpcnN0IHZhbHVlIGZvciBhIGdpdmVuIHBhcmFtZXRlciBvclxuXHQgKiAgIHVuZGVmaW5lZCBpZiB0aGUgZ2l2ZW4gcGFyYW1ldGVyIG5hbWUgZG9lcyBub3QgYXBwZWFyIGluIHRoZSBxdWVyeVxuXHQgKiAgIHN0cmluZy5cblx0ICovXG5cdGdldFBhcmFtZXRlclZhbHVlKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0cmV0dXJuIHRoaXMucXVlcnkuZ2V0KG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHZhbHVlPGI+czwvYj4gZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyIGFzIGEgbGlzdCBvZiBkZWNvZGVkXG5cdCAqIHF1ZXJ5IHBhcmFtZXRlciB2YWx1ZXMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBwYXJhbWV0ZXIgdG8gZ2V0IHZhbHVlcyBmb3IuXG5cdCAqIEByZXR1cm4geyFBcnJheTw/Pn0gVGhlIHZhbHVlcyBmb3IgYSBnaXZlbiBwYXJhbWV0ZXIgYXMgYSBsaXN0IG9mIGRlY29kZWRcblx0ICogICBxdWVyeSBwYXJhbWV0ZXIgdmFsdWVzLlxuXHQgKi9cblx0Z2V0UGFyYW1ldGVyVmFsdWVzKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0cmV0dXJuIHRoaXMucXVlcnkuZ2V0QWxsKG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIG5hbWU8Yj5zPC9iPiBvZiB0aGUgcGFyYW1ldGVycy5cblx0ICogQHJldHVybiB7IUFycmF5PHN0cmluZz59IFRoZSBuYW1lcyBmb3IgdGhlIHBhcmFtZXRlcnMgYXMgYSBsaXN0IG9mXG5cdCAqICAgc3RyaW5ncy5cblx0ICovXG5cdGdldFBhcmFtZXRlck5hbWVzKCkge1xuXHRcdHRoaXMuZW5zdXJlUXVlcnlJbml0aWFsaXplZF8oKTtcblx0XHRyZXR1cm4gdGhpcy5xdWVyeS5uYW1lcygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGZ1bmN0aW9uIGN1cnJlbnRseSBiZWluZyB1c2VkIHRvIHBhcnNlIFVSSXMuXG5cdCAqIEByZXR1cm4geyFmdW5jdGlvbigpfVxuXHQgKi9cblx0c3RhdGljIGdldFBhcnNlRm4oKSB7XG5cdFx0cmV0dXJuIHBhcnNlRm5fO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHBhdGhuYW1lIHBhcnQgb2YgdXJpLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRQYXRobmFtZSgpIHtcblx0XHRyZXR1cm4gdGhpcy51cmwucGF0aG5hbWU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcG9ydCBudW1iZXIgcGFydCBvZiB1cmkgYXMgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRQb3J0KCkge1xuXHRcdHJldHVybiB0aGlzLnVybC5wb3J0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHByb3RvY29sIHBhcnQgb2YgdXJpLiBFLmcuIDxjb2RlPmh0dHA6PC9jb2RlPi5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0UHJvdG9jb2woKSB7XG5cdFx0cmV0dXJuIHRoaXMudXJsLnByb3RvY29sO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHNlYXJjaCBwYXJ0IG9mIHVyaS4gU2VhcmNoIHZhbHVlIGlzIHJldHJpZXZlZCBmcm9tIHF1ZXJ5XG5cdCAqIHBhcmFtZXRlcnMuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldFNlYXJjaCgpIHtcblx0XHR2YXIgc2VhcmNoID0gJyc7XG5cdFx0dmFyIHF1ZXJ5c3RyaW5nID0gJyc7XG5cdFx0dGhpcy5nZXRQYXJhbWV0ZXJOYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcblx0XHRcdHRoaXMuZ2V0UGFyYW1ldGVyVmFsdWVzKG5hbWUpLmZvckVhY2goKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHF1ZXJ5c3RyaW5nICs9IG5hbWU7XG5cdFx0XHRcdGlmIChpc0RlZih2YWx1ZSkpIHtcblx0XHRcdFx0XHRxdWVyeXN0cmluZyArPSAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHF1ZXJ5c3RyaW5nICs9ICcmJztcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHRcdHF1ZXJ5c3RyaW5nID0gcXVlcnlzdHJpbmcuc2xpY2UoMCwgLTEpO1xuXHRcdGlmIChxdWVyeXN0cmluZykge1xuXHRcdFx0c2VhcmNoICs9ICc/JyArIHF1ZXJ5c3RyaW5nO1xuXHRcdH1cblx0XHRyZXR1cm4gc2VhcmNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB1cmkgY29udGFpbnMgdGhlIHBhcmFtZXRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGhhc1BhcmFtZXRlcihuYW1lKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdHJldHVybiB0aGlzLnF1ZXJ5LmNvbnRhaW5zKG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1ha2VzIHRoaXMgVVJMIHVuaXF1ZSBieSBhZGRpbmcgYSByYW5kb20gcGFyYW0gdG8gaXQuIFVzZWZ1bCBmb3IgYXZvaWRpbmdcblx0ICogY2FjaGUuXG5cdCAqL1xuXHRtYWtlVW5pcXVlKCkge1xuXHRcdHRoaXMuc2V0UGFyYW1ldGVyVmFsdWUoVXJpLlJBTkRPTV9QQVJBTSwgc3RyaW5nLmdldFJhbmRvbVN0cmluZygpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBhZGRzIHByb3RvY29sIGFuZCBhIGhvc3RuYW1lIHBsYWNlaG9sZGVyIG9uIGEgcGFyaWFsIFVSSSBpZiBuZWVkZWQuXG5cdCAqIFJlbGV2ZW50IGZvciBjb21wYXRpYmlsaXR5IHdpdGggPGNvZGU+VVJMPC9jb2RlPiBuYXRpdmUgb2JqZWN0LlxuXHQgKiBAcGFyYW0ge3N0cmluZz19IG9wdF91cmlcblx0ICogQHJldHVybiB7c3RyaW5nfSBVUkkgd2l0aCBwcm90b2NvbCBhbmQgaG9zdG5hbWUgcGxhY2Vob2xkZXIuXG5cdCAqL1xuXHRtYXliZUFkZFByb3RvY29sQW5kSG9zdG5hbWVfKG9wdF91cmkpIHtcblx0XHR2YXIgdXJsID0gb3B0X3VyaTtcblx0XHRpZiAob3B0X3VyaS5pbmRleE9mKCc6Ly8nKSA9PT0gLTEgJiZcblx0XHRcdG9wdF91cmkuaW5kZXhPZignamF2YXNjcmlwdDonKSAhPT0gMCkgeyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuXHRcdFx0dXJsID0gVXJpLkRFRkFVTFRfUFJPVE9DT0w7XG5cdFx0XHRpZiAob3B0X3VyaVswXSAhPT0gJy8nIHx8IG9wdF91cmlbMV0gIT09ICcvJykge1xuXHRcdFx0XHR1cmwgKz0gJy8vJztcblx0XHRcdH1cblxuXHRcdFx0c3dpdGNoIChvcHRfdXJpLmNoYXJBdCgwKSkge1xuXHRcdFx0XHRjYXNlICcuJzpcblx0XHRcdFx0Y2FzZSAnPyc6XG5cdFx0XHRcdGNhc2UgJyMnOlxuXHRcdFx0XHRcdHVybCArPSBVcmkuSE9TVE5BTUVfUExBQ0VIT0xERVI7XG5cdFx0XHRcdFx0dXJsICs9ICcvJztcblx0XHRcdFx0XHR1cmwgKz0gb3B0X3VyaTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnJzpcblx0XHRcdFx0Y2FzZSAnLyc6XG5cdFx0XHRcdFx0aWYgKG9wdF91cmlbMV0gIT09ICcvJykge1xuXHRcdFx0XHRcdFx0dXJsICs9IFVyaS5IT1NUTkFNRV9QTEFDRUhPTERFUjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dXJsICs9IG9wdF91cmk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0dXJsICs9IG9wdF91cmk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB1cmw7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuXHQgKiBAcGFyYW0geyo9fSBvcHRfdXJpIE9wdGlvbmFsIHN0cmluZyBVUkkgdG8gcGFyc2Vcblx0ICovXG5cdHN0YXRpYyBwYXJzZShvcHRfdXJpKSB7XG5cdFx0cmV0dXJuIHBhcnNlRm5fKG9wdF91cmkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIHBhcmFtZXRlciB0byByZW1vdmUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHJlbW92ZVBhcmFtZXRlcihuYW1lKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdHRoaXMucXVlcnkucmVtb3ZlKG5hbWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdW5pcXVlbmVzcyBwYXJhbWV0ZXIgb2YgdGhlIHVyaS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0cmVtb3ZlVW5pcXVlKCkge1xuXHRcdHRoaXMucmVtb3ZlUGFyYW1ldGVyKFVyaS5SQU5ET01fUEFSQU0pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGhhc2guXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldEhhc2goaGFzaCkge1xuXHRcdHRoaXMudXJsLmhhc2ggPSBoYXNoO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGhvc3RuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaG9zdG5hbWVcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0SG9zdG5hbWUoaG9zdG5hbWUpIHtcblx0XHR0aGlzLnVybC5ob3N0bmFtZSA9IGhvc3RuYW1lO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBuYW1lZCBxdWVyeSBwYXJhbWV0ZXJzLCBjbGVhcmluZyBwcmV2aW91cyB2YWx1ZXNcblx0ICogZm9yIHRoYXQga2V5LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhcmFtZXRlclZhbHVlKG5hbWUsIHZhbHVlKSB7XG5cdFx0dGhpcy5yZW1vdmVQYXJhbWV0ZXIobmFtZSk7XG5cdFx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShuYW1lLCB2YWx1ZSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdmFsdWVzIG9mIHRoZSBuYW1lZCBxdWVyeSBwYXJhbWV0ZXJzLCBjbGVhcmluZyBwcmV2aW91cyB2YWx1ZXNcblx0ICogZm9yIHRoYXQga2V5LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhcmFtZXRlclZhbHVlcyhuYW1lLCB2YWx1ZXMpIHtcblx0XHR0aGlzLnJlbW92ZVBhcmFtZXRlcihuYW1lKTtcblx0XHR2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwYXRobmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGhuYW1lXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhdGhuYW1lKHBhdGhuYW1lKSB7XG5cdFx0dGhpcy51cmwucGF0aG5hbWUgPSBwYXRobmFtZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwb3J0IG51bWJlci5cblx0ICogQHBhcmFtIHsqfSBwb3J0IFBvcnQgbnVtYmVyLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXRQb3J0KHBvcnQpIHtcblx0XHR0aGlzLnVybC5wb3J0ID0gcG9ydDtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgdXNlZCBmb3IgcGFyc2luZyB0aGUgb3JpZ2luYWwgc3RyaW5nIHVyaVxuXHQgKiBpbnRvIGFuIG9iamVjdC5cblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gcGFyc2VGblxuXHQgKi9cblx0c3RhdGljIHNldFBhcnNlRm4ocGFyc2VGbikge1xuXHRcdHBhcnNlRm5fID0gcGFyc2VGbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwcm90b2NvbC4gSWYgbWlzc2luZyA8Y29kZT5odHRwOjwvY29kZT4gaXMgdXNlZCBhcyBkZWZhdWx0LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcHJvdG9jb2xcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0UHJvdG9jb2wocHJvdG9jb2wpIHtcblx0XHR0aGlzLnVybC5wcm90b2NvbCA9IHByb3RvY29sO1xuXHRcdGlmICh0aGlzLnVybC5wcm90b2NvbFt0aGlzLnVybC5wcm90b2NvbC5sZW5ndGggLSAxXSAhPT0gJzonKSB7XG5cdFx0XHR0aGlzLnVybC5wcm90b2NvbCArPSAnOic7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZyBmb3JtIG9mIHRoZSB1cmwuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0dG9TdHJpbmcoKSB7XG5cdFx0dmFyIGhyZWYgPSAnJztcblx0XHR2YXIgaG9zdCA9IHRoaXMuZ2V0SG9zdCgpO1xuXHRcdGlmIChob3N0KSB7XG5cdFx0XHRocmVmICs9IHRoaXMuZ2V0UHJvdG9jb2woKSArICcvLyc7XG5cdFx0fVxuXHRcdGhyZWYgKz0gaG9zdCArIHRoaXMuZ2V0UGF0aG5hbWUoKSArIHRoaXMuZ2V0U2VhcmNoKCkgKyB0aGlzLmdldEhhc2goKTtcblx0XHRyZXR1cm4gaHJlZjtcblx0fVxuXG5cdC8qKlxuXHQgKiBKb2lucyB0aGUgZ2l2ZW4gcGF0aHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aFxuXHQgKiBAcGFyYW0gey4uLnN0cmluZ30gLi4ucGF0aHMgQW55IG51bWJlciBvZiBwYXRocyB0byBiZSBqb2luZWQgd2l0aCB0aGUgYmFzZSB1cmwuXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBqb2luUGF0aHMoYmFzZVBhdGgsIC4uLnBhdGhzKSB7XG5cdFx0aWYgKGJhc2VQYXRoLmNoYXJBdChiYXNlUGF0aC5sZW5ndGggLSAxKSA9PT0gJy8nKSB7XG5cdFx0XHRiYXNlUGF0aCA9IGJhc2VQYXRoLnN1YnN0cmluZygwLCBiYXNlUGF0aC5sZW5ndGggLSAxKTtcblx0XHR9XG5cdFx0cGF0aHMgPSBwYXRocy5tYXAocGF0aCA9PiBwYXRoLmNoYXJBdCgwKSA9PT0gJy8nID8gcGF0aC5zdWJzdHJpbmcoMSkgOiBwYXRoKTtcblx0XHRyZXR1cm4gW2Jhc2VQYXRoXS5jb25jYXQocGF0aHMpLmpvaW4oJy8nKS5yZXBsYWNlKC9cXC8kLywgJycpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVSTC1kZWNvZGVzIHRoZSBzdHJpbmcuIFdlIG5lZWQgdG8gc3BlY2lhbGx5IGhhbmRsZSAnKydzIGJlY2F1c2Vcblx0ICogdGhlIGphdmFzY3JpcHQgbGlicmFyeSBkb2Vzbid0IGNvbnZlcnQgdGhlbSB0byBzcGFjZXMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0byB1cmwgZGVjb2RlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBkZWNvZGVkIHtAY29kZSBzdHJ9LlxuXHQgKi9cblx0c3RhdGljIHVybERlY29kZShzdHIpIHtcblx0XHRyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0ci5yZXBsYWNlKC9cXCsvZywgJyAnKSk7XG5cdH1cblxufVxuXG4vKipcbiAqIERlZmF1bHQgcHJvdG9jb2wgdmFsdWUuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGRlZmF1bHQgaHR0cDpcbiAqIEBzdGF0aWNcbiAqL1xuY29uc3QgaXNTZWN1cmUgPSAoKSA9PlxuXHQodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR3aW5kb3cubG9jYXRpb24gJiZcblx0XHR3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgJiZcblx0XHR3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wuaW5kZXhPZignaHR0cHMnKSA9PT0gMCk7XG5cblVyaS5ERUZBVUxUX1BST1RPQ09MID0gaXNTZWN1cmUoKSA/ICdodHRwczonIDogJ2h0dHA6JztcblxuLyoqXG4gKiBIb3N0bmFtZSBwbGFjZWhvbGRlci4gUmVsZXZhbnQgdG8gaW50ZXJuYWwgdXNhZ2Ugb25seS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cblVyaS5IT1NUTkFNRV9QTEFDRUhPTERFUiA9ICdob3N0bmFtZScgKyBEYXRlLm5vdygpO1xuXG4vKipcbiAqIE5hbWUgdXNlZCBieSB0aGUgcGFyYW0gZ2VuZXJhdGVkIGJ5IGBtYWtlVW5pcXVlYC5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cblVyaS5SQU5ET01fUEFSQU0gPSAnengnO1xuXG5leHBvcnQgZGVmYXVsdCBVcmk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGV4aXREb2N1bWVudCB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBzdGF0aWMgdXRpbGl0eSBmdW5jdGlvbnMuXG4gKiBAY29uc3RcbiAqL1xuY2xhc3MgdXRpbHMge1xuXG5cdC8qKlxuXHQgKiBDb3BpZXMgYXR0cmlidXRlcyBmb3JtIHNvdXJjZSBub2RlIHRvIHRhcmdldCBub2RlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgY29weU5vZGVBdHRyaWJ1dGVzKHNvdXJjZSwgdGFyZ2V0KSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoc291cmNlLmF0dHJpYnV0ZXMpLmZvckVhY2goKGF0dHJpYnV0ZSkgPT4gdGFyZ2V0LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUubmFtZSwgYXR0cmlidXRlLnZhbHVlKSk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY3VycmVudCBicm93c2VyIHBhdGggaW5jbHVkaW5nIGhhc2hiYW5nLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0Q3VycmVudEJyb3dzZXJQYXRoKCkge1xuXHRcdHJldHVybiB0aGlzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCkgKyBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGN1cnJlbnQgYnJvd3NlciBwYXRoIGV4Y2x1ZGluZyBoYXNoYmFuZy5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCkge1xuXHRcdHJldHVybiBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnNlYXJjaDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBnaXZlbiBub2RlIG9mZnNldCBjb29yZGluYXRlcy5cblx0ICogQHJldHVybiB7IW9iamVjdH1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldE5vZGVPZmZzZXQobm9kZSkge1xuXHRcdGxldCBbb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wXSA9IFswLCAwXTtcblx0XHRkbyB7XG5cdFx0XHRvZmZzZXRMZWZ0ICs9IG5vZGUub2Zmc2V0TGVmdDtcblx0XHRcdG9mZnNldFRvcCArPSBub2RlLm9mZnNldFRvcDtcblx0XHRcdG5vZGUgPSBub2RlLm9mZnNldFBhcmVudDtcblx0XHR9IHdoaWxlIChub2RlKTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0b2Zmc2V0TGVmdCxcblx0XHRcdG9mZnNldFRvcFxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgdGhlIHBhdGggcGFydCBvZiBhbiB1cmwuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXRVcmxQYXRoKHVybCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHVybCk7XG5cdFx0cmV0dXJuIHVyaS5nZXRQYXRobmFtZSgpICsgdXJpLmdldFNlYXJjaCgpICsgdXJpLmdldEhhc2goKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyB0aGUgcGF0aCBwYXJ0IG9mIGFuIHVybCB3aXRob3V0IGhhc2hiYW5nLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0VXJsUGF0aFdpdGhvdXRIYXNoKHVybCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHVybCk7XG5cdFx0cmV0dXJuIHVyaS5nZXRQYXRobmFtZSgpICsgdXJpLmdldFNlYXJjaCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIHRoZSBwYXRoIHBhcnQgb2YgYW4gdXJsIHdpdGhvdXQgaGFzaGJhbmcgYW5kIHF1ZXJ5IHNlYXJjaC5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaCh1cmwpIHtcblx0XHR2YXIgdXJpID0gbmV3IFVyaSh1cmwpO1xuXHRcdHJldHVybiB1cmkuZ2V0UGF0aG5hbWUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdXJsIGlzIGluIHRoZSBzYW1lIGJyb3dzZXIgY3VycmVudCB1cmwgZXhjbHVkaW5nIHRoZSBoYXNoYmFuZy5cblx0ICogQHBhcmFtICB7IXN0cmluZ30gdXJsXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBpc0N1cnJlbnRCcm93c2VyUGF0aCh1cmwpIHtcblx0XHRpZiAodXJsKSB7XG5cdFx0XHRjb25zdCBjdXJyZW50QnJvd3NlclBhdGggPSB0aGlzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCk7XG5cdFx0XHQvLyB0aGUgZ2V0VXJsUGF0aCB3aWxsIGNyZWF0ZSBhIFVyaSBhbmQgd2lsbCBub3JtYWxpemUgdGhlIHBhdGggYW5kXG5cdFx0XHQvLyByZW1vdmUgdGhlIHRyYWlsbGluZyAnLycgZm9yIHByb3Blcmx5IGNvbXBhcmluZyBwYXRocy5cblx0XHRcdHJldHVybiB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2godXJsKSA9PT0gdGhpcy5nZXRVcmxQYXRoKGN1cnJlbnRCcm93c2VyUGF0aCk7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRydWUgaWYgSFRNTDUgSGlzdG9yeSBhcGkgaXMgc3VwcG9ydGVkLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgaXNIdG1sNUhpc3RvcnlTdXBwb3J0ZWQoKSB7XG5cdFx0cmV0dXJuICEhKGdsb2JhbHMud2luZG93Lmhpc3RvcnkgJiYgZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBhIGdpdmVuIHVybCBpcyBhIHZhbGlkIGh0dHAocykgdXJpIGFuZCByZXR1cm5zIHRoZSBmb3JtZWQgVXJpXG5cdCAqIG9yIGZhbHNlIGlmIHRoZSBwYXJzaW5nIGZhaWxlZFxuXHQgKiBAcmV0dXJuIHtVcml8Ym9vbGVhbn1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGlzV2ViVXJpKHVybCkge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gbmV3IFVyaSh1cmwpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJHtlcnIubWVzc2FnZX0gJHt1cmx9YCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGF0dHJpYnV0ZXMgZm9ybSBub2RlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgY2xlYXJOb2RlQXR0cmlidXRlcyhub2RlKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobm9kZS5hdHRyaWJ1dGVzKS5mb3JFYWNoKChhdHRyaWJ1dGUpID0+IG5vZGUucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZS5uYW1lKSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlIGVsZW1lbnRzIGZyb20gdGhlIGRvY3VtZW50LlxuXHQgKiBAcGFyYW0geyFBcnJheTxFbGVtZW50Pn0gZWxlbWVudHNcblx0ICovXG5cdHN0YXRpYyByZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudChlbGVtZW50cykge1xuXHRcdGVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IGV4aXREb2N1bWVudChlbGVtZW50KSk7XG5cdH1cblxuXHQvKipcblx0KiBSZW1vdmVzIHRyYWlsaW5nIHNsYXNoIGluIHBhdGguXG5cdCogQHBhcmFtIHshc3RyaW5nfVxuXHQqIEByZXR1cm4ge3N0cmluZ31cblx0Ki9cblx0c3RhdGljIHJlbW92ZVBhdGhUcmFpbGluZ1NsYXNoKHBhdGgpIHtcblx0XHR2YXIgbGVuZ3RoID0gcGF0aCA/IHBhdGgubGVuZ3RoIDogMDtcblx0XHRpZiAobGVuZ3RoID4gMSAmJiBwYXRoW2xlbmd0aCAtIDFdID09PSAnLycpIHtcblx0XHRcdHBhdGggPSBwYXRoLnN1YnN0cigwLCBsZW5ndGggLSAxKTtcblx0XHR9XG5cdFx0cmV0dXJuIHBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIHJhbmRvbSBzdWZmaXggdG8gdGhlIGhyZWYgYXR0cmlidXRlIG9mIHRoZSBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFlbGVtZW50fSBlbGVtZW50XG5cdCAqIEByZXR1cm4ge2VsZW1lbnR9XG5cdCAqL1xuXHRzdGF0aWMgc2V0RWxlbWVudFdpdGhSYW5kb21IcmVmKGVsZW1lbnQpIHtcblx0XHRlbGVtZW50LmhyZWYgPSBlbGVtZW50LmhyZWYgKyAnP3E9JyArIE1hdGgucmFuZG9tKCk7XG5cdFx0cmV0dXJuIGVsZW1lbnQ7XG5cdH1cblxuXHQvKipcblx0ICogT3ZlcnJpZGVzIGRvY3VtZW50IHJlZmVycmVyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSByZWZlcnJlclxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgc2V0UmVmZXJyZXIocmVmZXJyZXIpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFscy5kb2N1bWVudCwgJ3JlZmVycmVyJywge1xuXHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIHJlZmVycmVyO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHV0aWxzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG5cdGJhc2VQYXRoOiAnZGF0YS1zZW5uYS1iYXNlLXBhdGgnLFxuXHRsaW5rU2VsZWN0b3I6ICdkYXRhLXNlbm5hLWxpbmstc2VsZWN0b3InLFxuXHRsb2FkaW5nQ3NzQ2xhc3M6ICdkYXRhLXNlbm5hLWxvYWRpbmctY3NzLWNsYXNzJyxcblx0c2VubmE6ICdkYXRhLXNlbm5hJyxcblx0ZGlzcGF0Y2g6ICdkYXRhLXNlbm5hLWRpc3BhdGNoJyxcblx0c3VyZmFjZTogJ2RhdGEtc2VubmEtc3VyZmFjZScsXG5cdHVwZGF0ZVNjcm9sbFBvc2l0aW9uOiAnZGF0YS1zZW5uYS11cGRhdGUtc2Nyb2xsLXBvc2l0aW9uJ1xufTsiLCIvKiFcbiAqIFByb21pc2VzIHBvbHlmaWxsIGZyb20gR29vZ2xlJ3MgQ2xvc3VyZSBMaWJyYXJ5LlxuICpcbiAqICAgICAgQ29weXJpZ2h0IDIwMTMgVGhlIENsb3N1cmUgTGlicmFyeSBBdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE5PVEUoZWR1YXJkbyk6IFByb21pc2Ugc3VwcG9ydCBpcyBub3QgcmVhZHkgb24gYWxsIHN1cHBvcnRlZCBicm93c2VycyxcbiAqIHRoZXJlZm9yZSBtZXRhbC1wcm9taXNlIGlzIHRlbXBvcmFyaWx5IHVzaW5nIEdvb2dsZSdzIHByb21pc2VzIGFzIHBvbHlmaWxsLlxuICogSXQgc3VwcG9ydHMgY2FuY2VsbGFibGUgcHJvbWlzZXMgYW5kIGhhcyBjbGVhbiBhbmQgZmFzdCBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGlzRGVmLCBpc0Z1bmN0aW9uLCBpc09iamVjdCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IGFzeW5jIH0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIFByb3ZpZGVzIGEgbW9yZSBzdHJpY3QgaW50ZXJmYWNlIGZvciBUaGVuYWJsZXMgaW4gdGVybXMgb2ZcbiAqIGh0dHA6Ly9wcm9taXNlc2FwbHVzLmNvbSBmb3IgaW50ZXJvcCB3aXRoIHtAc2VlIENhbmNlbGxhYmxlUHJvbWlzZX0uXG4gKlxuICogQGludGVyZmFjZVxuICogQGV4dGVuZHMge0lUaGVuYWJsZS48VFlQRT59XG4gKiBAdGVtcGxhdGUgVFlQRVxuICovXG52YXIgVGhlbmFibGUgPSBmdW5jdGlvbigpIHt9O1xuXG4vKipcbiAqIEFkZHMgY2FsbGJhY2tzIHRoYXQgd2lsbCBvcGVyYXRlIG9uIHRoZSByZXN1bHQgb2YgdGhlIFRoZW5hYmxlLCByZXR1cm5pbmcgYVxuICogbmV3IGNoaWxkIFByb21pc2UuXG4gKlxuICogSWYgdGhlIFRoZW5hYmxlIGlzIGZ1bGZpbGxlZCwgdGhlIHtAY29kZSBvbkZ1bGZpbGxlZH0gY2FsbGJhY2sgd2lsbCBiZVxuICogaW52b2tlZCB3aXRoIHRoZSBmdWxmaWxsbWVudCB2YWx1ZSBhcyBhcmd1bWVudCwgYW5kIHRoZSBjaGlsZCBQcm9taXNlIHdpbGxcbiAqIGJlIGZ1bGZpbGxlZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrLiBJZiB0aGUgY2FsbGJhY2sgdGhyb3dzXG4gKiBhbiBleGNlcHRpb24sIHRoZSBjaGlsZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgdGhyb3duIHZhbHVlXG4gKiBpbnN0ZWFkLlxuICpcbiAqIElmIHRoZSBUaGVuYWJsZSBpcyByZWplY3RlZCwgdGhlIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWRcbiAqIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb24gYXMgYXJndW1lbnQsIGFuZCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkXG4gKiB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrIG9yIHRocm93biB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0gez8oZnVuY3Rpb24odGhpczpUSElTLCBUWVBFKTpcbiAqICAgICAgICAgICAgIChSRVNVTFR8SVRoZW5hYmxlLjxSRVNVTFQ+fFRoZW5hYmxlKSk9fSBvcHRfb25GdWxmaWxsZWQgQVxuICogICAgIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBpbnZva2VkIHdpdGggdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlmIHRoZSBQcm9taXNlXG4gKiAgICAgaXMgZnVsbGZpbGxlZC5cbiAqIEBwYXJhbSB7PyhmdW5jdGlvbigqKTogKik9fSBvcHRfb25SZWplY3RlZCBBIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBpbnZva2VkXG4gKiAgICAgd2l0aCB0aGUgcmVqZWN0aW9uIHJlYXNvbiBpZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZC5cbiAqIEBwYXJhbSB7VEhJUz19IG9wdF9jb250ZXh0IEFuIG9wdGlvbmFsIGNvbnRleHQgb2JqZWN0IHRoYXQgd2lsbCBiZSB0aGVcbiAqICAgICBleGVjdXRpb24gY29udGV4dCBmb3IgdGhlIGNhbGxiYWNrcy4gQnkgZGVmYXVsdCwgZnVuY3Rpb25zIGFyZSBleGVjdXRlZFxuICogICAgIHdpdGggdGhlIGRlZmF1bHQgdGhpcy5cbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPFJFU1VMVD59IEEgbmV3IFByb21pc2UgdGhhdCB3aWxsIHJlY2VpdmUgdGhlXG4gKiAgICAgcmVzdWx0IG9mIHRoZSBmdWxmaWxsbWVudCBvciByZWplY3Rpb24gY2FsbGJhY2suXG4gKiBAdGVtcGxhdGUgUkVTVUxULFRISVNcbiAqL1xuVGhlbmFibGUucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbigpIHt9O1xuXG5cbi8qKlxuICogQW4gZXhwYW5kbyBwcm9wZXJ0eSB0byBpbmRpY2F0ZSB0aGF0IGFuIG9iamVjdCBpbXBsZW1lbnRzXG4gKiB7QGNvZGUgVGhlbmFibGV9LlxuICpcbiAqIHtAc2VlIGFkZEltcGxlbWVudGF0aW9ufS5cbiAqXG4gKiBAY29uc3RcbiAqL1xuVGhlbmFibGUuSU1QTEVNRU5URURfQllfUFJPUCA9ICckZ29vZ19UaGVuYWJsZSc7XG5cblxuLyoqXG4gKiBNYXJrcyBhIGdpdmVuIGNsYXNzIChjb25zdHJ1Y3RvcikgYXMgYW4gaW1wbGVtZW50YXRpb24gb2YgVGhlbmFibGUsIHNvXG4gKiB0aGF0IHdlIGNhbiBxdWVyeSB0aGF0IGZhY3QgYXQgcnVudGltZS4gVGhlIGNsYXNzIG11c3QgaGF2ZSBhbHJlYWR5XG4gKiBpbXBsZW1lbnRlZCB0aGUgaW50ZXJmYWNlLlxuICogRXhwb3J0cyBhICd0aGVuJyBtZXRob2Qgb24gdGhlIGNvbnN0cnVjdG9yIHByb3RvdHlwZSwgc28gdGhhdCB0aGUgb2JqZWN0c1xuICogYWxzbyBpbXBsZW1lbnQgdGhlIGV4dGVybiB7QHNlZSBUaGVuYWJsZX0gaW50ZXJmYWNlIGZvciBpbnRlcm9wIHdpdGhcbiAqIG90aGVyIFByb21pc2UgaW1wbGVtZW50YXRpb25zLlxuICogQHBhcmFtIHtmdW5jdGlvbihuZXc6VGhlbmFibGUsLi4uWz9dKX0gY3RvciBUaGUgY2xhc3MgY29uc3RydWN0b3IuIFRoZVxuICogICAgIGNvcnJlc3BvbmRpbmcgY2xhc3MgbXVzdCBoYXZlIGFscmVhZHkgaW1wbGVtZW50ZWQgdGhlIGludGVyZmFjZS5cbiAqL1xuVGhlbmFibGUuYWRkSW1wbGVtZW50YXRpb24gPSBmdW5jdGlvbihjdG9yKSB7XG4gIGN0b3IucHJvdG90eXBlLnRoZW4gPSBjdG9yLnByb3RvdHlwZS50aGVuO1xuICBjdG9yLnByb3RvdHlwZS4kZ29vZ19UaGVuYWJsZSA9IHRydWU7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHsqfSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgYSBnaXZlbiBpbnN0YW5jZSBpbXBsZW1lbnRzIHtAY29kZSBUaGVuYWJsZX0uXG4gKiAgICAgVGhlIGNsYXNzL3N1cGVyY2xhc3Mgb2YgdGhlIGluc3RhbmNlIG11c3QgY2FsbCB7QGNvZGUgYWRkSW1wbGVtZW50YXRpb259LlxuICovXG5UaGVuYWJsZS5pc0ltcGxlbWVudGVkQnkgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgaWYgKCFvYmplY3QpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gISFvYmplY3QuJGdvb2dfVGhlbmFibGU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBQcm9wZXJ0eSBhY2Nlc3Mgc2VlbXMgdG8gYmUgZm9yYmlkZGVuLlxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuXG4vKipcbiAqIExpa2UgYmluZCgpLCBleGNlcHQgdGhhdCBhICd0aGlzIG9iamVjdCcgaXMgbm90IHJlcXVpcmVkLiBVc2VmdWwgd2hlbiB0aGVcbiAqIHRhcmdldCBmdW5jdGlvbiBpcyBhbHJlYWR5IGJvdW5kLlxuICpcbiAqIFVzYWdlOlxuICogdmFyIGcgPSBwYXJ0aWFsKGYsIGFyZzEsIGFyZzIpO1xuICogZyhhcmczLCBhcmc0KTtcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBBIGZ1bmN0aW9uIHRvIHBhcnRpYWxseSBhcHBseS5cbiAqIEBwYXJhbSB7Li4uKn0gdmFyX2FyZ3MgQWRkaXRpb25hbCBhcmd1bWVudHMgdGhhdCBhcmUgcGFydGlhbGx5IGFwcGxpZWQgdG8gZm4uXG4gKiBAcmV0dXJuIHshRnVuY3Rpb259IEEgcGFydGlhbGx5LWFwcGxpZWQgZm9ybSBvZiB0aGUgZnVuY3Rpb24gYmluZCgpIHdhc1xuICogICAgIGludm9rZWQgYXMgYSBtZXRob2Qgb2YuXG4gKi9cbnZhciBwYXJ0aWFsID0gZnVuY3Rpb24oZm4pIHtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgLy8gQ2xvbmUgdGhlIGFycmF5ICh3aXRoIHNsaWNlKCkpIGFuZCBhcHBlbmQgYWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICAvLyB0byB0aGUgZXhpc3RpbmcgYXJndW1lbnRzLlxuICAgIHZhciBuZXdBcmdzID0gYXJncy5zbGljZSgpO1xuICAgIG5ld0FyZ3MucHVzaC5hcHBseShuZXdBcmdzLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBuZXdBcmdzKTtcbiAgfTtcbn07XG5cbi8qKlxuICogUHJvbWlzZXMgcHJvdmlkZSBhIHJlc3VsdCB0aGF0IG1heSBiZSByZXNvbHZlZCBhc3luY2hyb25vdXNseS4gQSBQcm9taXNlIG1heVxuICogYmUgcmVzb2x2ZWQgYnkgYmVpbmcgZnVsZmlsbGVkIG9yIHJlamVjdGVkIHdpdGggYSB2YWx1ZSwgd2hpY2ggd2lsbCBiZSBrbm93blxuICogYXMgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIG9yIHRoZSByZWplY3Rpb24gcmVhc29uLiBXaGV0aGVyIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQsIHRoZSBQcm9taXNlIHJlc3VsdCBpcyBpbW11dGFibGUgb25jZSBpdCBpcyBzZXQuXG4gKlxuICogUHJvbWlzZXMgbWF5IHJlcHJlc2VudCByZXN1bHRzIG9mIGFueSB0eXBlLCBpbmNsdWRpbmcgdW5kZWZpbmVkLiBSZWplY3Rpb25cbiAqIHJlYXNvbnMgYXJlIHR5cGljYWxseSBFcnJvcnMsIGJ1dCBtYXkgYWxzbyBiZSBvZiBhbnkgdHlwZS4gQ2xvc3VyZSBQcm9taXNlc1xuICogYWxsb3cgZm9yIG9wdGlvbmFsIHR5cGUgYW5ub3RhdGlvbnMgdGhhdCBlbmZvcmNlIHRoYXQgZnVsZmlsbG1lbnQgdmFsdWVzIGFyZVxuICogb2YgdGhlIGFwcHJvcHJpYXRlIHR5cGVzIGF0IGNvbXBpbGUgdGltZS5cbiAqXG4gKiBUaGUgcmVzdWx0IG9mIGEgUHJvbWlzZSBpcyBhY2Nlc3NpYmxlIGJ5IGNhbGxpbmcge0Bjb2RlIHRoZW59IGFuZCByZWdpc3RlcmluZ1xuICoge0Bjb2RlIG9uRnVsZmlsbGVkfSBhbmQge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrcy4gT25jZSB0aGUgUHJvbWlzZVxuICogcmVzb2x2ZXMsIHRoZSByZWxldmFudCBjYWxsYmFja3MgYXJlIGludm9rZWQgd2l0aCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgb3JcbiAqIHJlamVjdGlvbiByZWFzb24gYXMgYXJndW1lbnQuIENhbGxiYWNrcyBhcmUgYWx3YXlzIGludm9rZWQgaW4gdGhlIG9yZGVyIHRoZXlcbiAqIHdlcmUgcmVnaXN0ZXJlZCwgZXZlbiB3aGVuIGFkZGl0aW9uYWwge0Bjb2RlIHRoZW59IGNhbGxzIGFyZSBtYWRlIGZyb20gaW5zaWRlXG4gKiBhbm90aGVyIGNhbGxiYWNrLiBBIGNhbGxiYWNrIGlzIGFsd2F5cyBydW4gYXN5bmNocm9ub3VzbHkgc29tZXRpbWUgYWZ0ZXIgdGhlXG4gKiBzY29wZSBjb250YWluaW5nIHRoZSByZWdpc3RlcmluZyB7QGNvZGUgdGhlbn0gaW52b2NhdGlvbiBoYXMgcmV0dXJuZWQuXG4gKlxuICogSWYgYSBQcm9taXNlIGlzIHJlc29sdmVkIHdpdGggYW5vdGhlciBQcm9taXNlLCB0aGUgZmlyc3QgUHJvbWlzZSB3aWxsIGJsb2NrXG4gKiB1bnRpbCB0aGUgc2Vjb25kIGlzIHJlc29sdmVkLCBhbmQgdGhlbiBhc3N1bWVzIHRoZSBzYW1lIHJlc3VsdCBhcyB0aGUgc2Vjb25kXG4gKiBQcm9taXNlLiBUaGlzIGFsbG93cyBQcm9taXNlcyB0byBkZXBlbmQgb24gdGhlIHJlc3VsdHMgb2Ygb3RoZXIgUHJvbWlzZXMsXG4gKiBsaW5raW5nIHRvZ2V0aGVyIG11bHRpcGxlIGFzeW5jaHJvbm91cyBvcGVyYXRpb25zLlxuICpcbiAqIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBQcm9taXNlcy9BKyBzcGVjaWZpY2F0aW9uIGFuZFxuICogcGFzc2VzIHRoYXQgc3BlY2lmaWNhdGlvbidzIGNvbmZvcm1hbmNlIHRlc3Qgc3VpdGUuIEEgQ2xvc3VyZSBQcm9taXNlIG1heSBiZVxuICogcmVzb2x2ZWQgd2l0aCBhIFByb21pc2UgaW5zdGFuY2UgKG9yIHN1ZmZpY2llbnRseSBjb21wYXRpYmxlIFByb21pc2UtbGlrZVxuICogb2JqZWN0KSBjcmVhdGVkIGJ5IG90aGVyIFByb21pc2UgaW1wbGVtZW50YXRpb25zLiBGcm9tIHRoZSBzcGVjaWZpY2F0aW9uLFxuICogUHJvbWlzZS1saWtlIG9iamVjdHMgYXJlIGtub3duIGFzIFwiVGhlbmFibGVzXCIuXG4gKlxuICogQHNlZSBodHRwOi8vcHJvbWlzZXNhcGx1cy5jb20vXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbihcbiAqICAgICAgICAgICAgIHRoaXM6UkVTT0xWRVJfQ09OVEVYVCxcbiAqICAgICAgICAgICAgIGZ1bmN0aW9uKChUWVBFfElUaGVuYWJsZS48VFlQRT58VGhlbmFibGUpKSxcbiAqICAgICAgICAgICAgIGZ1bmN0aW9uKCopKTogdm9pZH0gcmVzb2x2ZXJcbiAqICAgICBJbml0aWFsaXphdGlvbiBmdW5jdGlvbiB0aGF0IGlzIGludm9rZWQgaW1tZWRpYXRlbHkgd2l0aCB7QGNvZGUgcmVzb2x2ZX1cbiAqICAgICBhbmQge0Bjb2RlIHJlamVjdH0gZnVuY3Rpb25zIGFzIGFyZ3VtZW50cy4gVGhlIFByb21pc2UgaXMgcmVzb2x2ZWQgb3JcbiAqICAgICByZWplY3RlZCB3aXRoIHRoZSBmaXJzdCBhcmd1bWVudCBwYXNzZWQgdG8gZWl0aGVyIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtSRVNPTFZFUl9DT05URVhUPX0gb3B0X2NvbnRleHQgQW4gb3B0aW9uYWwgY29udGV4dCBmb3IgZXhlY3V0aW5nIHRoZVxuICogICAgIHJlc29sdmVyIGZ1bmN0aW9uLiBJZiB1bnNwZWNpZmllZCwgdGhlIHJlc29sdmVyIGZ1bmN0aW9uIHdpbGwgYmUgZXhlY3V0ZWRcbiAqICAgICBpbiB0aGUgZGVmYXVsdCBzY29wZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHN0cnVjdFxuICogQGZpbmFsXG4gKiBAaW1wbGVtZW50cyB7VGhlbmFibGUuPFRZUEU+fVxuICogQHRlbXBsYXRlIFRZUEUsUkVTT0xWRVJfQ09OVEVYVFxuICovXG52YXIgQ2FuY2VsbGFibGVQcm9taXNlID0gZnVuY3Rpb24ocmVzb2x2ZXIsIG9wdF9jb250ZXh0KSB7XG4gIC8qKlxuICAgKiBUaGUgaW50ZXJuYWwgc3RhdGUgb2YgdGhpcyBQcm9taXNlLiBFaXRoZXIgUEVORElORywgRlVMRklMTEVELCBSRUpFQ1RFRCwgb3JcbiAgICogQkxPQ0tFRC5cbiAgICogQHByaXZhdGUge0NhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV99XG4gICAqL1xuICB0aGlzLnN0YXRlXyA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORztcblxuICAvKipcbiAgICogVGhlIHJlc29sdmVkIHJlc3VsdCBvZiB0aGUgUHJvbWlzZS4gSW1tdXRhYmxlIG9uY2Ugc2V0IHdpdGggZWl0aGVyIGFcbiAgICogZnVsZmlsbG1lbnQgdmFsdWUgb3IgcmVqZWN0aW9uIHJlYXNvbi5cbiAgICogQHByaXZhdGUgeyp9XG4gICAqL1xuICB0aGlzLnJlc3VsdF8gPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEZvciBQcm9taXNlcyBjcmVhdGVkIGJ5IGNhbGxpbmcge0Bjb2RlIHRoZW4oKX0sIHRoZSBvcmlnaW5hdGluZyBwYXJlbnQuXG4gICAqIEBwcml2YXRlIHtDYW5jZWxsYWJsZVByb21pc2V9XG4gICAqL1xuICB0aGlzLnBhcmVudF8gPSBudWxsO1xuXG4gIC8qKlxuICAgKiBUaGUgbGlzdCBvZiB7QGNvZGUgb25GdWxmaWxsZWR9IGFuZCB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tzIGFkZGVkIHRvXG4gICAqIHRoaXMgUHJvbWlzZSBieSBjYWxscyB0byB7QGNvZGUgdGhlbigpfS5cbiAgICogQHByaXZhdGUge0FycmF5LjxDYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV8+fVxuICAgKi9cbiAgdGhpcy5jYWxsYmFja0VudHJpZXNfID0gbnVsbDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgUHJvbWlzZSBpcyBpbiB0aGUgcXVldWUgb2YgUHJvbWlzZXMgdG8gZXhlY3V0ZS5cbiAgICogQHByaXZhdGUge2Jvb2xlYW59XG4gICAqL1xuICB0aGlzLmV4ZWN1dGluZ18gPSBmYWxzZTtcblxuICBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPiAwKSB7XG4gICAgLyoqXG4gICAgICogQSB0aW1lb3V0IElEIHVzZWQgd2hlbiB0aGUge0Bjb2RlIFVOSEFORExFRF9SRUpFQ1RJT05fREVMQVl9IGlzIGdyZWF0ZXJcbiAgICAgKiB0aGFuIDAgbWlsbGlzZWNvbmRzLiBUaGUgSUQgaXMgc2V0IHdoZW4gdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQsIGFuZFxuICAgICAqIGNsZWFyZWQgb25seSBpZiBhbiB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgaXMgaW52b2tlZCBmb3IgdGhlXG4gICAgICogUHJvbWlzZSAob3Igb25lIG9mIGl0cyBkZXNjZW5kYW50cykgYmVmb3JlIHRoZSBkZWxheSBpcyBleGNlZWRlZC5cbiAgICAgKlxuICAgICAqIElmIHRoZSByZWplY3Rpb24gaXMgbm90IGhhbmRsZWQgYmVmb3JlIHRoZSB0aW1lb3V0IGNvbXBsZXRlcywgdGhlXG4gICAgICogcmVqZWN0aW9uIHJlYXNvbiBpcyBwYXNzZWQgdG8gdGhlIHVuaGFuZGxlZCByZWplY3Rpb24gaGFuZGxlci5cbiAgICAgKiBAcHJpdmF0ZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMudW5oYW5kbGVkUmVqZWN0aW9uSWRfID0gMDtcbiAgfSBlbHNlIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA9PT0gMCkge1xuICAgIC8qKlxuICAgICAqIFdoZW4gdGhlIHtAY29kZSBVTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZfSBpcyBzZXQgdG8gMCBtaWxsaXNlY29uZHMsIGFcbiAgICAgKiBib29sZWFuIHRoYXQgaXMgc2V0IGlmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBhbmQgcmVzZXQgdG8gZmFsc2UgaWYgYW5cbiAgICAgKiB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgaXMgaW52b2tlZCBmb3IgdGhlIFByb21pc2UgKG9yIG9uZSBvZiBpdHNcbiAgICAgKiBkZXNjZW5kYW50cykuIElmIHRoZSByZWplY3Rpb24gaXMgbm90IGhhbmRsZWQgYmVmb3JlIHRoZSBuZXh0IHRpbWVzdGVwLFxuICAgICAqIHRoZSByZWplY3Rpb24gcmVhc29uIGlzIHBhc3NlZCB0byB0aGUgdW5oYW5kbGVkIHJlamVjdGlvbiBoYW5kbGVyLlxuICAgICAqIEBwcml2YXRlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMuaGFkVW5oYW5kbGVkUmVqZWN0aW9uXyA9IGZhbHNlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgcmVzb2x2ZXIuY2FsbChcbiAgICAgIG9wdF9jb250ZXh0LCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBzZWxmLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uRlVMRklMTEVELCB2YWx1ZSk7XG4gICAgICB9LCBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAgICAgc2VsZi5yZXNvbHZlXyhDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVELCByZWFzb24pO1xuICAgICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQsIGUpO1xuICB9XG59O1xuXG4vKipcbiAqIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIGEgcmVqZWN0ZWQgUHJvbWlzZSdzIHJlYXNvbiBpcyBwYXNzZWQgdG9cbiAqIHRoZSByZWplY3Rpb24gaGFuZGxlci4gQnkgZGVmYXVsdCwgdGhlIHJlamVjdGlvbiBoYW5kbGVyIHJldGhyb3dzIHRoZVxuICogcmVqZWN0aW9uIHJlYXNvbiBzbyB0aGF0IGl0IGFwcGVhcnMgaW4gdGhlIGRldmVsb3BlciBjb25zb2xlIG9yXG4gKiB7QGNvZGUgd2luZG93Lm9uZXJyb3J9IGhhbmRsZXIuXG4gKiBSZWplY3Rpb25zIGFyZSByZXRocm93biBhcyBxdWlja2x5IGFzIHBvc3NpYmxlIGJ5IGRlZmF1bHQuIEEgbmVnYXRpdmUgdmFsdWVcbiAqIGRpc2FibGVzIHJlamVjdGlvbiBoYW5kbGluZyBlbnRpcmVseS5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID0gMDtcblxuXG4vKipcbiAqIFRoZSBwb3NzaWJsZSBpbnRlcm5hbCBzdGF0ZXMgZm9yIGEgUHJvbWlzZS4gVGhlc2Ugc3RhdGVzIGFyZSBub3QgZGlyZWN0bHlcbiAqIG9ic2VydmFibGUgdG8gZXh0ZXJuYWwgY2FsbGVycy5cbiAqIEBlbnVtIHtudW1iZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfID0ge1xuICAvKiogVGhlIFByb21pc2UgaXMgd2FpdGluZyBmb3IgcmVzb2x1dGlvbi4gKi9cbiAgUEVORElORzogMCxcblxuICAvKiogVGhlIFByb21pc2UgaXMgYmxvY2tlZCB3YWl0aW5nIGZvciB0aGUgcmVzdWx0IG9mIGFub3RoZXIgVGhlbmFibGUuICovXG4gIEJMT0NLRUQ6IDEsXG5cbiAgLyoqIFRoZSBQcm9taXNlIGhhcyBiZWVuIHJlc29sdmVkIHdpdGggYSBmdWxmaWxsbWVudCB2YWx1ZS4gKi9cbiAgRlVMRklMTEVEOiAyLFxuXG4gIC8qKiBUaGUgUHJvbWlzZSBoYXMgYmVlbiByZXNvbHZlZCB3aXRoIGEgcmVqZWN0aW9uIHJlYXNvbi4gKi9cbiAgUkVKRUNURUQ6IDNcbn07XG5cblxuLyoqXG4gKiBUeXBlZGVmIGZvciBlbnRyaWVzIGluIHRoZSBjYWxsYmFjayBjaGFpbi4gRWFjaCBjYWxsIHRvIHtAY29kZSB0aGVufSxcbiAqIHtAY29kZSB0aGVuQ2F0Y2h9LCBvciB7QGNvZGUgdGhlbkFsd2F5c30gY3JlYXRlcyBhbiBlbnRyeSBjb250YWluaW5nIHRoZVxuICogZnVuY3Rpb25zIHRoYXQgbWF5IGJlIGludm9rZWQgb25jZSB0aGUgUHJvbWlzZSBpcyByZXNvbHZlZC5cbiAqXG4gKiBAdHlwZWRlZiB7e1xuICogICBjaGlsZDogQ2FuY2VsbGFibGVQcm9taXNlLFxuICogICBvbkZ1bGZpbGxlZDogZnVuY3Rpb24oKiksXG4gKiAgIG9uUmVqZWN0ZWQ6IGZ1bmN0aW9uKCopXG4gKiB9fVxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLkNhbGxiYWNrRW50cnlfID0gbnVsbDtcblxuXG4vKipcbiAqIEBwYXJhbSB7KFRZUEV8VGhlbmFibGUuPFRZUEU+fFRoZW5hYmxlKT19IG9wdF92YWx1ZVxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48VFlQRT59IEEgbmV3IFByb21pc2UgdGhhdCBpcyBpbW1lZGlhdGVseSByZXNvbHZlZFxuICogICAgIHdpdGggdGhlIGdpdmVuIHZhbHVlLlxuICogQHRlbXBsYXRlIFRZUEVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUgPSBmdW5jdGlvbihvcHRfdmFsdWUpIHtcbiAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZShvcHRfdmFsdWUpO1xuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Kj19IG9wdF9yZWFzb25cbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9IEEgbmV3IFByb21pc2UgdGhhdCBpcyBpbW1lZGlhdGVseSByZWplY3RlZCB3aXRoIHRoZVxuICogICAgIGdpdmVuIHJlYXNvbi5cbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnJlamVjdCA9IGZ1bmN0aW9uKG9wdF9yZWFzb24pIHtcbiAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICByZWplY3Qob3B0X3JlYXNvbik7XG4gICAgfSk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHshQXJyYXkuPCEoVGhlbmFibGUuPFRZUEU+fFRoZW5hYmxlKT59IHByb21pc2VzXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlLjxUWVBFPn0gQSBQcm9taXNlIHRoYXQgcmVjZWl2ZXMgdGhlIHJlc3VsdCBvZiB0aGVcbiAqICAgICBmaXJzdCBQcm9taXNlIChvciBQcm9taXNlLWxpa2UpIGlucHV0IHRvIGNvbXBsZXRlLlxuICogQHRlbXBsYXRlIFRZUEVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnJhY2UgPSBmdW5jdGlvbihwcm9taXNlcykge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIGlmICghcHJvbWlzZXMubGVuZ3RoKSB7XG4gICAgICAgIHJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwLCBwcm9taXNlOyAocHJvbWlzZSA9IHByb21pc2VzW2ldKTsgaSsrKSB7XG4gICAgICAgIHByb21pc2UudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7IUFycmF5LjwhKFRoZW5hYmxlLjxUWVBFPnxUaGVuYWJsZSk+fSBwcm9taXNlc1xuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48IUFycmF5LjxUWVBFPj59IEEgUHJvbWlzZSB0aGF0IHJlY2VpdmVzIGEgbGlzdCBvZlxuICogICAgIGV2ZXJ5IGZ1bGZpbGxlZCB2YWx1ZSBvbmNlIGV2ZXJ5IGlucHV0IFByb21pc2UgKG9yIFByb21pc2UtbGlrZSkgaXNcbiAqICAgICBzdWNjZXNzZnVsbHkgZnVsZmlsbGVkLCBvciBpcyByZWplY3RlZCBieSB0aGUgZmlyc3QgcmVqZWN0aW9uIHJlc3VsdC5cbiAqIEB0ZW1wbGF0ZSBUWVBFXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5hbGwgPSBmdW5jdGlvbihwcm9taXNlcykge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciB0b0Z1bGZpbGwgPSBwcm9taXNlcy5sZW5ndGg7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG5cbiAgICAgIGlmICghdG9GdWxmaWxsKSB7XG4gICAgICAgIHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgb25GdWxmaWxsID0gZnVuY3Rpb24oaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIHRvRnVsZmlsbC0tO1xuICAgICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgIGlmICh0b0Z1bGZpbGwgPT09IDApIHtcbiAgICAgICAgICByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHZhciBvblJlamVjdCA9IGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgIH07XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBwcm9taXNlOyAocHJvbWlzZSA9IHByb21pc2VzW2ldKTsgaSsrKSB7XG4gICAgICAgIHByb21pc2UudGhlbihwYXJ0aWFsKG9uRnVsZmlsbCwgaSksIG9uUmVqZWN0KTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0geyFBcnJheS48IShUaGVuYWJsZS48VFlQRT58VGhlbmFibGUpPn0gcHJvbWlzZXNcbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPFRZUEU+fSBBIFByb21pc2UgdGhhdCByZWNlaXZlcyB0aGUgdmFsdWUgb2ZcbiAqICAgICB0aGUgZmlyc3QgaW5wdXQgdG8gYmUgZnVsZmlsbGVkLCBvciBpcyByZWplY3RlZCB3aXRoIGEgbGlzdCBvZiBldmVyeVxuICogICAgIHJlamVjdGlvbiByZWFzb24gaWYgYWxsIGlucHV0cyBhcmUgcmVqZWN0ZWQuXG4gKiBAdGVtcGxhdGUgVFlQRVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuZmlyc3RGdWxmaWxsZWQgPSBmdW5jdGlvbihwcm9taXNlcykge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciB0b1JlamVjdCA9IHByb21pc2VzLmxlbmd0aDtcbiAgICAgIHZhciByZWFzb25zID0gW107XG5cbiAgICAgIGlmICghdG9SZWplY3QpIHtcbiAgICAgICAgcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBvbkZ1bGZpbGwgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBvblJlamVjdCA9IGZ1bmN0aW9uKGluZGV4LCByZWFzb24pIHtcbiAgICAgICAgdG9SZWplY3QtLTtcbiAgICAgICAgcmVhc29uc1tpbmRleF0gPSByZWFzb247XG4gICAgICAgIGlmICh0b1JlamVjdCA9PT0gMCkge1xuICAgICAgICAgIHJlamVjdChyZWFzb25zKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIHByb21pc2U7IChwcm9taXNlID0gcHJvbWlzZXNbaV0pOyBpKyspIHtcbiAgICAgICAgcHJvbWlzZS50aGVuKG9uRnVsZmlsbCwgcGFydGlhbChvblJlamVjdCwgaSkpO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEFkZHMgY2FsbGJhY2tzIHRoYXQgd2lsbCBvcGVyYXRlIG9uIHRoZSByZXN1bHQgb2YgdGhlIFByb21pc2UsIHJldHVybmluZyBhXG4gKiBuZXcgY2hpbGQgUHJvbWlzZS5cbiAqXG4gKiBJZiB0aGUgUHJvbWlzZSBpcyBmdWxmaWxsZWQsIHRoZSB7QGNvZGUgb25GdWxmaWxsZWR9IGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZFxuICogd2l0aCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgYXMgYXJndW1lbnQsIGFuZCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlXG4gKiBmdWxmaWxsZWQgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjay4gSWYgdGhlIGNhbGxiYWNrIHRocm93cyBhblxuICogZXhjZXB0aW9uLCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHRocm93biB2YWx1ZSBpbnN0ZWFkLlxuICpcbiAqIElmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCB0aGUge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZFxuICogd2l0aCB0aGUgcmVqZWN0aW9uIHJlYXNvbiBhcyBhcmd1bWVudCwgYW5kIHRoZSBjaGlsZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWRcbiAqIHdpdGggdGhlIHJldHVybiB2YWx1ZSAob3IgdGhyb3duIHZhbHVlKSBvZiB0aGUgY2FsbGJhY2suXG4gKlxuICogQG92ZXJyaWRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbiA9IGZ1bmN0aW9uKG9wdF9vbkZ1bGZpbGxlZCwgb3B0X29uUmVqZWN0ZWQsIG9wdF9jb250ZXh0KSB7XG4gIHJldHVybiB0aGlzLmFkZENoaWxkUHJvbWlzZV8oXG4gICAgaXNGdW5jdGlvbihvcHRfb25GdWxmaWxsZWQpID8gb3B0X29uRnVsZmlsbGVkIDogbnVsbCxcbiAgICBpc0Z1bmN0aW9uKG9wdF9vblJlamVjdGVkKSA/IG9wdF9vblJlamVjdGVkIDogbnVsbCxcbiAgICBvcHRfY29udGV4dCk7XG59O1xuVGhlbmFibGUuYWRkSW1wbGVtZW50YXRpb24oQ2FuY2VsbGFibGVQcm9taXNlKTtcblxuXG4vKipcbiAqIEFkZHMgYSBjYWxsYmFjayB0aGF0IHdpbGwgYmUgaW52b2tlZCB3aGV0aGVyIHRoZSBQcm9taXNlIGlzIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQuIFRoZSBjYWxsYmFjayByZWNlaXZlcyBubyBhcmd1bWVudCwgYW5kIG5vIG5ldyBjaGlsZCBQcm9taXNlIGlzXG4gKiBjcmVhdGVkLiBUaGlzIGlzIHVzZWZ1bCBmb3IgZW5zdXJpbmcgdGhhdCBjbGVhbnVwIHRha2VzIHBsYWNlIGFmdGVyIGNlcnRhaW5cbiAqIGFzeW5jaHJvbm91cyBvcGVyYXRpb25zLiBDYWxsYmFja3MgYWRkZWQgd2l0aCB7QGNvZGUgdGhlbkFsd2F5c30gd2lsbCBiZVxuICogZXhlY3V0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgd2l0aCBvdGhlciBjYWxscyB0byB7QGNvZGUgdGhlbn0sXG4gKiB7QGNvZGUgdGhlbkFsd2F5c30sIG9yIHtAY29kZSB0aGVuQ2F0Y2h9LlxuICpcbiAqIFNpbmNlIGl0IGRvZXMgbm90IHByb2R1Y2UgYSBuZXcgY2hpbGQgUHJvbWlzZSwgY2FuY2VsbGF0aW9uIHByb3BhZ2F0aW9uIGlzXG4gKiBub3QgcHJldmVudGVkIGJ5IGFkZGluZyBjYWxsYmFja3Mgd2l0aCB7QGNvZGUgdGhlbkFsd2F5c30uIEEgUHJvbWlzZSB0aGF0IGhhc1xuICogYSBjbGVhbnVwIGhhbmRsZXIgYWRkZWQgd2l0aCB7QGNvZGUgdGhlbkFsd2F5c30gd2lsbCBiZSBjYW5jZWxlZCBpZiBhbGwgb2ZcbiAqIGl0cyBjaGlsZHJlbiBjcmVhdGVkIGJ5IHtAY29kZSB0aGVufSAob3Ige0Bjb2RlIHRoZW5DYXRjaH0pIGFyZSBjYW5jZWxlZC5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6VEhJUyk6IHZvaWR9IG9uUmVzb2x2ZWQgQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgaW52b2tlZFxuICogICAgIHdoZW4gdGhlIFByb21pc2UgaXMgcmVzb2x2ZWQuXG4gKiBAcGFyYW0ge1RISVM9fSBvcHRfY29udGV4dCBBbiBvcHRpb25hbCBjb250ZXh0IG9iamVjdCB0aGF0IHdpbGwgYmUgdGhlXG4gKiAgICAgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRoZSBjYWxsYmFja3MuIEJ5IGRlZmF1bHQsIGZ1bmN0aW9ucyBhcmUgZXhlY3V0ZWRcbiAqICAgICBpbiB0aGUgZ2xvYmFsIHNjb3BlLlxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48VFlQRT59IFRoaXMgUHJvbWlzZSwgZm9yIGNoYWluaW5nIGFkZGl0aW9uYWwgY2FsbHMuXG4gKiBAdGVtcGxhdGUgVEhJU1xuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRoZW5BbHdheXMgPSBmdW5jdGlvbihvblJlc29sdmVkLCBvcHRfY29udGV4dCkge1xuICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgLy8gRW5zdXJlIHRoYXQgbm8gYXJndW1lbnRzIGFyZSBwYXNzZWQgdG8gb25SZXNvbHZlZC5cbiAgICAgIG9uUmVzb2x2ZWQuY2FsbChvcHRfY29udGV4dCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBDYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXy5jYWxsKG51bGwsIGVycik7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuYWRkQ2FsbGJhY2tFbnRyeV8oe1xuICAgIGNoaWxkOiBudWxsLFxuICAgIG9uUmVqZWN0ZWQ6IGNhbGxiYWNrLFxuICAgIG9uRnVsZmlsbGVkOiBjYWxsYmFja1xuICB9KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbi8qKlxuICogQWRkcyBhIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBpbnZva2VkIG9ubHkgaWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQuIFRoaXNcbiAqIGlzIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHRoZW4obnVsbCwgb25SZWplY3RlZCl9LlxuICpcbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKHRoaXM6VEhJUywgKik6ICp9IG9uUmVqZWN0ZWQgQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmVcbiAqICAgICBpbnZva2VkIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb24gaWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQuXG4gKiBAcGFyYW0ge1RISVM9fSBvcHRfY29udGV4dCBBbiBvcHRpb25hbCBjb250ZXh0IG9iamVjdCB0aGF0IHdpbGwgYmUgdGhlXG4gKiAgICAgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRoZSBjYWxsYmFja3MuIEJ5IGRlZmF1bHQsIGZ1bmN0aW9ucyBhcmUgZXhlY3V0ZWRcbiAqICAgICBpbiB0aGUgZ2xvYmFsIHNjb3BlLlxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gQSBuZXcgUHJvbWlzZSB0aGF0IHdpbGwgcmVjZWl2ZSB0aGUgcmVzdWx0IG9mIHRoZVxuICogICAgIGNhbGxiYWNrLlxuICogQHRlbXBsYXRlIFRISVNcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50aGVuQ2F0Y2ggPSBmdW5jdGlvbihvblJlamVjdGVkLCBvcHRfY29udGV4dCkge1xuICByZXR1cm4gdGhpcy5hZGRDaGlsZFByb21pc2VfKG51bGwsIG9uUmVqZWN0ZWQsIG9wdF9jb250ZXh0KTtcbn07XG5cbi8qKlxuICogQWxpYXMgb2Yge0BsaW5rIENhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbkNhdGNofVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmNhdGNoID0gQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50aGVuQ2F0Y2g7XG5cblxuLyoqXG4gKiBDYW5jZWxzIHRoZSBQcm9taXNlIGlmIGl0IGlzIHN0aWxsIHBlbmRpbmcgYnkgcmVqZWN0aW5nIGl0IHdpdGggYSBjYW5jZWxcbiAqIEVycm9yLiBObyBhY3Rpb24gaXMgcGVyZm9ybWVkIGlmIHRoZSBQcm9taXNlIGlzIGFscmVhZHkgcmVzb2x2ZWQuXG4gKlxuICogQWxsIGNoaWxkIFByb21pc2VzIG9mIHRoZSBjYW5jZWxlZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgc2FtZVxuICogY2FuY2VsIGVycm9yLCBhcyB3aXRoIG5vcm1hbCBQcm9taXNlIHJlamVjdGlvbi4gSWYgdGhlIFByb21pc2UgdG8gYmUgY2FuY2VsZWRcbiAqIGlzIHRoZSBvbmx5IGNoaWxkIG9mIGEgcGVuZGluZyBQcm9taXNlLCB0aGUgcGFyZW50IFByb21pc2Ugd2lsbCBhbHNvIGJlXG4gKiBjYW5jZWxlZC4gQ2FuY2VsbGF0aW9uIG1heSBwcm9wYWdhdGUgdXB3YXJkIHRocm91Z2ggbXVsdGlwbGUgZ2VuZXJhdGlvbnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfbWVzc2FnZSBBbiBvcHRpb25hbCBkZWJ1Z2dpbmcgbWVzc2FnZSBmb3IgZGVzY3JpYmluZyB0aGVcbiAqICAgICBjYW5jZWxsYXRpb24gcmVhc29uLlxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uKG9wdF9tZXNzYWdlKSB7XG4gIGlmICh0aGlzLnN0YXRlXyA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HKSB7XG4gICAgYXN5bmMucnVuKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVyciA9IG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3Iob3B0X21lc3NhZ2UpO1xuICAgICAgZXJyLklTX0NBTkNFTExBVElPTl9FUlJPUiA9IHRydWU7XG4gICAgICB0aGlzLmNhbmNlbEludGVybmFsXyhlcnIpO1xuICAgIH0sIHRoaXMpO1xuICB9XG59O1xuXG5cbi8qKlxuICogQ2FuY2VscyB0aGlzIFByb21pc2Ugd2l0aCB0aGUgZ2l2ZW4gZXJyb3IuXG4gKlxuICogQHBhcmFtIHshRXJyb3J9IGVyciBUaGUgY2FuY2VsbGF0aW9uIGVycm9yLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5jYW5jZWxJbnRlcm5hbF8gPSBmdW5jdGlvbihlcnIpIHtcbiAgaWYgKHRoaXMuc3RhdGVfID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkcpIHtcbiAgICBpZiAodGhpcy5wYXJlbnRfKSB7XG4gICAgICAvLyBDYW5jZWwgdGhlIFByb21pc2UgYW5kIHJlbW92ZSBpdCBmcm9tIHRoZSBwYXJlbnQncyBjaGlsZCBsaXN0LlxuICAgICAgdGhpcy5wYXJlbnRfLmNhbmNlbENoaWxkXyh0aGlzLCBlcnIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQsIGVycik7XG4gICAgfVxuICB9XG59O1xuXG5cbi8qKlxuICogQ2FuY2VscyBhIGNoaWxkIFByb21pc2UgZnJvbSB0aGUgbGlzdCBvZiBjYWxsYmFjayBlbnRyaWVzLiBJZiB0aGUgUHJvbWlzZSBoYXNcbiAqIG5vdCBhbHJlYWR5IGJlZW4gcmVzb2x2ZWQsIHJlamVjdCBpdCB3aXRoIGEgY2FuY2VsIGVycm9yLiBJZiB0aGVyZSBhcmUgbm9cbiAqIG90aGVyIGNoaWxkcmVuIGluIHRoZSBsaXN0IG9mIGNhbGxiYWNrIGVudHJpZXMsIHByb3BhZ2F0ZSB0aGUgY2FuY2VsbGF0aW9uXG4gKiBieSBjYW5jZWxpbmcgdGhpcyBQcm9taXNlIGFzIHdlbGwuXG4gKlxuICogQHBhcmFtIHshQ2FuY2VsbGFibGVQcm9taXNlfSBjaGlsZFByb21pc2UgVGhlIFByb21pc2UgdG8gY2FuY2VsLlxuICogQHBhcmFtIHshRXJyb3J9IGVyciBUaGUgY2FuY2VsIGVycm9yIHRvIHVzZSBmb3IgcmVqZWN0aW5nIHRoZSBQcm9taXNlLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5jYW5jZWxDaGlsZF8gPSBmdW5jdGlvbihjaGlsZFByb21pc2UsIGVycikge1xuICBpZiAoIXRoaXMuY2FsbGJhY2tFbnRyaWVzXykge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgY2hpbGRDb3VudCA9IDA7XG4gIHZhciBjaGlsZEluZGV4ID0gLTE7XG5cbiAgLy8gRmluZCB0aGUgY2FsbGJhY2sgZW50cnkgZm9yIHRoZSBjaGlsZFByb21pc2UsIGFuZCBjb3VudCB3aGV0aGVyIHRoZXJlIGFyZVxuICAvLyBhZGRpdGlvbmFsIGNoaWxkIFByb21pc2VzLlxuICBmb3IgKHZhciBpID0gMCwgZW50cnk7IChlbnRyeSA9IHRoaXMuY2FsbGJhY2tFbnRyaWVzX1tpXSk7IGkrKykge1xuICAgIHZhciBjaGlsZCA9IGVudHJ5LmNoaWxkO1xuICAgIGlmIChjaGlsZCkge1xuICAgICAgY2hpbGRDb3VudCsrO1xuICAgICAgaWYgKGNoaWxkID09PSBjaGlsZFByb21pc2UpIHtcbiAgICAgICAgY2hpbGRJbmRleCA9IGk7XG4gICAgICB9XG4gICAgICBpZiAoY2hpbGRJbmRleCA+PSAwICYmIGNoaWxkQ291bnQgPiAxKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIElmIHRoZSBjaGlsZCBQcm9taXNlIHdhcyB0aGUgb25seSBjaGlsZCwgY2FuY2VsIHRoaXMgUHJvbWlzZSBhcyB3ZWxsLlxuICAvLyBPdGhlcndpc2UsIHJlamVjdCBvbmx5IHRoZSBjaGlsZCBQcm9taXNlIHdpdGggdGhlIGNhbmNlbCBlcnJvci5cbiAgaWYgKGNoaWxkSW5kZXggPj0gMCkge1xuICAgIGlmICh0aGlzLnN0YXRlXyA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HICYmIGNoaWxkQ291bnQgPT09IDEpIHtcbiAgICAgIHRoaXMuY2FuY2VsSW50ZXJuYWxfKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBjYWxsYmFja0VudHJ5ID0gdGhpcy5jYWxsYmFja0VudHJpZXNfLnNwbGljZShjaGlsZEluZGV4LCAxKVswXTtcbiAgICAgIHRoaXMuZXhlY3V0ZUNhbGxiYWNrXyhcbiAgICAgICAgY2FsbGJhY2tFbnRyeSwgQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCwgZXJyKTtcbiAgICB9XG4gIH1cbn07XG5cblxuLyoqXG4gKiBBZGRzIGEgY2FsbGJhY2sgZW50cnkgdG8gdGhlIGN1cnJlbnQgUHJvbWlzZSwgYW5kIHNjaGVkdWxlcyBjYWxsYmFja1xuICogZXhlY3V0aW9uIGlmIHRoZSBQcm9taXNlIGhhcyBhbHJlYWR5IGJlZW4gcmVzb2x2ZWQuXG4gKlxuICogQHBhcmFtIHtDYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV99IGNhbGxiYWNrRW50cnkgUmVjb3JkIGNvbnRhaW5pbmdcbiAqICAgICB7QGNvZGUgb25GdWxmaWxsZWR9IGFuZCB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tzIHRvIGV4ZWN1dGUgYWZ0ZXJcbiAqICAgICB0aGUgUHJvbWlzZSBpcyByZXNvbHZlZC5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuYWRkQ2FsbGJhY2tFbnRyeV8gPSBmdW5jdGlvbihjYWxsYmFja0VudHJ5KSB7XG4gIGlmICgoIXRoaXMuY2FsbGJhY2tFbnRyaWVzXyB8fCAhdGhpcy5jYWxsYmFja0VudHJpZXNfLmxlbmd0aCkgJiZcbiAgICAodGhpcy5zdGF0ZV8gPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uRlVMRklMTEVEIHx8XG4gICAgdGhpcy5zdGF0ZV8gPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQpKSB7XG4gICAgdGhpcy5zY2hlZHVsZUNhbGxiYWNrc18oKTtcbiAgfVxuICBpZiAoIXRoaXMuY2FsbGJhY2tFbnRyaWVzXykge1xuICAgIHRoaXMuY2FsbGJhY2tFbnRyaWVzXyA9IFtdO1xuICB9XG4gIHRoaXMuY2FsbGJhY2tFbnRyaWVzXy5wdXNoKGNhbGxiYWNrRW50cnkpO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYSBjaGlsZCBQcm9taXNlIGFuZCBhZGRzIGl0IHRvIHRoZSBjYWxsYmFjayBlbnRyeSBsaXN0LiBUaGUgcmVzdWx0IG9mXG4gKiB0aGUgY2hpbGQgUHJvbWlzZSBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBzdGF0ZSBvZiB0aGUgcGFyZW50IFByb21pc2UgYW5kIHRoZVxuICogcmVzdWx0IG9mIHRoZSB7QGNvZGUgb25GdWxmaWxsZWR9IG9yIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFja3MgYXNcbiAqIHNwZWNpZmllZCBpbiB0aGUgUHJvbWlzZSByZXNvbHV0aW9uIHByb2NlZHVyZS5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9wcm9taXNlc2FwbHVzLmNvbS8jdGhlX19tZXRob2RcbiAqXG4gKiBAcGFyYW0gez9mdW5jdGlvbih0aGlzOlRISVMsIFRZUEUpOlxuICogICAgICAgICAgKFJFU1VMVHxDYW5jZWxsYWJsZVByb21pc2UuPFJFU1VMVD58VGhlbmFibGUpfSBvbkZ1bGZpbGxlZCBBIGNhbGxiYWNrIHRoYXRcbiAqICAgICB3aWxsIGJlIGludm9rZWQgaWYgdGhlIFByb21pc2UgaXMgZnVsbGZpbGxlZCwgb3IgbnVsbC5cbiAqIEBwYXJhbSB7P2Z1bmN0aW9uKHRoaXM6VEhJUywgKik6ICp9IG9uUmVqZWN0ZWQgQSBjYWxsYmFjayB0aGF0IHdpbGwgYmVcbiAqICAgICBpbnZva2VkIGlmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBvciBudWxsLlxuICogQHBhcmFtIHtUSElTPX0gb3B0X2NvbnRleHQgQW4gb3B0aW9uYWwgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRoZSBjYWxsYmFja3MuXG4gKiAgICAgaW4gdGhlIGRlZmF1bHQgY2FsbGluZyBjb250ZXh0LlxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gVGhlIGNoaWxkIFByb21pc2UuXG4gKiBAdGVtcGxhdGUgUkVTVUxULFRISVNcbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuYWRkQ2hpbGRQcm9taXNlXyA9IGZ1bmN0aW9uKFxub25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9wdF9jb250ZXh0KSB7XG5cbiAgdmFyIGNhbGxiYWNrRW50cnkgPSB7XG4gICAgY2hpbGQ6IG51bGwsXG4gICAgb25GdWxmaWxsZWQ6IG51bGwsXG4gICAgb25SZWplY3RlZDogbnVsbFxuICB9O1xuXG4gIGNhbGxiYWNrRW50cnkuY2hpbGQgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIC8vIEludm9rZSBvbkZ1bGZpbGxlZCwgb3IgcmVzb2x2ZSB3aXRoIHRoZSBwYXJlbnQncyB2YWx1ZSBpZiBhYnNlbnQuXG4gICAgY2FsbGJhY2tFbnRyeS5vbkZ1bGZpbGxlZCA9IG9uRnVsZmlsbGVkID8gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBvbkZ1bGZpbGxlZC5jYWxsKG9wdF9jb250ZXh0LCB2YWx1ZSk7XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgIH1cbiAgICB9IDogcmVzb2x2ZTtcblxuICAgIC8vIEludm9rZSBvblJlamVjdGVkLCBvciByZWplY3Qgd2l0aCB0aGUgcGFyZW50J3MgcmVhc29uIGlmIGFic2VudC5cbiAgICBjYWxsYmFja0VudHJ5Lm9uUmVqZWN0ZWQgPSBvblJlamVjdGVkID8gZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gb25SZWplY3RlZC5jYWxsKG9wdF9jb250ZXh0LCByZWFzb24pO1xuICAgICAgICBpZiAoIWlzRGVmKHJlc3VsdCkgJiYgcmVhc29uLklTX0NBTkNFTExBVElPTl9FUlJPUikge1xuICAgICAgICAgIC8vIFByb3BhZ2F0ZSBjYW5jZWxsYXRpb24gdG8gY2hpbGRyZW4gaWYgbm8gb3RoZXIgcmVzdWx0IGlzIHJldHVybmVkLlxuICAgICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfVxuICAgIH0gOiByZWplY3Q7XG4gIH0pO1xuXG4gIGNhbGxiYWNrRW50cnkuY2hpbGQucGFyZW50XyA9IHRoaXM7XG4gIHRoaXMuYWRkQ2FsbGJhY2tFbnRyeV8oXG4gICAgLyoqIEB0eXBlIHtDYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV99ICovIChjYWxsYmFja0VudHJ5KSk7XG4gIHJldHVybiBjYWxsYmFja0VudHJ5LmNoaWxkO1xufTtcblxuXG4vKipcbiAqIFVuYmxvY2tzIHRoZSBQcm9taXNlIGFuZCBmdWxmaWxscyBpdCB3aXRoIHRoZSBnaXZlbiB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge1RZUEV9IHZhbHVlXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnVuYmxvY2tBbmRGdWxmaWxsXyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGlmICh0aGlzLnN0YXRlXyAhPT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5CTE9DS0VEKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5jZWxsYWJsZVByb21pc2UgaXMgbm90IGJsb2NrZWQuJyk7XG4gIH1cbiAgdGhpcy5zdGF0ZV8gPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkc7XG4gIHRoaXMucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5GVUxGSUxMRUQsIHZhbHVlKTtcbn07XG5cblxuLyoqXG4gKiBVbmJsb2NrcyB0aGUgUHJvbWlzZSBhbmQgcmVqZWN0cyBpdCB3aXRoIHRoZSBnaXZlbiByZWplY3Rpb24gcmVhc29uLlxuICpcbiAqIEBwYXJhbSB7Kn0gcmVhc29uXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnVuYmxvY2tBbmRSZWplY3RfID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gIGlmICh0aGlzLnN0YXRlXyAhPT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5CTE9DS0VEKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5jZWxsYWJsZVByb21pc2UgaXMgbm90IGJsb2NrZWQuJyk7XG4gIH1cbiAgdGhpcy5zdGF0ZV8gPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkc7XG4gIHRoaXMucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCwgcmVhc29uKTtcbn07XG5cblxuLyoqXG4gKiBBdHRlbXB0cyB0byByZXNvbHZlIGEgUHJvbWlzZSB3aXRoIGEgZ2l2ZW4gcmVzb2x1dGlvbiBzdGF0ZSBhbmQgdmFsdWUuIFRoaXNcbiAqIGlzIGEgbm8tb3AgaWYgdGhlIGdpdmVuIFByb21pc2UgaGFzIGFscmVhZHkgYmVlbiByZXNvbHZlZC5cbiAqXG4gKiBJZiB0aGUgZ2l2ZW4gcmVzdWx0IGlzIGEgVGhlbmFibGUgKHN1Y2ggYXMgYW5vdGhlciBQcm9taXNlKSwgdGhlIFByb21pc2Ugd2lsbFxuICogYmUgcmVzb2x2ZWQgd2l0aCB0aGUgc2FtZSBzdGF0ZSBhbmQgcmVzdWx0IGFzIHRoZSBUaGVuYWJsZSBvbmNlIGl0IGlzIGl0c2VsZlxuICogcmVzb2x2ZWQuXG4gKlxuICogSWYgdGhlIGdpdmVuIHJlc3VsdCBpcyBub3QgYSBUaGVuYWJsZSwgdGhlIFByb21pc2Ugd2lsbCBiZSBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkIHdpdGggdGhhdCByZXN1bHQgYmFzZWQgb24gdGhlIGdpdmVuIHN0YXRlLlxuICpcbiAqIEBzZWUgaHR0cDovL3Byb21pc2VzYXBsdXMuY29tLyN0aGVfcHJvbWlzZV9yZXNvbHV0aW9uX3Byb2NlZHVyZVxuICpcbiAqIEBwYXJhbSB7Q2FuY2VsbGFibGVQcm9taXNlLlN0YXRlX30gc3RhdGVcbiAqIEBwYXJhbSB7Kn0geCBUaGUgcmVzdWx0IHRvIGFwcGx5IHRvIHRoZSBQcm9taXNlLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5yZXNvbHZlXyA9IGZ1bmN0aW9uKHN0YXRlLCB4KSB7XG4gIGlmICh0aGlzLnN0YXRlXyAhPT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHRoaXMgPT09IHgpIHtcbiAgICBzdGF0ZSA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQ7XG4gICAgeCA9IG5ldyBUeXBlRXJyb3IoJ0NhbmNlbGxhYmxlUHJvbWlzZSBjYW5ub3QgcmVzb2x2ZSB0byBpdHNlbGYnKTtcblxuICB9IGVsc2UgaWYgKFRoZW5hYmxlLmlzSW1wbGVtZW50ZWRCeSh4KSkge1xuICAgIHggPSAvKiogQHR5cGUgeyFUaGVuYWJsZX0gKi8gKHgpO1xuICAgIHRoaXMuc3RhdGVfID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5CTE9DS0VEO1xuICAgIHgudGhlbih0aGlzLnVuYmxvY2tBbmRGdWxmaWxsXywgdGhpcy51bmJsb2NrQW5kUmVqZWN0XywgdGhpcyk7XG4gICAgcmV0dXJuO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoeCkpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHRoZW4gPSB4LnRoZW47XG4gICAgICBpZiAoaXNGdW5jdGlvbih0aGVuKSkge1xuICAgICAgICB0aGlzLnRyeVRoZW5fKHgsIHRoZW4pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc3RhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVEO1xuICAgICAgeCA9IGU7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5yZXN1bHRfID0geDtcbiAgdGhpcy5zdGF0ZV8gPSBzdGF0ZTtcbiAgdGhpcy5zY2hlZHVsZUNhbGxiYWNrc18oKTtcblxuICBpZiAoc3RhdGUgPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQgJiYgIXguSVNfQ0FOQ0VMTEFUSU9OX0VSUk9SKSB7XG4gICAgQ2FuY2VsbGFibGVQcm9taXNlLmFkZFVuaGFuZGxlZFJlamVjdGlvbl8odGhpcywgeCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBBdHRlbXB0cyB0byBjYWxsIHRoZSB7QGNvZGUgdGhlbn0gbWV0aG9kIG9uIGFuIG9iamVjdCBpbiB0aGUgaG9wZXMgdGhhdCBpdCBpc1xuICogYSBQcm9taXNlLWNvbXBhdGlibGUgaW5zdGFuY2UuIFRoaXMgYWxsb3dzIGludGVyb3BlcmF0aW9uIGJldHdlZW4gZGlmZmVyZW50XG4gKiBQcm9taXNlIGltcGxlbWVudGF0aW9ucywgaG93ZXZlciBhIG5vbi1jb21wbGlhbnQgb2JqZWN0IG1heSBjYXVzZSBhIFByb21pc2VcbiAqIHRvIGhhbmcgaW5kZWZpbml0ZWx5LiBJZiB0aGUge0Bjb2RlIHRoZW59IG1ldGhvZCB0aHJvd3MgYW4gZXhjZXB0aW9uLCB0aGVcbiAqIGRlcGVuZGVudCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgdGhyb3duIHZhbHVlLlxuICpcbiAqIEBzZWUgaHR0cDovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC03MFxuICpcbiAqIEBwYXJhbSB7VGhlbmFibGV9IHRoZW5hYmxlIEFuIG9iamVjdCB3aXRoIGEge0Bjb2RlIHRoZW59IG1ldGhvZCB0aGF0IG1heSBiZVxuICogICAgIGNvbXBhdGlibGUgd2l0aCB0aGUgUHJvbWlzZS9BKyBzcGVjaWZpY2F0aW9uLlxuICogQHBhcmFtIHshRnVuY3Rpb259IHRoZW4gVGhlIHtAY29kZSB0aGVufSBtZXRob2Qgb2YgdGhlIFRoZW5hYmxlIG9iamVjdC5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudHJ5VGhlbl8gPSBmdW5jdGlvbih0aGVuYWJsZSwgdGhlbikge1xuICB0aGlzLnN0YXRlXyA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uQkxPQ0tFRDtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG5cbiAgdmFyIHJlc29sdmUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgcHJvbWlzZS51bmJsb2NrQW5kRnVsZmlsbF8odmFsdWUpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgcmVqZWN0ID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICBwcm9taXNlLnVuYmxvY2tBbmRSZWplY3RfKHJlYXNvbik7XG4gICAgfVxuICB9O1xuXG4gIHRyeSB7XG4gICAgdGhlbi5jYWxsKHRoZW5hYmxlLCByZXNvbHZlLCByZWplY3QpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmVqZWN0KGUpO1xuICB9XG59O1xuXG5cbi8qKlxuICogRXhlY3V0ZXMgdGhlIHBlbmRpbmcgY2FsbGJhY2tzIG9mIGEgcmVzb2x2ZWQgUHJvbWlzZSBhZnRlciBhIHRpbWVvdXQuXG4gKlxuICogU2VjdGlvbiAyLjIuNCBvZiB0aGUgUHJvbWlzZXMvQSsgc3BlY2lmaWNhdGlvbiByZXF1aXJlcyB0aGF0IFByb21pc2VcbiAqIGNhbGxiYWNrcyBtdXN0IG9ubHkgYmUgaW52b2tlZCBmcm9tIGEgY2FsbCBzdGFjayB0aGF0IG9ubHkgY29udGFpbnMgUHJvbWlzZVxuICogaW1wbGVtZW50YXRpb24gY29kZSwgd2hpY2ggd2UgYWNjb21wbGlzaCBieSBpbnZva2luZyBjYWxsYmFjayBleGVjdXRpb24gYWZ0ZXJcbiAqIGEgdGltZW91dC4gSWYge0Bjb2RlIHN0YXJ0RXhlY3V0aW9uX30gaXMgY2FsbGVkIG11bHRpcGxlIHRpbWVzIGZvciB0aGUgc2FtZVxuICogUHJvbWlzZSwgdGhlIGNhbGxiYWNrIGNoYWluIHdpbGwgYmUgZXZhbHVhdGVkIG9ubHkgb25jZS4gQWRkaXRpb25hbCBjYWxsYmFja3NcbiAqIG1heSBiZSBhZGRlZCBkdXJpbmcgdGhlIGV2YWx1YXRpb24gcGhhc2UsIGFuZCB3aWxsIGJlIGV4ZWN1dGVkIGluIHRoZSBzYW1lXG4gKiBldmVudCBsb29wLlxuICpcbiAqIEFsbCBQcm9taXNlcyBhZGRlZCB0byB0aGUgd2FpdGluZyBsaXN0IGR1cmluZyB0aGUgc2FtZSBicm93c2VyIGV2ZW50IGxvb3BcbiAqIHdpbGwgYmUgZXhlY3V0ZWQgaW4gb25lIGJhdGNoIHRvIGF2b2lkIHVzaW5nIGEgc2VwYXJhdGUgdGltZW91dCBwZXIgUHJvbWlzZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnNjaGVkdWxlQ2FsbGJhY2tzXyA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuZXhlY3V0aW5nXykge1xuICAgIHRoaXMuZXhlY3V0aW5nXyA9IHRydWU7XG4gICAgYXN5bmMucnVuKHRoaXMuZXhlY3V0ZUNhbGxiYWNrc18sIHRoaXMpO1xuICB9XG59O1xuXG5cbi8qKlxuICogRXhlY3V0ZXMgYWxsIHBlbmRpbmcgY2FsbGJhY2tzIGZvciB0aGlzIFByb21pc2UuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5leGVjdXRlQ2FsbGJhY2tzXyA9IGZ1bmN0aW9uKCkge1xuICB3aGlsZSAodGhpcy5jYWxsYmFja0VudHJpZXNfICYmIHRoaXMuY2FsbGJhY2tFbnRyaWVzXy5sZW5ndGgpIHtcbiAgICB2YXIgZW50cmllcyA9IHRoaXMuY2FsbGJhY2tFbnRyaWVzXztcbiAgICB0aGlzLmNhbGxiYWNrRW50cmllc18gPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5leGVjdXRlQ2FsbGJhY2tfKGVudHJpZXNbaV0sIHRoaXMuc3RhdGVfLCB0aGlzLnJlc3VsdF8pO1xuICAgIH1cbiAgfVxuICB0aGlzLmV4ZWN1dGluZ18gPSBmYWxzZTtcbn07XG5cblxuLyoqXG4gKiBFeGVjdXRlcyBhIHBlbmRpbmcgY2FsbGJhY2sgZm9yIHRoaXMgUHJvbWlzZS4gSW52b2tlcyBhbiB7QGNvZGUgb25GdWxmaWxsZWR9XG4gKiBvciB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgYmFzZWQgb24gdGhlIHJlc29sdmVkIHN0YXRlIG9mIHRoZSBQcm9taXNlLlxuICpcbiAqIEBwYXJhbSB7IUNhbmNlbGxhYmxlUHJvbWlzZS5DYWxsYmFja0VudHJ5X30gY2FsbGJhY2tFbnRyeSBBbiBlbnRyeSBjb250YWluaW5nIHRoZVxuICogICAgIG9uRnVsZmlsbGVkIGFuZC9vciBvblJlamVjdGVkIGNhbGxiYWNrcyBmb3IgdGhpcyBzdGVwLlxuICogQHBhcmFtIHtDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVffSBzdGF0ZSBUaGUgcmVzb2x1dGlvbiBzdGF0dXMgb2YgdGhlIFByb21pc2UsXG4gKiAgICAgZWl0aGVyIEZVTEZJTExFRCBvciBSRUpFQ1RFRC5cbiAqIEBwYXJhbSB7Kn0gcmVzdWx0IFRoZSByZXNvbHZlZCByZXN1bHQgb2YgdGhlIFByb21pc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmV4ZWN1dGVDYWxsYmFja18gPSBmdW5jdGlvbihcbmNhbGxiYWNrRW50cnksIHN0YXRlLCByZXN1bHQpIHtcbiAgaWYgKHN0YXRlID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkZVTEZJTExFRCkge1xuICAgIGNhbGxiYWNrRW50cnkub25GdWxmaWxsZWQocmVzdWx0KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnJlbW92ZVVuaGFuZGxlZFJlamVjdGlvbl8oKTtcbiAgICBjYWxsYmFja0VudHJ5Lm9uUmVqZWN0ZWQocmVzdWx0KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIE1hcmtzIHRoaXMgcmVqZWN0ZWQgUHJvbWlzZSBhcyBoYXZpbmcgYmVpbmcgaGFuZGxlZC4gQWxzbyBtYXJrcyBhbnkgcGFyZW50XG4gKiBQcm9taXNlcyBpbiB0aGUgcmVqZWN0ZWQgc3RhdGUgYXMgaGFuZGxlZC4gVGhlIHJlamVjdGlvbiBoYW5kbGVyIHdpbGwgbm9cbiAqIGxvbmdlciBiZSBpbnZva2VkIGZvciB0aGlzIFByb21pc2UgKGlmIGl0IGhhcyBub3QgYmVlbiBjYWxsZWQgYWxyZWFkeSkuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5yZW1vdmVVbmhhbmRsZWRSZWplY3Rpb25fID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwO1xuICBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPiAwKSB7XG4gICAgZm9yIChwID0gdGhpczsgcCAmJiBwLnVuaGFuZGxlZFJlamVjdGlvbklkXzsgcCA9IHAucGFyZW50Xykge1xuICAgICAgY2xlYXJUaW1lb3V0KHAudW5oYW5kbGVkUmVqZWN0aW9uSWRfKTtcbiAgICAgIHAudW5oYW5kbGVkUmVqZWN0aW9uSWRfID0gMDtcbiAgICB9XG4gIH0gZWxzZSBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPT09IDApIHtcbiAgICBmb3IgKHAgPSB0aGlzOyBwICYmIHAuaGFkVW5oYW5kbGVkUmVqZWN0aW9uXzsgcCA9IHAucGFyZW50Xykge1xuICAgICAgcC5oYWRVbmhhbmRsZWRSZWplY3Rpb25fID0gZmFsc2U7XG4gICAgfVxuICB9XG59O1xuXG5cbi8qKlxuICogTWFya3MgdGhpcyByZWplY3RlZCBQcm9taXNlIGFzIHVuaGFuZGxlZC4gSWYgbm8ge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrXG4gKiBpcyBjYWxsZWQgZm9yIHRoaXMgUHJvbWlzZSBiZWZvcmUgdGhlIHtAY29kZSBVTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZfVxuICogZXhwaXJlcywgdGhlIHJlYXNvbiB3aWxsIGJlIHBhc3NlZCB0byB0aGUgdW5oYW5kbGVkIHJlamVjdGlvbiBoYW5kbGVyLiBUaGVcbiAqIGhhbmRsZXIgdHlwaWNhbGx5IHJldGhyb3dzIHRoZSByZWplY3Rpb24gcmVhc29uIHNvIHRoYXQgaXQgYmVjb21lcyB2aXNpYmxlIGluXG4gKiB0aGUgZGV2ZWxvcGVyIGNvbnNvbGUuXG4gKlxuICogQHBhcmFtIHshQ2FuY2VsbGFibGVQcm9taXNlfSBwcm9taXNlIFRoZSByZWplY3RlZCBQcm9taXNlLlxuICogQHBhcmFtIHsqfSByZWFzb24gVGhlIFByb21pc2UgcmVqZWN0aW9uIHJlYXNvbi5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5hZGRVbmhhbmRsZWRSZWplY3Rpb25fID0gZnVuY3Rpb24ocHJvbWlzZSwgcmVhc29uKSB7XG4gIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA+IDApIHtcbiAgICBwcm9taXNlLnVuaGFuZGxlZFJlamVjdGlvbklkXyA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBDYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXy5jYWxsKG51bGwsIHJlYXNvbik7XG4gICAgfSwgQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkpO1xuXG4gIH0gZWxzZSBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPT09IDApIHtcbiAgICBwcm9taXNlLmhhZFVuaGFuZGxlZFJlamVjdGlvbl8gPSB0cnVlO1xuICAgIGFzeW5jLnJ1bihmdW5jdGlvbigpIHtcbiAgICAgIGlmIChwcm9taXNlLmhhZFVuaGFuZGxlZFJlamVjdGlvbl8pIHtcbiAgICAgICAgQ2FuY2VsbGFibGVQcm9taXNlLmhhbmRsZVJlamVjdGlvbl8uY2FsbChudWxsLCByZWFzb24pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5cbi8qKlxuICogQSBtZXRob2QgdGhhdCBpcyBpbnZva2VkIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb25zIGZvciBQcm9taXNlcyB0aGF0IGFyZVxuICogcmVqZWN0ZWQgYnV0IGhhdmUgbm8ge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrcyByZWdpc3RlcmVkIHlldC5cbiAqIEB0eXBlIHtmdW5jdGlvbigqKX1cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5oYW5kbGVSZWplY3Rpb25fID0gYXN5bmMudGhyb3dFeGNlcHRpb247XG5cblxuLyoqXG4gKiBTZXRzIGEgaGFuZGxlciB0aGF0IHdpbGwgYmUgY2FsbGVkIHdpdGggcmVhc29ucyBmcm9tIHVuaGFuZGxlZCByZWplY3RlZFxuICogUHJvbWlzZXMuIElmIHRoZSByZWplY3RlZCBQcm9taXNlIChvciBvbmUgb2YgaXRzIGRlc2NlbmRhbnRzKSBoYXMgYW5cbiAqIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayByZWdpc3RlcmVkLCB0aGUgcmVqZWN0aW9uIHdpbGwgYmUgY29uc2lkZXJlZFxuICogaGFuZGxlZCwgYW5kIHRoZSByZWplY3Rpb24gaGFuZGxlciB3aWxsIG5vdCBiZSBjYWxsZWQuXG4gKlxuICogQnkgZGVmYXVsdCwgdW5oYW5kbGVkIHJlamVjdGlvbnMgYXJlIHJldGhyb3duIHNvIHRoYXQgdGhlIGVycm9yIG1heSBiZVxuICogY2FwdHVyZWQgYnkgdGhlIGRldmVsb3BlciBjb25zb2xlIG9yIGEge0Bjb2RlIHdpbmRvdy5vbmVycm9yfSBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKil9IGhhbmRsZXIgQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdpdGggcmVhc29ucyBmcm9tXG4gKiAgICAgcmVqZWN0ZWQgUHJvbWlzZXMuIERlZmF1bHRzIHRvIHtAY29kZSBhc3luYy50aHJvd0V4Y2VwdGlvbn0uXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5zZXRVbmhhbmRsZWRSZWplY3Rpb25IYW5kbGVyID0gZnVuY3Rpb24oaGFuZGxlcikge1xuICBDYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXyA9IGhhbmRsZXI7XG59O1xuXG5cblxuLyoqXG4gKiBFcnJvciB1c2VkIGFzIGEgcmVqZWN0aW9uIHJlYXNvbiBmb3IgY2FuY2VsZWQgUHJvbWlzZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfbWVzc2FnZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyB7RXJyb3J9XG4gKiBAZmluYWxcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG9wdF9tZXNzYWdlKSB7XG4gICAgIHN1cGVyKG9wdF9tZXNzYWdlKTtcblxuICAgICBpZiAob3B0X21lc3NhZ2UpIHtcbiAgICAgICB0aGlzLm1lc3NhZ2UgPSBvcHRfbWVzc2FnZTtcbiAgICAgfVxuICAgfVxufTtcblxuLyoqIEBvdmVycmlkZSAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yLnByb3RvdHlwZS5uYW1lID0gJ2NhbmNlbCc7XG5cbmV4cG9ydCB7Q2FuY2VsbGFibGVQcm9taXNlfTtcbmV4cG9ydCBkZWZhdWx0IENhbmNlbGxhYmxlUHJvbWlzZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gICogRGVib3VuY2VzIGZ1bmN0aW9uIGV4ZWN1dGlvbi5cbiAgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBmblxuICAqIEBwYXJhbSB7bnVtYmVyfSBkZWxheVxuICAqIEByZXR1cm4geyFmdW5jdGlvbigpfVxuICAqL1xuZnVuY3Rpb24gZGVib3VuY2UoZm4sIGRlbGF5KSB7XG5cdHJldHVybiBmdW5jdGlvbiBkZWJvdW5jZWQoKSB7XG5cdFx0dmFyIGFyZ3MgPSBhcmd1bWVudHM7XG5cdFx0Y2FuY2VsRGVib3VuY2UoZGVib3VuY2VkKTtcblx0XHRkZWJvdW5jZWQuaWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0Zm4uYXBwbHkobnVsbCwgYXJncyk7XG5cdFx0fSwgZGVsYXkpO1xuXHR9O1xufVxuXG4vKipcbiAqIENhbmNlbHMgdGhlIHNjaGVkdWxlZCBkZWJvdW5jZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNhbmNlbERlYm91bmNlKGRlYm91bmNlZCkge1xuXHRjbGVhclRpbWVvdXQoZGVib3VuY2VkLmlkKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZGVib3VuY2U7XG5leHBvcnQgeyBjYW5jZWxEZWJvdW5jZSwgZGVib3VuY2UgfTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGNvcmUgZnJvbSAnbWV0YWwnO1xuXG5jb25zdCBSRUdFWCA9IC8oW1xcL10pPyg/Oig/OlxcOihcXHcrKSg/OlxcKCgoPzpcXFxcLnxbXlxcXFwoKV0pKilcXCkpP3xcXCgoKD86XFxcXC58W15cXFxcKCldKSspXFwpKShbKyo/XSk/KS9nO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBhcnJheSBvZiByZWdleCBtYXRjaGVzIHRvIGEgbW9yZSByZWFkYWJsZSBvYmplY3QgZm9ybWF0LlxuICogQHBhcmFtIHshQXJyYXk8c3RyaW5nPn0gbWF0Y2hlc1xuICogQHJldHVybiB7IU9iamVjdH1cbiAqL1xuZnVuY3Rpb24gY29udmVydE1hdGNoZXNUb09iaihtYXRjaGVzKSB7XG5cdHJldHVybiB7XG5cdFx0bWF0Y2g6IG1hdGNoZXNbMF0sXG5cdFx0cHJlZml4OiBtYXRjaGVzWzFdLFxuXHRcdG5hbWU6IG1hdGNoZXNbMl0sXG5cdFx0cGFyYW1QYXR0ZXJuOiBtYXRjaGVzWzNdLFxuXHRcdHVubmFtZWRQYXR0ZXJuOiBtYXRjaGVzWzRdLFxuXHRcdG1vZGlmaWVyOiBtYXRjaGVzWzVdXG5cdH07XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIHRva2VucyBwYXJzZWQgZnJvbSBhIHJvdXRlIGZvcm1hdCBzdHJpbmcgdG8gYSByZWdleC5cbiAqIEBwYXJhbSB7IUFycmF5PHN0cmluZ3whT2JqZWN0Pn0gdG9rZW5zXG4gKiBAcmV0dXJuIHshUmVnRXhwfVxuICovXG5mdW5jdGlvbiBjb252ZXJ0VG9rZW5zVG9SZWdleCh0b2tlbnMpIHtcblx0bGV0IHJlZ2V4ID0gJyc7XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKGNvcmUuaXNTdHJpbmcodG9rZW5zW2ldKSkge1xuXHRcdFx0cmVnZXggKz0gZXNjYXBlKHRva2Vuc1tpXSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxldCBjYXB0dXJlID0gZW5jbG9zZU5vbkNhcHR1cmluZ0dyb3VwKHRva2Vuc1tpXS5wYXR0ZXJuKTtcblx0XHRcdGlmICh0b2tlbnNbaV0ucmVwZWF0KSB7XG5cdFx0XHRcdGNhcHR1cmUgKz0gZW5jbG9zZU5vbkNhcHR1cmluZ0dyb3VwKCdcXFxcLycgKyBjYXB0dXJlKSArICcqJztcblx0XHRcdH1cblx0XHRcdGNhcHR1cmUgPSBlc2NhcGUodG9rZW5zW2ldLnByZWZpeCkgKyBgKCR7Y2FwdHVyZX0pYDtcblx0XHRcdGlmICh0b2tlbnNbaV0ub3B0aW9uYWwpIHtcblx0XHRcdFx0aWYgKCF0b2tlbnNbaV0ucGFydGlhbCkge1xuXHRcdFx0XHRcdGNhcHR1cmUgPSBlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAoY2FwdHVyZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y2FwdHVyZSArPSAnPyc7XG5cdFx0XHR9XG5cdFx0XHRyZWdleCArPSBjYXB0dXJlO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbmV3IFJlZ0V4cCgnXicgKyBtYWtlVHJhaWxpbmdTbGFzaE9wdGlvbmFsKHJlZ2V4KSArICckJyk7XG59XG5cbi8qKlxuICogRW5jbG9zZXMgdGhlIGdpdmVuIHJlZ2V4IHBhdHRlcm4gaW50byBhIG5vbiBjYXB0dXJpbmcgZ3JvdXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0dGVyblxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAocGF0dGVybikge1xuXHRyZXR1cm4gYCg/OiR7cGF0dGVybn0pYDtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHRoZSBnaXZlbiBzdHJpbmcgdG8gc2hvdyB1cCBpbiB0aGUgcGF0aCByZWdleC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZXNjYXBlKHN0cikge1xuXHRyZXR1cm4gc3RyLnJlcGxhY2UoLyhbLisqPz1eIToke30oKVtcXF18XFwvXFxcXF0pL2csICdcXFxcJDEnKTtcbn1cblxuLyoqXG4gKiBNYWtlcyB0cmFpbGluZyBzbGFzaCBvcHRpb25hbCBvbiBwYXRocy5cbiAqIEBwYXJhbSB7c3RyaW5nfSByZWdleFxuICogQHBhcmFtIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIG1ha2VUcmFpbGluZ1NsYXNoT3B0aW9uYWwocmVnZXgpIHtcblx0aWYgKC9cXC8kLy50ZXN0KHJlZ2V4KSkge1xuXHRcdHJlZ2V4ICs9ICc/Jztcblx0fSBlbHNlIHtcblx0XHRyZWdleCArPSAnXFxcXC8/Jztcblx0fVxuXHRyZXR1cm4gcmVnZXg7XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiByb3V0ZSBmb3JtYXQgc3RyaW5nIGludG8gdG9rZW5zIHJlcHJlc2VudGluZyBpdHMgY29udGVudHMuXG4gKiBAcGFyYW0geyFBcnJheXxzdHJpbmd9IHJvdXRlT3JUb2tlbnMgRWl0aGVyIGEgcm91dGUgZm9ybWF0IHN0cmluZyBvciB0b2tlbnNcbiAqICAgICBwcmV2aW91c2x5IHBhcnNlZCB2aWEgdGhlIGBwYXJzZWAgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHshQXJyYXk8c3RyaW5nfCFPYmplY3Q+fSBBbiBhcnJheSBvZiB0b2tlbnMgdGhhdCBjYW4gYmUgZWl0aGVyIHBsYWluXG4gKiAgICAgc3RyaW5ncyAocGFydCBvZiB0aGUgcm91dGUpIG9yIG9iamVjdHMgY29udGFpbmluZyBpbmZvcm1hdGlvbnMgb24gcGFyYW1zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2Uocm91dGVPclRva2Vucykge1xuXHRpZiAoIWNvcmUuaXNTdHJpbmcocm91dGVPclRva2VucykpIHtcblx0XHRyZXR1cm4gcm91dGVPclRva2Vucztcblx0fVxuXG5cdGNvbnN0IHJvdXRlID0gcm91dGVPclRva2Vucztcblx0bGV0IHVubmFtZWRDb3VudCA9IDA7XG5cdGNvbnN0IHRva2VucyA9IFtdO1xuXHRsZXQgY3VyclBhdGggPSAnJztcblx0bGV0IGluZGV4ID0gMDtcblxuXHRsZXQgbWF0Y2hlcyA9IFJFR0VYLmV4ZWMocm91dGUpO1xuXHR3aGlsZSAobWF0Y2hlcykge1xuXHRcdGNvbnN0IGRhdGEgPSBjb252ZXJ0TWF0Y2hlc1RvT2JqKG1hdGNoZXMpO1xuXG5cdFx0Y3VyclBhdGggPSByb3V0ZS5zbGljZShpbmRleCwgbWF0Y2hlcy5pbmRleCk7XG5cdFx0aW5kZXggPSBtYXRjaGVzLmluZGV4ICsgZGF0YS5tYXRjaC5sZW5ndGg7XG5cdFx0dG9rZW5zLnB1c2goY3VyclBhdGgpO1xuXG5cdFx0dG9rZW5zLnB1c2goe1xuXHRcdFx0bmFtZTogZGF0YS5uYW1lID8gZGF0YS5uYW1lIDogJycgKyB1bm5hbWVkQ291bnQrKyxcblx0XHRcdHBhcnRpYWw6IHJvdXRlW2luZGV4XSAmJiByb3V0ZVtpbmRleF0gIT09IGRhdGEucHJlZml4LFxuXHRcdFx0cHJlZml4OiBkYXRhLnByZWZpeCB8fCAnJyxcblx0XHRcdHBhdHRlcm46IGRhdGEucGFyYW1QYXR0ZXJuIHx8IGRhdGEudW5uYW1lZFBhdHRlcm4gfHwgJ1teXFxcXC9dKycsXG5cdFx0XHRyZXBlYXQ6IGRhdGEubW9kaWZpZXIgPT09ICcqJyB8fCBkYXRhLm1vZGlmaWVyID09PSAnKycsXG5cdFx0XHRvcHRpb25hbDogZGF0YS5tb2RpZmllciA9PT0gJyonIHx8IGRhdGEubW9kaWZpZXIgPT09ICc/J1xuXHRcdH0pO1xuXG5cdFx0bWF0Y2hlcyA9IFJFR0VYLmV4ZWMocm91dGUpO1xuXHR9XG5cblx0aWYgKGluZGV4IDwgcm91dGUubGVuZ3RoKSB7XG5cdFx0dG9rZW5zLnB1c2gocm91dGUuc3Vic3RyKGluZGV4KSk7XG5cdH1cblx0cmV0dXJuIHRva2Vucztcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gcm91dGUgZm9ybWF0IHN0cmluZyB0byBhIHJlZ2V4IHRoYXQgY2FuIGV4dHJhY3QgcGFyYW1cbiAqIGRhdGEgZnJvbSBwYXRocyBtYXRjaGluZyBpdC5cbiAqIEBwYXJhbSB7IUFycmF5fHN0cmluZ30gcm91dGVPclRva2VucyBFaXRoZXIgYSByb3V0ZSBmb3JtYXQgc3RyaW5nIG9yIHRva2Vuc1xuICogICAgIHByZXZpb3VzbHkgcGFyc2VkIHZpYSB0aGUgYHBhcnNlYCBmdW5jdGlvbi5cbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1JlZ2V4KHJvdXRlT3JUb2tlbnMpIHtcblx0cmV0dXJuIGNvbnZlcnRUb2tlbnNUb1JlZ2V4KHBhcnNlKHJvdXRlT3JUb2tlbnMpKTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0cyBkYXRhIGZyb20gdGhlIGdpdmVuIHBhdGggYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgcm91dGUgZm9ybWF0LlxuICogQHBhcmFtIHshQXJyYXl8c3RyaW5nfSByb3V0ZU9yVG9rZW5zIEVpdGhlciBhIHJvdXRlIGZvcm1hdCBzdHJpbmcgb3IgdG9rZW5zXG4gKiAgICAgcHJldmlvdXNseSBwYXJzZWQgdmlhIHRoZSBgcGFyc2VgIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IFRoZSBwYXRoIHRvIGV4dHJhY3QgcGFyYW0gZGF0YSBmcm9tLlxuICogQHJldHVybiB7T2JqZWN0PHN0cmluZywgc3RyaW5nPn0gVGhlIGRhdGEgb2JqZWN0LCBvciBudWxsIGlmIHRoZSBwYXRoIGRvZXNuJ3RcbiAqICAgICBtYXRjaCB0aGUgZ2l2ZW4gZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdERhdGEocm91dGVPclRva2VucywgcGF0aCkge1xuXHRjb25zdCBkYXRhID0ge307XG5cdGNvbnN0IHRva2VucyA9IHBhcnNlKHJvdXRlT3JUb2tlbnMpO1xuXHRjb25zdCBtYXRjaCA9IHBhdGgubWF0Y2goY29udmVydFRva2Vuc1RvUmVnZXgodG9rZW5zKSk7XG5cblx0aWYgKCFtYXRjaCkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0bGV0IHBhcmFtSW5kZXggPSAxO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuXHRcdGlmICghY29yZS5pc1N0cmluZyh0b2tlbnNbaV0pKSB7XG5cdFx0XHRsZXQgdmFsdWUgPSBtYXRjaFtwYXJhbUluZGV4KytdO1xuXHRcdFx0aWYgKGNvcmUuaXNEZWYodmFsdWUpKSB7XG5cdFx0XHRcdGlmICh0b2tlbnNbaV0ucmVwZWF0KSB7XG5cdFx0XHRcdFx0dmFsdWUgPSB2YWx1ZS5zcGxpdCgnLycpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRhdGFbdG9rZW5zW2ldLm5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiBkYXRhO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0RlZkFuZE5vdE51bGwsIGlzRnVuY3Rpb24sIGlzU3RyaW5nIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgZXh0cmFjdERhdGEsIHBhcnNlLCB0b1JlZ2V4IH0gZnJvbSAnbWV0YWwtcGF0aC1wYXJzZXInO1xuXG5jbGFzcyBSb3V0ZSB7XG5cblx0LyoqXG5cdCAqIFJvdXRlIGNsYXNzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd8UmVnRXhwfEZ1bmN0aW9ufSBwYXRoXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBoYW5kbGVyXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IocGF0aCwgaGFuZGxlcikge1xuXHRcdGlmICghaXNEZWZBbmROb3ROdWxsKHBhdGgpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1JvdXRlIHBhdGggbm90IHNwZWNpZmllZC4nKTtcblx0XHR9XG5cdFx0aWYgKCFpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1JvdXRlIGhhbmRsZXIgaXMgbm90IGEgZnVuY3Rpb24uJyk7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogRGVmaW5lcyB0aGUgaGFuZGxlciB3aGljaCB3aWxsIGV4ZWN1dGUgb25jZSBhIFVSTCBpbiB0aGUgYXBwbGljYXRpb25cblx0XHQgKiBtYXRjaGVzIHRoZSBwYXRoLlxuXHRcdCAqIEB0eXBlIHshRnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG5cblx0XHQvKipcblx0XHQgKiBEZWZpbmVzIHRoZSBwYXRoIHdoaWNoIHdpbGwgdHJpZ2dlciB0aGUgcm91dGUgaGFuZGxlci5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ3xSZWdFeHB8RnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucGF0aCA9IHBhdGg7XG5cdH1cblxuXHQvKipcblx0KiBCdWlsZHMgcGFyc2VkIGRhdGEgKHJlZ2V4IGFuZCB0b2tlbnMpIGZvciB0aGlzIHJvdXRlLlxuXHQqIEByZXR1cm4geyFPYmplY3R9XG5cdCogQHByb3RlY3RlZFxuXHQqL1xuXHRidWlsZFBhcnNlZERhdGFfKCkge1xuXHRcdGlmICghdGhpcy5wYXJzZWREYXRhXykge1xuXHRcdFx0dmFyIHRva2VucyA9IHBhcnNlKHRoaXMucGF0aCk7XG5cdFx0XHR2YXIgcmVnZXggPSB0b1JlZ2V4KHRva2Vucyk7XG5cdFx0XHR0aGlzLnBhcnNlZERhdGFfID0ge1xuXHRcdFx0XHRyZWdleCxcblx0XHRcdFx0dG9rZW5zXG5cdFx0XHR9O1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5wYXJzZWREYXRhXztcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyBwYXJhbSBkYXRhIGZyb20gdGhlIGdpdmVuIHBhdGgsIGFjY29yZGluZyB0byB0aGlzIHJvdXRlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgdXJsIHBhdGggdG8gZXh0cmFjdCBwYXJhbXMgZnJvbS5cblx0ICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXh0cmFjdGVkIGRhdGEsIGlmIHRoZSBwYXRoIG1hdGNoZXMgdGhpcyByb3V0ZSwgb3Jcblx0ICogICAgIG51bGwgb3RoZXJ3aXNlLlxuXHQgKi9cblx0ZXh0cmFjdFBhcmFtcyhwYXRoKSB7XG5cdFx0aWYgKGlzU3RyaW5nKHRoaXMucGF0aCkpIHtcblx0XHRcdHJldHVybiBleHRyYWN0RGF0YSh0aGlzLmJ1aWxkUGFyc2VkRGF0YV8oKS50b2tlbnMsIHBhdGgpO1xuXHRcdH1cblx0XHRyZXR1cm4ge307XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcm91dGUgaGFuZGxlci5cblx0ICogQHJldHVybiB7IUZ1bmN0aW9ufVxuXHQgKi9cblx0Z2V0SGFuZGxlcigpIHtcblx0XHRyZXR1cm4gdGhpcy5oYW5kbGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHJvdXRlIHBhdGguXG5cdCAqIEByZXR1cm4geyFzdHJpbmd8UmVnRXhwfEZ1bmN0aW9ufVxuXHQgKi9cblx0Z2V0UGF0aCgpIHtcblx0XHRyZXR1cm4gdGhpcy5wYXRoO1xuXHR9XG5cblx0LyoqXG4gXHQgKiBNYXRjaGVzIGlmIHRoZSByb3V0ZXIgY2FuIGhhbmRsZSB0aGUgdGVzdGVkIHBhdGguXG4gXHQgKiBAcGFyYW0geyFzdHJpbmd9IHZhbHVlIFBhdGggdG8gdGVzdCAobWF5IGNvbnRhaW4gdGhlIHF1ZXJ5c3RyaW5nIHBhcnQpLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgbWF0Y2hlcyBhbnkgcm91dGUuXG5cdCAqL1xuXHRtYXRjaGVzUGF0aCh2YWx1ZSkge1xuXHRcdHZhciBwYXRoID0gdGhpcy5wYXRoO1xuXG5cdFx0aWYgKGlzRnVuY3Rpb24ocGF0aCkpIHtcblx0XHRcdHJldHVybiBwYXRoKHZhbHVlKTtcblx0XHR9XG5cdFx0aWYgKGlzU3RyaW5nKHBhdGgpKSB7XG5cdFx0XHRwYXRoID0gdGhpcy5idWlsZFBhcnNlZERhdGFfKCkucmVnZXg7XG5cdFx0fVxuXHRcdGlmIChwYXRoIGluc3RhbmNlb2YgUmVnRXhwKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWUuc2VhcmNoKHBhdGgpID4gLTE7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgUm91dGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IERpc3Bvc2FibGUgfSBmcm9tICdtZXRhbCc7XG5cbmNsYXNzIENhY2hlYWJsZSBleHRlbmRzIERpc3Bvc2FibGUge1xuXG5cdC8qKlxuXHQgKiBBYnN0cmFjdCBjbGFzcyBmb3IgZGVmaW5pbmcgY2FjaGVhYmxlIGJlaGF2aW9yLlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgY2FjaGVkIGRhdGEuXG5cdFx0ICogQHR5cGUgeyFPYmplY3R9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmNhY2hlID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHdoZXRoZXIgY2xhc3MgaXMgY2FjaGVhYmxlLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IGZhbHNlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuY2FjaGVhYmxlID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBjb250ZW50IHRvIHRoZSBjYWNoZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnQgQ29udGVudCB0byBiZSBjYWNoZWQuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZENhY2hlKGNvbnRlbnQpIHtcblx0XHRpZiAodGhpcy5jYWNoZWFibGUpIHtcblx0XHRcdHRoaXMuY2FjaGUgPSBjb250ZW50O1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhcnMgdGhlIGNhY2hlLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRjbGVhckNhY2hlKCkge1xuXHRcdHRoaXMuY2FjaGUgPSBudWxsO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5jbGVhckNhY2hlKCk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY2FjaGVkIGNvbnRlbnQuXG5cdCAqIEByZXR1cm4ge09iamVjdH0gQ2FjaGVkIGNvbnRlbnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGdldENhY2hlKCkge1xuXHRcdHJldHVybiB0aGlzLmNhY2hlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdoZXRoZXIgdGhlIGNsYXNzIGlzIGNhY2hlYWJsZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIHdoZW4gY2xhc3MgaXMgY2FjaGVhYmxlLCBmYWxzZSBvdGhlcndpc2UuXG5cdCAqL1xuXHRpc0NhY2hlYWJsZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5jYWNoZWFibGU7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB3aGV0aGVyIHRoZSBjbGFzcyBpcyBjYWNoZWFibGUuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gY2FjaGVhYmxlXG5cdCAqL1xuXHRzZXRDYWNoZWFibGUoY2FjaGVhYmxlKSB7XG5cdFx0aWYgKCFjYWNoZWFibGUpIHtcblx0XHRcdHRoaXMuY2xlYXJDYWNoZSgpO1xuXHRcdH1cblx0XHR0aGlzLmNhY2hlYWJsZSA9IGNhY2hlYWJsZTtcblx0fVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IENhY2hlYWJsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgZ2xvYmFsRXZhbCB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgQ2FjaGVhYmxlIGZyb20gJy4uL2NhY2hlYWJsZS9DYWNoZWFibGUnO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcblxuY2xhc3MgU2NyZWVuIGV4dGVuZHMgQ2FjaGVhYmxlIHtcblxuXHQvKipcblx0ICogU2NyZWVuIGNsYXNzIGlzIGEgc3BlY2lhbCB0eXBlIG9mIHJvdXRlIGhhbmRsZXIgdGhhdCBwcm92aWRlcyBoZWxwZXJcblx0ICogdXRpbGl0aWVzIHRoYXQgYWRkcyBsaWZlY3ljbGUgYW5kIG1ldGhvZHMgdG8gcHJvdmlkZSBjb250ZW50IHRvIGVhY2hcblx0ICogcmVnaXN0ZXJlZCBzdXJmYWNlLlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQGV4dGVuZHMge0NhY2hlYWJsZX1cblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgc2NyZWVuIGlkLlxuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaWQgPSB0aGlzLm1ha2VJZF8oZ2V0VWlkKCkpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHNjcmVlbiBtZXRhIHRhZ3MuIFJlbGV2YW50IHdoZW4gdGhlIG1ldGEgdGFnc1xuXHRcdCAqIHNob3VsZCBiZSB1cGRhdGVkIHdoZW4gc2NyZWVuIGlzIHJlbmRlcmVkLlxuXHRcdCAqL1xuXHRcdHRoaXMubWV0YXMgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHNjcmVlbiB0aXRsZS4gUmVsZXZhbnQgd2hlbiB0aGUgcGFnZSB0aXRsZSBzaG91bGQgYmVcblx0XHQgKiB1cGFkYXRlZCB3aGVuIHNjcmVlbiBpcyByZW5kZXJlZC5cblx0XHQgKiBAdHlwZSB7P3N0cmluZz19XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnRpdGxlID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaXJlcyB3aGVuIHRoZSBzY3JlZW4gaXMgYWN0aXZlLiBBbGxvd3MgYSBzY3JlZW4gdG8gcGVyZm9ybSBhbnkgc2V0dXBcblx0ICogdGhhdCByZXF1aXJlcyBpdHMgRE9NIHRvIGJlIHZpc2libGUuIExpZmVjeWNsZS5cblx0ICovXG5cdGFjdGl2YXRlKCkge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gYWN0aXZhdGUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHaXZlcyB0aGUgU2NyZWVuIGEgY2hhbmNlIHRvIGNhbmNlbCB0aGUgbmF2aWdhdGlvbiBhbmQgc3RvcCBpdHNlbGYgZnJvbVxuXHQgKiBhY3RpdmF0aW5nLiBDYW4gYmUgdXNlZCwgZm9yIGV4YW1wbGUsIHRvIHByZXZlbnQgbmF2aWdhdGlvbiBpZiBhIHVzZXJcblx0ICogaXMgbm90IGF1dGhlbnRpY2F0ZWQuIExpZmVjeWNsZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbj18P0NhbmNlbGxhYmxlUHJvbWlzZT19IElmIHJldHVybnMgb3IgcmVzb2x2ZXMgdG8gdHJ1ZSxcblx0ICogICAgIHRoZSBjdXJyZW50IHNjcmVlbiBpcyBsb2NrZWQgYW5kIHRoZSBuZXh0IG5hZ2l2YXRpb24gaW50ZXJydXB0ZWQuXG5cdCAqL1xuXHRiZWZvcmVBY3RpdmF0ZSgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGJlZm9yZUFjdGl2YXRlJyk7XG5cdH1cblxuXHQvKipcblx0ICogR2l2ZXMgdGhlIFNjcmVlbiBhIGNoYW5jZSB0byBjYW5jZWwgdGhlIG5hdmlnYXRpb24gYW5kIHN0b3AgaXRzZWxmIGZyb21cblx0ICogYmVpbmcgZGVhY3RpdmF0ZWQuIENhbiBiZSB1c2VkLCBmb3IgZXhhbXBsZSwgaWYgdGhlIHNjcmVlbiBoYXMgdW5zYXZlZFxuXHQgKiBzdGF0ZS4gTGlmZWN5Y2xlLiBDbGVhbi11cCBzaG91bGQgbm90IGJlIHByZWZvcm1lZCBoZXJlLCBzaW5jZSB0aGVcblx0ICogbmF2aWdhdGlvbiBtYXkgc3RpbGwgYmUgY2FuY2VsbGVkLiBEbyBjbGVhbi11cCBpbiBkZWFjdGl2YXRlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFuPXw/Q2FuY2VsbGFibGVQcm9taXNlPX0gSWYgcmV0dXJucyBvciByZXNvbHZlcyB0byB0cnVlLFxuXHQgKiAgICAgdGhlIGN1cnJlbnQgc2NyZWVuIGlzIGxvY2tlZCBhbmQgdGhlIG5leHQgbmFnaXZhdGlvbiBpbnRlcnJ1cHRlZC5cblx0ICovXG5cdGJlZm9yZURlYWN0aXZhdGUoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBiZWZvcmVEZWFjdGl2YXRlJyk7XG5cdH1cblxuXHQvKipcblx0ICogR2l2ZXMgdGhlIFNjcmVlbiBhIGNoYW5jZSBmb3JtYXQgdGhlIHBhdGggYmVmb3JlIGhpc3RvcnkgdXBkYXRlLlxuXHQgKiBAcGF0aCB7IXN0cmluZ30gcGF0aCBOYXZpZ2F0aW9uIHBhdGguXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9IE5hdmlnYXRpb24gcGF0aCB0byB1c2Ugb24gaGlzdG9yeS5cblx0ICovXG5cdGJlZm9yZVVwZGF0ZUhpc3RvcnlQYXRoKHBhdGgpIHtcblx0XHRyZXR1cm4gcGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHaXZlcyB0aGUgU2NyZWVuIGEgY2hhbmNlIGZvcm1hdCB0aGUgc3RhdGUgYmVmb3JlIGhpc3RvcnkgdXBkYXRlLlxuXHQgKiBAcGF0aCB7IW9iamVjdH0gc3RhdGUgSGlzdG9yeSBzdGF0ZS5cblx0ICogQHJldHVybiB7IW9iamVjdH0gSGlzdG9yeSBzdGF0ZSB0byB1c2Ugb24gaGlzdG9yeS5cblx0ICovXG5cdGJlZm9yZVVwZGF0ZUhpc3RvcnlTdGF0ZShzdGF0ZSkge1xuXHRcdHJldHVybiBzdGF0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gZG8gYW55IGNsZWFudXAgbmVjZXNzYXJ5IGFmdGVyIGl0IGhhcyBiZWVuXG5cdCAqIGRlYWN0aXZhdGVkLCBmb3IgZXhhbXBsZSBjYW5jZWxsaW5nIG91dHN0YW5kaW5nIHJlcXVlc3RzIG9yIHN0b3BwaW5nXG5cdCAqIHRpbWVycy4gTGlmZWN5Y2xlLlxuXHQgKi9cblx0ZGVhY3RpdmF0ZSgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGRlYWN0aXZhdGUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlIGEgc2NyZWVuLCBlaXRoZXIgYWZ0ZXIgaXQgaXMgZGVhY3RpdmF0ZWQgKGluIHRoZSBjYXNlIG9mIGFcblx0ICogbm9uLWNhY2hlYWJsZSB2aWV3KSBvciB3aGVuIHRoZSBBcHAgaXMgaXRzZWxmIGRpc3Bvc2VkIGZvciB3aGF0ZXZlclxuXHQgKiByZWFzb24uIExpZmVjeWNsZS5cblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHRzdXBlci5kaXNwb3NlSW50ZXJuYWwoKTtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGRpc3Bvc2UnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gZXZhbHVhdGUgc2NyaXB0cyBiZWZvcmUgdGhlIGVsZW1lbnQgaXMgbWFkZSB2aXNpYmxlLlxuXHQgKiBMaWZlY3ljbGUuXG5cdCAqIEBwYXJhbSB7IW9iamVjdH0gc3VyZmFjZXMgTWFwIG9mIHN1cmZhY2VzIHRvIGZsaXAga2V5ZWQgYnkgc3VyZmFjZSBpZC5cblx0ICogQHJldHVybiB7P0NhbmNlbGxhYmxlUHJvbWlzZT19IFRoaXMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIHdpbGxcblx0ICogICAgIHBhdXNlIHRoZSBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0ZXZhbHVhdGVTY3JpcHRzKHN1cmZhY2VzKSB7XG5cdFx0T2JqZWN0LmtleXMoc3VyZmFjZXMpLmZvckVhY2goc0lkID0+IHtcblx0XHRcdGlmIChzdXJmYWNlc1tzSWRdLmFjdGl2ZUNoaWxkKSB7XG5cdFx0XHRcdGdsb2JhbEV2YWwucnVuU2NyaXB0c0luRWxlbWVudChzdXJmYWNlc1tzSWRdLmFjdGl2ZUNoaWxkKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gZXZhbHVhdGUgc3R5bGVzIGJlZm9yZSB0aGUgZWxlbWVudCBpcyBtYWRlIHZpc2libGUuXG5cdCAqIExpZmVjeWNsZS5cblx0ICogQHBhcmFtIHshb2JqZWN0fSBzdXJmYWNlcyBNYXAgb2Ygc3VyZmFjZXMgdG8gZmxpcCBrZXllZCBieSBzdXJmYWNlIGlkLlxuXHQgKiBAcmV0dXJuIHs/Q2FuY2VsbGFibGVQcm9taXNlPX0gVGhpcyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggd2lsbFxuXHQgKiAgICAgcGF1c2UgdGhlIG5hdmlnYXRpb24gdW50aWwgaXQgaXMgcmVzb2x2ZWQuXG5cdCAqL1xuXHRldmFsdWF0ZVN0eWxlcygpIHtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gcGVyZm9ybSBhbnkgc2V0dXAgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBlbGVtZW50IGlzXG5cdCAqIG1hZGUgdmlzaWJsZS4gTGlmZWN5Y2xlLlxuXHQgKiBAcGFyYW0geyFvYmplY3R9IHN1cmZhY2VzIE1hcCBvZiBzdXJmYWNlcyB0byBmbGlwIGtleWVkIGJ5IHN1cmZhY2UgaWQuXG5cdCAqIEByZXR1cm4gez9DYW5jZWxsYWJsZVByb21pc2U9fSBUaGlzIGNhbiByZXR1cm4gYSBwcm9taXNlLCB3aGljaCB3aWxsIHBhdXNlIHRoZVxuXHQgKiAgICAgbmF2aWdhdGlvbiB1bnRpbCBpdCBpcyByZXNvbHZlZC5cblx0ICovXG5cdGZsaXAoc3VyZmFjZXMpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGZsaXAnKTtcblxuXHRcdHZhciB0cmFuc2l0aW9ucyA9IFtdO1xuXG5cdFx0T2JqZWN0LmtleXMoc3VyZmFjZXMpLmZvckVhY2goc0lkID0+IHtcblx0XHRcdHZhciBzdXJmYWNlID0gc3VyZmFjZXNbc0lkXTtcblx0XHRcdHZhciBkZWZlcnJlZCA9IHN1cmZhY2Uuc2hvdyh0aGlzLmlkKTtcblx0XHRcdHRyYW5zaXRpb25zLnB1c2goZGVmZXJyZWQpO1xuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5hbGwodHJhbnNpdGlvbnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHNjcmVlbiBpZC5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0SWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2NyZWVuIG1ldGEgdGFncy5cblx0ICogQHJldHVybiB7Tm9kZUxpc3R8Tm9kZX1cblx0ICovXG5cdGdldE1ldGFzKCkge1xuXHRcdHJldHVybiB0aGlzLm1ldGFzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGNvbnRlbnQgZm9yIHRoZSBnaXZlbiBzdXJmYWNlLCBvciBudWxsIGlmIHRoZSBzdXJmYWNlIGlzbid0XG5cdCAqIHVzZWQgYnkgdGhpcyBzY3JlZW4uIFRoaXMgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHNjcmVlbiBpcyBpbml0aWFsbHlcblx0ICogY29uc3RydWN0ZWQgb3IsIGlmIGEgc2NyZWVuIGlzIG5vbi1jYWNoZWFibGUsIHdoZW4gbmF2aWdhdGVkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHN1cmZhY2VJZCBUaGUgaWQgb2YgdGhlIHN1cmZhY2UgRE9NIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gcGFyYW1zIFBhcmFtcyBleHRyYWN0ZWQgZnJvbSB0aGUgY3VycmVudCBwYXRoLlxuXHQgKiBAcmV0dXJuIHs/c3RyaW5nfEVsZW1lbnQ9fSBUaGlzIGNhbiByZXR1cm4gYSBzdHJpbmcgb3Igbm9kZSByZXByZXNlbnRpbmdcblx0ICogICAgIHRoZSBjb250ZW50IG9mIHRoZSBzdXJmYWNlLiBJZiByZXR1cm5zIGZhbHN5IHZhbHVlcyBzdXJmYWNlIGRlZmF1bHRcblx0ICogICAgIGNvbnRlbnQgaXMgcmVzdG9yZWQuXG5cdCAqL1xuXHRnZXRTdXJmYWNlQ29udGVudCgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGdldFN1cmZhY2VDb250ZW50Jyk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2NyZWVuIHRpdGxlLlxuXHQgKiBAcmV0dXJuIHs/c3RyaW5nPX1cblx0ICovXG5cdGdldFRpdGxlKCkge1xuXHRcdHJldHVybiB0aGlzLnRpdGxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYWxsIGNvbnRlbnRzIGZvciB0aGUgc3VyZmFjZXMuIFRoaXMgd2lsbCBwYXNzIHRoZSBsb2FkZWQgY29udGVudFxuXHQgKiB0byA8Y29kZT5TY3JlZW4ubG9hZDwvY29kZT4gd2l0aCBhbGwgaW5mb3JtYXRpb24geW91XG5cdCAqIG5lZWQgdG8gZnVsZmlsbCB0aGUgc3VyZmFjZXMuIExpZmVjeWNsZS5cblx0ICogQHBhcmFtIHshc3RyaW5nPX0gcGF0aCBUaGUgcmVxdWVzdGVkIHBhdGguXG5cdCAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9IFRoaXMgY2FuIHJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlXG5cdCAqICAgICBjb250ZW50cyBvZiB0aGUgc3VyZmFjZXMgb3IgYSBwcm9taXNlLCB3aGljaCB3aWxsIHBhdXNlIHRoZSBuYXZpZ2F0aW9uXG5cdCAqICAgICB1bnRpbCBpdCBpcyByZXNvbHZlZC4gVGhpcyBpcyB1c2VmdWwgZm9yIGxvYWRpbmcgYXN5bmMgY29udGVudC5cblx0ICovXG5cdGxvYWQoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBsb2FkJyk7XG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKCk7XG5cdH1cblxuXHQvKipcblx0ICogTWFrZXMgdGhlIGlkIGZvciB0aGUgc2NyZWVuLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGlkIFRoZSBzY3JlZW4gaWQgdGhlIGNvbnRlbnQgYmVsb25ncyB0b28uXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICogQHByaXZhdGVcblx0ICovXG5cdG1ha2VJZF8oaWQpIHtcblx0XHRyZXR1cm4gJ3NjcmVlbl8nICsgaWQ7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgc2NyZWVuIGlkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGlkXG5cdCAqL1xuXHRzZXRJZChpZCkge1xuXHRcdHRoaXMuaWQgPSBpZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzY3JlZW4gbWV0YSB0YWdzLlxuXHQgKiBAcGFyYW0ge05vZGVMaXN0fE5vZGV9IG1ldGFzXG5cdCAqL1xuXHRzZXRNZXRhcyhtZXRhcykge1xuXHRcdHRoaXMubWV0YXMgPSBtZXRhcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzY3JlZW4gdGl0bGUuXG5cdCAqIEBwYXJhbSB7P3N0cmluZz19IHRpdGxlXG5cdCAqL1xuXHRzZXRUaXRsZSh0aXRsZSkge1xuXHRcdHRoaXMudGl0bGUgPSB0aXRsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gdGhpcy5pZDtcblx0fVxuXG59XG5cbi8qKlxuICogQHBhcmFtIHsqfSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgYSBnaXZlbiBpbnN0YW5jZSBpbXBsZW1lbnRzXG4gKiA8Y29kZT5TY3JlZW48L2NvZGU+LlxuICovXG5TY3JlZW4uaXNJbXBsZW1lbnRlZEJ5ID0gZnVuY3Rpb24ob2JqZWN0KSB7XG5cdHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBTY3JlZW47XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTY3JlZW47XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgeyBEaXNwb3NhYmxlLCBpc0RlZkFuZE5vdE51bGwgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgeyBhcHBlbmQsIHJlbW92ZUNoaWxkcmVuLCBleGl0RG9jdW1lbnQgfSBmcm9tICdtZXRhbC1kb20nO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcblxuY2xhc3MgU3VyZmFjZSBleHRlbmRzIERpc3Bvc2FibGUge1xuXG5cdC8qKlxuXHQgKiBTdXJmYWNlIGNsYXNzIHJlcHJlc2VudGluZyB0aGUgcmVmZXJlbmNlcyB0byBlbGVtZW50cyBvbiB0aGUgcGFnZSB0aGF0XG5cdCAqIGNhbiBwb3RlbnRpYWxseSBiZSB1cGRhdGVkIGJ5IDxjb2RlPkFwcDwvY29kZT4uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKGlkKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdGlmICghaWQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignU3VyZmFjZSBlbGVtZW50IGlkIG5vdCBzcGVjaWZpZWQuIEEgc3VyZmFjZSBlbGVtZW50IHJlcXVpcmVzIGEgdmFsaWQgaWQuJyk7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGFjdGl2ZSBjaGlsZCBlbGVtZW50LlxuXHRcdCAqIEB0eXBlIHtFbGVtZW50fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5hY3RpdmVDaGlsZCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgZGVmYXVsdCBjaGlsZCBlbGVtZW50LlxuXHRcdCAqIEB0eXBlIHtFbGVtZW50fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5kZWZhdWx0Q2hpbGQgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHN1cmZhY2UgaWQsIGlmIG5vdCBmb3VuZCBjcmVhdGVzIGFcblx0XHQgKiBuZXcgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuXG5cdFx0ICogQHR5cGUge0VsZW1lbnR9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmVsZW1lbnQgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHN1cmZhY2UgaWQuXG5cdFx0ICogQHR5cGUge1N0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaWQgPSBpZDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBkZWZhdWx0IHRyYW5zaXRpb25GbiBmb3IgdGhlIHN1cmZhY2VzLlxuXHRcdCAqIEBwYXJhbSB7P0VsZW1lbnQ9fSBmcm9tIFRoZSB2aXNpYmxlIHN1cmZhY2UgZWxlbWVudC5cblx0XHQgKiBAcGFyYW0gez9FbGVtZW50PX0gdG8gVGhlIHN1cmZhY2UgZWxlbWVudCB0byBiZSBmbGlwcGVkLlxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKi9cblx0XHR0aGlzLnRyYW5zaXRpb25GbiA9IG51bGw7XG5cblx0XHR0aGlzLmRlZmF1bHRDaGlsZCA9IHRoaXMuZ2V0Q2hpbGQoU3VyZmFjZS5ERUZBVUxUKTtcblx0XHR0aGlzLm1heWJlV3JhcENvbnRlbnRBc0RlZmF1bHRfKCk7XG5cdFx0dGhpcy5hY3RpdmVDaGlsZCA9IHRoaXMuZGVmYXVsdENoaWxkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgc2NyZWVuIGNvbnRlbnQgdG8gYSBzdXJmYWNlLiBJZiBjb250ZW50IGhhc24ndCBiZWVuIHBhc3NlZCwgc2VlIGlmXG5cdCAqIGFuIGVsZW1lbnQgZXhpc3RzIGluIHRoZSBET00gdGhhdCBtYXRjaGVzIHRoZSBpZC4gQnkgY29udmVudGlvbiwgdGhlXG5cdCAqIGVsZW1lbnQgc2hvdWxkIGFscmVhZHkgYmUgbmVzdGVkIGluIHRoZSByaWdodCBlbGVtZW50IGFuZCBzaG91bGQgaGF2ZSBhblxuXHQgKiBpZCB0aGF0IGlzIGEgY29uY2F0ZW50YXRpb24gb2YgdGhlIHN1cmZhY2UgaWQgKyAnLScgKyB0aGUgc2NyZWVuIGlkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQgdGhlIGNvbnRlbnQgYmVsb25ncyB0b28uXG5cdCAqIEBwYXJhbSB7P3N0cmluZ3xFbGVtZW50PX0gb3B0X2NvbnRlbnQgVGhlIHN0cmluZyBjb250ZW50IG9yIGVsZW1lbnQgdG9cblx0ICogICAgIGFkZCBiZSBhZGRlZCBhcyBzdXJmYWNlIGNvbnRlbnQuXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9XG5cdCAqL1xuXHRhZGRDb250ZW50KHNjcmVlbklkLCBvcHRfY29udGVudCkge1xuXHRcdHZhciBjaGlsZCA9IHRoaXMuZGVmYXVsdENoaWxkO1xuXG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChvcHRfY29udGVudCkpIHtcblx0XHRcdGNoaWxkID0gdGhpcy5nZXRDaGlsZChzY3JlZW5JZCk7XG5cdFx0XHRpZiAoY2hpbGQpIHtcblx0XHRcdFx0cmVtb3ZlQ2hpbGRyZW4oY2hpbGQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2hpbGQgPSB0aGlzLmNyZWF0ZUNoaWxkKHNjcmVlbklkKTtcblx0XHRcdFx0dGhpcy50cmFuc2l0aW9uKGNoaWxkLCBudWxsKTtcblx0XHRcdH1cblx0XHRcdGFwcGVuZChjaGlsZCwgb3B0X2NvbnRlbnQpO1xuXHRcdH1cblxuXHRcdHZhciBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KCk7XG5cblx0XHRpZiAoZWxlbWVudCAmJiBjaGlsZCkge1xuXHRcdFx0YXBwZW5kKGVsZW1lbnQsIGNoaWxkKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gY2hpbGQ7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBjaGlsZCBub2RlIGZvciB0aGUgc3VyZmFjZS5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkLlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fVxuXHQgKi9cblx0Y3JlYXRlQ2hpbGQoc2NyZWVuSWQpIHtcblx0XHR2YXIgY2hpbGQgPSBnbG9iYWxzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdGNoaWxkLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLm1ha2VJZF8oc2NyZWVuSWQpKTtcblx0XHRyZXR1cm4gY2hpbGQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBjaGlsZCBub2RlIG9mIHRoZSBzdXJmYWNlLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQuXG5cdCAqIEByZXR1cm4gez9FbGVtZW50fVxuXHQgKi9cblx0Z2V0Q2hpbGQoc2NyZWVuSWQpIHtcblx0XHRyZXR1cm4gZ2xvYmFscy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm1ha2VJZF8oc2NyZWVuSWQpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzdXJmYWNlIGVsZW1lbnQgZnJvbSBlbGVtZW50LCBhbmQgc2V0cyBpdCB0byB0aGUgZWwgcHJvcGVydHkgb2Zcblx0ICogdGhlIGN1cnJlbnQgaW5zdGFuY2UuXG5cdCAqIDxjb2RlPnRoaXMuZWxlbWVudDwvY29kZT4gd2lsbCBiZSB1c2VkLlxuXHQgKiBAcmV0dXJuIHs/RWxlbWVudH0gVGhlIGN1cnJlbnQgc3VyZmFjZSBlbGVtZW50LlxuXHQgKi9cblx0Z2V0RWxlbWVudCgpIHtcblx0XHRpZiAodGhpcy5lbGVtZW50KSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lbGVtZW50O1xuXHRcdH1cblx0XHR0aGlzLmVsZW1lbnQgPSBnbG9iYWxzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuaWQpO1xuXHRcdHJldHVybiB0aGlzLmVsZW1lbnQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc3VyZmFjZSBpZC5cblx0ICogQHJldHVybiB7U3RyaW5nfVxuXHQgKi9cblx0Z2V0SWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc3VyZmFjZSB0cmFuc2l0aW9uIGZ1bmN0aW9uLlxuXHQgKiBTZWUgPGNvZGU+U3VyZmFjZS5kZWZhdWx0VHJhbnNpdGlvbjwvY29kZT4uXG5cdCAqIEByZXR1cm4gez9GdW5jdGlvbj19IFRoZSB0cmFuc2l0aW9uIGZ1bmN0aW9uLlxuXHQgKi9cblx0Z2V0VHJhbnNpdGlvbkZuKCkge1xuXHRcdHJldHVybiB0aGlzLnRyYW5zaXRpb25Gbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYWtlcyB0aGUgaWQgZm9yIHRoZSBlbGVtZW50IHRoYXQgaG9sZHMgY29udGVudCBmb3IgYSBzY3JlZW4uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2NyZWVuSWQgVGhlIHNjcmVlbiBpZCB0aGUgY29udGVudCBiZWxvbmdzIHRvby5cblx0ICogQHJldHVybiB7U3RyaW5nfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0bWFrZUlkXyhzY3JlZW5JZCkge1xuXHRcdHJldHVybiB0aGlzLmlkICsgJy0nICsgc2NyZWVuSWQ7XG5cdH1cblxuXHQvKipcblx0ICogSWYgZGVmYXVsdCBjaGlsZCBpcyBtaXNzaW5nLCB3cmFwcyBzdXJmYWNlIGNvbnRlbnQgYXMgZGVmYXVsdCBjaGlsZC4gSWZcblx0ICogc3VyZmFjZSBoYXZlIHN0YXRpYyBjb250ZW50LCBtYWtlIHN1cmUgdG8gcGxhY2UgYVxuXHQgKiA8Y29kZT5zdXJmYWNlSWQtZGVmYXVsdDwvY29kZT4gZWxlbWVudCBpbnNpZGUgc3VyZmFjZSwgb25seSBjb250ZW50c1xuXHQgKiBpbnNpZGUgdGhlIGRlZmF1bHQgY2hpbGQgd2lsbCBiZSByZXBsYWNlZCBieSBuYXZpZ2F0aW9uLlxuXHQgKi9cblx0bWF5YmVXcmFwQ29udGVudEFzRGVmYXVsdF8oKSB7XG5cdFx0dmFyIGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnQoKTtcblx0XHRpZiAoZWxlbWVudCAmJiAhdGhpcy5kZWZhdWx0Q2hpbGQpIHtcblx0XHRcdHZhciBmcmFnbWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuXHRcdFx0d2hpbGUgKGVsZW1lbnQuZmlyc3RDaGlsZCkge1xuXHRcdFx0XHRmcmFnbWVudC5hcHBlbmRDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5kZWZhdWx0Q2hpbGQgPSB0aGlzLmFkZENvbnRlbnQoU3VyZmFjZS5ERUZBVUxULCBmcmFnbWVudCk7XG5cdFx0XHR0aGlzLnRyYW5zaXRpb24obnVsbCwgdGhpcy5kZWZhdWx0Q2hpbGQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzdXJmYWNlIGlkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGlkXG5cdCAqL1xuXHRzZXRJZChpZCkge1xuXHRcdHRoaXMuaWQgPSBpZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzdXJmYWNlIHRyYW5zaXRpb24gZnVuY3Rpb24uXG5cdCAqIFNlZSA8Y29kZT5TdXJmYWNlLmRlZmF1bHRUcmFuc2l0aW9uPC9jb2RlPi5cblx0ICogQHBhcmFtIHs/RnVuY3Rpb249fSB0cmFuc2l0aW9uRm4gVGhlIHRyYW5zaXRpb24gZnVuY3Rpb24uXG5cdCAqL1xuXHRzZXRUcmFuc2l0aW9uRm4odHJhbnNpdGlvbkZuKSB7XG5cdFx0dGhpcy50cmFuc2l0aW9uRm4gPSB0cmFuc2l0aW9uRm47XG5cdH1cblxuXHQvKipcblx0ICogU2hvd3Mgc2NyZWVuIGNvbnRlbnQgZnJvbSBhIHN1cmZhY2UuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkIHRvIHNob3cuXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUGF1c2VzIHRoZSBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0c2hvdyhzY3JlZW5JZCkge1xuXHRcdHZhciBmcm9tID0gdGhpcy5hY3RpdmVDaGlsZDtcblx0XHR2YXIgdG8gPSB0aGlzLmdldENoaWxkKHNjcmVlbklkKTtcblx0XHRpZiAoIXRvKSB7XG5cdFx0XHR0byA9IHRoaXMuZGVmYXVsdENoaWxkO1xuXHRcdH1cblx0XHR0aGlzLmFjdGl2ZUNoaWxkID0gdG87XG5cdFx0cmV0dXJuIHRoaXMudHJhbnNpdGlvbihmcm9tLCB0bykudGhlbkFsd2F5cygoKSA9PiB7XG5cdFx0XHRpZiAoZnJvbSAmJiBmcm9tICE9PSB0bykge1xuXHRcdFx0XHRleGl0RG9jdW1lbnQoZnJvbSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBzY3JlZW4gY29udGVudCBmcm9tIGEgc3VyZmFjZS5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkIHRvIHJlbW92ZS5cblx0ICovXG5cdHJlbW92ZShzY3JlZW5JZCkge1xuXHRcdHZhciBjaGlsZCA9IHRoaXMuZ2V0Q2hpbGQoc2NyZWVuSWQpO1xuXHRcdGlmIChjaGlsZCkge1xuXHRcdFx0ZXhpdERvY3VtZW50KGNoaWxkKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7U3RyaW5nfVxuXHQgKi9cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQ7XG5cdH1cblxuXHQvKipcblx0ICogSW52b2tlcyB0aGUgdHJhbnNpdGlvbiBmdW5jdGlvbiBzcGVjaWZpZWQgb24gPGNvZGU+dHJhbnNpdGlvbjwvY29kZT4gYXR0cmlidXRlLlxuXHQgKiBAcGFyYW0gez9FbGVtZW50PX0gZnJvbVxuXHQgKiBAcGFyYW0gez9FbGVtZW50PX0gdG9cblx0ICogQHJldHVybiB7P0NhbmNlbGxhYmxlUHJvbWlzZT19IFRoaXMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIHdpbGwgcGF1c2UgdGhlXG5cdCAqICAgICBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0dHJhbnNpdGlvbihmcm9tLCB0bykge1xuXHRcdHZhciB0cmFuc2l0aW9uRm4gPSB0aGlzLnRyYW5zaXRpb25GbiB8fCBTdXJmYWNlLmRlZmF1bHRUcmFuc2l0aW9uO1xuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSh0cmFuc2l0aW9uRm4uY2FsbCh0aGlzLCBmcm9tLCB0bykpO1xuXHR9XG5cbn1cblxuLyoqXG4gICAqIEhvbGRzIHRoZSBkZWZhdWx0IHN1cmZhY2UgbmFtZS4gRWxlbWVudHMgb24gdGhlIHBhZ2UgbXVzdCBjb250YWluIGEgY2hpbGRcbiAgICogZWxlbWVudCBjb250YWluaW5nIHRoZSBkZWZhdWx0IGNvbnRlbnQsIHRoaXMgZWxlbWVudCBtdXN0IGJlIGFzIGZvbGxvd2luZzpcbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogPGNvZGU+XG4gICAqICAgPGRpdiBpZD1cIm15c3VyZmFjZVwiPlxuICAgKiAgICAgPGRpdiBpZD1cIm15c3VyZmFjZS1kZWZhdWx0XCI+RGVmYXVsdCBzdXJmYWNlIGNvbnRlbnQuPC9kaXY+XG4gICAqICAgPC9kaXY+XG4gICAqIDwvY29kZT5cbiAgICpcbiAgICogVGhlIGRlZmF1bHQgY29udGVudCBpcyByZWxldmFudCBmb3IgdGhlIGluaXRpYWwgcGFnZSBjb250ZW50LiBXaGVuIGFcbiAgICogc2NyZWVuIGRvZXNuJ3QgcHJvdmlkZSBjb250ZW50IGZvciB0aGUgc3VyZmFjZSB0aGUgZGVmYXVsdCBjb250ZW50IGlzXG4gICAqIHJlc3RvcmVkIGludG8gdGhlIHBhZ2UuXG4gICAqXG4gICAqIEB0eXBlIHshU3RyaW5nfVxuICAgKiBAZGVmYXVsdCBkZWZhdWx0XG4gICAqIEBzdGF0aWNcbiAgICovXG5TdXJmYWNlLkRFRkFVTFQgPSAnZGVmYXVsdCc7XG5cbi8qKlxuICogSG9sZHMgdGhlIGRlZmF1bHQgdHJhbnNpdGlvbiBmb3IgYWxsIHN1cmZhY2VzLiBFYWNoIHN1cmZhY2UgY291bGQgaGF2ZSBpdHNcbiAqIG93biB0cmFuc2l0aW9uLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogPGNvZGU+XG4gKiBzdXJmYWNlLnNldFRyYW5zaXRpb25GbihmdW5jdGlvbihmcm9tLCB0bykge1xuICogICBpZiAoZnJvbSkge1xuICogICAgIGZyb20uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAqICAgICBmcm9tLmNsYXNzTGlzdC5yZW1vdmUoJ2ZsaXBwZWQnKTtcbiAqICAgfVxuICogICBpZiAodG8pIHtcbiAqICAgICB0by5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAqICAgICB0by5jbGFzc0xpc3QuYWRkKCdmbGlwcGVkJyk7XG4gKiAgIH1cbiAqICAgcmV0dXJuIG51bGw7XG4gKiB9KTtcbiAqIDwvY29kZT5cbiAqXG4gKiBAcGFyYW0gez9FbGVtZW50PX0gZnJvbSBUaGUgdmlzaWJsZSBzdXJmYWNlIGVsZW1lbnQuXG4gKiBAcGFyYW0gez9FbGVtZW50PX0gdG8gVGhlIHN1cmZhY2UgZWxlbWVudCB0byBiZSBmbGlwcGVkLlxuICogQHN0YXRpY1xuICovXG5TdXJmYWNlLmRlZmF1bHRUcmFuc2l0aW9uID0gZnVuY3Rpb24oZnJvbSwgdG8pIHtcblx0aWYgKGZyb20pIHtcblx0XHRmcm9tLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0ZnJvbS5jbGFzc0xpc3QucmVtb3ZlKCdmbGlwcGVkJyk7XG5cdH1cblx0aWYgKHRvKSB7XG5cdFx0dG8uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cdFx0dG8uY2xhc3NMaXN0LmFkZCgnZmxpcHBlZCcpO1xuXHR9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTdXJmYWNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBhZGRDbGFzc2VzLCBkZWxlZ2F0ZSwgbWF0Y2gsIG9uLCByZW1vdmVDbGFzc2VzIH0gZnJvbSAnbWV0YWwtZG9tJztcbmltcG9ydCB7IGFycmF5LCBhc3luYywgaXNEZWZBbmROb3ROdWxsLCBpc1N0cmluZywgb2JqZWN0IH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBFdmVudEhhbmRsZXIgfSBmcm9tICdtZXRhbC1ldmVudHMnO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcbmltcG9ydCBkZWJvdW5jZSBmcm9tICdtZXRhbC1kZWJvdW5jZSc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFJvdXRlIGZyb20gJy4uL3JvdXRlL1JvdXRlJztcbmltcG9ydCBTY3JlZW4gZnJvbSAnLi4vc2NyZWVuL1NjcmVlbic7XG5pbXBvcnQgU3VyZmFjZSBmcm9tICcuLi9zdXJmYWNlL1N1cmZhY2UnO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uL3V0aWxzL3V0aWxzJztcblxuY29uc3QgTmF2aWdhdGlvblN0cmF0ZWd5ID0ge1xuXHRJTU1FRElBVEU6ICdpbW1lZGlhdGUnLFxuXHRTQ0hFRFVMRV9MQVNUOiAnc2NoZWR1bGVMYXN0J1xufTtcblxuY2xhc3MgQXBwIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuXHQvKipcblx0ICogQXBwIGNsYXNzIHRoYXQgaGFuZGxlIHJvdXRlcyBhbmQgc2NyZWVucyBsaWZlY3ljbGUuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAZXh0ZW5kcyB7RXZlbnRFbWl0dGVyfVxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBhY3RpdmUgc2NyZWVuLlxuXHRcdCAqIEB0eXBlIHs/U2NyZWVufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmFjdGl2ZVNjcmVlbiA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgYWN0aXZlIHBhdGggY29udGFpbmluZyB0aGUgcXVlcnkgcGFyYW1ldGVycy5cblx0XHQgKiBAdHlwZSB7P3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5hY3RpdmVQYXRoID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEFsbG93cyBwcmV2ZW50IG5hdmlnYXRlIGZyb20gZG9tIHByZXZlbnRlZCBldmVudC5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCB0cnVlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYWxsb3dQcmV2ZW50TmF2aWdhdGUgPSB0cnVlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgbGluayBiYXNlIHBhdGguXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgJydcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5iYXNlUGF0aCA9ICcnO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHZhbHVlIG9mIHRoZSBicm93c2VyIHBhdGggYmVmb3JlIGEgbmF2aWdhdGlvbiBpcyBwZXJmb3JtZWQuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgdGhlIGN1cnJlbnQgYnJvd3NlciBwYXRoLlxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmJyb3dzZXJQYXRoQmVmb3JlTmF2aWdhdGUgPSB1dGlscy5nZXRDdXJyZW50QnJvd3NlclBhdGhXaXRob3V0SGFzaCgpO1xuXG5cdFx0LyoqXG5cdFx0ICogQ2FwdHVyZXMgc2Nyb2xsIHBvc2l0aW9uIGZyb20gc2Nyb2xsIGV2ZW50LlxuXHRcdCAqIEB0eXBlIHshYm9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCB0cnVlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuY2FwdHVyZVNjcm9sbFBvc2l0aW9uRnJvbVNjcm9sbEV2ZW50ID0gdHJ1ZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBkZWZhdWx0IHBhZ2UgdGl0bGUuXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZGVmYXVsdFRpdGxlID0gZ2xvYmFscy5kb2N1bWVudC50aXRsZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBmb3JtIHNlbGVjdG9yIHRvIGRlZmluZSBmb3JtcyB0aGF0IGFyZSByb3V0ZWQuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgZm9ybVtlbmN0eXBlPVwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXTpub3QoW2RhdGEtc2VubmEtb2ZmXSlcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5mb3JtU2VsZWN0b3IgPSAnZm9ybVtlbmN0eXBlPVwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXTpub3QoW2RhdGEtc2VubmEtb2ZmXSknO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBlbmFibGVkLCB0aGUgcm91dGUgbWF0Y2hpbmcgaWdub3JlcyBxdWVyeSBzdHJpbmcgZnJvbSB0aGUgcGF0aC5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCBmYWxzZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCA9IGZhbHNlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGxpbmsgc2VsZWN0b3IgdG8gZGVmaW5lIGxpbmtzIHRoYXQgYXJlIHJvdXRlZC5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBhOm5vdChbZGF0YS1zZW5uYS1vZmZdKVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmxpbmtTZWxlY3RvciA9ICdhOm5vdChbZGF0YS1zZW5uYS1vZmZdKTpub3QoW3RhcmdldD1cIl9ibGFua1wiXSknO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGxvYWRpbmcgY3NzIGNsYXNzLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IHNlbm5hLWxvYWRpbmdcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5sb2FkaW5nQ3NzQ2xhc3MgPSAnc2VubmEtbG9hZGluZyc7XG5cblx0XHQvKipcblx0XHQgKiBVc2luZyB0aGUgSGlzdG9yeSBBUEkgdG8gbWFuYWdlIHlvdXIgVVJMcyBpcyBhd2Vzb21lIGFuZCwgYXMgaXQgaGFwcGVucyxcblx0XHQgKiBhIGNydWNpYWwgZmVhdHVyZSBvZiBnb29kIHdlYiBhcHBzLiBPbmUgb2YgaXRzIGRvd25zaWRlcywgaG93ZXZlciwgaXNcblx0XHQgKiB0aGF0IHNjcm9sbCBwb3NpdGlvbnMgYXJlIHN0b3JlZCBhbmQgdGhlbiwgbW9yZSBpbXBvcnRhbnRseSwgcmVzdG9yZWRcblx0XHQgKiB3aGVuZXZlciB5b3UgdHJhdmVyc2UgdGhlIGhpc3RvcnkuIFRoaXMgb2Z0ZW4gbWVhbnMgdW5zaWdodGx5IGp1bXBzIGFzXG5cdFx0ICogdGhlIHNjcm9sbCBwb3NpdGlvbiBjaGFuZ2VzIGF1dG9tYXRpY2FsbHksIGFuZCBlc3BlY2lhbGx5IHNvIGlmIHlvdXIgYXBwXG5cdFx0ICogZG9lcyB0cmFuc2l0aW9ucywgb3IgY2hhbmdlcyB0aGUgY29udGVudHMgb2YgdGhlIHBhZ2UgaW4gYW55IHdheS5cblx0XHQgKiBVbHRpbWF0ZWx5IHRoaXMgbGVhZHMgdG8gYW4gaG9ycmlibGUgdXNlciBleHBlcmllbmNlLiBUaGUgZ29vZCBuZXdzIGlzLFxuXHRcdCAqIGhvd2V2ZXIsIHRoYXQgdGhlcmXigJlzIGEgcG90ZW50aWFsIGZpeDogaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbi5cblx0XHQgKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS93ZWIvdXBkYXRlcy8yMDE1LzA5L2hpc3RvcnktYXBpLXNjcm9sbC1yZXN0b3JhdGlvblxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uU3VwcG9ydGVkID0gKCdzY3JvbGxSZXN0b3JhdGlvbicgaW4gZ2xvYmFscy53aW5kb3cuaGlzdG9yeSk7XG5cblx0XHQvKipcblx0XHQgKiBXaGVuIHNldCB0byBOYXZpZ2F0aW9uU3RyYXRlZ3kuU0NIRURVTEVfTEFTVCBtZWFucyB0aGF0IHRoZSBjdXJyZW50IG5hdmlnYXRpb25cblx0XHQgKiBjYW5ub3QgYmUgQ2FuY2VsbGVkIHRvIHN0YXJ0IGFub3RoZXIgYW5kIHdpbGwgYmUgcXVldWVkIGluXG5cdFx0ICogc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLiBXaGVuIE5hdmlnYXRpb25TdHJhdGVneS5JTU1FRElBVEUgbWVhbnMgdGhhdCBhbGxcblx0XHQgKiBuYXZpZ2F0aW9uIHdpbGwgYmUgY2FuY2VsbGVkIHRvIHN0YXJ0IGFub3RoZXIuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgaW1tZWRpYXRlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubmF2aWdhdGlvblN0cmF0ZWd5ID0gTmF2aWdhdGlvblN0cmF0ZWd5LklNTUVESUFURTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZW4gc2V0IHRvIHRydWUgdGhlcmUgaXMgYSBwZW5kaW5nTmF2aWdhdGUgdGhhdCBoYXMgbm90IHlldCBiZWVuXG5cdFx0ICogcmVzb2x2ZWQgb3IgcmVqZWN0ZWQuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgZmFsc2Vcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5pc05hdmlnYXRpb25QZW5kaW5nID0gZmFsc2U7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBhIGRlZmVycmVkIHdpdGggdGhlIGN1cnJlbnQgbmF2aWdhdGlvbi5cblx0XHQgKiBAdHlwZSB7P0NhbmNlbGxhYmxlUHJvbWlzZX1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSB3aW5kb3cgaG9yaXpvbnRhbCBzY3JvbGwgcG9zaXRpb24gd2hlbiB0aGUgbmF2aWdhdGlvbiB1c2luZ1xuXHRcdCAqIGJhY2sgb3IgZm9yd2FyZCBoYXBwZW5zIHRvIGJlIHJlc3RvcmVkIGFmdGVyIHRoZSBzdXJmYWNlcyBhcmUgdXBkYXRlZC5cblx0XHQgKiBAdHlwZSB7IU51bWJlcn1cblx0XHQgKiBAZGVmYXVsdCAwXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucG9wc3RhdGVTY3JvbGxMZWZ0ID0gMDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSB3aW5kb3cgdmVydGljYWwgc2Nyb2xsIHBvc2l0aW9uIHdoZW4gdGhlIG5hdmlnYXRpb24gdXNpbmdcblx0XHQgKiBiYWNrIG9yIGZvcndhcmQgaGFwcGVucyB0byBiZSByZXN0b3JlZCBhZnRlciB0aGUgc3VyZmFjZXMgYXJlIHVwZGF0ZWQuXG5cdFx0ICogQHR5cGUgeyFOdW1iZXJ9XG5cdFx0ICogQGRlZmF1bHQgMFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBvcHN0YXRlU2Nyb2xsVG9wID0gMDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSByZWRpcmVjdCBwYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5IHBhcmFtZXRlcnMuXG5cdFx0ICogQHR5cGUgez9zdHJpbmd9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucmVkaXJlY3RQYXRoID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBzY3JlZW4gcm91dGVzIGNvbmZpZ3VyYXRpb24uXG5cdFx0ICogQHR5cGUgez9BcnJheX1cblx0XHQgKiBAZGVmYXVsdCBbXVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnJvdXRlcyA9IFtdO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgYSBxdWV1ZSB0aGF0IHN0b3JlcyBldmVyeSBET00gZXZlbnQgdGhhdCBjYW4gaW5pdGlhdGUgYSBuYXZpZ2F0aW9uLlxuXHRcdCAqIEB0eXBlIHshRXZlbnR9XG5cdFx0ICogQGRlZmF1bHQgW11cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUgPSBbXTtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcHMgdGhlIHNjcmVlbiBpbnN0YW5jZXMgYnkgdGhlIHVybCBjb250YWluaW5nIHRoZSBwYXJhbWV0ZXJzLlxuXHRcdCAqIEB0eXBlIHs/T2JqZWN0fVxuXHRcdCAqIEBkZWZhdWx0IHt9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuc2NyZWVucyA9IHt9O1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBzZXQgdG8gdHJ1ZSB0aGUgZmlyc3QgZXJyb25lb3VzIHBvcHN0YXRlIGZpcmVkIG9uIHBhZ2UgbG9hZCB3aWxsIGJlXG5cdFx0ICogaWdub3JlZCwgb25seSBpZiA8Y29kZT5nbG9iYWxzLndpbmRvdy5oaXN0b3J5LnN0YXRlPC9jb2RlPiBpcyBhbHNvXG5cdFx0ICogPGNvZGU+bnVsbDwvY29kZT4uXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgZmFsc2Vcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5za2lwTG9hZFBvcHN0YXRlID0gZmFsc2U7XG5cblx0XHQvKipcblx0XHQgKiBNYXBzIHRoYXQgaW5kZXggdGhlIHN1cmZhY2VzIGluc3RhbmNlcyBieSB0aGUgc3VyZmFjZSBpZC5cblx0XHQgKiBAdHlwZSB7P09iamVjdH1cblx0XHQgKiBAZGVmYXVsdCB7fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnN1cmZhY2VzID0ge307XG5cblx0XHQvKipcblx0XHQgKiBXaGVuIHNldCB0byB0cnVlLCBtb3ZlcyB0aGUgc2Nyb2xsIHBvc2l0aW9uIGFmdGVyIHBvcHN0YXRlLCBvciB0byB0aGVcblx0XHQgKiB0b3Agb2YgdGhlIHZpZXdwb3J0IGZvciBuZXcgbmF2aWdhdGlvbi4gSWYgZmFsc2UsIHRoZSBicm93c2VyIHdpbGxcblx0XHQgKiB0YWtlIGNhcmUgb2Ygc2Nyb2xsIHJlc3RvcmF0aW9uLlxuXHRcdCAqIEB0eXBlIHshYm9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCB0cnVlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMudXBkYXRlU2Nyb2xsUG9zaXRpb24gPSB0cnVlO1xuXG5cdFx0dGhpcy5hcHBFdmVudEhhbmRsZXJzXyA9IG5ldyBFdmVudEhhbmRsZXIoKTtcblxuXHRcdHRoaXMuYXBwRXZlbnRIYW5kbGVyc18uYWRkKFxuXHRcdFx0b24oZ2xvYmFscy53aW5kb3csICdzY3JvbGwnLCBkZWJvdW5jZSh0aGlzLm9uU2Nyb2xsXy5iaW5kKHRoaXMpLCAxMDApKSxcblx0XHRcdG9uKGdsb2JhbHMud2luZG93LCAnbG9hZCcsIHRoaXMub25Mb2FkXy5iaW5kKHRoaXMpKSxcblx0XHRcdG9uKGdsb2JhbHMud2luZG93LCAncG9wc3RhdGUnLCB0aGlzLm9uUG9wc3RhdGVfLmJpbmQodGhpcykpXG5cdFx0KTtcblxuXHRcdHRoaXMub24oJ3N0YXJ0TmF2aWdhdGUnLCB0aGlzLm9uU3RhcnROYXZpZ2F0ZV8pO1xuXHRcdHRoaXMub24oJ2JlZm9yZU5hdmlnYXRlJywgdGhpcy5vbkJlZm9yZU5hdmlnYXRlXyk7XG5cdFx0dGhpcy5vbignYmVmb3JlTmF2aWdhdGUnLCB0aGlzLm9uQmVmb3JlTmF2aWdhdGVEZWZhdWx0XywgdHJ1ZSk7XG5cdFx0dGhpcy5vbignYmVmb3JlVW5sb2FkJywgdGhpcy5vbkJlZm9yZVVubG9hZERlZmF1bHRfKTtcblxuXHRcdHRoaXMuc2V0TGlua1NlbGVjdG9yKHRoaXMubGlua1NlbGVjdG9yKTtcblx0XHR0aGlzLnNldEZvcm1TZWxlY3Rvcih0aGlzLmZvcm1TZWxlY3Rvcik7XG5cblx0XHR0aGlzLm1heWJlT3ZlcmxvYWRCZWZvcmVVbmxvYWRfKCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBvbmUgb3IgbW9yZSBzY3JlZW5zIHRvIHRoZSBhcHBsaWNhdGlvbi5cblx0ICpcblx0ICogRXhhbXBsZTpcblx0ICpcblx0ICogPGNvZGU+XG5cdCAqICAgYXBwLmFkZFJvdXRlcyh7IHBhdGg6ICcvZm9vJywgaGFuZGxlcjogRm9vU2NyZWVuIH0pO1xuXHQgKiAgIG9yXG5cdCAqICAgYXBwLmFkZFJvdXRlcyhbeyBwYXRoOiAnL2ZvbycsIGhhbmRsZXI6IGZ1bmN0aW9uKHJvdXRlKSB7IHJldHVybiBuZXcgRm9vU2NyZWVuKCk7IH0gfV0pO1xuXHQgKiA8L2NvZGU+XG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvciB7QXJyYXl9IHJvdXRlcyBTaW5nbGUgb2JqZWN0IG9yIGFuIGFycmF5IG9mIG9iamVjdC5cblx0ICogICAgIEVhY2ggb2JqZWN0IHNob3VsZCBjb250YWluIDxjb2RlPnBhdGg8L2NvZGU+IGFuZCA8Y29kZT5zY3JlZW48L2NvZGU+LlxuXHQgKiAgICAgVGhlIDxjb2RlPnBhdGg8L2NvZGU+IHNob3VsZCBiZSBhIHN0cmluZyBvciBhIHJlZ2V4IHRoYXQgbWFwcyB0aGVcblx0ICogICAgIG5hdmlnYXRpb24gcm91dGUgdG8gYSBzY3JlZW4gY2xhc3MgZGVmaW5pdGlvbiAobm90IGFuIGluc3RhbmNlKSwgZS5nOlxuXHQgKiAgICAgICAgIDxjb2RlPnsgcGF0aDogXCIvaG9tZTpwYXJhbTFcIiwgaGFuZGxlcjogTXlTY3JlZW4gfTwvY29kZT5cblx0ICogICAgICAgICA8Y29kZT57IHBhdGg6IC9mb28uKy8sIGhhbmRsZXI6IE15U2NyZWVuIH08L2NvZGU+XG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFJvdXRlcyhyb3V0ZXMpIHtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkocm91dGVzKSkge1xuXHRcdFx0cm91dGVzID0gW3JvdXRlc107XG5cdFx0fVxuXHRcdHJvdXRlcy5mb3JFYWNoKChyb3V0ZSkgPT4ge1xuXHRcdFx0aWYgKCEocm91dGUgaW5zdGFuY2VvZiBSb3V0ZSkpIHtcblx0XHRcdFx0cm91dGUgPSBuZXcgUm91dGUocm91dGUucGF0aCwgcm91dGUuaGFuZGxlcik7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnJvdXRlcy5wdXNoKHJvdXRlKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIG9uZSBvciBtb3JlIHN1cmZhY2VzIHRvIHRoZSBhcHBsaWNhdGlvbi5cblx0ICogQHBhcmFtIHtTdXJmYWNlfFN0cmluZ3xBcnJheS48U3VyZmFjZXxTdHJpbmc+fSBzdXJmYWNlc1xuXHQgKiAgICAgU3VyZmFjZSBlbGVtZW50IGlkIG9yIHN1cmZhY2UgaW5zdGFuY2UuIFlvdSBjYW4gYWxzbyBwYXNzIGFuIEFycmF5XG5cdCAqICAgICB3aGljaGNvbnRhaW5zIHN1cmZhY2UgaW5zdGFuY2VzIG9yIGlkLiBJbiBjYXNlIG9mIElELCB0aGVzZSBzaG91bGQgYmVcblx0ICogICAgIHRoZSBpZCBvZiBzdXJmYWNlIGVsZW1lbnQuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFN1cmZhY2VzKHN1cmZhY2VzKSB7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KHN1cmZhY2VzKSkge1xuXHRcdFx0c3VyZmFjZXMgPSBbc3VyZmFjZXNdO1xuXHRcdH1cblx0XHRzdXJmYWNlcy5mb3JFYWNoKChzdXJmYWNlKSA9PiB7XG5cdFx0XHRpZiAoaXNTdHJpbmcoc3VyZmFjZSkpIHtcblx0XHRcdFx0c3VyZmFjZSA9IG5ldyBTdXJmYWNlKHN1cmZhY2UpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5zdXJmYWNlc1tzdXJmYWNlLmdldElkKCldID0gc3VyZmFjZTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGlmIGNhbiBuYXZpZ2F0ZSB0byBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHVybFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Y2FuTmF2aWdhdGUodXJsKSB7XG5cdFx0Y29uc3QgdXJpID0gdXRpbHMuaXNXZWJVcmkodXJsKTtcblxuXHRcdGlmICghdXJpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Y29uc3QgcGF0aCA9IHV0aWxzLmdldFVybFBhdGgodXJsKTtcblxuXHRcdGlmICghdGhpcy5pc0xpbmtTYW1lT3JpZ2luXyh1cmkuZ2V0SG9zdCgpKSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ09mZnNpdGUgbGluayBjbGlja2VkJyk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5pc1NhbWVCYXNlUGF0aF8ocGF0aCkpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdMaW5rIGNsaWNrZWQgb3V0c2lkZSBhcHBcXCdzIGJhc2UgcGF0aCcpO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHQvLyBQcmV2ZW50cyBuYXZpZ2F0aW9uIGlmIGl0J3MgYSBoYXNoIGNoYW5nZSBvbiB0aGUgc2FtZSB1cmwuXG5cdFx0aWYgKHVyaS5nZXRIYXNoKCkgJiYgdXRpbHMuaXNDdXJyZW50QnJvd3NlclBhdGgocGF0aCkpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCF0aGlzLmZpbmRSb3V0ZShwYXRoKSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ05vIHJvdXRlIGZvciAnICsgcGF0aCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQ2xlYXIgc2NyZWVucyBjYWNoZS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0Y2xlYXJTY3JlZW5zQ2FjaGUoKSB7XG5cdFx0T2JqZWN0LmtleXModGhpcy5zY3JlZW5zKS5mb3JFYWNoKChwYXRoKSA9PiB7XG5cdFx0XHRpZiAocGF0aCA9PT0gdGhpcy5hY3RpdmVQYXRoKSB7XG5cdFx0XHRcdHRoaXMuYWN0aXZlU2NyZWVuLmNsZWFyQ2FjaGUoKTtcblx0XHRcdH0gZWxzZSBpZiAoISh0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgJiYgdGhpcy5wZW5kaW5nTmF2aWdhdGUucGF0aCA9PT0gcGF0aCkpIHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTY3JlZW4ocGF0aCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIG9yIGNyZWF0ZSBhIHNjcmVlbiBpbnN0YW5jZSB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEByZXR1cm4ge1NjcmVlbn1cblx0ICovXG5cdGNyZWF0ZVNjcmVlbkluc3RhbmNlKHBhdGgsIHJvdXRlKSB7XG5cdFx0aWYgKCF0aGlzLnBlbmRpbmdOYXZpZ2F0ZSAmJiBwYXRoID09PSB0aGlzLmFjdGl2ZVBhdGgpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdBbHJlYWR5IGF0IGRlc3RpbmF0aW9uLCByZWZyZXNoIG5hdmlnYXRpb24nKTtcblx0XHRcdHJldHVybiB0aGlzLmFjdGl2ZVNjcmVlbjtcblx0XHR9XG5cdFx0LyoganNoaW50IG5ld2NhcDogZmFsc2UgKi9cblx0XHR2YXIgc2NyZWVuID0gdGhpcy5zY3JlZW5zW3BhdGhdO1xuXHRcdGlmICghc2NyZWVuKSB7XG5cdFx0XHR2YXIgaGFuZGxlciA9IHJvdXRlLmdldEhhbmRsZXIoKTtcblx0XHRcdGlmIChoYW5kbGVyID09PSBTY3JlZW4gfHwgU2NyZWVuLmlzSW1wbGVtZW50ZWRCeShoYW5kbGVyLnByb3RvdHlwZSkpIHtcblx0XHRcdFx0c2NyZWVuID0gbmV3IGhhbmRsZXIoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNjcmVlbiA9IGhhbmRsZXIocm91dGUpIHx8IG5ldyBTY3JlZW4oKTtcblx0XHRcdH1cblx0XHRcdGNvbnNvbGUubG9nKCdDcmVhdGUgc2NyZWVuIGZvciBbJyArIHBhdGggKyAnXSBbJyArIHNjcmVlbiArICddJyk7XG5cdFx0fVxuXHRcdHJldHVybiBzY3JlZW47XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4pIHtcblx0XHRcdHRoaXMucmVtb3ZlU2NyZWVuKHRoaXMuYWN0aXZlUGF0aCk7XG5cdFx0fVxuXHRcdHRoaXMuY2xlYXJTY3JlZW5zQ2FjaGUoKTtcblx0XHR0aGlzLmZvcm1FdmVudEhhbmRsZXJfLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0dGhpcy5saW5rRXZlbnRIYW5kbGVyXy5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdHRoaXMuYXBwRXZlbnRIYW5kbGVyc18ucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cdFx0c3VwZXIuZGlzcG9zZUludGVybmFsKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcGF0Y2hlcyB0byB0aGUgZmlyc3Qgcm91dGUgaGFuZGxlciB0aGF0IG1hdGNoZXMgdGhlIGN1cnJlbnQgcGF0aCwgaWZcblx0ICogYW55LlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IFJldHVybnMgYSBwZW5kaW5nIHJlcXVlc3QgY2FuY2VsbGFibGUgcHJvbWlzZS5cblx0ICovXG5cdGRpc3BhdGNoKCkge1xuXHRcdHJldHVybiB0aGlzLm5hdmlnYXRlKHV0aWxzLmdldEN1cnJlbnRCcm93c2VyUGF0aCgpLCB0cnVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgbmF2aWdhdGlvbiB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZXBsYWNlSGlzdG9yeSBSZXBsYWNlcyBicm93c2VyIGhpc3RvcnkuXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUmV0dXJucyBhIHBlbmRpbmcgcmVxdWVzdCBjYW5jZWxsYWJsZSBwcm9taXNlLlxuXHQgKi9cblx0ZG9OYXZpZ2F0ZV8ocGF0aCwgb3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0dmFyIHJvdXRlID0gdGhpcy5maW5kUm91dGUocGF0aCk7XG5cdFx0aWYgKCFyb3V0ZSkge1xuXHRcdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IoJ05vIHJvdXRlIGZvciAnICsgcGF0aCkpO1xuXHRcdFx0cmV0dXJuIHRoaXMucGVuZGluZ05hdmlnYXRlO1xuXHRcdH1cblxuXHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0ZSB0byBbJyArIHBhdGggKyAnXScpO1xuXG5cdFx0dGhpcy5zdG9wUGVuZGluZ05hdmlnYXRlXygpO1xuXHRcdHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyA9IHRydWU7XG5cblx0XHR2YXIgbmV4dFNjcmVlbiA9IHRoaXMuY3JlYXRlU2NyZWVuSW5zdGFuY2UocGF0aCwgcm91dGUpO1xuXG5cdFx0cmV0dXJuIHRoaXMubWF5YmVQcmV2ZW50RGVhY3RpdmF0ZV8oKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5tYXliZVByZXZlbnRBY3RpdmF0ZV8obmV4dFNjcmVlbikpXG5cdFx0XHQudGhlbigoKSA9PiBuZXh0U2NyZWVuLmxvYWQocGF0aCkpXG5cdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdC8vIEF0IHRoaXMgcG9pbnQgd2UgY2Fubm90IHN0b3AgbmF2aWdhdGlvbiBhbmQgYWxsIHJlY2VpdmVkXG5cdFx0XHRcdC8vIG5hdmlnYXRlIGNhbmRpZGF0ZXMgd2lsbCBiZSBxdWV1ZWQgYXQgc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLlxuXHRcdFx0XHR0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9IE5hdmlnYXRpb25TdHJhdGVneS5TQ0hFRFVMRV9MQVNUO1xuXG5cdFx0XHRcdGlmICh0aGlzLmFjdGl2ZVNjcmVlbikge1xuXHRcdFx0XHRcdHRoaXMuYWN0aXZlU2NyZWVuLmRlYWN0aXZhdGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLnByZXBhcmVOYXZpZ2F0ZUhpc3RvcnlfKHBhdGgsIG5leHRTY3JlZW4sIG9wdF9yZXBsYWNlSGlzdG9yeSk7XG5cdFx0XHRcdHRoaXMucHJlcGFyZU5hdmlnYXRlU3VyZmFjZXNfKFxuXHRcdFx0XHRcdG5leHRTY3JlZW4sXG5cdFx0XHRcdFx0dGhpcy5zdXJmYWNlcyxcblx0XHRcdFx0XHR0aGlzLmV4dHJhY3RQYXJhbXMocm91dGUsIHBhdGgpXG5cdFx0XHRcdCk7XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4oKCkgPT4gbmV4dFNjcmVlbi5ldmFsdWF0ZVN0eWxlcyh0aGlzLnN1cmZhY2VzKSlcblx0XHRcdC50aGVuKCgpID0+IG5leHRTY3JlZW4uZmxpcCh0aGlzLnN1cmZhY2VzKSlcblx0XHRcdC50aGVuKCgpID0+IG5leHRTY3JlZW4uZXZhbHVhdGVTY3JpcHRzKHRoaXMuc3VyZmFjZXMpKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5tYXliZVVwZGF0ZVNjcm9sbFBvc2l0aW9uU3RhdGVfKCkpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLnN5bmNTY3JvbGxQb3NpdGlvblN5bmNUaGVuQXN5bmNfKCkpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLmZpbmFsaXplTmF2aWdhdGVfKHBhdGgsIG5leHRTY3JlZW4pKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5tYXliZU92ZXJsb2FkQmVmb3JlVW5sb2FkXygpKVxuXHRcdFx0LmNhdGNoKChyZWFzb24pID0+IHtcblx0XHRcdFx0dGhpcy5pc05hdmlnYXRpb25QZW5kaW5nID0gZmFsc2U7XG5cdFx0XHRcdHRoaXMuaGFuZGxlTmF2aWdhdGVFcnJvcl8ocGF0aCwgbmV4dFNjcmVlbiwgcmVhc29uKTtcblx0XHRcdFx0dGhyb3cgcmVhc29uO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuQWx3YXlzKCgpID0+IHtcblx0XHRcdFx0dGhpcy5uYXZpZ2F0aW9uU3RyYXRlZ3kgPSBOYXZpZ2F0aW9uU3RyYXRlZ3kuSU1NRURJQVRFO1xuXG5cdFx0XHRcdGlmICh0aGlzLnNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZS5sZW5ndGgpIHtcblx0XHRcdFx0XHRjb25zdCBzY2hlZHVsZWROYXZpZ2F0aW9uID0gdGhpcy5zY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUuc2hpZnQoKTtcblx0XHRcdFx0XHR0aGlzLm1heWJlTmF2aWdhdGVfKHNjaGVkdWxlZE5hdmlnYXRpb24uaHJlZiwgc2NoZWR1bGVkTmF2aWdhdGlvbik7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIHBhcmFtcyBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHBhdGggYW5kIHJvdXRlLlxuXHQgKiBAcGFyYW0geyFSb3V0ZX0gcm91dGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcblx0ICogQHBhcmFtIHshT2JqZWN0fVxuXHQgKi9cblx0ZXh0cmFjdFBhcmFtcyhyb3V0ZSwgcGF0aCkge1xuXHRcdHJldHVybiByb3V0ZS5leHRyYWN0UGFyYW1zKHRoaXMuZ2V0Um91dGVQYXRoKHBhdGgpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaW5hbGl6ZXMgYSBzY3JlZW4gbmF2aWdhdGlvbi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHBhcmFtIHshU2NyZWVufSBuZXh0U2NyZWVuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGZpbmFsaXplTmF2aWdhdGVfKHBhdGgsIG5leHRTY3JlZW4pIHtcblx0XHRuZXh0U2NyZWVuLmFjdGl2YXRlKCk7XG5cblx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4gJiYgIXRoaXMuYWN0aXZlU2NyZWVuLmlzQ2FjaGVhYmxlKCkpIHtcblx0XHRcdGlmICh0aGlzLmFjdGl2ZVNjcmVlbiAhPT0gbmV4dFNjcmVlbikge1xuXHRcdFx0XHR0aGlzLnJlbW92ZVNjcmVlbih0aGlzLmFjdGl2ZVBhdGgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuYWN0aXZlUGF0aCA9IHBhdGg7XG5cdFx0dGhpcy5hY3RpdmVTY3JlZW4gPSBuZXh0U2NyZWVuO1xuXHRcdHRoaXMuYnJvd3NlclBhdGhCZWZvcmVOYXZpZ2F0ZSA9IHV0aWxzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCk7XG5cdFx0dGhpcy5zY3JlZW5zW3BhdGhdID0gbmV4dFNjcmVlbjtcblx0XHR0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgPSBmYWxzZTtcblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IG51bGw7XG5cdFx0Z2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50ID0gbnVsbDtcblx0XHRnbG9iYWxzLmNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQgPSBudWxsO1xuXHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0aW9uIGRvbmUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaW5kcyBhIHJvdXRlIGZvciB0aGUgdGVzdCBwYXRoLiBSZXR1cm5zIHRydWUgaWYgbWF0Y2hlcyBoYXMgYSByb3V0ZSxcblx0ICogb3RoZXJ3aXNlIHJldHVybnMgbnVsbC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHJldHVybiB7P09iamVjdH0gUm91dGUgaGFuZGxlciBpZiBtYXRjaCBhbnkgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlXG5cdCAqICAgICBwYXRoIGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IHVybCBhbmQgdGhlIHBhdGggY29udGFpbnMgYSBmcmFnbWVudC5cblx0ICovXG5cdGZpbmRSb3V0ZShwYXRoKSB7XG5cdFx0cGF0aCA9IHRoaXMuZ2V0Um91dGVQYXRoKHBhdGgpO1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5yb3V0ZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciByb3V0ZSA9IHRoaXMucm91dGVzW2ldO1xuXHRcdFx0aWYgKHJvdXRlLm1hdGNoZXNQYXRoKHBhdGgpKSB7XG5cdFx0XHRcdHJldHVybiByb3V0ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIGFsbG93IHByZXZlbnQgbmF2aWdhdGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRnZXRBbGxvd1ByZXZlbnROYXZpZ2F0ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIGxpbmsgYmFzZSBwYXRoLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0QmFzZVBhdGgoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYmFzZVBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZGVmYXVsdCBwYWdlIHRpdGxlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IGRlZmF1bHRUaXRsZVxuXHQgKi9cblx0Z2V0RGVmYXVsdFRpdGxlKCkge1xuXHRcdHJldHVybiB0aGlzLmRlZmF1bHRUaXRsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBmb3JtIHNlbGVjdG9yLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0Rm9ybVNlbGVjdG9yKCkge1xuXHRcdHJldHVybiB0aGlzLmZvcm1TZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVjayBpZiByb3V0ZSBtYXRjaGluZyBpcyBpZ25vcmluZyBxdWVyeSBzdHJpbmcgZnJvbSB0aGUgcm91dGUgcGF0aC5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGdldElnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCgpIHtcblx0XHRyZXR1cm4gdGhpcy5pZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbGluayBzZWxlY3Rvci5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldExpbmtTZWxlY3RvcigpIHtcblx0XHRyZXR1cm4gdGhpcy5saW5rU2VsZWN0b3I7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbG9hZGluZyBjc3MgY2xhc3MuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRMb2FkaW5nQ3NzQ2xhc3MoKSB7XG5cdFx0cmV0dXJuIHRoaXMubG9hZGluZ0Nzc0NsYXNzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGdpdmVuIHBhdGggZm9ybWF0dGVkIHRvIGJlIG1hdGNoZWQgYnkgYSByb3V0ZS4gVGhpcyB3aWxsLFxuXHQgKiBmb3IgZXhhbXBsZSwgcmVtb3ZlIHRoZSBiYXNlIHBhdGggZnJvbSBpdCwgYnV0IG1ha2Ugc3VyZSBpdCB3aWxsIGVuZFxuXHQgKiB3aXRoIGEgJy8nLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRSb3V0ZVBhdGgocGF0aCkge1xuXHRcdGlmICh0aGlzLmdldElnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCgpKSB7XG5cdFx0XHRwYXRoID0gdXRpbHMuZ2V0VXJsUGF0aFdpdGhvdXRIYXNoQW5kU2VhcmNoKHBhdGgpO1xuXHRcdFx0cmV0dXJuIHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaChwYXRoLnN1YnN0cih0aGlzLmJhc2VQYXRoLmxlbmd0aCkpO1xuXHRcdH1cblxuXHRcdHBhdGggPSB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2gocGF0aCk7XG5cdFx0cmV0dXJuIHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaChwYXRoLnN1YnN0cih0aGlzLmJhc2VQYXRoLmxlbmd0aCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gdmFsdWUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRnZXRVcGRhdGVTY3JvbGxQb3NpdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy51cGRhdGVTY3JvbGxQb3NpdGlvbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGUgbmF2aWdhdGlvbiBlcnJvci5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHBhcmFtIHshU2NyZWVufSBuZXh0U2NyZWVuXG5cdCAqIEBwYXJhbSB7IUVycm9yfSBlcnJvclxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRoYW5kbGVOYXZpZ2F0ZUVycm9yXyhwYXRoLCBuZXh0U2NyZWVuLCBlcnJvcikge1xuXHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0aW9uIGVycm9yIGZvciBbJyArIG5leHRTY3JlZW4gKyAnXSAoJyArIGVycm9yLnN0YWNrICsgJyknKTtcblx0XHR0aGlzLmVtaXQoJ25hdmlnYXRpb25FcnJvcicsIHtcblx0XHRcdGVycm9yLFxuXHRcdFx0bmV4dFNjcmVlbixcblx0XHRcdHBhdGhcblx0XHR9KTtcblx0XHRpZiAoIXV0aWxzLmlzQ3VycmVudEJyb3dzZXJQYXRoKHBhdGgpKSB7XG5cdFx0XHRpZiAodGhpcy5pc05hdmlnYXRpb25QZW5kaW5nICYmIHRoaXMucGVuZGluZ05hdmlnYXRlKSB7XG5cdFx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlLnRoZW5BbHdheXMoKCkgPT4gdGhpcy5yZW1vdmVTY3JlZW4ocGF0aCksIHRoaXMpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTY3JlZW4ocGF0aCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBhcHAgaGFzIHJvdXRlcy5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGhhc1JvdXRlcygpIHtcblx0XHRyZXR1cm4gdGhpcy5yb3V0ZXMubGVuZ3RoID4gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUZXN0cyBpZiBob3N0IGlzIGFuIG9mZnNpdGUgbGluay5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBob3N0IExpbmsgaG9zdCB0byBjb21wYXJlIHdpdGhcblx0ICogICAgIDxjb2RlPmdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhvc3Q8L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRpc0xpbmtTYW1lT3JpZ2luXyhob3N0KSB7XG5cdFx0Y29uc3QgaG9zdFVyaSA9IG5ldyBVcmkoaG9zdCk7XG5cdFx0Y29uc3QgbG9jYXRpb25Ib3N0VXJpID0gbmV3IFVyaShnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ob3N0KTtcblxuXHRcdHJldHVybiBob3N0VXJpLmdldFBvcnQoKSA9PT0gbG9jYXRpb25Ib3N0VXJpLmdldFBvcnQoKSAmJiBob3N0VXJpLmdldEhvc3RuYW1lKCkgPT09IGxvY2F0aW9uSG9zdFVyaS5nZXRIb3N0bmFtZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIGlmIGxpbmsgZWxlbWVudCBoYXMgdGhlIHNhbWUgYXBwJ3MgYmFzZSBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggTGluayBwYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGlzU2FtZUJhc2VQYXRoXyhwYXRoKSB7XG5cdFx0cmV0dXJuIHBhdGguaW5kZXhPZih0aGlzLmJhc2VQYXRoKSA9PT0gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBMb2NrIHRoZSBkb2N1bWVudCBzY3JvbGwgaW4gb3JkZXIgdG8gYXZvaWQgdGhlIGJyb3dzZXIgbmF0aXZlIGJhY2sgYW5kXG5cdCAqIGZvcndhcmQgbmF2aWdhdGlvbiB0byBjaGFuZ2UgdGhlIHNjcm9sbCBwb3NpdGlvbi4gSW4gdGhlIGVuZCBvZlxuXHQgKiBuYXZpZ2F0aW9uIGxpZmVjeWNsZSBzY3JvbGwgaXMgcmVwb3NpdGlvbmVkLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRsb2NrSGlzdG9yeVNjcm9sbFBvc2l0aW9uXygpIHtcblx0XHR2YXIgc3RhdGUgPSBnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnN0YXRlO1xuXHRcdGlmICghc3RhdGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Ly8gQnJvd3NlcnMgYXJlIGluY29uc2lzdGVudCB3aGVuIHJlLXBvc2l0aW9uaW5nIHRoZSBzY3JvbGwgaGlzdG9yeSBvblxuXHRcdC8vIHBvcHN0YXRlLiBBdCBzb21lIGJyb3dzZXJzLCBoaXN0b3J5IHNjcm9sbCBoYXBwZW5zIGJlZm9yZSBwb3BzdGF0ZSwgdGhlblxuXHRcdC8vIGxvY2sgdGhlIHNjcm9sbCBvbiB0aGUgbGFzdCBrbm93biBwb3NpdGlvbiBhcyBzb29uIGFzIHBvc3NpYmxlIGFmdGVyIHRoZVxuXHRcdC8vIGN1cnJlbnQgSlMgZXhlY3V0aW9uIGNvbnRleHQgYW5kIGNhcHR1cmUgdGhlIGN1cnJlbnQgdmFsdWUuIFNvbWUgb3RoZXJzLFxuXHRcdC8vIGhpc3Rvcnkgc2Nyb2xsIGhhcHBlbnMgYWZ0ZXIgcG9wc3RhdGUsIGluIHRoaXMgY2FzZSwgd2UgYmluZCBhbiBvbmNlXG5cdFx0Ly8gc2Nyb2xsIGV2ZW50IHRvIGxvY2sgdGhlIGxhcyBrbm93biBwb3NpdGlvbi4gTGFzdGx5LCB0aGUgcHJldmlvdXMgdHdvXG5cdFx0Ly8gYmVoYXZpb3JzIGNhbiBoYXBwZW4gZXZlbiBvbiB0aGUgc2FtZSBicm93c2VyLCBoZW5jZSB0aGUgcmFjZSB3aWxsIGRlY2lkZVxuXHRcdC8vIHRoZSB3aW5uZXIuXG5cdFx0dmFyIHdpbm5lciA9IGZhbHNlO1xuXHRcdHZhciBzd2l0Y2hTY3JvbGxQb3NpdGlvblJhY2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdGdsb2JhbHMuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgc3dpdGNoU2Nyb2xsUG9zaXRpb25SYWNlLCBmYWxzZSk7XG5cdFx0XHRpZiAoIXdpbm5lcikge1xuXHRcdFx0XHRnbG9iYWxzLndpbmRvdy5zY3JvbGxUbyhzdGF0ZS5zY3JvbGxMZWZ0LCBzdGF0ZS5zY3JvbGxUb3ApO1xuXHRcdFx0XHR3aW5uZXIgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0YXN5bmMubmV4dFRpY2soc3dpdGNoU2Nyb2xsUG9zaXRpb25SYWNlKTtcblx0XHRnbG9iYWxzLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHN3aXRjaFNjcm9sbFBvc2l0aW9uUmFjZSwgZmFsc2UpO1xuXHR9XG5cblx0LyoqXG5cdCAqIElmIHN1cHBvcnRlZCBieSB0aGUgYnJvd3NlciwgZGlzYWJsZXMgbmF0aXZlIHNjcm9sbCByZXN0b3JhdGlvbiBhbmRcblx0ICogc3RvcmVzIGN1cnJlbnQgdmFsdWUuXG5cdCAqL1xuXHRtYXliZURpc2FibGVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbigpIHtcblx0XHRpZiAodGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvblN1cHBvcnRlZCkge1xuXHRcdFx0dGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvbl8gPSBnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uO1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9ICdtYW51YWwnO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGV2YWx1YXRlIGlmIGlzIHBvc3NpYmxlIHRvIHF1ZXVlIHJlY2VpdmVkXG5cdCAqICBkb20gZXZlbnQgdG8gc2NoZWR1bGVOYXZpZ2F0aW9uUXVldWUgYW5kIGVucXVldWUgaXQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIEluZm9ybWF0aW9uIGFib3V0IHRoZSBsaW5rJ3MgaHJlZi5cblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnQgRG9tIGV2ZW50IHRoYXQgaW5pdGlhdGVkIHRoZSBuYXZpZ2F0aW9uLlxuXHQgKi9cblx0bWF5YmVTY2hlZHVsZU5hdmlnYXRpb25fKGhyZWYsIGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyAmJiB0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9PT0gTmF2aWdhdGlvblN0cmF0ZWd5LlNDSEVEVUxFX0xBU1QpIHtcblx0XHRcdHRoaXMuc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlID0gW29iamVjdC5taXhpbih7XG5cdFx0XHRcdGhyZWYsXG5cdFx0XHRcdGlzU2NoZWR1bGVkTmF2aWdhdGlvbjogdHJ1ZVxuXHRcdFx0fSwgZXZlbnQpXTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgbmF2aWdhdGUgdG8gYSBwYXRoLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaHJlZiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgbGluaydzIGhyZWYuXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IERvbSBldmVudCB0aGF0IGluaXRpYXRlZCB0aGUgbmF2aWdhdGlvbi5cblx0ICovXG5cdG1heWJlTmF2aWdhdGVfKGhyZWYsIGV2ZW50KSB7XG5cdFx0aWYgKCF0aGlzLmNhbk5hdmlnYXRlKGhyZWYpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgaXNOYXZpZ2F0aW9uU2NoZWR1bGVkID0gdGhpcy5tYXliZVNjaGVkdWxlTmF2aWdhdGlvbl8oaHJlZiwgZXZlbnQpO1xuXG5cdFx0aWYgKGlzTmF2aWdhdGlvblNjaGVkdWxlZCkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgbmF2aWdhdGVGYWlsZWQgPSBmYWxzZTtcblx0XHR0cnkge1xuXHRcdFx0dGhpcy5uYXZpZ2F0ZSh1dGlscy5nZXRVcmxQYXRoKGhyZWYpLCBmYWxzZSwgZXZlbnQpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Ly8gRG8gbm90IHByZXZlbnQgbGluayBuYXZpZ2F0aW9uIGluIGNhc2Ugc29tZSBzeW5jaHJvbm91cyBlcnJvciBvY2N1cnNcblx0XHRcdG5hdmlnYXRlRmFpbGVkID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoIW5hdmlnYXRlRmFpbGVkICYmICFldmVudC5pc1NjaGVkdWxlZE5hdmlnYXRpb24pIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyB3aGV0aGVyIHRoZSBvbmJlZm9yZXVubG9hZCBnbG9iYWwgZXZlbnQgaGFuZGxlciBpcyBvdmVybG9hZGVkXG5cdCAqIGJ5IGNsaWVudCBjb2RlLiBJZiBzbywgaXQgcmVwbGFjZXMgd2l0aCBhIGZ1bmN0aW9uIHRoYXQgaGFsdHMgdGhlIG5vcm1hbFxuXHQgKiBldmVudCBmbG93IGluIHJlbGF0aW9uIHdpdGggdGhlIGNsaWVudCBvbmJlZm9yZXVubG9hZCBmdW5jdGlvbi5cblx0ICogVGhpcyBjYW4gYmUgaW4gbW9zdCBwYXJ0IHVzZWQgdG8gcHJlbWF0dXJlbHkgdGVybWluYXRlIG5hdmlnYXRpb24gdG8gb3RoZXIgcGFnZXNcblx0ICogYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBjb25zdHJhaXQocykuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG1heWJlT3ZlcmxvYWRCZWZvcmVVbmxvYWRfKCkge1xuXHRcdGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2Ygd2luZG93Lm9uYmVmb3JldW5sb2FkKSB7XG5cdFx0XHR3aW5kb3cuX29uYmVmb3JldW5sb2FkID0gd2luZG93Lm9uYmVmb3JldW5sb2FkO1xuXG5cdFx0XHR3aW5kb3cub25iZWZvcmV1bmxvYWQgPSBldmVudCA9PiB7XG5cdFx0XHRcdHRoaXMuZW1pdCgnYmVmb3JlVW5sb2FkJywgZXZlbnQpO1xuXHRcdFx0XHRpZiAoZXZlbnQgJiYgZXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBtYXJrIHRoZSB1cGRhdGVkIGhhbmRsZXIgZHVlIHVud2FudGVkIHJlY3Vyc2lvblxuXHRcdFx0d2luZG93Lm9uYmVmb3JldW5sb2FkLl9vdmVybG9hZGVkID0gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2FuY2VscyBuYXZpZ2F0aW9uIGlmIG5leHRTY3JlZW4ncyBiZWZvcmVBY3RpdmF0ZSBsaWZlY3ljbGUgbWV0aG9kXG5cdCAqIHJlc29sdmVzIHRvIHRydWUuXG5cdCAqIEBwYXJhbSB7IVNjcmVlbn0gbmV4dFNjcmVlblxuXHQgKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlfVxuXHQgKi9cblx0bWF5YmVQcmV2ZW50QWN0aXZhdGVfKG5leHRTY3JlZW4pIHtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gbmV4dFNjcmVlbi5iZWZvcmVBY3RpdmF0ZSgpO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuKHByZXZlbnQgPT4ge1xuXHRcdFx0XHRpZiAocHJldmVudCkge1xuXHRcdFx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gQ2FuY2VsbGFibGVQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yKCdDYW5jZWxsZWQgYnkgbmV4dCBzY3JlZW4nKSk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMucGVuZGluZ05hdmlnYXRlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYW5jZWxzIG5hdmlnYXRpb24gaWYgYWN0aXZlU2NyZWVuJ3MgYmVmb3JlRGVhY3RpdmF0ZSBsaWZlY3ljbGVcblx0ICogbWV0aG9kIHJlc29sdmVzIHRvIHRydWUuXG5cdCAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9XG5cdCAqL1xuXHRtYXliZVByZXZlbnREZWFjdGl2YXRlXygpIHtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4pIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5hY3RpdmVTY3JlZW4uYmVmb3JlRGVhY3RpdmF0ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4ocHJldmVudCA9PiB7XG5cdFx0XHRcdGlmIChwcmV2ZW50KSB7XG5cdFx0XHRcdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IoJ0NhbmNlbGxlZCBieSBhY3RpdmUgc2NyZWVuJykpO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgcmVwb3NpdGlvbiBzY3JvbGwgdG8gaGFzaGVkIGFuY2hvci5cblx0ICovXG5cdG1heWJlUmVwb3NpdGlvblNjcm9sbFRvSGFzaGVkQW5jaG9yKCkge1xuXHRcdGNvbnN0IGhhc2ggPSBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdGlmIChoYXNoKSB7XG5cdFx0XHRsZXQgYW5jaG9yRWxlbWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGFzaC5zdWJzdHJpbmcoMSkpO1xuXHRcdFx0aWYgKGFuY2hvckVsZW1lbnQpIHtcblx0XHRcdFx0Y29uc3Qge29mZnNldExlZnQsIG9mZnNldFRvcH0gPSB1dGlscy5nZXROb2RlT2Zmc2V0KGFuY2hvckVsZW1lbnQpO1xuXHRcdFx0XHRnbG9iYWxzLndpbmRvdy5zY3JvbGxUbyhvZmZzZXRMZWZ0LCBvZmZzZXRUb3ApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBJZiBzdXBwb3J0ZWQgYnkgdGhlIGJyb3dzZXIsIHJlc3RvcmVzIG5hdGl2ZSBzY3JvbGwgcmVzdG9yYXRpb24gdG8gdGhlXG5cdCAqIHZhbHVlIGNhcHR1cmVkIGJ5IGBtYXliZURpc2FibGVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbmAuXG5cdCAqL1xuXHRtYXliZVJlc3RvcmVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbigpIHtcblx0XHRpZiAodGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvblN1cHBvcnRlZCAmJiB0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uXykge1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IHRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25fO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSByZXN0b3JlIHJlZGlyZWN0ZWQgcGF0aCBoYXNoIGluIGNhc2UgYm90aCB0aGUgY3VycmVudCBwYXRoIGFuZFxuXHQgKiB0aGUgZ2l2ZW4gcGF0aCBhcmUgdGhlIHNhbWUuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGJlZm9yZSBuYXZpZ2F0aW9uLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHJlZGlyZWN0UGF0aCBQYXRoIGFmdGVyIG5hdmlnYXRpb24uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaGFzaCBIYXNoIHRvIGJlIGFkZGVkIHRvIHRoZSBwYXRoLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfSBSZXR1cm5zIHRoZSBwYXRoIHdpdGggdGhlIGhhc2ggcmVzdG9yZWQuXG5cdCAqL1xuXHRtYXliZVJlc3RvcmVSZWRpcmVjdFBhdGhIYXNoXyhwYXRoLCByZWRpcmVjdFBhdGgsIGhhc2gpIHtcblx0XHRpZiAocmVkaXJlY3RQYXRoID09PSB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2gocGF0aCkpIHtcblx0XHRcdHJldHVybiByZWRpcmVjdFBhdGggKyBoYXNoO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVkaXJlY3RQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gaW4gaGlzdG9yeSBzdGF0ZSB0byBhbmNob3Igb24gcGF0aC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyBhbmNob3Jcblx0ICovXG5cdG1heWJlVXBkYXRlU2Nyb2xsUG9zaXRpb25TdGF0ZV8oKSB7XG5cdFx0dmFyIGhhc2ggPSBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdHZhciBhbmNob3JFbGVtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChoYXNoLnN1YnN0cmluZygxKSk7XG5cdFx0aWYgKGFuY2hvckVsZW1lbnQpIHtcblx0XHRcdGNvbnN0IHtvZmZzZXRMZWZ0LCBvZmZzZXRUb3B9ID0gdXRpbHMuZ2V0Tm9kZU9mZnNldChhbmNob3JFbGVtZW50KTtcblx0XHRcdHRoaXMuc2F2ZUhpc3RvcnlDdXJyZW50UGFnZVNjcm9sbFBvc2l0aW9uXyhvZmZzZXRUb3AsIG9mZnNldExlZnQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBOYXZpZ2F0ZXMgdG8gdGhlIHNwZWNpZmllZCBwYXRoIGlmIHRoZXJlIGlzIGEgcm91dGUgaGFuZGxlciB0aGF0IG1hdGNoZXMuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIHRvIG5hdmlnYXRlIGNvbnRhaW5pbmcgdGhlIGJhc2UgcGF0aC5cblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JlcGxhY2VIaXN0b3J5IFJlcGxhY2VzIGJyb3dzZXIgaGlzdG9yeS5cblx0ICogQHBhcmFtIHtFdmVudD19IGV2ZW50IE9wdGlvbmFsIGV2ZW50IG9iamVjdCB0aGF0IHRyaWdnZXJlZCB0aGUgbmF2aWdhdGlvbi5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfSBSZXR1cm5zIGEgcGVuZGluZyByZXF1ZXN0IGNhbmNlbGxhYmxlIHByb21pc2UuXG5cdCAqL1xuXHRuYXZpZ2F0ZShwYXRoLCBvcHRfcmVwbGFjZUhpc3RvcnksIG9wdF9ldmVudCkge1xuXHRcdGlmICghdXRpbHMuaXNIdG1sNUhpc3RvcnlTdXBwb3J0ZWQoKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdIVE1MNSBIaXN0b3J5IGlzIG5vdCBzdXBwb3J0ZWQuIFNlbm5hIHdpbGwgbm90IGludGVyY2VwdCBuYXZpZ2F0aW9uLicpO1xuXHRcdH1cblxuXHRcdGlmIChvcHRfZXZlbnQpIHtcblx0XHRcdGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCA9IG9wdF9ldmVudC5jYXB0dXJlZEZvcm1FbGVtZW50O1xuXHRcdFx0Z2xvYmFscy5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50ID0gb3B0X2V2ZW50LmNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gV2hlbiByZWxvYWRpbmcgdGhlIHNhbWUgcGF0aCBkbyByZXBsYWNlU3RhdGUgaW5zdGVhZCBvZiBwdXNoU3RhdGUgdG9cblx0XHQvLyBhdm9pZCBwb2xsdXRpbmcgaGlzdG9yeSB3aXRoIHN0YXRlcyB3aXRoIHRoZSBzYW1lIHBhdGguXG5cdFx0aWYgKHBhdGggPT09IHRoaXMuYWN0aXZlUGF0aCkge1xuXHRcdFx0b3B0X3JlcGxhY2VIaXN0b3J5ID0gdHJ1ZTtcblx0XHR9XG5cblx0XHR0aGlzLmVtaXQoJ2JlZm9yZU5hdmlnYXRlJywge1xuXHRcdFx0ZXZlbnQ6IG9wdF9ldmVudCxcblx0XHRcdHBhdGg6IHBhdGgsXG5cdFx0XHRyZXBsYWNlSGlzdG9yeTogISFvcHRfcmVwbGFjZUhpc3Rvcnlcblx0XHR9KTtcblxuXHRcdHJldHVybiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBCZWZvcmVzIG5hdmlnYXRpb24gdG8gYSBwYXRoLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlIGNvbnRhaW5pbmcgPGNvZGU+cGF0aDwvY29kZT4gYW5kXG5cdCAqICAgICA8Y29kZT5yZXBsYWNlSGlzdG9yeTwvY29kZT4uXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uQmVmb3JlTmF2aWdhdGVfKGV2ZW50KSB7XG5cdFx0aWYgKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCkge1xuXHRcdFx0ZXZlbnQuZm9ybSA9IGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudDtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQmVmb3JlcyBuYXZpZ2F0aW9uIHRvIGEgcGF0aC4gUnVucyBhZnRlciBleHRlcm5hbCBsaXN0ZW5lcnMuXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGUgY29udGFpbmluZyA8Y29kZT5wYXRoPC9jb2RlPiBhbmRcblx0ICogICAgIDxjb2RlPnJlcGxhY2VIaXN0b3J5PC9jb2RlPi5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25CZWZvcmVOYXZpZ2F0ZURlZmF1bHRfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMucGVuZGluZ05hdmlnYXRlKSB7XG5cdFx0XHRpZiAodGhpcy5wZW5kaW5nTmF2aWdhdGUucGF0aCA9PT0gZXZlbnQucGF0aCB8fCB0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9PT0gTmF2aWdhdGlvblN0cmF0ZWd5LlNDSEVEVUxFX0xBU1QpIHtcblx0XHRcdFx0Y29uc29sZS5sb2coJ1dhaXRpbmcuLi4nKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuZW1pdCgnYmVmb3JlVW5sb2FkJywgZXZlbnQpO1xuXG5cdFx0dGhpcy5lbWl0KCdzdGFydE5hdmlnYXRlJywge1xuXHRcdFx0Zm9ybTogZXZlbnQuZm9ybSxcblx0XHRcdHBhdGg6IGV2ZW50LnBhdGgsXG5cdFx0XHRyZXBsYWNlSGlzdG9yeTogZXZlbnQucmVwbGFjZUhpc3Rvcnlcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0aGF0IGV4ZWN1dGVzIHRoZSBvcmlnaW5hbCBsaXN0ZW5lciB0aGF0IGhhcyBiZWVuXG5cdCAqIGFkZGVkIGJ5IHRoZSBjbGllbnQgY29kZSBhbmQgdGVybWluYXRlcyB0aGUgbmF2aWdhdGlvbiBhY2NvcmRpbmdseS5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IG9yaWdpbmFsIEV2ZW50IGZhY2FkZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25CZWZvcmVVbmxvYWREZWZhdWx0XyhldmVudCkge1xuXHRcdHZhciBmdW5jID0gd2luZG93Ll9vbmJlZm9yZXVubG9hZDtcblx0XHRpZiAoZnVuYyAmJiAhZnVuYy5fb3ZlcmxvYWRlZCAmJiBmdW5jKCkpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEludGVyY2VwdHMgZG9jdW1lbnQgY2xpY2tzIGFuZCB0ZXN0IGxpbmsgZWxlbWVudHMgaW4gb3JkZXIgdG8gZGVjaWRlXG5cdCAqIHdoZXRoZXIgU3VyZmFjZSBhcHAgY2FuIG5hdmlnYXRlLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uRG9jQ2xpY2tEZWxlZ2F0ZV8oZXZlbnQpIHtcblx0XHRpZiAoZXZlbnQuYWx0S2V5IHx8IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBldmVudC5zaGlmdEtleSB8fCBldmVudC5idXR0b24pIHtcblx0XHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0ZSBhYm9ydGVkLCBpbnZhbGlkIG1vdXNlIGJ1dHRvbiBvciBtb2RpZmllciBrZXkgcHJlc3NlZC4nKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5tYXliZU5hdmlnYXRlXyhldmVudC5kZWxlZ2F0ZVRhcmdldC5ocmVmLCBldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogSW50ZXJjZXB0cyBkb2N1bWVudCBmb3JtIHN1Ym1pdHMgYW5kIHRlc3QgYWN0aW9uIHBhdGggaW4gb3JkZXIgdG8gZGVjaWRlXG5cdCAqIHdoZXRoZXIgU3VyZmFjZSBhcHAgY2FuIG5hdmlnYXRlLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uRG9jU3VibWl0RGVsZWdhdGVfKGV2ZW50KSB7XG5cdFx0dmFyIGZvcm0gPSBldmVudC5kZWxlZ2F0ZVRhcmdldDtcblx0XHRpZiAoZm9ybS5tZXRob2QgPT09ICdnZXQnKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnR0VUIG1ldGhvZCBub3Qgc3VwcG9ydGVkJyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGV2ZW50LmNhcHR1cmVkRm9ybUVsZW1lbnQgPSBmb3JtO1xuXHRcdGNvbnN0IGJ1dHRvblNlbGVjdG9yID0gJ2J1dHRvbjpub3QoW3R5cGVdKSxidXR0b25bdHlwZT1zdWJtaXRdLGlucHV0W3R5cGU9c3VibWl0XSc7XG5cdFx0aWYgKG1hdGNoKGdsb2JhbHMuZG9jdW1lbnQuYWN0aXZlRWxlbWVudCwgYnV0dG9uU2VsZWN0b3IpKSB7XG5cdFx0XHRldmVudC5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRldmVudC5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50ID0gZm9ybS5xdWVyeVNlbGVjdG9yKGJ1dHRvblNlbGVjdG9yKTtcblx0XHR9XG5cdFx0dGhpcy5tYXliZU5hdmlnYXRlXyhmb3JtLmFjdGlvbiwgZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIExpc3RlbnMgdG8gdGhlIHdpbmRvdydzIGxvYWQgZXZlbnQgaW4gb3JkZXIgdG8gYXZvaWQgaXNzdWVzIHdpdGggc29tZSBicm93c2Vyc1xuXHQgKiB0aGF0IHRyaWdnZXIgcG9wc3RhdGUgY2FsbHMgb24gdGhlIGZpcnN0IGxvYWQuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZVxuXHQgKiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzY0MjE3NjkvcG9wc3RhdGUtb24tcGFnZXMtbG9hZC1pbi1jaHJvbWUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uTG9hZF8oKSB7XG5cdFx0dGhpcy5za2lwTG9hZFBvcHN0YXRlID0gdHJ1ZTtcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdC8vIFRoZSB0aW1lb3V0IGVuc3VyZXMgdGhhdCBwb3BzdGF0ZSBldmVudHMgd2lsbCBiZSB1bmJsb2NrZWQgcmlnaHRcblx0XHRcdC8vIGFmdGVyIHRoZSBsb2FkIGV2ZW50IG9jY3VyZWQsIGJ1dCBub3QgaW4gdGhlIHNhbWUgZXZlbnQtbG9vcCBjeWNsZS5cblx0XHRcdHRoaXMuc2tpcExvYWRQb3BzdGF0ZSA9IGZhbHNlO1xuXHRcdH0sIDApO1xuXHRcdC8vIFRyeSB0byByZXBvc2l0aW9uIHNjcm9sbCB0byB0aGUgaGFzaGVkIGFuY2hvciB3aGVuIHBhZ2UgbG9hZHMuXG5cdFx0dGhpcy5tYXliZVJlcG9zaXRpb25TY3JvbGxUb0hhc2hlZEFuY2hvcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhhbmRsZXMgYnJvd3NlciBoaXN0b3J5IGNoYW5nZXMgYW5kIGZpcmVzIGFwcCdzIG5hdmlnYXRpb24gaWYgdGhlIHN0YXRlXG5cdCAqIGJlbG93cyB0byB1cy4gSWYgd2UgZGV0ZWN0IGEgcG9wc3RhdGUgYW5kIHRoZSBzdGF0ZSBpcyA8Y29kZT5udWxsPC9jb2RlPixcblx0ICogYXNzdW1lIGl0IGlzIG5hdmlnYXRpbmcgdG8gYW4gZXh0ZXJuYWwgcGFnZSBvciB0byBhIHBhZ2Ugd2UgZG9uJ3QgaGF2ZVxuXHQgKiByb3V0ZSwgdGhlbiA8Y29kZT5nbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTwvY29kZT4gaXMgaW52b2tlZCBpbiBvcmRlciB0b1xuXHQgKiByZWxvYWQgdGhlIGNvbnRlbnQgdG8gdGhlIGN1cnJlbnQgdXJsLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uUG9wc3RhdGVfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuc2tpcExvYWRQb3BzdGF0ZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERvIG5vdCBuYXZpZ2F0ZSBpZiB0aGUgcG9wc3RhdGUgd2FzIHRyaWdnZXJlZCBieSBhIGhhc2ggY2hhbmdlLlxuXHRcdGlmICh1dGlscy5pc0N1cnJlbnRCcm93c2VyUGF0aCh0aGlzLmJyb3dzZXJQYXRoQmVmb3JlTmF2aWdhdGUpKSB7XG5cdFx0XHR0aGlzLm1heWJlUmVwb3NpdGlvblNjcm9sbFRvSGFzaGVkQW5jaG9yKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIHN0YXRlID0gZXZlbnQuc3RhdGU7XG5cblx0XHRpZiAoIXN0YXRlKSB7XG5cdFx0XHRpZiAoZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaGFzaCkge1xuXHRcdFx0XHQvLyBJZiBzZW5uYSBpcyBvbiBhbiByZWRpcmVjdCBwYXRoIGFuZCBhIGhhc2ggcG9wc3RhdGUgaGFwcGVuc1xuXHRcdFx0XHQvLyB0byBhIGRpZmZlcmVudCB1cmwsIHJlbG9hZCB0aGUgYnJvd3Nlci4gVGhpcyBiZWhhdmlvciBkb2Vzbid0XG5cdFx0XHRcdC8vIHJlcXVpcmUgc2VubmEgdG8gcm91dGUgaGFzaGVkIGxpbmtzIGFuZCBpcyBjbG9zZXIgdG8gbmF0aXZlXG5cdFx0XHRcdC8vIGJyb3dzZXIgYmVoYXZpb3IuXG5cdFx0XHRcdGlmICh0aGlzLnJlZGlyZWN0UGF0aCAmJiAhdXRpbHMuaXNDdXJyZW50QnJvd3NlclBhdGgodGhpcy5yZWRpcmVjdFBhdGgpKSB7XG5cdFx0XHRcdFx0dGhpcy5yZWxvYWRQYWdlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gQWx3YXlzIHRyeSB0byByZXBvc2l0aW9uIHNjcm9sbCB0byB0aGUgaGFzaGVkIGFuY2hvciB3aGVuXG5cdFx0XHRcdC8vIGhhc2ggcG9wc3RhdGUgaGFwcGVucy5cblx0XHRcdFx0dGhpcy5tYXliZVJlcG9zaXRpb25TY3JvbGxUb0hhc2hlZEFuY2hvcigpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5yZWxvYWRQYWdlKCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKHN0YXRlLnNlbm5hKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnSGlzdG9yeSBuYXZpZ2F0aW9uIHRvIFsnICsgc3RhdGUucGF0aCArICddJyk7XG5cdFx0XHR0aGlzLnBvcHN0YXRlU2Nyb2xsVG9wID0gc3RhdGUuc2Nyb2xsVG9wO1xuXHRcdFx0dGhpcy5wb3BzdGF0ZVNjcm9sbExlZnQgPSBzdGF0ZS5zY3JvbGxMZWZ0O1xuXHRcdFx0aWYgKCF0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uU3VwcG9ydGVkKSB7XG5cdFx0XHRcdHRoaXMubG9ja0hpc3RvcnlTY3JvbGxQb3NpdGlvbl8oKTtcblx0XHRcdH1cblx0XHRcdHRoaXMub25jZSgnZW5kTmF2aWdhdGUnLCAoKSA9PiB7XG5cdFx0XHRcdGlmIChzdGF0ZS5yZWZlcnJlcikge1xuXHRcdFx0XHRcdHV0aWxzLnNldFJlZmVycmVyKHN0YXRlLnJlZmVycmVyKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRjb25zdCB1cmkgPSBuZXcgVXJpKHN0YXRlLnBhdGgpO1xuXHRcdFx0dXJpLnNldEhvc3RuYW1lKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhvc3RuYW1lKTtcblx0XHRcdHVyaS5zZXRQb3J0KGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnBvcnQpO1xuXHRcdFx0Y29uc3QgaXNOYXZpZ2F0aW9uU2NoZWR1bGVkID0gdGhpcy5tYXliZVNjaGVkdWxlTmF2aWdhdGlvbl8odXJpLnRvU3RyaW5nKCksIHt9KTtcblx0XHRcdGlmIChpc05hdmlnYXRpb25TY2hlZHVsZWQpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5uYXZpZ2F0ZShzdGF0ZS5wYXRoLCB0cnVlKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTGlzdGVucyBkb2N1bWVudCBzY3JvbGwgY2hhbmdlcyBpbiBvcmRlciB0byBjYXB0dXJlIHRoZSBwb3NzaWJsZSBsb2NrXG5cdCAqIHNjcm9sbCBwb3NpdGlvbiBmb3IgaGlzdG9yeSBzY3JvbGxpbmcuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uU2Nyb2xsXygpIHtcblx0XHRpZiAodGhpcy5jYXB0dXJlU2Nyb2xsUG9zaXRpb25Gcm9tU2Nyb2xsRXZlbnQpIHtcblx0XHRcdHRoaXMuc2F2ZUhpc3RvcnlDdXJyZW50UGFnZVNjcm9sbFBvc2l0aW9uXyhnbG9iYWxzLndpbmRvdy5wYWdlWU9mZnNldCwgZ2xvYmFscy53aW5kb3cucGFnZVhPZmZzZXQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgbmF2aWdhdGlvbiB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGUgY29udGFpbmluZyA8Y29kZT5wYXRoPC9jb2RlPiBhbmRcblx0ICogICAgIDxjb2RlPnJlcGxhY2VIaXN0b3J5PC9jb2RlPi5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25TdGFydE5hdmlnYXRlXyhldmVudCkge1xuXHRcdHRoaXMubWF5YmVEaXNhYmxlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb24oKTtcblx0XHR0aGlzLmNhcHR1cmVTY3JvbGxQb3NpdGlvbkZyb21TY3JvbGxFdmVudCA9IGZhbHNlO1xuXHRcdGFkZENsYXNzZXMoZ2xvYmFscy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIHRoaXMubG9hZGluZ0Nzc0NsYXNzKTtcblxuXHRcdHZhciBlbmROYXZpZ2F0ZVBheWxvYWQgPSB7XG5cdFx0XHRmb3JtOiBldmVudC5mb3JtLFxuXHRcdFx0cGF0aDogZXZlbnQucGF0aFxuXHRcdH07XG5cblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IHRoaXMuZG9OYXZpZ2F0ZV8oZXZlbnQucGF0aCwgZXZlbnQucmVwbGFjZUhpc3RvcnkpXG5cdFx0XHQuY2F0Y2goKHJlYXNvbikgPT4ge1xuXHRcdFx0XHRlbmROYXZpZ2F0ZVBheWxvYWQuZXJyb3IgPSByZWFzb247XG5cdFx0XHRcdHRocm93IHJlYXNvbjtcblx0XHRcdH0pXG5cdFx0XHQudGhlbkFsd2F5cygoKSA9PiB7XG5cdFx0XHRcdGlmICghdGhpcy5wZW5kaW5nTmF2aWdhdGUgJiYgIXRoaXMuc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLmxlbmd0aCkge1xuXHRcdFx0XHRcdHJlbW92ZUNsYXNzZXMoZ2xvYmFscy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIHRoaXMubG9hZGluZ0Nzc0NsYXNzKTtcblx0XHRcdFx0XHR0aGlzLm1heWJlUmVzdG9yZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uKCk7XG5cdFx0XHRcdFx0dGhpcy5jYXB0dXJlU2Nyb2xsUG9zaXRpb25Gcm9tU2Nyb2xsRXZlbnQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuZW1pdCgnZW5kTmF2aWdhdGUnLCBlbmROYXZpZ2F0ZVBheWxvYWQpO1xuXHRcdFx0fSk7XG5cblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZS5wYXRoID0gZXZlbnQucGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQcmVmZXRjaGVzIHRoZSBzcGVjaWZpZWQgcGF0aCBpZiB0aGVyZSBpcyBhIHJvdXRlIGhhbmRsZXIgdGhhdCBtYXRjaGVzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCB0byBuYXZpZ2F0ZSBjb250YWluaW5nIHRoZSBiYXNlIHBhdGguXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUmV0dXJucyBhIHBlbmRpbmcgcmVxdWVzdCBjYW5jZWxsYWJsZSBwcm9taXNlLlxuXHQgKi9cblx0cHJlZmV0Y2gocGF0aCkge1xuXHRcdHZhciByb3V0ZSA9IHRoaXMuZmluZFJvdXRlKHBhdGgpO1xuXHRcdGlmICghcm91dGUpIHtcblx0XHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IoJ05vIHJvdXRlIGZvciAnICsgcGF0aCkpO1xuXHRcdH1cblxuXHRcdGNvbnNvbGUubG9nKCdQcmVmZXRjaGluZyBbJyArIHBhdGggKyAnXScpO1xuXG5cdFx0dmFyIG5leHRTY3JlZW4gPSB0aGlzLmNyZWF0ZVNjcmVlbkluc3RhbmNlKHBhdGgsIHJvdXRlKTtcblxuXHRcdHJldHVybiBuZXh0U2NyZWVuLmxvYWQocGF0aClcblx0XHRcdC50aGVuKCgpID0+IHRoaXMuc2NyZWVuc1twYXRoXSA9IG5leHRTY3JlZW4pXG5cdFx0XHQuY2F0Y2goKHJlYXNvbikgPT4ge1xuXHRcdFx0XHR0aGlzLmhhbmRsZU5hdmlnYXRlRXJyb3JfKHBhdGgsIG5leHRTY3JlZW4sIHJlYXNvbik7XG5cdFx0XHRcdHRocm93IHJlYXNvbjtcblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFByZXBhcmVzIHNjcmVlbiBmbGlwLiBVcGRhdGVzIGhpc3Rvcnkgc3RhdGUgYW5kIHN1cmZhY2VzIGNvbnRlbnQuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEBwYXJhbSB7IVNjcmVlbn0gbmV4dFNjcmVlblxuXHQgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmVwbGFjZUhpc3RvcnkgUmVwbGFjZXMgYnJvd3NlciBoaXN0b3J5LlxuXHQgKi9cblx0cHJlcGFyZU5hdmlnYXRlSGlzdG9yeV8ocGF0aCwgbmV4dFNjcmVlbiwgb3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0bGV0IHRpdGxlID0gbmV4dFNjcmVlbi5nZXRUaXRsZSgpO1xuXHRcdGlmICghaXNTdHJpbmcodGl0bGUpKSB7XG5cdFx0XHR0aXRsZSA9IHRoaXMuZ2V0RGVmYXVsdFRpdGxlKCk7XG5cdFx0fVxuXHRcdGxldCByZWRpcmVjdFBhdGggPSBuZXh0U2NyZWVuLmJlZm9yZVVwZGF0ZUhpc3RvcnlQYXRoKHBhdGgpO1xuXHRcdGNvbnN0IGhpc3RvcnlTdGF0ZSA9IHtcblx0XHRcdGZvcm06IGlzRGVmQW5kTm90TnVsbChnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQpLFxuXHRcdFx0cGF0aCxcblx0XHRcdHJlZGlyZWN0UGF0aCxcblx0XHRcdHNjcm9sbExlZnQ6IDAsXG5cdFx0XHRzY3JvbGxUb3A6IDAsXG5cdFx0XHRzZW5uYTogdHJ1ZVxuXHRcdH07XG5cdFx0aWYgKG9wdF9yZXBsYWNlSGlzdG9yeSkge1xuXHRcdFx0aGlzdG9yeVN0YXRlLnNjcm9sbFRvcCA9IHRoaXMucG9wc3RhdGVTY3JvbGxUb3A7XG5cdFx0XHRoaXN0b3J5U3RhdGUuc2Nyb2xsTGVmdCA9IHRoaXMucG9wc3RhdGVTY3JvbGxMZWZ0O1xuXHRcdH1cblx0XHRjb25zdCBoYXNoID0gbmV3IFVyaShwYXRoKS5nZXRIYXNoKCk7XG5cdFx0cmVkaXJlY3RQYXRoID0gdGhpcy5tYXliZVJlc3RvcmVSZWRpcmVjdFBhdGhIYXNoXyhwYXRoLCByZWRpcmVjdFBhdGgsIGhhc2gpO1xuXHRcdHRoaXMudXBkYXRlSGlzdG9yeV8odGl0bGUsIHJlZGlyZWN0UGF0aCwgbmV4dFNjcmVlbi5iZWZvcmVVcGRhdGVIaXN0b3J5U3RhdGUoaGlzdG9yeVN0YXRlKSwgb3B0X3JlcGxhY2VIaXN0b3J5KTtcblx0XHR0aGlzLnJlZGlyZWN0UGF0aCA9IHJlZGlyZWN0UGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQcmVwYXJlcyBzY3JlZW4gZmxpcC4gVXBkYXRlcyBoaXN0b3J5IHN0YXRlIGFuZCBzdXJmYWNlcyBjb250ZW50LlxuXHQgKiBAcGFyYW0geyFTY3JlZW59IG5leHRTY3JlZW5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBzdXJmYWNlcyBNYXAgb2Ygc3VyZmFjZXMgdG8gZmxpcCBrZXllZCBieSBzdXJmYWNlIGlkLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IHBhcmFtcyBQYXJhbXMgZXh0cmFjdGVkIGZyb20gdGhlIGN1cnJlbnQgcGF0aC5cblx0ICovXG5cdHByZXBhcmVOYXZpZ2F0ZVN1cmZhY2VzXyhuZXh0U2NyZWVuLCBzdXJmYWNlcywgcGFyYW1zKSB7XG5cdFx0T2JqZWN0LmtleXMoc3VyZmFjZXMpLmZvckVhY2goKGlkKSA9PiB7XG5cdFx0XHR2YXIgc3VyZmFjZUNvbnRlbnQgPSBuZXh0U2NyZWVuLmdldFN1cmZhY2VDb250ZW50KGlkLCBwYXJhbXMpO1xuXHRcdFx0c3VyZmFjZXNbaWRdLmFkZENvbnRlbnQobmV4dFNjcmVlbi5nZXRJZCgpLCBzdXJmYWNlQ29udGVudCk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgbmV4dFNjcmVlbi5nZXRJZCgpICsgJ10gYWRkIGNvbnRlbnQgdG8gc3VyZmFjZSAnICtcblx0XHRcdFx0J1snICsgc3VyZmFjZXNbaWRdICsgJ10gWycgKyAoaXNEZWZBbmROb3ROdWxsKHN1cmZhY2VDb250ZW50KSA/ICcuLi4nIDogJ2VtcHR5JykgKyAnXScpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbG9hZHMgdGhlIHBhZ2UgYnkgcGVyZm9ybWluZyBgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpYC5cblx0ICovXG5cdHJlbG9hZFBhZ2UoKSB7XG5cdFx0Z2xvYmFscy53aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyByb3V0ZSBpbnN0YW5jZSBmcm9tIGFwcCByb3V0ZXMuXG5cdCAqIEBwYXJhbSB7Um91dGV9IHJvdXRlXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgYW4gZWxlbWVudCB3YXMgcmVtb3ZlZC5cblx0ICovXG5cdHJlbW92ZVJvdXRlKHJvdXRlKSB7XG5cdFx0cmV0dXJuIGFycmF5LnJlbW92ZSh0aGlzLnJvdXRlcywgcm91dGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYSBzY3JlZW4uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqL1xuXHRyZW1vdmVTY3JlZW4ocGF0aCkge1xuXHRcdHZhciBzY3JlZW4gPSB0aGlzLnNjcmVlbnNbcGF0aF07XG5cdFx0aWYgKHNjcmVlbikge1xuXHRcdFx0T2JqZWN0LmtleXModGhpcy5zdXJmYWNlcykuZm9yRWFjaCgoc3VyZmFjZUlkKSA9PiB0aGlzLnN1cmZhY2VzW3N1cmZhY2VJZF0ucmVtb3ZlKHNjcmVlbi5nZXRJZCgpKSk7XG5cdFx0XHRzY3JlZW4uZGlzcG9zZSgpO1xuXHRcdFx0ZGVsZXRlIHRoaXMuc2NyZWVuc1twYXRoXTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2F2ZXMgZ2l2ZW4gc2Nyb2xsIHBvc2l0aW9uIGludG8gaGlzdG9yeSBzdGF0ZS5cblx0ICogQHBhcmFtIHshbnVtYmVyfSBzY3JvbGxUb3AgTnVtYmVyIGNvbnRhaW5pbmcgdGhlIHRvcCBzY3JvbGwgcG9zaXRpb24gdG8gYmUgc2F2ZWQuXG5cdCAqIEBwYXJhbSB7IW51bWJlcn0gc2Nyb2xsTGVmdCBOdW1iZXIgY29udGFpbmluZyB0aGUgbGVmdCBzY3JvbGwgcG9zaXRpb24gdG8gYmUgc2F2ZWQuXG5cdCAqL1xuXHRzYXZlSGlzdG9yeUN1cnJlbnRQYWdlU2Nyb2xsUG9zaXRpb25fKHNjcm9sbFRvcCwgc2Nyb2xsTGVmdCkge1xuXHRcdHZhciBzdGF0ZSA9IGdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc3RhdGU7XG5cdFx0aWYgKHN0YXRlICYmIHN0YXRlLnNlbm5hKSB7XG5cdFx0XHRbc3RhdGUuc2Nyb2xsVG9wLCBzdGF0ZS5zY3JvbGxMZWZ0XSA9IFtzY3JvbGxUb3AsIHNjcm9sbExlZnRdO1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoc3RhdGUsIG51bGwsIG51bGwpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIGFsbG93IHByZXZlbnQgbmF2aWdhdGUuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gYWxsb3dQcmV2ZW50TmF2aWdhdGVcblx0ICovXG5cdHNldEFsbG93UHJldmVudE5hdmlnYXRlKGFsbG93UHJldmVudE5hdmlnYXRlKSB7XG5cdFx0dGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZSA9IGFsbG93UHJldmVudE5hdmlnYXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgbGluayBiYXNlIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aFxuXHQgKi9cblx0c2V0QmFzZVBhdGgoYmFzZVBhdGgpIHtcblx0XHR0aGlzLmJhc2VQYXRoID0gdXRpbHMucmVtb3ZlUGF0aFRyYWlsaW5nU2xhc2goYmFzZVBhdGgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGRlZmF1bHQgcGFnZSB0aXRsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGRlZmF1bHRUaXRsZVxuXHQgKi9cblx0c2V0RGVmYXVsdFRpdGxlKGRlZmF1bHRUaXRsZSkge1xuXHRcdHRoaXMuZGVmYXVsdFRpdGxlID0gZGVmYXVsdFRpdGxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGZvcm0gc2VsZWN0b3IuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gZm9ybVNlbGVjdG9yXG5cdCAqL1xuXHRzZXRGb3JtU2VsZWN0b3IoZm9ybVNlbGVjdG9yKSB7XG5cdFx0dGhpcy5mb3JtU2VsZWN0b3IgPSBmb3JtU2VsZWN0b3I7XG5cdFx0aWYgKHRoaXMuZm9ybUV2ZW50SGFuZGxlcl8pIHtcblx0XHRcdHRoaXMuZm9ybUV2ZW50SGFuZGxlcl8ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR9XG5cdFx0dGhpcy5mb3JtRXZlbnRIYW5kbGVyXyA9IGRlbGVnYXRlKGRvY3VtZW50LCAnc3VibWl0JywgdGhpcy5mb3JtU2VsZWN0b3IsIHRoaXMub25Eb2NTdWJtaXREZWxlZ2F0ZV8uYmluZCh0aGlzKSwgdGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBpZiByb3V0ZSBtYXRjaGluZyBzaG91bGQgaWdub3JlIHF1ZXJ5IHN0cmluZyBmcm9tIHRoZSByb3V0ZSBwYXRoLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aFxuXHQgKi9cblx0c2V0SWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoKGlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCkge1xuXHRcdHRoaXMuaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoID0gaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGxpbmsgc2VsZWN0b3IuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gbGlua1NlbGVjdG9yXG5cdCAqL1xuXHRzZXRMaW5rU2VsZWN0b3IobGlua1NlbGVjdG9yKSB7XG5cdFx0dGhpcy5saW5rU2VsZWN0b3IgPSBsaW5rU2VsZWN0b3I7XG5cdFx0aWYgKHRoaXMubGlua0V2ZW50SGFuZGxlcl8pIHtcblx0XHRcdHRoaXMubGlua0V2ZW50SGFuZGxlcl8ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR9XG5cdFx0dGhpcy5saW5rRXZlbnRIYW5kbGVyXyA9IGRlbGVnYXRlKGRvY3VtZW50LCAnY2xpY2snLCB0aGlzLmxpbmtTZWxlY3RvciwgdGhpcy5vbkRvY0NsaWNrRGVsZWdhdGVfLmJpbmQodGhpcyksIHRoaXMuYWxsb3dQcmV2ZW50TmF2aWdhdGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGxvYWRpbmcgY3NzIGNsYXNzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGxvYWRpbmdDc3NDbGFzc1xuXHQgKi9cblx0c2V0TG9hZGluZ0Nzc0NsYXNzKGxvYWRpbmdDc3NDbGFzcykge1xuXHRcdHRoaXMubG9hZGluZ0Nzc0NsYXNzID0gbG9hZGluZ0Nzc0NsYXNzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gdmFsdWUuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gdXBkYXRlU2Nyb2xsUG9zaXRpb25cblx0ICovXG5cdHNldFVwZGF0ZVNjcm9sbFBvc2l0aW9uKHVwZGF0ZVNjcm9sbFBvc2l0aW9uKSB7XG5cdFx0dGhpcy51cGRhdGVTY3JvbGxQb3NpdGlvbiA9IHVwZGF0ZVNjcm9sbFBvc2l0aW9uO1xuXHR9XG5cblx0LyoqXG5cdCAqIENhbmNlbHMgcGVuZGluZyBuYXZpZ2F0ZSB3aXRoIDxjb2RlPkNhbmNlbCBwZW5kaW5nIG5hdmlnYXRpb248L2NvZGU+IGVycm9yLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzdG9wUGVuZGluZ05hdmlnYXRlXygpIHtcblx0XHRpZiAodGhpcy5wZW5kaW5nTmF2aWdhdGUpIHtcblx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlLmNhbmNlbCgnQ2FuY2VsIHBlbmRpbmcgbmF2aWdhdGlvbicpO1xuXHRcdH1cblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogU3luYyBkb2N1bWVudCBzY3JvbGwgcG9zaXRpb24gdHdpY2UsIHRoZSBmaXJzdCBvbmUgc3luY2hyb25vdXMgYW5kIHRoZW5cblx0ICogb25lIGluc2lkZSA8Y29kZT5hc3luYy5uZXh0VGljazwvY29kZT4uIFJlbGV2YW50IHRvIGJyb3dzZXJzIHRoYXQgZmlyZXNcblx0ICogc2Nyb2xsIHJlc3RvcmF0aW9uIGFzeW5jaHJvbm91c2x5IGFmdGVyIHBvcHN0YXRlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEByZXR1cm4gez9DYW5jZWxsYWJsZVByb21pc2U9fVxuXHQgKi9cblx0c3luY1Njcm9sbFBvc2l0aW9uU3luY1RoZW5Bc3luY18oKSB7XG5cdFx0dmFyIHN0YXRlID0gZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5zdGF0ZTtcblx0XHRpZiAoIXN0YXRlKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIHNjcm9sbFRvcCA9IHN0YXRlLnNjcm9sbFRvcDtcblx0XHR2YXIgc2Nyb2xsTGVmdCA9IHN0YXRlLnNjcm9sbExlZnQ7XG5cblx0XHR2YXIgc3luYyA9ICgpID0+IHtcblx0XHRcdGlmICh0aGlzLnVwZGF0ZVNjcm9sbFBvc2l0aW9uKSB7XG5cdFx0XHRcdGdsb2JhbHMud2luZG93LnNjcm9sbFRvKHNjcm9sbExlZnQsIHNjcm9sbFRvcCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiBzeW5jKCkgJiBhc3luYy5uZXh0VGljaygoKSA9PiBzeW5jKCkgJiByZXNvbHZlKCkpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIG9yIHJlcGxhY2UgYnJvd3NlciBoaXN0b3J5LlxuXHQgKiBAcGFyYW0gez9zdHJpbmd9IHRpdGxlIERvY3VtZW50IHRpdGxlLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcGFyYW0geyFvYmplY3R9IHN0YXRlXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZXBsYWNlSGlzdG9yeSBSZXBsYWNlcyBicm93c2VyIGhpc3RvcnkuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHVwZGF0ZUhpc3RvcnlfKHRpdGxlLCBwYXRoLCBzdGF0ZSwgb3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0Y29uc3QgcmVmZXJyZXIgPSBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ocmVmO1xuXG5cdFx0aWYgKHN0YXRlKSB7XG5cdFx0XHRzdGF0ZS5yZWZlcnJlciA9IHJlZmVycmVyO1xuXHRcdH1cblxuXHRcdGlmIChvcHRfcmVwbGFjZUhpc3RvcnkpIHtcblx0XHRcdGdsb2JhbHMud2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHN0YXRlLCB0aXRsZSwgcGF0aCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGdsb2JhbHMud2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKHN0YXRlLCB0aXRsZSwgcGF0aCk7XG5cdFx0fVxuXG5cdFx0dXRpbHMuc2V0UmVmZXJyZXIocmVmZXJyZXIpO1xuXG5cdFx0bGV0IHRpdGxlTm9kZSA9IGdsb2JhbHMuZG9jdW1lbnQucXVlcnlTZWxlY3RvcigndGl0bGUnKTtcblx0XHRpZiAodGl0bGVOb2RlKSB7XG5cdFx0XHR0aXRsZU5vZGUuaW5uZXJIVE1MID0gdGl0bGU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGdsb2JhbHMuZG9jdW1lbnQudGl0bGUgPSB0aXRsZTtcblx0XHR9XG5cdH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBBcHA7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGlzRGVmLCBpc0RlZkFuZE5vdE51bGwgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgVXJpIGZyb20gJ21ldGFsLXVyaSc7XG5pbXBvcnQgeyBDYW5jZWxsYWJsZVByb21pc2UgYXMgUHJvbWlzZSB9IGZyb20gJ21ldGFsLXByb21pc2UnO1xuXG5jbGFzcyBBamF4IHtcblxuXHQvKipcblx0ICogWG1sSHR0cFJlcXVlc3QncyBnZXRBbGxSZXNwb25zZUhlYWRlcnMoKSBtZXRob2QgcmV0dXJucyBhIHN0cmluZyBvZlxuXHQgKiByZXNwb25zZSBoZWFkZXJzIGFjY29yZGluZyB0byB0aGUgZm9ybWF0IGRlc2NyaWJlZCBvbiB0aGUgc3BlYzpcblx0ICoge0BsaW5rIGh0dHA6Ly93d3cudzMub3JnL1RSL1hNTEh0dHBSZXF1ZXN0LyN0aGUtZ2V0YWxscmVzcG9uc2VoZWFkZXJzLW1ldGhvZH0uXG5cdCAqIFRoaXMgbWV0aG9kIHBhcnNlcyB0aGF0IHN0cmluZyBpbnRvIGEgdXNlci1mcmllbmRseSBuYW1lL3ZhbHVlIHBhaXJcblx0ICogb2JqZWN0LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gYWxsSGVhZGVycyBBbGwgaGVhZGVycyBhcyBzdHJpbmcuXG5cdCAqIEByZXR1cm4geyFBcnJheS48T2JqZWN0PHN0cmluZywgc3RyaW5nPj59XG5cdCAqL1xuXHRzdGF0aWMgcGFyc2VSZXNwb25zZUhlYWRlcnMoYWxsSGVhZGVycykge1xuXHRcdHZhciBoZWFkZXJzID0gW107XG5cdFx0aWYgKCFhbGxIZWFkZXJzKSB7XG5cdFx0XHRyZXR1cm4gaGVhZGVycztcblx0XHR9XG5cdFx0dmFyIHBhaXJzID0gYWxsSGVhZGVycy5zcGxpdCgnXFx1MDAwZFxcdTAwMGEnKTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHBhaXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgaW5kZXggPSBwYWlyc1tpXS5pbmRleE9mKCdcXHUwMDNhXFx1MDAyMCcpO1xuXHRcdFx0aWYgKGluZGV4ID4gMCkge1xuXHRcdFx0XHR2YXIgbmFtZSA9IHBhaXJzW2ldLnN1YnN0cmluZygwLCBpbmRleCk7XG5cdFx0XHRcdHZhciB2YWx1ZSA9IHBhaXJzW2ldLnN1YnN0cmluZyhpbmRleCArIDIpO1xuXHRcdFx0XHRoZWFkZXJzLnB1c2goe1xuXHRcdFx0XHRcdG5hbWU6IG5hbWUsXG5cdFx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gaGVhZGVycztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXF1ZXN0cyB0aGUgdXJsIHVzaW5nIFhNTEh0dHBSZXF1ZXN0LlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHVybFxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IG1ldGhvZFxuXHQgKiBAcGFyYW0gez9zdHJpbmd9IGJvZHlcblx0ICogQHBhcmFtIHtNdWx0aU1hcD19IG9wdF9oZWFkZXJzXG5cdCAqIEBwYXJhbSB7TXVsdGlNYXA9fSBvcHRfcGFyYW1zXG5cdCAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3RpbWVvdXRcblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3N5bmNcblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3dpdGhDcmVkZW50aWFsc1xuXHQgKiBAcmV0dXJuIHtQcm9taXNlfSBEZWZlcnJlZCBhamF4IHJlcXVlc3QuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHN0YXRpYyByZXF1ZXN0KHVybCwgbWV0aG9kLCBib2R5LCBvcHRfaGVhZGVycywgb3B0X3BhcmFtcywgb3B0X3RpbWVvdXQsIG9wdF9zeW5jLCBvcHRfd2l0aENyZWRlbnRpYWxzKSB7XG5cdFx0dXJsID0gdXJsIHx8ICcnO1xuXHRcdG1ldGhvZCA9IG1ldGhvZCB8fCAnR0VUJztcblxuXHRcdHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cdFx0dmFyIHByZXZpb3VzUmVhZHlTdGF0ZSA9IDA7XG5cblx0XHR2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdFx0cmVxdWVzdC5vbmxvYWQgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKHJlcXVlc3QuYWJvcnRlZCkge1xuXHRcdFx0XHRcdHJlcXVlc3Qub25lcnJvcigpO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXNvbHZlKHJlcXVlc3QpO1xuXHRcdFx0fTtcblx0XHRcdHJlcXVlc3Qub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmIChwcmV2aW91c1JlYWR5U3RhdGUgJiYgcHJldmlvdXNSZWFkeVN0YXRlIDwgMyAmJiA0ID09PSByZXF1ZXN0LnJlYWR5U3RhdGUpIHtcblx0XHRcdFx0XHRyZXF1ZXN0LnRlcm1pbmF0ZWRQcmVtYXR1cmVseSA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0cHJldmlvdXNSZWFkeVN0YXRlID0gcmVxdWVzdC5yZWFkeVN0YXRlO1xuXHRcdFx0fTtcblx0XHRcdHJlcXVlc3Qub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbWVzc2FnZSA9ICdSZXF1ZXN0IGVycm9yJztcblx0XHRcdFx0aWYgKHJlcXVlc3QudGVybWluYXRlZFByZW1hdHVyZWx5KSB7XG5cdFx0XHRcdFx0bWVzc2FnZSA9ICdSZXF1ZXN0IHRlcm1pbmF0ZWQgcHJlbWF0dXJlbHknO1xuXHRcdFx0XHR9IFxuXHRcdFx0XHR2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG5cdFx0XHRcdGVycm9yLnJlcXVlc3QgPSByZXF1ZXN0O1xuXHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0fTtcblx0XHR9KS50aGVuQ2F0Y2goZnVuY3Rpb24ocmVhc29uKSB7XG5cdFx0XHRyZXF1ZXN0LmFib3J0KCk7XG5cdFx0XHR0aHJvdyByZWFzb247XG5cdFx0fSkudGhlbkFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblx0XHR9KTtcblxuXHRcdHVybCA9IG5ldyBVcmkodXJsKTtcblxuXHRcdGlmIChvcHRfcGFyYW1zKSB7XG5cdFx0XHR1cmwuYWRkUGFyYW1ldGVyc0Zyb21NdWx0aU1hcChvcHRfcGFyYW1zKS50b1N0cmluZygpO1xuXHRcdH1cblxuXHRcdHVybCA9IHVybC50b1N0cmluZygpO1xuXG5cdFx0cmVxdWVzdC5vcGVuKG1ldGhvZCwgdXJsLCAhb3B0X3N5bmMpO1xuXG5cdFx0aWYgKG9wdF93aXRoQ3JlZGVudGlhbHMpIHtcblx0XHRcdHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAob3B0X2hlYWRlcnMpIHtcblx0XHRcdG9wdF9oZWFkZXJzLm5hbWVzKCkuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG5cdFx0XHRcdHJlcXVlc3Quc2V0UmVxdWVzdEhlYWRlcihuYW1lLCBvcHRfaGVhZGVycy5nZXRBbGwobmFtZSkuam9pbignLCAnKSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRyZXF1ZXN0LnNlbmQoaXNEZWYoYm9keSkgPyBib2R5IDogbnVsbCk7XG5cblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKG9wdF90aW1lb3V0KSkge1xuXHRcdFx0dmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRwcm9taXNlLmNhbmNlbCgnUmVxdWVzdCB0aW1lb3V0Jyk7XG5cdFx0XHR9LCBvcHRfdGltZW91dCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHByb21pc2U7XG5cdH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBBamF4O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEhvbGRzIHZhbHVlIGVycm9yIG1lc3NhZ2VzLlxuICogQGNvbnN0XG4gKi9cbmNsYXNzIGVycm9ycyB7XG59XG5cbi8qKlxuICogSW52YWxpZCBzdGF0dXMgZXJyb3IgbWVzc2FnZS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cbmVycm9ycy5JTlZBTElEX1NUQVRVUyA9ICdJbnZhbGlkIHN0YXR1cyBjb2RlJztcblxuLyoqXG4gKiBSZXF1ZXN0IGVycm9yIG1lc3NhZ2UuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQHN0YXRpY1xuICovXG5lcnJvcnMuUkVRVUVTVF9FUlJPUiA9ICdSZXF1ZXN0IGVycm9yJztcblxuLyoqXG4gKiBSZXF1ZXN0IHRpbWVvdXQgZXJyb3IgbWVzc2FnZS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cbmVycm9ycy5SRVFVRVNUX1RJTUVPVVQgPSAnUmVxdWVzdCB0aW1lb3V0JztcblxuLyoqXG4gKiBSZXF1ZXN0IGlzIGJsb2NrZWQgYnkgQ09SUyBpc3N1ZSBtZXNzYWdlLlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuZXJyb3JzLlJFUVVFU1RfUFJFTUFUVVJFX1RFUk1JTkFUSU9OID0gJ1JlcXVlc3QgdGVybWluYXRlZCBwcmVtYXR1cmVseSc7XG5cbmV4cG9ydCBkZWZhdWx0IGVycm9ycztcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtpc1NlcnZlclNpZGV9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBNZXRhbC5qcyBicm93c2VyIHVzZXIgYWdlbnQgZGV0ZWN0aW9uLiBJdCdzIGV4dHJlbWVseSByZWNvbW1lbmRlZCB0aGUgdXNhZ2VcbiAqIG9mIGZlYXR1cmUgY2hlY2tpbmcgb3ZlciBicm93c2VyIHVzZXIgYWdlbnQgc25pZmZpbmcuIFVuZm9ydHVuYXRlbHksIGluIHNvbWVcbiAqIHNpdHVhdGlvbnMgZmVhdHVyZSBjaGVja2luZyBjYW4gYmUgc2xvdyBvciBldmVuIGltcG9zc2libGUsIHRoZXJlZm9yZSB1c2VcbiAqIHRoaXMgdXRpbGl0eSB3aXRoIGNhdXRpb24uXG4gKiBAc2VlIDxhIGhyZWY9XCJodHRwOi8vd3d3LnVzZXJhZ2VudHN0cmluZy5jb20vXCI+VXNlciBhZ2VudCBzdHJpbmdzPC9hPi5cbiAqL1xuY2xhc3MgVUEge1xuXHQvKipcblx0ICogR2V0cyB0aGUgbmF0aXZlIHVzZXJBZ2VudCBzdHJpbmcgZnJvbSBuYXZpZ2F0b3IgaWYgaXQgZXhpc3RzLiBJZlxuXHQgKiBuYXZpZ2F0b3Igb3IgbmF2aWdhdG9yLnVzZXJBZ2VudCBzdHJpbmcgaXMgbWlzc2luZywgcmV0dXJucyBhbiBlbXB0eVxuXHQgKiBzdHJpbmcuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICogQHByaXZhdGVcblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldE5hdGl2ZVVzZXJBZ2VudCgpIHtcblx0XHRsZXQgbmF2aWdhdG9yID0gVUEuZ2xvYmFscy53aW5kb3cgJiYgVUEuZ2xvYmFscy53aW5kb3cubmF2aWdhdG9yO1xuXHRcdGlmIChuYXZpZ2F0b3IpIHtcblx0XHRcdGxldCB1c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuXHRcdFx0aWYgKHVzZXJBZ2VudCkge1xuXHRcdFx0XHRyZXR1cm4gdXNlckFnZW50O1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gJyc7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbmF0aXZlIHBsYXRmb3JtIHN0cmluZyBmcm9tIG5hdmlnYXRvciBpZiBpdCBleGlzdHMuIElmXG5cdCAqIG5hdmlnYXRvciBvciBuYXZpZ2F0b3IucGxhdGZvcm0gc3RyaW5nIGlzIG1pc3NpbmcsIHJldHVybnMgYW4gZW1wdHlcblx0ICogc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXROYXRpdmVQbGF0Zm9ybSgpIHtcblx0XHRsZXQgbmF2aWdhdG9yID0gVUEuZ2xvYmFscy53aW5kb3cgJiYgVUEuZ2xvYmFscy53aW5kb3cubmF2aWdhdG9yO1xuXHRcdGlmIChuYXZpZ2F0b3IpIHtcblx0XHRcdGxldCBwbGF0Zm9ybSA9IG5hdmlnYXRvci5wbGF0Zm9ybTtcblx0XHRcdGlmIChwbGF0Zm9ybSkge1xuXHRcdFx0XHRyZXR1cm4gcGxhdGZvcm07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAnJztcblx0fVxuXG5cdC8qKlxuXHQgKiBXaGV0aGVyIHRoZSBwbGF0Zm9ybSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLCBpZ25vcmluZyBjYXNlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBtYXRjaFBsYXRmb3JtKHN0cikge1xuXHRcdHJldHVybiBVQS5wbGF0Zm9ybS5pbmRleE9mKHN0cikgIT09IC0xO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdoZXRoZXIgdGhlIHVzZXIgYWdlbnQgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZywgaWdub3JpbmcgY2FzZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0clxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgbWF0Y2hVc2VyQWdlbnQoc3RyKSB7XG5cdFx0cmV0dXJuIFVBLnVzZXJBZ2VudC5pbmRleE9mKHN0cikgIT09IC0xO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHRoZSB1c2VyIGFnZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdXNlckFnZW50IFRoZSB1c2VyIGFnZW50IHN0cmluZy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBsYXRmb3JtXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyB0ZXN0VXNlckFnZW50KHVzZXJBZ2VudCA9ICcnLCBwbGF0Zm9ybSA9ICcnKSB7XG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHVzZXIgYWdlbnQgdmFsdWUgZXh0cmFjdGVkIGZyb20gYnJvd3NlciBuYXRpdmUgdXNlciBhZ2VudC5cblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS51c2VyQWdlbnQgPSB1c2VyQWdlbnQ7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgcGxhdGZvcm0gdmFsdWUgZXh0cmFjdGVkIGZyb20gYnJvd3NlciBuYXRpdmUgcGxhdGZvcm0uXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBPUyBpcyBNYWMuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzTWFjID0gVUEubWF0Y2hQbGF0Zm9ybSgnTWFjJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgT1MgaXMgV2luLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc1dpbiA9IFVBLm1hdGNoUGxhdGZvcm0oJ1dpbicpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgT3BlcmEuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzT3BlcmEgPSBVQS5tYXRjaFVzZXJBZ2VudCgnT3BlcmEnKSB8fCBVQS5tYXRjaFVzZXJBZ2VudCgnT1BSJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBJRS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNJZSA9IFVBLm1hdGNoVXNlckFnZW50KCdUcmlkZW50JykgfHwgVUEubWF0Y2hVc2VyQWdlbnQoJ01TSUUnKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIEVkZ2UuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzRWRnZSA9IFVBLm1hdGNoVXNlckFnZW50KCdFZGdlJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBJRSBvciBFZGdlLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc0llT3JFZGdlID0gVUEuaXNJZSB8fCBVQS5pc0VkZ2U7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBDaHJvbWUuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzQ2hyb21lID1cblx0XHRcdChVQS5tYXRjaFVzZXJBZ2VudCgnQ2hyb21lJykgfHwgVUEubWF0Y2hVc2VyQWdlbnQoJ0NyaU9TJykpICYmXG5cdFx0XHQhVUEuaXNPcGVyYSAmJlxuXHRcdFx0IVVBLmlzRWRnZTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIFNhZmFyaS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNTYWZhcmkgPVxuXHRcdFx0VUEubWF0Y2hVc2VyQWdlbnQoJ1NhZmFyaScpICYmXG5cdFx0XHQhKFVBLmlzQ2hyb21lIHx8IFVBLmlzT3BlcmEgfHwgVUEuaXNFZGdlKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIEZpcmVmb3guXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzRmlyZWZveCA9IFVBLm1hdGNoVXNlckFnZW50KCdGaXJlZm94Jyk7XG5cdH1cbn1cblxuLyoqXG4gKiBFeHBvc2VzIGdsb2JhbCByZWZlcmVuY2VzLlxuICogQHR5cGUge29iamVjdH1cbiAqIEBzdGF0aWNcbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFVBLCAnZ2xvYmFscycsIHtcblx0d3JpdGFibGU6IHRydWUsXG5cdHZhbHVlOiB7XG5cdFx0d2luZG93OiBpc1NlcnZlclNpZGUoKSA/IG51bGwgOiB3aW5kb3csXG5cdH0sXG59KTtcblxuVUEudGVzdFVzZXJBZ2VudChVQS5nZXROYXRpdmVVc2VyQWdlbnQoKSwgVUEuZ2V0TmF0aXZlUGxhdGZvcm0oKSk7XG5cbmV4cG9ydCBkZWZhdWx0IFVBO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0RlZkFuZE5vdE51bGwgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgQWpheCBmcm9tICdtZXRhbC1hamF4JztcbmltcG9ydCB7IE11bHRpTWFwIH0gZnJvbSAnbWV0YWwtc3RydWN0cyc7XG5pbXBvcnQgQ2FuY2VsbGFibGVQcm9taXNlIGZyb20gJ21ldGFsLXByb21pc2UnO1xuaW1wb3J0IGVycm9ycyBmcm9tICcuLi9lcnJvcnMvZXJyb3JzJztcbmltcG9ydCB1dGlscyBmcm9tICcuLi91dGlscy91dGlscyc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFNjcmVlbiBmcm9tICcuL1NjcmVlbic7XG5pbXBvcnQgVXJpIGZyb20gJ21ldGFsLXVyaSc7XG5pbXBvcnQgVUEgZnJvbSAnbWV0YWwtdXNlcmFnZW50JztcblxuY2xhc3MgUmVxdWVzdFNjcmVlbiBleHRlbmRzIFNjcmVlbiB7XG5cblx0LyoqXG5cdCAqIFJlcXVlc3Qgc2NyZWVuIGFic3RyYWN0IGNsYXNzIHRvIHBlcmZvcm0gaW8gb3BlcmF0aW9ucyBvbiBkZXNjZW5kYW50XG5cdCAqIHNjcmVlbnMuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAZXh0ZW5kcyB7U2NyZWVufVxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEBpbmhlcml0RG9jXG5cdFx0ICogQGRlZmF1bHQgdHJ1ZVxuXHRcdCAqL1xuXHRcdHRoaXMuY2FjaGVhYmxlID0gdHJ1ZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGRlZmF1bHQgaHR0cCBoZWFkZXJzIHRvIHNldCBvbiByZXF1ZXN0LlxuXHRcdCAqIEB0eXBlIHs/T2JqZWN0PX1cblx0XHQgKiBAZGVmYXVsdCB7XG5cdFx0ICogICAnWC1QSkFYJzogJ3RydWUnLFxuXHRcdCAqICAgJ1gtUmVxdWVzdGVkLVdpdGgnOiAnWE1MSHR0cFJlcXVlc3QnXG5cdFx0ICogfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmh0dHBIZWFkZXJzID0ge1xuXHRcdFx0J1gtUEpBWCc6ICd0cnVlJyxcblx0XHRcdCdYLVJlcXVlc3RlZC1XaXRoJzogJ1hNTEh0dHBSZXF1ZXN0J1xuXHRcdH07XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBkZWZhdWx0IGh0dHAgbWV0aG9kIHRvIHBlcmZvcm0gdGhlIHJlcXVlc3QuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgUmVxdWVzdFNjcmVlbi5HRVRcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5odHRwTWV0aG9kID0gUmVxdWVzdFNjcmVlbi5HRVQ7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgWEhSIG9iamVjdCByZXNwb25zaWJsZSBmb3IgdGhlIHJlcXVlc3QuXG5cdFx0ICogQHR5cGUge1hNTEh0dHBSZXF1ZXN0fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5yZXF1ZXN0ID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuXHRcdCAqIEB0eXBlIHshbnVtYmVyfVxuXHRcdCAqIEBkZWZhdWx0IDMwMDAwXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMudGltZW91dCA9IDMwMDAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFzc2VydHMgdGhhdCByZXNwb25zZSBzdGF0dXMgY29kZSBpcyB2YWxpZC5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXR1c1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRhc3NlcnRWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZShzdGF0dXMpIHtcblx0XHRpZiAoIXRoaXMuaXNWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZShzdGF0dXMpKSB7XG5cdFx0XHR2YXIgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3JzLklOVkFMSURfU1RBVFVTKTtcblx0XHRcdGVycm9yLmludmFsaWRTdGF0dXMgPSB0cnVlO1xuXHRcdFx0ZXJyb3Iuc3RhdHVzQ29kZSA9IHN0YXR1cztcblx0XHRcdHRocm93IGVycm9yO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0YmVmb3JlVXBkYXRlSGlzdG9yeVBhdGgocGF0aCkge1xuXHRcdHZhciByZWRpcmVjdFBhdGggPSB0aGlzLmdldFJlcXVlc3RQYXRoKCk7XG5cdFx0aWYgKHJlZGlyZWN0UGF0aCAmJiByZWRpcmVjdFBhdGggIT09IHBhdGgpIHtcblx0XHRcdHJldHVybiByZWRpcmVjdFBhdGg7XG5cdFx0fVxuXHRcdHJldHVybiBwYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRiZWZvcmVVcGRhdGVIaXN0b3J5U3RhdGUoc3RhdGUpIHtcblx0XHQvLyBJZiBzdGF0ZSBpcyBvdXJzIGFuZCBuYXZpZ2F0ZSB0byBwb3N0LXdpdGhvdXQtcmVkaXJlY3QtZ2V0IHNldFxuXHRcdC8vIGhpc3Rvcnkgc3RhdGUgdG8gbnVsbCwgdGhhdCB3YXkgU2VubmEgd2lsbCByZWxvYWQgdGhlIHBhZ2Ugb25cblx0XHQvLyBwb3BzdGF0ZSBzaW5jZSBpdCBjYW5ub3QgcHJlZGljdCBwb3N0IGRhdGEuXG5cdFx0aWYgKHN0YXRlLnNlbm5hICYmIHN0YXRlLmZvcm0gJiYgc3RhdGUucmVkaXJlY3RQYXRoID09PSBzdGF0ZS5wYXRoKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cdFx0cmV0dXJuIHN0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEZvcm1hdHMgbG9hZCBwYXRoIGJlZm9yZSBpbnZva2luZyBhamF4IGNhbGwuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gRm9ybWF0dGVkIHBhdGg7XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGZvcm1hdExvYWRQYXRoKHBhdGgpIHtcblx0XHR2YXIgdXJpID0gbmV3IFVyaShwYXRoKTtcblxuXHRcdHVyaS5zZXRIb3N0bmFtZShnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSk7XG5cdFx0dXJpLnNldFByb3RvY29sKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnByb3RvY29sKTtcblxuXHRcdGlmIChnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wb3J0KSB7XG5cdFx0XHR1cmkuc2V0UG9ydChnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wb3J0KTtcblx0XHR9XG5cblx0XHRpZiAoVUEuaXNJZU9yRWRnZSAmJiB0aGlzLmh0dHBNZXRob2QgPT09IFJlcXVlc3RTY3JlZW4uR0VUKSB7XG5cdFx0XHRyZXR1cm4gdXJpLm1ha2VVbmlxdWUoKS50b1N0cmluZygpO1xuXHRcdH1cblxuXHRcdHJldHVybiB1cmkudG9TdHJpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBodHRwIGhlYWRlcnMuXG5cdCAqIEByZXR1cm4gez9PYmplY3Q9fVxuXHQgKi9cblx0Z2V0SHR0cEhlYWRlcnMoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaHR0cEhlYWRlcnM7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgaHR0cCBtZXRob2QuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRIdHRwTWV0aG9kKCkge1xuXHRcdHJldHVybiB0aGlzLmh0dHBNZXRob2Q7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyByZXF1ZXN0IHBhdGguXG5cdCAqIEByZXR1cm4ge3N0cmluZz19XG5cdCAqL1xuXHRnZXRSZXF1ZXN0UGF0aCgpIHtcblx0XHR2YXIgcmVxdWVzdCA9IHRoaXMuZ2V0UmVxdWVzdCgpO1xuXHRcdGlmIChyZXF1ZXN0KSB7XG5cdFx0XHR2YXIgcmVxdWVzdFBhdGggPSByZXF1ZXN0LnJlcXVlc3RQYXRoO1xuXHRcdFx0dmFyIHJlc3BvbnNlVXJsID0gdGhpcy5tYXliZUV4dHJhY3RSZXNwb25zZVVybEZyb21SZXF1ZXN0KHJlcXVlc3QpO1xuXHRcdFx0aWYgKHJlc3BvbnNlVXJsKSB7XG5cdFx0XHRcdHJlcXVlc3RQYXRoID0gcmVzcG9uc2VVcmw7XG5cdFx0XHR9XG5cdFx0XHRpZiAoVUEuaXNJZU9yRWRnZSAmJiB0aGlzLmh0dHBNZXRob2QgPT09IFJlcXVlc3RTY3JlZW4uR0VUKSB7XG5cdFx0XHRcdHJlcXVlc3RQYXRoID0gbmV3IFVyaShyZXF1ZXN0UGF0aCkucmVtb3ZlVW5pcXVlKCkudG9TdHJpbmcoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB1dGlscy5nZXRVcmxQYXRoKHJlcXVlc3RQYXRoKTtcblx0XHR9XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcmVxdWVzdCBvYmplY3QuXG5cdCAqIEByZXR1cm4gez9PYmplY3R9XG5cdCAqL1xuXHRnZXRSZXF1ZXN0KCkge1xuXHRcdHJldHVybiB0aGlzLnJlcXVlc3Q7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcmVxdWVzdCB0aW1lb3V0LlxuXHQgKiBAcmV0dXJuIHshbnVtYmVyfVxuXHQgKi9cblx0Z2V0VGltZW91dCgpIHtcblx0XHRyZXR1cm4gdGhpcy50aW1lb3V0O1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiByZXNwb25zZSBzdWNjZWVkZWQuIEFueSBzdGF0dXMgY29kZSAyeHggb3IgM3h4IGlzIGNvbnNpZGVyZWRcblx0ICogdmFsaWQuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGF0dXNDb2RlXG5cdCAqL1xuXHRpc1ZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlKHN0YXR1c0NvZGUpIHtcblx0XHRyZXR1cm4gc3RhdHVzQ29kZSA+PSAyMDAgJiYgc3RhdHVzQ29kZSA8PSAzOTk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGxvYWQocGF0aCkge1xuXHRcdGNvbnN0IGNhY2hlID0gdGhpcy5nZXRDYWNoZSgpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwoY2FjaGUpKSB7XG5cdFx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoY2FjaGUpO1xuXHRcdH1cblx0XHRsZXQgYm9keSA9IG51bGw7XG5cdFx0bGV0IGh0dHBNZXRob2QgPSB0aGlzLmh0dHBNZXRob2Q7XG5cdFx0Y29uc3QgaGVhZGVycyA9IG5ldyBNdWx0aU1hcCgpO1xuXHRcdE9iamVjdC5rZXlzKHRoaXMuaHR0cEhlYWRlcnMpLmZvckVhY2goaGVhZGVyID0+IGhlYWRlcnMuYWRkKGhlYWRlciwgdGhpcy5odHRwSGVhZGVyc1toZWFkZXJdKSk7XG5cdFx0aWYgKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCkge1xuXHRcdFx0dGhpcy5hZGRTYWZhcmlYSFJQb2x5ZmlsbCgpO1xuXHRcdFx0Ym9keSA9IG5ldyBGb3JtRGF0YShnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQpO1xuXHRcdFx0dGhpcy5tYXliZUFwcGVuZFN1Ym1pdEJ1dHRvblZhbHVlXyhib2R5KTtcblx0XHRcdGh0dHBNZXRob2QgPSBSZXF1ZXN0U2NyZWVuLlBPU1Q7XG5cdFx0XHRpZiAoVUEuaXNJZU9yRWRnZSkge1xuXHRcdFx0XHRoZWFkZXJzLmFkZCgnSWYtTm9uZS1NYXRjaCcsICdcIjBcIicpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRjb25zdCByZXF1ZXN0UGF0aCA9IHRoaXMuZm9ybWF0TG9hZFBhdGgocGF0aCk7XG5cdFx0cmV0dXJuIEFqYXhcblx0XHRcdC5yZXF1ZXN0KHJlcXVlc3RQYXRoLCBodHRwTWV0aG9kLCBib2R5LCBoZWFkZXJzLCBudWxsLCB0aGlzLnRpbWVvdXQpXG5cdFx0XHQudGhlbih4aHIgPT4ge1xuXHRcdFx0XHR0aGlzLnJlbW92ZVNhZmFyaVhIUlBvbHlmaWxsKCk7XG5cdFx0XHRcdHRoaXMuc2V0UmVxdWVzdCh4aHIpO1xuXHRcdFx0XHR0aGlzLmFzc2VydFZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlKHhoci5zdGF0dXMpO1xuXHRcdFx0XHRpZiAoaHR0cE1ldGhvZCA9PT0gUmVxdWVzdFNjcmVlbi5HRVQgJiYgdGhpcy5pc0NhY2hlYWJsZSgpKSB7XG5cdFx0XHRcdFx0dGhpcy5hZGRDYWNoZSh4aHIucmVzcG9uc2VUZXh0KTtcblx0XHRcdFx0fVxuXHRcdFx0XHR4aHIucmVxdWVzdFBhdGggPSByZXF1ZXN0UGF0aDtcblx0XHRcdFx0cmV0dXJuIHhoci5yZXNwb25zZVRleHQ7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKChyZWFzb24pID0+IHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTYWZhcmlYSFJQb2x5ZmlsbCgpO1xuXHRcdFx0XHRzd2l0Y2ggKHJlYXNvbi5tZXNzYWdlKSB7XG5cdFx0XHRcdFx0Y2FzZSBlcnJvcnMuUkVRVUVTVF9USU1FT1VUOlxuXHRcdFx0XHRcdFx0cmVhc29uLnRpbWVvdXQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBlcnJvcnMuUkVRVUVTVF9FUlJPUjpcblx0XHRcdFx0XHRcdHJlYXNvbi5yZXF1ZXN0RXJyb3IgPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBlcnJvcnMuUkVRVUVTVF9QUkVNQVRVUkVfVEVSTUlOQVRJT046XG5cdFx0XHRcdFx0XHRyZWFzb24ucmVxdWVzdEVycm9yID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHJlYXNvbi5yZXF1ZXN0UHJlbWF0dXJlVGVybWluYXRpb24gPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhyb3cgcmVhc29uO1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhZGl0aW9uYWwgZGF0YSB0byB0aGUgYm9keSBvZiB0aGUgcmVxdWVzdCBpbiBjYXNlIGEgc3VibWl0IGJ1dHRvblxuXHQgKiBpcyBjYXB0dXJlZCBkdXJpbmcgZm9ybSBzdWJtaXNzaW9uLlxuXHQgKiBAcGFyYW0geyFGb3JtRGF0YX0gYm9keSBUaGUgRm9ybURhdGEgY29udGFpbmluZyB0aGUgcmVxdWVzdCBib2R5LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXliZUFwcGVuZFN1Ym1pdEJ1dHRvblZhbHVlXyhib2R5KSB7XG5cdFx0Y29uc3QgYnV0dG9uID0gZ2xvYmFscy5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50O1xuXHRcdGlmIChidXR0b24gJiYgYnV0dG9uLm5hbWUpIHtcblx0XHRcdGJvZHkuYXBwZW5kKGJ1dHRvbi5uYW1lLCBidXR0b24udmFsdWUpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgZm9sbG93aW5nIG1ldGhvZCB0cmllcyB0byBleHRyYWN0IHRoZSByZXNwb25zZSB1cmwgdmFsdWUgYnkgY2hlY2tpbmdcblx0ICogdGhlIGN1c3RvbSByZXNwb25zZSBoZWFkZXIgJ1gtUmVxdWVzdC1VUkwnIGlmIHByb3BlciB2YWx1ZSBpcyBub3QgcHJlc2VudFxuXHQgKiBpbiBYTUxIdHRwUmVxdWVzdC4gVGhlIHZhbHVlIG9mIHJlc3BvbnNlVVJMIHdpbGwgYmUgdGhlIGZpbmFsIFVSTFxuXHQgKiBvYnRhaW5lZCBhZnRlciBhbnkgcmVkaXJlY3RzLiBJbnRlcm5ldCBFeHBsb3JlciwgRWRnZSBhbmQgU2FmYXJpIDw9IDdcblx0ICogZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGZlYXR1cmUuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZTpcblx0ICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1hNTEh0dHBSZXF1ZXN0L3Jlc3BvbnNlVVJMXG5cdCAqIGh0dHBzOi8veGhyLnNwZWMud2hhdHdnLm9yZy8jdGhlLXJlc3BvbnNldXJsLWF0dHJpYnV0ZVxuXHQgKiBAcGFyYW0ge1hNTEh0dHBSZXF1ZXN0fSByZXF1ZXN0XG5cdCAqIEByZXR1cm4gez9zdHJpbmd9IFJlc3BvbnNlIHVybCBiZXN0IG1hdGNoLlxuXHQgKi9cblx0bWF5YmVFeHRyYWN0UmVzcG9uc2VVcmxGcm9tUmVxdWVzdChyZXF1ZXN0KSB7XG5cdFx0dmFyIHJlc3BvbnNlVXJsID0gcmVxdWVzdC5yZXNwb25zZVVSTDtcblx0XHRpZiAocmVzcG9uc2VVcmwpIHtcblx0XHRcdHJldHVybiByZXNwb25zZVVybDtcblx0XHR9XG5cdFx0cmV0dXJuIHJlcXVlc3QuZ2V0UmVzcG9uc2VIZWFkZXIoUmVxdWVzdFNjcmVlbi5YX1JFUVVFU1RfVVJMX0hFQURFUik7XG5cdH1cblxuXHQvKipcblx0ICogVGhpcyBmdW5jdGlvbiBzZXQgYXR0cmlidXRlIGRhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWQgdG8gXG5cdCAqIHRydWUgYW5kIHNldCBkaXNhYmxlIGF0dHJpYnV0ZSBvZiBhbiBpbnB1dCB0eXBlPVwiZmlsZVwiIHRhZ1xuXHQgKiBpcyB1c2VkIGFzIGEgcG9seWZpbGwgZm9yIGlPUyAxMS4zIFNhZmFyaSAvIG1hY09TIFNhZmFyaSAxMS4xIFxuXHQgKiBlbXB0eSA8aW5wdXQgdHlwZT1cImZpbGVcIj4gWEhSIGJ1Zy5cblx0ICogaHR0cHM6Ly9naXRodWIuY29tL3JhaWxzL3JhaWxzL2lzc3Vlcy8zMjQ0MFxuXHQgKiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTg0NDkwXG5cdCAqL1xuXHRhZGRTYWZhcmlYSFJQb2x5ZmlsbCgpIHtcblx0XHRpZiAoZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50ICYmIFVBLmlzU2FmYXJpKSB7XG5cdFx0XHRsZXQgaW5wdXRzID0gZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9XCJmaWxlXCJdOm5vdChbZGlzYWJsZWRdKScpO1xuXHRcdFx0Zm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGlucHV0cy5sZW5ndGg7IGluZGV4KyspIHtcblx0XHRcdFx0bGV0IGlucHV0ID0gaW5wdXRzW2luZGV4XTtcblx0XHRcdFx0aWYgKGlucHV0LmZpbGVzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCdkYXRhLXNhZmFyaS10ZW1wLWRpc2FibGVkJywgJ3RydWUnKTtcblx0XHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsICcnKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVGhpcyBmdW5jdGlvbiByZW1vdmUgYXR0cmlidXRlIGRhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWQgYW5kIGRpc2FibGUgYXR0cmlidXRlXG5cdCAqIG9mIGFuIGlucHV0IHR5cGU9XCJmaWxlXCIgdGFnIGlzIHVzZWQgYXMgYSBwb2x5ZmlsbCBmb3IgaU9TIDExLjMgU2FmYXJpIC8gbWFjT1MgU2FmYXJpIDExLjFcblx0ICogZW1wdHkgPGlucHV0IHR5cGU9XCJmaWxlXCI+IFhIUiBidWcuXG5cdCAqIGh0dHBzOi8vZ2l0aHViLmNvbS9yYWlscy9yYWlscy9pc3N1ZXMvMzI0NDBcblx0ICogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE4NDQ5MFxuXHQgKi9cblx0cmVtb3ZlU2FmYXJpWEhSUG9seWZpbGwoKSB7XG5cdFx0aWYgKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCAmJiBVQS5pc1NhZmFyaSkge1xuXHRcdFx0bGV0IGlucHV0cyA9IGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwiZmlsZVwiXVtkYXRhLXNhZmFyaS10ZW1wLWRpc2FibGVkXScpO1xuXHRcdFx0Zm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGlucHV0cy5sZW5ndGg7IGluZGV4KyspIHtcblx0XHRcdFx0Y29uc3QgaW5wdXQgPSBpbnB1dHNbaW5kZXhdO1xuXHRcdFx0XHRpbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWQnKTtcblx0XHRcdFx0aW5wdXQucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBodHRwIGhlYWRlcnMuXG5cdCAqIEBwYXJhbSB7P09iamVjdD19IGh0dHBIZWFkZXJzXG5cdCAqL1xuXHRzZXRIdHRwSGVhZGVycyhodHRwSGVhZGVycykge1xuXHRcdHRoaXMuaHR0cEhlYWRlcnMgPSBodHRwSGVhZGVycztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBodHRwIG1ldGhvZC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBodHRwTWV0aG9kXG5cdCAqL1xuXHRzZXRIdHRwTWV0aG9kKGh0dHBNZXRob2QpIHtcblx0XHR0aGlzLmh0dHBNZXRob2QgPSBodHRwTWV0aG9kLnRvTG93ZXJDYXNlKCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgcmVxdWVzdCBvYmplY3QuXG5cdCAqIEBwYXJhbSB7P09iamVjdH0gcmVxdWVzdFxuXHQgKi9cblx0c2V0UmVxdWVzdChyZXF1ZXN0KSB7XG5cdFx0dGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuXHQgKiBAcGFyYW0geyFudW1iZXJ9IHRpbWVvdXRcblx0ICovXG5cdHNldFRpbWVvdXQodGltZW91dCkge1xuXHRcdHRoaXMudGltZW91dCA9IHRpbWVvdXQ7XG5cdH1cblxufVxuXG4vKipcbiAqIEhvbGRzIHZhbHVlIGZvciBtZXRob2QgZ2V0LlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBkZWZhdWx0ICdnZXQnXG4gKiBAc3RhdGljXG4gKi9cblJlcXVlc3RTY3JlZW4uR0VUID0gJ2dldCc7XG5cbi8qKlxuICogSG9sZHMgdmFsdWUgZm9yIG1ldGhvZCBwb3N0LlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBkZWZhdWx0ICdwb3N0J1xuICogQHN0YXRpY1xuICovXG5SZXF1ZXN0U2NyZWVuLlBPU1QgPSAncG9zdCc7XG5cbi8qKlxuICogRmFsbGJhY2sgaHR0cCBoZWFkZXIgdG8gcmV0cmlldmUgcmVzcG9uc2UgcmVxdWVzdCB1cmwuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGRlZmF1bHQgJ1gtUmVxdWVzdC1VUkwnXG4gKiBAc3RhdGljXG4gKi9cblJlcXVlc3RTY3JlZW4uWF9SRVFVRVNUX1VSTF9IRUFERVIgPSAnWC1SZXF1ZXN0LVVSTCc7XG5cbmV4cG9ydCBkZWZhdWx0IFJlcXVlc3RTY3JlZW47XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IGJ1aWxkRnJhZ21lbnQsIGdsb2JhbEV2YWwsIGdsb2JhbEV2YWxTdHlsZXMsIG1hdGNoIH0gZnJvbSAnbWV0YWwtZG9tJztcbmltcG9ydCBDYW5jZWxsYWJsZVByb21pc2UgZnJvbSAnbWV0YWwtcHJvbWlzZSc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFJlcXVlc3RTY3JlZW4gZnJvbSAnLi9SZXF1ZXN0U2NyZWVuJztcbmltcG9ydCBTdXJmYWNlIGZyb20gJy4uL3N1cmZhY2UvU3VyZmFjZSc7XG5pbXBvcnQgVUEgZnJvbSAnbWV0YWwtdXNlcmFnZW50JztcbmltcG9ydCBVcmkgZnJvbSAnbWV0YWwtdXJpJztcbmltcG9ydCB1dGlscyBmcm9tICcuLi91dGlscy91dGlscyc7XG5cbmNsYXNzIEh0bWxTY3JlZW4gZXh0ZW5kcyBSZXF1ZXN0U2NyZWVuIHtcblxuXHQvKipcblx0ICogU2NyZWVuIGNsYXNzIHRoYXQgcGVyZm9ybSBhIHJlcXVlc3QgYW5kIGV4dHJhY3RzIHN1cmZhY2UgY29udGVudHMgZnJvbVxuXHQgKiB0aGUgcmVzcG9uc2UgY29udGVudC5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqIEBleHRlbmRzIHtSZXF1ZXN0U2NyZWVufVxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBtZXRhIHNlbGVjdG9yLiBSZWxldmFudCB0byBleHRyYWN0IDxjb2RlPm1ldGE8L2NvZGU+IHRhZ3Ncblx0XHQgKiBlbGVtZW50cyBmcm9tIHJlcXVlc3QgZnJhZ21lbnRzIHRvIHVzZSBhcyB0aGUgc2NyZWVuLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IG1ldGFcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5tZXRhVGFnc1NlbGVjdG9yID0gJ21ldGEnO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHRpdGxlIHNlbGVjdG9yLiBSZWxldmFudCB0byBleHRyYWN0IHRoZSA8Y29kZT48dGl0bGU+PC9jb2RlPlxuXHRcdCAqIGVsZW1lbnQgZnJvbSByZXF1ZXN0IGZyYWdtZW50cyB0byB1c2UgYXMgdGhlIHNjcmVlbiB0aXRsZS5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCB0aXRsZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnRpdGxlU2VsZWN0b3IgPSAndGl0bGUnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRhY3RpdmF0ZSgpIHtcblx0XHRzdXBlci5hY3RpdmF0ZSgpO1xuXHRcdHRoaXMucmVsZWFzZVZpcnR1YWxEb2N1bWVudCgpO1xuXHRcdHRoaXMucGVuZGluZ1N0eWxlcyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb2NhdGVzIHZpcnR1YWwgZG9jdW1lbnQgZm9yIGNvbnRlbnQuIEFmdGVyIGFsbG9jYXRlZCB2aXJ0dWFsIGRvY3VtZW50XG5cdCAqIGNhbiBiZSBhY2Nlc3NlZCBieSA8Y29kZT50aGlzLnZpcnR1YWxEb2N1bWVudDwvY29kZT4uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaHRtbFN0cmluZ1xuXHQgKi9cblx0YWxsb2NhdGVWaXJ0dWFsRG9jdW1lbnRGb3JDb250ZW50KGh0bWxTdHJpbmcpIHtcblx0XHRpZiAoIXRoaXMudmlydHVhbERvY3VtZW50KSB7XG5cdFx0XHR0aGlzLnZpcnR1YWxEb2N1bWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaHRtbCcpO1xuXHRcdH1cblxuXHRcdHRoaXMuY29weU5vZGVBdHRyaWJ1dGVzRnJvbUNvbnRlbnRfKGh0bWxTdHJpbmcsIHRoaXMudmlydHVhbERvY3VtZW50KTtcblxuXHRcdHRoaXMudmlydHVhbERvY3VtZW50LmlubmVySFRNTCA9IGh0bWxTdHJpbmc7XG5cdH1cblxuXHQvKipcblx0ICogQ3VzdG9taXplcyBsb2dpYyB0byBhcHBlbmQgc3R5bGVzIGludG8gZG9jdW1lbnQuIFJlbGV2YW50IHRvIHdoZW5cblx0ICogdHJhY2tpbmcgYSBzdHlsZSBieSBpZCBtYWtlIHN1cmUgdG8gcmUtcG9zaXRpb25zIHRoZSBuZXcgc3R5bGUgaW4gdGhlXG5cdCAqIHNhbWUgZG9tIG9yZGVyLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IG5ld1N0eWxlXG5cdCAqL1xuXHRhcHBlbmRTdHlsZUludG9Eb2N1bWVudF8obmV3U3R5bGUpIHtcblx0XHR2YXIgaXNUZW1wb3JhcnlTdHlsZSA9IG1hdGNoKG5ld1N0eWxlLCBIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXNUZW1wb3JhcnkpO1xuXHRcdGlmIChpc1RlbXBvcmFyeVN0eWxlKSB7XG5cdFx0XHR0aGlzLnBlbmRpbmdTdHlsZXMucHVzaChuZXdTdHlsZSk7XG5cdFx0fVxuXHRcdGlmIChuZXdTdHlsZS5pZCkge1xuXHRcdFx0dmFyIHN0eWxlSW5Eb2MgPSBnbG9iYWxzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG5ld1N0eWxlLmlkKTtcblx0XHRcdGlmIChzdHlsZUluRG9jKSB7XG5cdFx0XHRcdHN0eWxlSW5Eb2MucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3U3R5bGUsIHN0eWxlSW5Eb2MubmV4dFNpYmxpbmcpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGdsb2JhbHMuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChuZXdTdHlsZSk7XG5cdH1cblxuXHQvKipcblx0ICogSWYgYm9keSBpcyB1c2VkIGFzIHN1cmZhY2UgZm9yY2VzIHRoZSByZXF1ZXN0ZWQgZG9jdW1lbnRzIHRvIGhhdmUgc2FtZSBpZFxuXHQgKiBvZiB0aGUgaW5pdGlhbCBwYWdlLlxuXHQgKi9cblx0YXNzZXJ0U2FtZUJvZHlJZEluVmlydHVhbERvY3VtZW50KCkge1xuXHRcdHZhciBib2R5U3VyZmFjZSA9IHRoaXMudmlydHVhbERvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKTtcblx0XHRpZiAoIWdsb2JhbHMuZG9jdW1lbnQuYm9keS5pZCkge1xuXHRcdFx0Z2xvYmFscy5kb2N1bWVudC5ib2R5LmlkID0gJ3Nlbm5hX3N1cmZhY2VfJyArIGdldFVpZCgpO1xuXHRcdH1cblx0XHRpZiAoYm9keVN1cmZhY2UpIHtcblx0XHRcdGJvZHlTdXJmYWNlLmlkID0gZ2xvYmFscy5kb2N1bWVudC5ib2R5LmlkO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDb3BpZXMgYXR0cmlidXRlcyBmcm9tIHRoZSA8aHRtbD4gdGFnIG9mIGNvbnRlbnQgdG8gdGhlIGdpdmVuIG5vZGUuXG5cdCAqL1xuXHRjb3B5Tm9kZUF0dHJpYnV0ZXNGcm9tQ29udGVudF8oY29udGVudCwgbm9kZSkge1xuXHRcdGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UoL1s8XVxccypodG1sL2lnLCAnPHNlbm5hJyk7XG5cdFx0Y29udGVudCA9IGNvbnRlbnQucmVwbGFjZSgvXFwvaHRtbFxccypcXD4vaWcsICcvc2VubmE+Jyk7XG5cdFx0bGV0IHBsYWNlaG9sZGVyO1xuXHRcdGlmIChVQS5pc0llKSB7XG5cdFx0XHRjb25zdCB0ZW1wTm9kZSA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoY29udGVudCk7XG5cdFx0XHRwbGFjZWhvbGRlciA9IHRlbXBOb2RlLnF1ZXJ5U2VsZWN0b3IoJ3Nlbm5hJyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG5vZGUuaW5uZXJIVE1MID0gY29udGVudDtcblx0XHRcdHBsYWNlaG9sZGVyID0gbm9kZS5xdWVyeVNlbGVjdG9yKCdzZW5uYScpO1xuXHRcdH1cblxuXHRcdGlmIChwbGFjZWhvbGRlcikge1xuXHRcdFx0dXRpbHMuY2xlYXJOb2RlQXR0cmlidXRlcyhub2RlKTtcblx0XHRcdHV0aWxzLmNvcHlOb2RlQXR0cmlidXRlcyhwbGFjZWhvbGRlciwgbm9kZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBPdmVycmlkZVxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMuZGlzcG9zZVBlbmRpbmdTdHlsZXMoKTtcblx0XHRzdXBlci5kaXNwb3NlSW50ZXJuYWwoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBwZW5kaW5nIHN0eWxlcyBpZiBzY3JlZW4gZ2V0IGRpc3Bvc2VkIHByaW9yIHRvIGl0cyBsb2FkaW5nLlxuXHQgKi9cblx0ZGlzcG9zZVBlbmRpbmdTdHlsZXMoKSB7XG5cdFx0aWYgKHRoaXMucGVuZGluZ1N0eWxlcykge1xuXHRcdFx0dXRpbHMucmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQodGhpcy5wZW5kaW5nU3R5bGVzKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQE92ZXJyaWRlXG5cdCAqL1xuXHRldmFsdWF0ZVNjcmlwdHMoc3VyZmFjZXMpIHtcblx0XHR2YXIgZXZhbHVhdGVUcmFja2VkU2NyaXB0cyA9IHRoaXMuZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyhcblx0XHRcdGdsb2JhbEV2YWwucnVuU2NyaXB0c0luRWxlbWVudCwgSHRtbFNjcmVlbi5zZWxlY3RvcnMuc2NyaXB0cyxcblx0XHRcdEh0bWxTY3JlZW4uc2VsZWN0b3JzLnNjcmlwdHNUZW1wb3JhcnksIEh0bWxTY3JlZW4uc2VsZWN0b3JzLnNjcmlwdHNQZXJtYW5lbnQpO1xuXG5cdFx0cmV0dXJuIGV2YWx1YXRlVHJhY2tlZFNjcmlwdHMudGhlbigoKSA9PiBzdXBlci5ldmFsdWF0ZVNjcmlwdHMoc3VyZmFjZXMpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAT3ZlcnJpZGVcblx0ICovXG5cdGV2YWx1YXRlU3R5bGVzKHN1cmZhY2VzKSB7XG5cdFx0dGhpcy5wZW5kaW5nU3R5bGVzID0gW107XG5cdFx0dmFyIGV2YWx1YXRlVHJhY2tlZFN0eWxlcyA9IHRoaXMuZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyhcblx0XHRcdGdsb2JhbEV2YWxTdHlsZXMucnVuU3R5bGVzSW5FbGVtZW50LCBIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXMsXG5cdFx0XHRIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXNUZW1wb3JhcnksIEh0bWxTY3JlZW4uc2VsZWN0b3JzLnN0eWxlc1Blcm1hbmVudCxcblx0XHRcdHRoaXMuYXBwZW5kU3R5bGVJbnRvRG9jdW1lbnRfLmJpbmQodGhpcykpO1xuXG5cdFx0cmV0dXJuIGV2YWx1YXRlVHJhY2tlZFN0eWxlcy50aGVuKCgpID0+IHN1cGVyLmV2YWx1YXRlU3R5bGVzKHN1cmZhY2VzKSk7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb3dzIGEgc2NyZWVuIHRvIGV2YWx1YXRlIHRoZSBmYXZpY29uIHN0eWxlIGJlZm9yZSB0aGUgc2NyZWVuIGJlY29tZXMgdmlzaWJsZS5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfVxuXHQgKi9cblx0ZXZhbHVhdGVGYXZpY29uXygpIHtcblx0XHRjb25zdCByZXNvdXJjZXNJblZpcnR1YWwgPSB0aGlzLnZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyhIdG1sU2NyZWVuLnNlbGVjdG9ycy5mYXZpY29uKTtcblx0XHRjb25zdCByZXNvdXJjZXNJbkRvY3VtZW50ID0gdGhpcy5xdWVyeVNlbGVjdG9yQWxsXyhIdG1sU2NyZWVuLnNlbGVjdG9ycy5mYXZpY29uKTtcblxuXHRcdHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdFx0XHR1dGlscy5yZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudChyZXNvdXJjZXNJbkRvY3VtZW50KTtcblx0XHRcdHRoaXMucnVuRmF2aWNvbkluRWxlbWVudF8ocmVzb3VyY2VzSW5WaXJ0dWFsKS50aGVuKCgpID0+IHJlc29sdmUoKSk7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogRXZhbHVhdGVzIHRyYWNrZWQgcmVzb3VyY2VzIGluc2lkZSBpbmNvbWluZyBmcmFnbWVudCBhbmQgcmVtb3ZlIGV4aXN0aW5nXG5cdCAqIHRlbXBvcmFyeSByZXNvdXJjZXMuXG5cdCAqIEBwYXJhbSB7P2Z1bmN0aW9uKCl9IGFwcGVuZEZuIEZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZSBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yIFNlbGVjdG9yIHVzZWQgdG8gZmluZCByZXNvdXJjZXMgdG8gdHJhY2suXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2VsZWN0b3JUZW1wb3JhcnkgU2VsZWN0b3IgdXNlZCB0byBmaW5kIHRlbXBvcmFyeVxuXHQgKiAgICAgcmVzb3VyY2VzIHRvIHRyYWNrLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yUGVybWFuZW50IFNlbGVjdG9yIHVzZWQgdG8gZmluZCBwZXJtYW5lbnRcblx0ICogICAgIHJlc291cmNlcyB0byB0cmFjay5cblx0ICogQHBhcmFtIHshZnVuY3Rpb259IG9wdF9hcHBlbmRSZXNvdXJjZUZuIE9wdGlvbmFsIGZ1bmN0aW9uIHVzZWQgdG9cblx0ICogICAgIGV2YWx1YXRlIGZyYWdtZW50IGNvbnRhaW5pbmcgcmVzb3VyY2VzLlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IERlZmVycmVkIHRoYXQgd2FpdHMgcmVzb3VyY2VzIGV2YWx1YXRpb24gdG9cblx0ICogICAgIGNvbXBsZXRlLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyhldmFsdWF0b3JGbiwgc2VsZWN0b3IsIHNlbGVjdG9yVGVtcG9yYXJ5LCBzZWxlY3RvclBlcm1hbmVudCwgb3B0X2FwcGVuZFJlc291cmNlRm4pIHtcblx0XHR2YXIgdHJhY2tlZCA9IHRoaXMudmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yKTtcblx0XHR2YXIgdGVtcG9yYXJpZXNJbkRvYyA9IHRoaXMucXVlcnlTZWxlY3RvckFsbF8oc2VsZWN0b3JUZW1wb3JhcnkpO1xuXHRcdHZhciBwZXJtYW5lbnRzSW5Eb2MgPSB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yUGVybWFuZW50KTtcblxuXHRcdC8vIEFkZHMgcGVybWFuZW50IHJlc291cmNlcyBpbiBkb2N1bWVudCB0byBjYWNoZS5cblx0XHRwZXJtYW5lbnRzSW5Eb2MuZm9yRWFjaCgocmVzb3VyY2UpID0+IHtcblx0XHRcdHZhciByZXNvdXJjZUtleSA9IHRoaXMuZ2V0UmVzb3VyY2VLZXlfKHJlc291cmNlKTtcblx0XHRcdGlmIChyZXNvdXJjZUtleSkge1xuXHRcdFx0XHRIdG1sU2NyZWVuLnBlcm1hbmVudFJlc291cmNlc0luRG9jW3Jlc291cmNlS2V5XSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR2YXIgZnJhZyA9IGJ1aWxkRnJhZ21lbnQoKTtcblx0XHR0cmFja2VkLmZvckVhY2goKHJlc291cmNlKSA9PiB7XG5cdFx0XHR2YXIgcmVzb3VyY2VLZXkgPSB0aGlzLmdldFJlc291cmNlS2V5XyhyZXNvdXJjZSk7XG5cdFx0XHQvLyBEbyBub3QgbG9hZCBwZXJtYW5lbnQgcmVzb3VyY2VzIGlmIGFscmVhZHkgaW4gZG9jdW1lbnQuXG5cdFx0XHRpZiAoIUh0bWxTY3JlZW4ucGVybWFuZW50UmVzb3VyY2VzSW5Eb2NbcmVzb3VyY2VLZXldKSB7XG5cdFx0XHRcdGZyYWcuYXBwZW5kQ2hpbGQocmVzb3VyY2UpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gSWYgcmVzb3VyY2UgaGFzIGtleSBhbmQgaXMgcGVybWFuZW50IGFkZCB0byBjYWNoZS5cblx0XHRcdGlmIChyZXNvdXJjZUtleSAmJiBtYXRjaChyZXNvdXJjZSwgc2VsZWN0b3JQZXJtYW5lbnQpKSB7XG5cdFx0XHRcdEh0bWxTY3JlZW4ucGVybWFuZW50UmVzb3VyY2VzSW5Eb2NbcmVzb3VyY2VLZXldID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdFx0XHRldmFsdWF0b3JGbihmcmFnLCAoKSA9PiB7XG5cdFx0XHRcdHV0aWxzLnJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50KHRlbXBvcmFyaWVzSW5Eb2MpO1xuXHRcdFx0XHRyZXNvbHZlKCk7XG5cdFx0XHR9LCBvcHRfYXBwZW5kUmVzb3VyY2VGbik7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQE92ZXJyaWRlXG5cdCAqL1xuXHRmbGlwKHN1cmZhY2VzKSB7XG5cdFx0cmV0dXJuIHN1cGVyLmZsaXAoc3VyZmFjZXMpLnRoZW4oKCkgPT4ge1xuXHRcdFx0dXRpbHMuY2xlYXJOb2RlQXR0cmlidXRlcyhnbG9iYWxzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCk7XG5cdFx0XHR1dGlscy5jb3B5Tm9kZUF0dHJpYnV0ZXModGhpcy52aXJ0dWFsRG9jdW1lbnQsIGdsb2JhbHMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KTtcblx0XHRcdHRoaXMuZXZhbHVhdGVGYXZpY29uXygpO1xuXHRcdFx0dGhpcy51cGRhdGVNZXRhVGFnc18oKTtcblx0XHR9KTtcblx0fVxuXG5cdHVwZGF0ZU1ldGFUYWdzXygpIHtcblx0XHRjb25zdCBjdXJyZW50TWV0YU5vZGVzID0gdGhpcy5xdWVyeVNlbGVjdG9yQWxsXygnbWV0YScpO1xuXHRcdGNvbnN0IG1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudCA9IHRoaXMubWV0YXM7XG5cdFx0aWYgKGN1cnJlbnRNZXRhTm9kZXMpIHtcblx0XHRcdHV0aWxzLnJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50KGN1cnJlbnRNZXRhTm9kZXMpO1xuXHRcdFx0aWYgKG1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudCkge1xuXHRcdFx0XHRtZXRhc0Zyb21WaXJ0dWFsRG9jdW1lbnQuZm9yRWFjaCgobWV0YSkgPT4gZ2xvYmFscy5kb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGEpKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgYSBrZXkgdG8gaWRlbnRpZnkgdGhlIHJlc291cmNlIGJhc2VkIG9uIGl0cyBhdHRyaWJ1dGVzLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IHJlc291cmNlXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gRXh0cmFjdGVkIGtleSBiYXNlZCBvbiByZXNvdXJjZSBhdHRyaWJ1dGVzIGluIG9yZGVyIG9mXG5cdCAqICAgICBwcmVmZXJlbmNlOiBpZCwgaHJlZiwgc3JjLlxuXHQgKi9cblx0Z2V0UmVzb3VyY2VLZXlfKHJlc291cmNlKSB7XG5cdFx0cmV0dXJuIHJlc291cmNlLmlkIHx8IHJlc291cmNlLmhyZWYgfHwgcmVzb3VyY2Uuc3JjIHx8ICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRnZXRTdXJmYWNlQ29udGVudChzdXJmYWNlSWQpIHtcblx0XHR2YXIgc3VyZmFjZSA9IHRoaXMudmlydHVhbERvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyMnICsgc3VyZmFjZUlkKTtcblx0XHRpZiAoc3VyZmFjZSkge1xuXHRcdFx0dmFyIGRlZmF1bHRDaGlsZCA9IHN1cmZhY2UucXVlcnlTZWxlY3RvcignIycgKyBzdXJmYWNlSWQgKyAnLScgKyBTdXJmYWNlLkRFRkFVTFQpO1xuXHRcdFx0aWYgKGRlZmF1bHRDaGlsZCkge1xuXHRcdFx0XHRyZXR1cm4gZGVmYXVsdENoaWxkLmlubmVySFRNTDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBzdXJmYWNlLmlubmVySFRNTDsgLy8gSWYgZGVmYXVsdCBjb250ZW50IG5vdCBmb3VuZCwgdXNlIHN1cmZhY2UgY29udGVudFxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSB0aXRsZSBzZWxlY3Rvci5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldFRpdGxlU2VsZWN0b3IoKSB7XG5cdFx0cmV0dXJuIHRoaXMudGl0bGVTZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0bG9hZChwYXRoKSB7XG5cdFx0cmV0dXJuIHN1cGVyLmxvYWQocGF0aClcblx0XHRcdC50aGVuKGNvbnRlbnQgPT4ge1xuXHRcdFx0XHR0aGlzLmFsbG9jYXRlVmlydHVhbERvY3VtZW50Rm9yQ29udGVudChjb250ZW50KTtcblx0XHRcdFx0dGhpcy5yZXNvbHZlVGl0bGVGcm9tVmlydHVhbERvY3VtZW50KCk7XG5cdFx0XHRcdHRoaXMucmVzb2x2ZU1ldGFUYWdzRnJvbVZpcnR1YWxEb2N1bWVudCgpO1xuXHRcdFx0XHR0aGlzLmFzc2VydFNhbWVCb2R5SWRJblZpcnR1YWxEb2N1bWVudCgpO1xuXHRcdFx0XHRpZiAoVUEuaXNJZSkge1xuXHRcdFx0XHRcdHRoaXMubWFrZVRlbXBvcmFyeVN0eWxlc0hyZWZzVW5pcXVlXygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb250ZW50O1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUXVlcmllcyB0ZW1wb3Jhcnkgc3R5bGVzIGZyb20gdmlydHVhbCBkb2N1bWVudCwgYW5kIG1ha2VzIHRoZW0gdW5pcXVlLlxuXHQgKiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3IgY2FjaGluZyBhbmQgbG9hZCBldmVudCBmaXJpbmcgaXNzdWVzIHNwZWNpZmljIHRvXG5cdCAqIElFMTEuIGh0dHBzOi8vZGV2ZWxvcGVyLm1pY3Jvc29mdC5jb20vZW4tdXMvbWljcm9zb2Z0LWVkZ2UvcGxhdGZvcm0vaXNzdWVzLzc5NDAxNzEvXG5cdCAqL1xuXHRtYWtlVGVtcG9yYXJ5U3R5bGVzSHJlZnNVbmlxdWVfKCkge1xuXHRcdHZhciB0ZW1wb3Jhcmllc0luRG9jID0gdGhpcy52aXJ0dWFsUXVlcnlTZWxlY3RvckFsbF8oSHRtbFNjcmVlbi5zZWxlY3RvcnMuc3R5bGVzVGVtcG9yYXJ5KTtcblx0XHR0ZW1wb3Jhcmllc0luRG9jLmZvckVhY2goKHN0eWxlKSA9PiB0aGlzLnJlcGxhY2VTdHlsZUFuZE1ha2VVbmlxdWVfKHN0eWxlKSk7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBlbGVtZW50IGZyb20gZ2l2ZW4sIGNvcGllcyBhdHRyaWJ1dGVzLCBtdXRhdGVzIGhyZWYgdG8gYmVcblx0ICogdW5pcXVlIHRvIHByZXZlbnQgY2FjaGluZyBhbmQgbW9yZSB0aGFuIG9uZSBsb2FkL2Vycm9yIGV2ZW50IGZyb20gZmlyaW5nLlxuXHQgKi9cblx0cmVwbGFjZVN0eWxlQW5kTWFrZVVuaXF1ZV8oc3R5bGUpIHtcblx0XHRpZiAoc3R5bGUuaHJlZikge1xuXHRcdFx0dmFyIG5ld1N0eWxlID0gZ2xvYmFscy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KHN0eWxlLnRhZ05hbWUpO1xuXHRcdFx0c3R5bGUuaHJlZiA9IG5ldyBVcmkoc3R5bGUuaHJlZikubWFrZVVuaXF1ZSgpLnRvU3RyaW5nKCk7XG5cdFx0XHR1dGlscy5jb3B5Tm9kZUF0dHJpYnV0ZXMoc3R5bGUsIG5ld1N0eWxlKTtcblx0XHRcdHN0eWxlLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld1N0eWxlLCBzdHlsZSk7XG5cdFx0XHRzdHlsZS5kaXNhYmxlZCA9IHRydWU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIGZhdmljb24gZWxlbWVudHMgdG8gdGhlIGRvY3VtZW50LlxuXHQgKiBAcGFyYW0geyFBcnJheTxFbGVtZW50Pn0gZWxlbWVudHNcblx0ICogQHByaXZhdGVcblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfVxuXHQgKi9cblx0cnVuRmF2aWNvbkluRWxlbWVudF8oZWxlbWVudHMpIHtcblx0XHRyZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuXHRcdFx0ZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4gZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChcblx0XHRcdFx0VUEuaXNJZSA/IGVsZW1lbnQgOiB1dGlscy5zZXRFbGVtZW50V2l0aFJhbmRvbUhyZWYoZWxlbWVudClcblx0XHRcdCkpO1xuXHRcdFx0cmVzb2x2ZSgpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFF1ZXJpZXMgZWxlbWVudHMgZnJvbSB2aXJ0dWFsIGRvY3VtZW50IGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGVsZW1lbnRzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yXG5cdCAqIEByZXR1cm4ge2FycmF5LjxFbGVtZW50Pn1cblx0ICovXG5cdHZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyhzZWxlY3Rvcikge1xuXHRcdHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLnZpcnR1YWxEb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG5cdH1cblxuXHQvKipcblx0ICogUXVlcmllcyBlbGVtZW50cyBmcm9tIGRvY3VtZW50IGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGVsZW1lbnRzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yXG5cdCAqIEByZXR1cm4ge2FycmF5LjxFbGVtZW50Pn1cblx0ICovXG5cdHF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGdsb2JhbHMuZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbGVhc2VzIHZpcnR1YWwgZG9jdW1lbnQgYWxsb2NhdGVkIGZvciBjb250ZW50LlxuXHQgKi9cblx0cmVsZWFzZVZpcnR1YWxEb2N1bWVudCgpIHtcblx0XHR0aGlzLnZpcnR1YWxEb2N1bWVudCA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogUmVzb2x2ZXMgdGl0bGUgZnJvbSBhbGxvY2F0ZWQgdmlydHVhbCBkb2N1bWVudC5cblx0ICovXG5cdHJlc29sdmVUaXRsZUZyb21WaXJ0dWFsRG9jdW1lbnQoKSB7XG5cdFx0Y29uc3QgdGl0bGUgPSB0aGlzLnZpcnR1YWxEb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMudGl0bGVTZWxlY3Rvcik7XG5cdFx0aWYgKHRpdGxlKSB7XG5cdFx0XHR0aGlzLnNldFRpdGxlKHRpdGxlLnRleHRDb250ZW50LnRyaW0oKSk7XG5cdFx0fVxuXHR9XG5cblx0cmVzb2x2ZU1ldGFUYWdzRnJvbVZpcnR1YWxEb2N1bWVudCgpIHtcblx0XHRjb25zdCBtZXRhcyA9IHRoaXMudmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfKHRoaXMubWV0YVRhZ3NTZWxlY3Rvcik7XG5cdFx0aWYgKG1ldGFzKSB7XG5cdFx0XHR0aGlzLnNldE1ldGFzKG1ldGFzKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdGl0bGUgc2VsZWN0b3IuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gdGl0bGVTZWxlY3RvclxuXHQgKi9cblx0c2V0VGl0bGVTZWxlY3Rvcih0aXRsZVNlbGVjdG9yKSB7XG5cdFx0dGhpcy50aXRsZVNlbGVjdG9yID0gdGl0bGVTZWxlY3Rvcjtcblx0fVxuXG59XG5cbi8qKlxuICogSGVscGVyIHNlbGVjdG9yIGZvciBpZ25vcmUgZmF2aWNvbiB3aGVuIGV4aXN0IGRhdGEtc2VubmEtdHJhY2suXG4gKi9cbmNvbnN0IGlnbm9yZUZhdmljb24gPSAnOm5vdChbcmVsPVwiU2hvcnRjdXQgSWNvblwiXSk6bm90KFtyZWw9XCJzaG9ydGN1dCBpY29uXCJdKTpub3QoW3JlbD1cImljb25cIl0pOm5vdChbaHJlZiQ9XCJmYXZpY29uLmljb25cIl0pJztcblxuLyoqXG4gKiBIZWxwZXIgc2VsZWN0b3JzIGZvciB0cmFja2luZyByZXNvdXJjZXMuXG4gKiBAdHlwZSB7b2JqZWN0fVxuICogQHByb3RlY3RlZFxuICogQHN0YXRpY1xuICovXG5IdG1sU2NyZWVuLnNlbGVjdG9ycyA9IHtcblx0ZmF2aWNvbjogJ2xpbmtbcmVsPVwiU2hvcnRjdXQgSWNvblwiXSxsaW5rW3JlbD1cInNob3J0Y3V0IGljb25cIl0sbGlua1tyZWw9XCJpY29uXCJdLGxpbmtbaHJlZiQ9XCJmYXZpY29uLmljb25cIl0nLFxuXHRzY3JpcHRzOiAnc2NyaXB0W2RhdGEtc2VubmEtdHJhY2tdJyxcblx0c2NyaXB0c1Blcm1hbmVudDogJ3NjcmlwdFtkYXRhLXNlbm5hLXRyYWNrPVwicGVybWFuZW50XCJdJyxcblx0c2NyaXB0c1RlbXBvcmFyeTogJ3NjcmlwdFtkYXRhLXNlbm5hLXRyYWNrPVwidGVtcG9yYXJ5XCJdJyxcblx0c3R5bGVzOiBgc3R5bGVbZGF0YS1zZW5uYS10cmFja10sbGlua1tkYXRhLXNlbm5hLXRyYWNrXSR7aWdub3JlRmF2aWNvbn1gLFxuXHRzdHlsZXNQZXJtYW5lbnQ6IGBzdHlsZVtkYXRhLXNlbm5hLXRyYWNrPVwicGVybWFuZW50XCJdLGxpbmtbZGF0YS1zZW5uYS10cmFjaz1cInBlcm1hbmVudFwiXSR7aWdub3JlRmF2aWNvbn1gLFxuXHRzdHlsZXNUZW1wb3Jhcnk6IGBzdHlsZVtkYXRhLXNlbm5hLXRyYWNrPVwidGVtcG9yYXJ5XCJdLGxpbmtbZGF0YS1zZW5uYS10cmFjaz1cInRlbXBvcmFyeVwiXSR7aWdub3JlRmF2aWNvbn1gXG59O1xuXG4vKipcbiAqIENhY2hlcyBwZXJtYW5lbnQgcmVzb3VyY2Uga2V5cy5cbiAqIEB0eXBlIHtvYmplY3R9XG4gKiBAcHJvdGVjdGVkXG4gKiBAc3RhdGljXG4gKi9cbkh0bWxTY3JlZW4ucGVybWFuZW50UmVzb3VyY2VzSW5Eb2MgPSB7fTtcblxuZXhwb3J0IGRlZmF1bHQgSHRtbFNjcmVlbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgRGlzcG9zYWJsZSwgZ2V0VWlkLCBpc0RlZkFuZE5vdE51bGwsIGlzRWxlbWVudCwgb2JqZWN0IH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IGRhdGFBdHRyaWJ1dGVzIGZyb20gJy4vZGF0YUF0dHJpYnV0ZXMnO1xuaW1wb3J0IGdsb2JhbHMgZnJvbSAnLi4vZ2xvYmFscy9nbG9iYWxzJztcbmltcG9ydCBBcHAgZnJvbSAnLi9BcHAnO1xuaW1wb3J0IEh0bWxTY3JlZW4gZnJvbSAnLi4vc2NyZWVuL0h0bWxTY3JlZW4nO1xuaW1wb3J0IFJvdXRlIGZyb20gJy4uL3JvdXRlL1JvdXRlJztcblxuY2xhc3MgQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXIgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblxuXHQvKipcblx0ICogSW5pdGlsaXplcyBBcHAsIHJlZ2lzdGVyIHN1cmZhY2VzIGFuZCByb3V0ZXMgZnJvbSBkYXRhIGF0dHJpYnV0ZXMuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBhcHAgcmVmZXJlbmNlIGluaXRpYWxpemVkIGJ5IGRhdGEgYXR0cmlidXRlcy5cblx0XHQgKiBAdHlwZSB7QXBwfVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKi9cblx0XHR0aGlzLmFwcCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgYmFzZSBlbGVtZW50IHRvIHNlYXJjaCBpbml0aWFsaXphdGlvbiBkYXRhIGF0dHJpYnV0ZXMuIFRoaXNcblx0XHQgKiBlbGVtZW50IGlzIHRoZSBjb250YWluZXIgdXNlZCB0byBlbmFibGUgaW5pdGlhbGl6YXRpb24gYmFzZWQgb24gdGhlXG5cdFx0ICogcHJlc2VuY2Ugb2YgYGRhdGEtc2VubmFgIGF0dHJpYnV0ZS5cblx0XHQgKiBAdHlwZSB7RWxlbWVudH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICovXG5cdFx0dGhpcy5iYXNlRWxlbWVudCA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogSW5pdHMgYXBwbGljYXRpb24gYmFzZWQgb24gaW5mb3JtYXRpb24gc2Nhbm5lZCBmcm9tIGRvY3VtZW50LlxuXHQgKi9cblx0aGFuZGxlKCkge1xuXHRcdGlmICghaXNFbGVtZW50KHRoaXMuYmFzZUVsZW1lbnQpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1Nlbm5hIGRhdGEgYXR0cmlidXRlIGhhbmRsZXIgYmFzZSBlbGVtZW50ICcgK1xuXHRcdFx0XHQnbm90IHNldCBvciBpbnZhbGlkLCB0cnkgc2V0dGluZyBhIHZhbGlkIGVsZW1lbnQgdGhhdCAnICtcblx0XHRcdFx0J2NvbnRhaW5zIGEgYGRhdGEtc2VubmFgIGF0dHJpYnV0ZS4nKTtcblx0XHR9XG5cblx0XHRpZiAoIXRoaXMuYmFzZUVsZW1lbnQuaGFzQXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLnNlbm5hKSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHdhcyBub3QgaW5pdGlhbGl6ZWQgZnJvbSBkYXRhIGF0dHJpYnV0ZXMuICcgK1xuXHRcdFx0XHQnSW4gb3JkZXIgdG8gZW5hYmxlIGl0cyB1c2FnZSBmcm9tIGRhdGEgYXR0cmlidXRlcyB0cnkgc2V0dGluZyAnICtcblx0XHRcdFx0J2luIHRoZSBiYXNlIGVsZW1lbnQsIGUuZy4gYDxib2R5IGRhdGEtc2VubmE+YC4nKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5hcHApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignU2VubmEgYXBwIHdhcyBhbHJlYWR5IGluaXRpYWxpemVkLicpO1xuXHRcdH1cblxuXHRcdGNvbnNvbGUubG9nKCdTZW5uYSBpbml0aWFsaXplZCBmcm9tIGRhdGEgYXR0cmlidXRlLicpO1xuXG5cdFx0dGhpcy5hcHAgPSBuZXcgQXBwKCk7XG5cdFx0dGhpcy5tYXliZUFkZFJvdXRlc18oKTtcblx0XHR0aGlzLm1heWJlQWRkU3VyZmFjZXNfKCk7XG5cdFx0dGhpcy5tYXliZVNldEJhc2VQYXRoXygpO1xuXHRcdHRoaXMubWF5YmVTZXRMaW5rU2VsZWN0b3JfKCk7XG5cdFx0dGhpcy5tYXliZVNldExvYWRpbmdDc3NDbGFzc18oKTtcblx0XHR0aGlzLm1heWJlU2V0VXBkYXRlU2Nyb2xsUG9zaXRpb25fKCk7XG5cdFx0dGhpcy5tYXliZURpc3BhdGNoXygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0aWYgKHRoaXMuYXBwKSB7XG5cdFx0XHR0aGlzLmFwcC5kaXNwb3NlKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGFwcCByZWZlcmVuY2UuXG5cdCAqIEByZXR1cm4ge0FwcH1cblx0ICovXG5cdGdldEFwcCgpIHtcblx0XHRyZXR1cm4gdGhpcy5hcHA7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgYmFzZSBlbGVtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBiYXNlRWxlbWVudFxuXHQgKi9cblx0Z2V0QmFzZUVsZW1lbnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYmFzZUVsZW1lbnQ7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgYWRkcyBhcHAgcm91dGVzIGZyb20gbGluayBlbGVtZW50cyB0aGF0IGFyZSBgc2VubmEtcm91dGVgLlxuXHQgKi9cblx0bWF5YmVBZGRSb3V0ZXNfKCkge1xuXHRcdHZhciByb3V0ZXNTZWxlY3RvciA9ICdsaW5rW3JlbD1cInNlbm5hLXJvdXRlXCJdJztcblx0XHR0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxBc0FycmF5Xyhyb3V0ZXNTZWxlY3RvcikuZm9yRWFjaCgobGluaykgPT4gdGhpcy5tYXliZVBhcnNlTGlua1JvdXRlXyhsaW5rKSk7XG5cdFx0aWYgKCF0aGlzLmFwcC5oYXNSb3V0ZXMoKSkge1xuXHRcdFx0dGhpcy5hcHAuYWRkUm91dGVzKG5ldyBSb3V0ZSgvLiovLCBIdG1sU2NyZWVuKSk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgY2FuXFwndCBmaW5kIHJvdXRlIGVsZW1lbnRzLCBhZGRpbmcgZGVmYXVsdC4nKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgYWRkcyBhcHAgc3VyZmFjZXMgYnkgc2Nhbm5pbmcgYGRhdGEtc2VubmEtc3VyZmFjZWAgZGF0YSBhdHRyaWJ1dGUuXG5cdCAqL1xuXHRtYXliZUFkZFN1cmZhY2VzXygpIHtcblx0XHR2YXIgc3VyZmFjZXNTZWxlY3RvciA9ICdbJyArIGRhdGFBdHRyaWJ1dGVzLnN1cmZhY2UgKyAnXSc7XG5cdFx0dGhpcy5xdWVyeVNlbGVjdG9yQWxsQXNBcnJheV8oc3VyZmFjZXNTZWxlY3RvcikuZm9yRWFjaCgoc3VyZmFjZUVsZW1lbnQpID0+IHtcblx0XHRcdHRoaXMudXBkYXRlRWxlbWVudElkSWZTcGVjaWFsU3VyZmFjZV8oc3VyZmFjZUVsZW1lbnQpO1xuXHRcdFx0dGhpcy5hcHAuYWRkU3VyZmFjZXMoc3VyZmFjZUVsZW1lbnQuaWQpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3BhdGNoZXMgYXBwIG5hdmlnYXRpb24gdG8gdGhlIGN1cnJlbnQgcGF0aCB3aGVuIGluaXRpYWxpemVzLlxuXHQgKi9cblx0bWF5YmVEaXNwYXRjaF8oKSB7XG5cdFx0aWYgKHRoaXMuYmFzZUVsZW1lbnQuaGFzQXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLmRpc3BhdGNoKSkge1xuXHRcdFx0dGhpcy5hcHAuZGlzcGF0Y2goKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhcHAgcm91dGUgYnkgcGFyc2luZyB2YWxpZCBsaW5rIGVsZW1lbnRzLiBBIHZhbGlkIGxpbmsgZWxlbWVudCBpcyBvZlxuXHQgKiB0aGUga2luZCBgcmVsPVwic2VubmEtcm91dGVcImAuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGlua1xuXHQgKi9cblx0bWF5YmVQYXJzZUxpbmtSb3V0ZV8obGluaykge1xuXHRcdHZhciByb3V0ZSA9IG5ldyBSb3V0ZSh0aGlzLm1heWJlUGFyc2VMaW5rUm91dGVQYXRoXyhsaW5rKSwgdGhpcy5tYXliZVBhcnNlTGlua1JvdXRlSGFuZGxlcl8obGluaykpO1xuXHRcdHRoaXMuYXBwLmFkZFJvdXRlcyhyb3V0ZSk7XG5cdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHNjYW5uZWQgcm91dGUgJyArIHJvdXRlLmdldFBhdGgoKSk7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgcGFyc2UgbGluayByb3V0ZSBoYW5kbGVyLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGxpbmtcblx0ICogQHJldHVybiB7P3N0cmluZ31cblx0ICovXG5cdG1heWJlUGFyc2VMaW5rUm91dGVIYW5kbGVyXyhsaW5rKSB7XG5cdFx0dmFyIGhhbmRsZXIgPSBsaW5rLmdldEF0dHJpYnV0ZSgndHlwZScpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwoaGFuZGxlcikpIHtcblx0XHRcdGhhbmRsZXIgPSBvYmplY3QuZ2V0T2JqZWN0QnlOYW1lKGhhbmRsZXIpO1xuXHRcdH1cblx0XHRyZXR1cm4gaGFuZGxlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBwYXJzZSBsaW5rIHJvdXRlIHBhdGguXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGlua1xuXHQgKiBAcmV0dXJuIHs/c3RyaW5nfVxuXHQgKi9cblx0bWF5YmVQYXJzZUxpbmtSb3V0ZVBhdGhfKGxpbmspIHtcblx0XHR2YXIgcGF0aCA9IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChwYXRoKSkge1xuXHRcdFx0aWYgKHBhdGguaW5kZXhPZigncmVnZXg6JykgPT09IDApIHtcblx0XHRcdFx0cGF0aCA9IG5ldyBSZWdFeHAocGF0aC5zdWJzdHJpbmcoNikpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBzZXRzIGFwcCBiYXNlIHBhdGggZnJvbSBgZGF0YS1zZW5uYS1iYXNlLXBhdGhgIGRhdGEgYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRCYXNlUGF0aF8oKSB7XG5cdFx0dmFyIGJhc2VQYXRoID0gdGhpcy5iYXNlRWxlbWVudC5nZXRBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMuYmFzZVBhdGgpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwoYmFzZVBhdGgpKSB7XG5cdFx0XHR0aGlzLmFwcC5zZXRCYXNlUGF0aChiYXNlUGF0aCk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCBiYXNlIHBhdGggJyArIGJhc2VQYXRoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgc2V0cyBhcHAgbGluayBzZWxlY3RvciBmcm9tIGBkYXRhLXNlbm5hLWxpbmstc2VsZWN0b3JgIGRhdGFcblx0ICogYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRMaW5rU2VsZWN0b3JfKCkge1xuXHRcdHZhciBsaW5rU2VsZWN0b3IgPSB0aGlzLmJhc2VFbGVtZW50LmdldEF0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy5saW5rU2VsZWN0b3IpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwobGlua1NlbGVjdG9yKSkge1xuXHRcdFx0dGhpcy5hcHAuc2V0TGlua1NlbGVjdG9yKGxpbmtTZWxlY3Rvcik7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCBsaW5rIHNlbGVjdG9yICcgKyBsaW5rU2VsZWN0b3IpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBzZXRzIGFwcCBsaW5rIGxvYWRpbmcgY3NzIGNsYXNzIGZyb20gYGRhdGEtc2VubmEtbG9hZGluZy1jc3MtY2xhc3NgXG5cdCAqIGRhdGEgYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRMb2FkaW5nQ3NzQ2xhc3NfKCkge1xuXHRcdHZhciBsb2FkaW5nQ3NzQ2xhc3MgPSB0aGlzLmJhc2VFbGVtZW50LmdldEF0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy5sb2FkaW5nQ3NzQ2xhc3MpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwobG9hZGluZ0Nzc0NsYXNzKSkge1xuXHRcdFx0dGhpcy5hcHAuc2V0TG9hZGluZ0Nzc0NsYXNzKGxvYWRpbmdDc3NDbGFzcyk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCBsb2FkaW5nIGNzcyBjbGFzcyAnICsgbG9hZGluZ0Nzc0NsYXNzKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgc2V0cyBhcHAgdXBkYXRlIHNjcm9sbCBwb3NpdGlvbiBmcm9tXG5cdCAqIGBkYXRhLXNlbm5hLXVwZGF0ZS1zY3JvbGwtcG9zaXRpb25gIGRhdGEgYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRVcGRhdGVTY3JvbGxQb3NpdGlvbl8oKSB7XG5cdFx0dmFyIHVwZGF0ZVNjcm9sbFBvc2l0aW9uID0gdGhpcy5iYXNlRWxlbWVudC5nZXRBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMudXBkYXRlU2Nyb2xsUG9zaXRpb24pO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwodXBkYXRlU2Nyb2xsUG9zaXRpb24pKSB7XG5cdFx0XHRpZiAodXBkYXRlU2Nyb2xsUG9zaXRpb24gPT09ICdmYWxzZScpIHtcblx0XHRcdFx0dGhpcy5hcHAuc2V0VXBkYXRlU2Nyb2xsUG9zaXRpb24oZmFsc2UpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5hcHAuc2V0VXBkYXRlU2Nyb2xsUG9zaXRpb24odHJ1ZSk7XG5cdFx0XHR9XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCB1cGRhdGUgc2Nyb2xsIHBvc2l0aW9uICcgKyB1cGRhdGVTY3JvbGxQb3NpdGlvbik7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFF1ZXJpZXMgZWxlbWVudHMgZnJvbSBkb2N1bWVudCBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBlbGVtZW50cy5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzZWxlY3RvclxuXHQgKiBAcmV0dXJuIHthcnJheS48RWxlbWVudD59XG5cdCAqL1xuXHRxdWVyeVNlbGVjdG9yQWxsQXNBcnJheV8oc2VsZWN0b3IpIHtcblx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZ2xvYmFscy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyBlbGVtZW50IGlkIGlmIGhhbmRsZWQgYXMgc3BlY2lhbCBzdXJmYWNlIGVsZW1lbnQuIFNvbWUgc3VyZmFjZXNcblx0ICogYXJlIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIG90aGVycywgbGlrZSB3aGVuIHRocmVhdGluZyA8Y29kZT5ib2R5PC9jb2RlPlxuXHQgKiBhcyBzdXJmYWNlLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcblx0ICovXG5cdHVwZGF0ZUVsZW1lbnRJZElmU3BlY2lhbFN1cmZhY2VfKGVsZW1lbnQpIHtcblx0XHRpZiAoIWVsZW1lbnQuaWQgJiYgZWxlbWVudCA9PT0gZ2xvYmFscy5kb2N1bWVudC5ib2R5KSB7XG5cdFx0XHRlbGVtZW50LmlkID0gJ3Nlbm5hX3N1cmZhY2VfJyArIGdldFVpZCgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBiYXNlIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gYmFzZUVsZW1lbnRcblx0ICovXG5cdHNldEJhc2VFbGVtZW50KGJhc2VFbGVtZW50KSB7XG5cdFx0dGhpcy5iYXNlRWxlbWVudCA9IGJhc2VFbGVtZW50O1xuXHR9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXIgZnJvbSAnLi9BcHBEYXRhQXR0cmlidXRlSGFuZGxlcic7XG5cbi8qKlxuICogRGF0YSBhdHRyaWJ1dGUgaGFuZGxlci5cbiAqIEB0eXBlIHtBcHBEYXRhQXR0cmlidXRlSGFuZGxlcn1cbiAqL1xudmFyIGRhdGFBdHRyaWJ1dGVIYW5kbGVyID0gbmV3IEFwcERhdGFBdHRyaWJ1dGVIYW5kbGVyKCk7XG5cbmdsb2JhbHMuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGZ1bmN0aW9uKCkge1xuXHRkYXRhQXR0cmlidXRlSGFuZGxlci5zZXRCYXNlRWxlbWVudChnbG9iYWxzLmRvY3VtZW50LmJvZHkpO1xuXHRkYXRhQXR0cmlidXRlSGFuZGxlci5oYW5kbGUoKTtcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBkYXRhQXR0cmlidXRlSGFuZGxlcjsiLCIvKipcbiAqIEByZXR1cm5zIFN0cmluZyBjb250YWluaW5nIHRoZSBjdXJyZW50IHNlbm5hIHZlcnNpb25cbiAqL1xuXG5jb25zdCB2ZXJzaW9uID0gJzwlPSB2ZXJzaW9uICU+JztcblxuZXhwb3J0IGRlZmF1bHQgdmVyc2lvbjsiXSwibmFtZXMiOlsiY29tcGF0aWJpbGl0eU1vZGVEYXRhXyIsInVuaXF1ZUlkQ291bnRlcl8iLCJVSURfUFJPUEVSVFkiLCJNYXRoIiwicmFuZG9tIiwiYWJzdHJhY3RNZXRob2QiLCJFcnJvciIsImRpc2FibGVDb21wYXRpYmlsaXR5TW9kZSIsInVuZGVmaW5lZCIsImVuYWJsZUNvbXBhdGliaWxpdHlNb2RlIiwiZGF0YSIsImdldENvbXBhdGliaWxpdHlNb2RlRGF0YSIsIndpbmRvdyIsIl9fTUVUQUxfQ09NUEFUSUJJTElUWV9fIiwiZ2V0Rmlyc3RUcnV0aHlfIiwiYSIsImIiLCJnZXRGdW5jdGlvbk5hbWUiLCJmbiIsIm5hbWUiLCJzdHIiLCJ0b1N0cmluZyIsInN1YnN0cmluZyIsImluZGV4T2YiLCJnZXRTdGF0aWNQcm9wZXJ0eSIsImN0b3IiLCJwcm9wZXJ0eU5hbWUiLCJtZXJnZUZuIiwibWVyZ2VkTmFtZSIsImhhc093blByb3BlcnR5IiwibWVyZ2VkIiwiX19wcm90b19fIiwiaXNQcm90b3R5cGVPZiIsIkZ1bmN0aW9uIiwiZ2V0VWlkIiwib2JqZWN0Iiwibm9Jbmhlcml0YW5jZSIsImlkIiwiaWRlbnRpdHlGdW5jdGlvbiIsInJldHVyblZhbHVlIiwiaXNCb29sZWFuIiwidmFsIiwiaXNEZWYiLCJpc0RlZkFuZE5vdE51bGwiLCJpc051bGwiLCJpc0RvY3VtZW50Iiwibm9kZVR5cGUiLCJpc0RvY3VtZW50RnJhZ21lbnQiLCJpc0VsZW1lbnQiLCJpc0Z1bmN0aW9uIiwiaXNOdW1iZXIiLCJpc1dpbmRvdyIsImlzT2JqZWN0IiwidHlwZSIsImlzUHJvbWlzZSIsInRoZW4iLCJpc1N0cmluZyIsIlN0cmluZyIsImlzU2VydmVyU2lkZSIsIm9wdGlvbnMiLCJjaGVja0VudiIsInNlcnZlclNpZGUiLCJwcm9jZXNzIiwiYnJvd3NlciIsImVudiIsIk5PREVfRU5WIiwibnVsbEZ1bmN0aW9uIiwiYXJyYXkiLCJhcnIxIiwiYXJyMiIsImxlbmd0aCIsImkiLCJhcnIiLCJvdXRwdXQiLCJBcnJheSIsImlzQXJyYXkiLCJmbGF0dGVuIiwicHVzaCIsIm9iaiIsInJ2IiwicmVtb3ZlQXQiLCJwcm90b3R5cGUiLCJzcGxpY2UiLCJjYWxsIiwic3RhcnQiLCJlbmQiLCJzbGljZWQiLCJhc3luYyIsInRocm93RXhjZXB0aW9uIiwiZXhjZXB0aW9uIiwibmV4dFRpY2siLCJydW4iLCJjYWxsYmFjayIsImNvbnRleHQiLCJ3b3JrUXVldWVTY2hlZHVsZWRfIiwicHJvY2Vzc1dvcmtRdWV1ZSIsIndvcmtRdWV1ZV8iLCJXb3JrSXRlbV8iLCJ3b3JrSXRlbXMiLCJ3b3JrSXRlbSIsInNjb3BlIiwiZSIsImNiIiwiYmluZCIsIndyYXBDYWxsYmFja18iLCJzZXRJbW1lZGlhdGVfIiwic2V0SW1tZWRpYXRlIiwiZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfIiwiQ2hhbm5lbCIsIk1lc3NhZ2VDaGFubmVsIiwicG9zdE1lc3NhZ2UiLCJhZGRFdmVudExpc3RlbmVyIiwiaWZyYW1lIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50Iiwic3R5bGUiLCJkaXNwbGF5Iiwic3JjIiwidGl0bGUiLCJkb2N1bWVudEVsZW1lbnQiLCJhcHBlbmRDaGlsZCIsIndpbiIsImNvbnRlbnRXaW5kb3ciLCJkb2MiLCJvcGVuIiwid3JpdGUiLCJjbG9zZSIsIm1lc3NhZ2UiLCJvcmlnaW4iLCJsb2NhdGlvbiIsInByb3RvY29sIiwiaG9zdCIsIm9ubWVzc2FnZSIsInBvcnQxIiwicG9ydDIiLCJjaGFubmVsIiwiaGVhZCIsInRhaWwiLCJuZXh0Iiwic2NyaXB0Iiwib25yZWFkeXN0YXRlY2hhbmdlIiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwiRGlzcG9zYWJsZSIsImRpc3Bvc2VkXyIsImRpc3Bvc2VJbnRlcm5hbCIsInRhcmdldCIsImtleSIsInNvdXJjZSIsImFyZ3MiLCJwYXJ0cyIsInNwbGl0IiwicmVkdWNlIiwicGFydCIsIm1hcHBlZE9iaiIsImtleXMiLCJPYmplY3QiLCJvYmoxIiwib2JqMiIsImtleXMxIiwia2V5czIiLCJzdHJpbmciLCJzdHIxIiwic3RyMiIsInRlc3QxIiwidG9Mb3dlckNhc2UiLCJ0ZXN0MiIsInJlcGxhY2UiLCJ4IiwiZmxvb3IiLCJhYnMiLCJEYXRlIiwibm93IiwiaGFzaCIsImxlbiIsImNoYXJDb2RlQXQiLCJ2YWx1ZSIsIk1FVEFMX0RBVEEiLCJkb21EYXRhIiwiZWxlbWVudCIsImluaXRpYWxWYWx1ZSIsIkV2ZW50SGFuZGxlIiwiZW1pdHRlciIsImV2ZW50IiwibGlzdGVuZXIiLCJlbWl0dGVyXyIsImV2ZW50XyIsImxpc3RlbmVyXyIsInJlbW92ZUxpc3RlbmVyIiwiaXNEaXNwb3NlZCIsInNpbmdsZUFycmF5XyIsIkV2ZW50RW1pdHRlciIsImV2ZW50c18iLCJsaXN0ZW5lckhhbmRsZXJzXyIsInNob3VsZFVzZUZhY2FkZV8iLCJob2xkZXIiLCJoYW5kbGVyIiwiZGVmYXVsdExpc3RlbmVyIiwidmFsaWRhdGVMaXN0ZW5lcl8iLCJldmVudHMiLCJ0b0V2ZW50c0FycmF5XyIsImFkZFNpbmdsZUxpc3RlbmVyXyIsInJ1bkxpc3RlbmVySGFuZGxlcnNfIiwiYWRkSGFuZGxlcl8iLCJnZXRTaG91bGRVc2VGYWNhZGUiLCJmYWNhZGUiLCJwcmV2ZW50ZWREZWZhdWx0IiwibGlzdGVuZXJzIiwiZ2V0UmF3TGlzdGVuZXJzXyIsInNsaWNlIiwiYXJndW1lbnRzIiwicnVuTGlzdGVuZXJzXyIsImJ1aWxkRmFjYWRlXyIsImRpcmVjdExpc3RlbmVycyIsInRvQXJyYXkiLCJjb25jYXQiLCJtYXAiLCJhbW91bnQiLCJtYW55XyIsInNlbGYiLCJoYW5kbGVySW50ZXJuYWwiLCJhcHBseSIsImxpc3RlbmVyT2JqIiwicmVtb3ZlTWF0Y2hpbmdMaXN0ZW5lck9ianNfIiwiYWRkTGlzdGVuZXIiLCJtYW55IiwibGlzdGVuZXJPYmpzIiwiZmluYWxMaXN0ZW5lcnMiLCJtYXRjaGVzTGlzdGVuZXJfIiwib2ZmIiwiaGFuZGxlcnMiLCJkZWZhdWx0TGlzdGVuZXJzIiwiZGVmYXVsdCIsImoiLCJzaG91bGRVc2VGYWNhZGUiLCJUeXBlRXJyb3IiLCJFdmVudEVtaXR0ZXJQcm94eSIsIm9yaWdpbkVtaXR0ZXIiLCJ0YXJnZXRFbWl0dGVyIiwiYmxhY2tsaXN0Iiwid2hpdGVsaXN0IiwiYmxhY2tsaXN0XyIsIm9yaWdpbkVtaXR0ZXJfIiwicGVuZGluZ0V2ZW50c18iLCJwcm94aWVkRXZlbnRzXyIsInRhcmdldEVtaXR0ZXJfIiwid2hpdGVsaXN0XyIsInN0YXJ0UHJveHlfIiwib24iLCJyZW1vdmVMaXN0ZW5lcnNfIiwiZW1pdCIsInNob3VsZFByb3h5RXZlbnRfIiwidHJ5VG9BZGRMaXN0ZW5lcl8iLCJmb3JFYWNoIiwicHJveHlFdmVudCIsIm9uTGlzdGVuZXIiLCJhZGRMaXN0ZW5lcl8iLCJlbWl0T25UYXJnZXRfIiwiRXZlbnRIYW5kbGVyIiwiZXZlbnRIYW5kbGVzXyIsIkRvbURlbGVnYXRlZEV2ZW50SGFuZGxlIiwic2VsZWN0b3IiLCJzZWxlY3Rvcl8iLCJkZWxlZ2F0aW5nIiwiZ2V0Iiwic2VsZWN0b3JzIiwicmVtb3ZlIiwiRG9tRXZlbnRIYW5kbGUiLCJjYXB0dXJlIiwiY2FwdHVyZV8iLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiZWxlbWVudHNCeVRhZ18iLCJzdXBwb3J0Q2FjaGVfIiwiY3VzdG9tRXZlbnRzIiwiTEFTVF9DT05UQUlORVIiLCJVU0VfQ0FQVFVSRSIsImFkZENsYXNzZXMiLCJlbGVtZW50cyIsImNsYXNzZXMiLCJhZGRDbGFzc2VzV2l0aE5hdGl2ZV8iLCJjbGFzc05hbWUiLCJjbGFzc0xpc3QiLCJhZGQiLCJhZGRDbGFzc2VzV2l0aG91dE5hdGl2ZV8iLCJlbGVtZW50Q2xhc3NOYW1lIiwiY2xhc3Nlc1RvQXBwZW5kIiwiYWRkRWxlbWVudExpc3RlbmVyXyIsImV2ZW50TmFtZSIsImFkZFNlbGVjdG9yTGlzdGVuZXJfIiwiZGVsZWdhdGluZ0RhdGEiLCJhZGRUb0Fycl8iLCJhdHRhY2hEZWxlZ2F0ZUV2ZW50XyIsImhhbmRsZURlbGVnYXRlRXZlbnRfIiwiY2xvc2VzdCIsIm1hdGNoIiwiYXBwZW5kIiwicGFyZW50IiwiY2hpbGQiLCJidWlsZEZyYWdtZW50IiwiaXNOb2RlTGlzdExpa2UiLCJjaGlsZEFyciIsImh0bWxTdHJpbmciLCJ0ZW1wRGl2IiwiaW5uZXJIVE1MIiwiZmlyc3RDaGlsZCIsImZyYWdtZW50IiwiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCIsImNvbnRhaW5zIiwiZWxlbWVudDEiLCJlbGVtZW50MiIsImRlbGVnYXRlIiwic2VsZWN0b3JPclRhcmdldCIsImN1c3RvbUNvbmZpZyIsIm9yaWdpbmFsRXZlbnQiLCJkZWZhdWx0TGlzdGVuZXJfIiwiaXNBYmxlVG9JbnRlcmFjdFdpdGhfIiwibm9kZSIsImV2ZW50T2JqIiwiYnV0dG9uIiwibWF0Y2hlc1NlbGVjdG9yIiwidGFnTmFtZSIsImRpc2FibGVkIiwiaXRlbSIsImV4aXREb2N1bWVudCIsInJldCIsImNvbnRhaW5lciIsImN1cnJlbnRUYXJnZXQiLCJkZWZGbnMiLCJ0cmlnZ2VyRGVsZWdhdGVkTGlzdGVuZXJzXyIsInRyaWdnZXJEZWZhdWx0RGVsZWdhdGVkTGlzdGVuZXJzXyIsImRlbGVnYXRlVGFyZ2V0IiwicCIsIkVsZW1lbnQiLCJtIiwibWF0Y2hlcyIsIndlYmtpdE1hdGNoZXNTZWxlY3RvciIsIm1vek1hdGNoZXNTZWxlY3RvciIsIm1zTWF0Y2hlc1NlbGVjdG9yIiwib01hdGNoZXNTZWxlY3RvciIsIm1hdGNoRmFsbGJhY2tfIiwibm9kZXMiLCJxdWVyeVNlbGVjdG9yQWxsIiwibm9ybWFsaXplRGVsZWdhdGVFdmVudF8iLCJzdG9wUHJvcGFnYXRpb24iLCJzdG9wUHJvcGFnYXRpb25fIiwic3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uIiwic3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uXyIsIm9uY2UiLCJkb21FdmVudEhhbmRsZSIsInJlZ2lzdGVyQ3VzdG9tRXZlbnQiLCJyZW1vdmVDaGlsZHJlbiIsInJlbW92ZUNsYXNzZXMiLCJyZW1vdmVDbGFzc2VzV2l0aE5hdGl2ZV8iLCJyZW1vdmVDbGFzc2VzV2l0aG91dE5hdGl2ZV8iLCJ0cmltIiwic3RvcHBlZCIsInN0b3BwZWRJbW1lZGlhdGUiLCJzdXBwb3J0c0V2ZW50IiwidGFnIiwiZGVmYXVsdFByZXZlbnRlZCIsImRlZmF1bHRGbnMiLCJjdXJyRWxlbWVudCIsImxpbWl0IiwidHJpZ2dlckVsZW1lbnRMaXN0ZW5lcnNfIiwidHJpZ2dlclNlbGVjdG9yTGlzdGVuZXJzXyIsImxhc3RDb250YWluZXIiLCJ0cmlnZ2VyTGlzdGVuZXJzXyIsIkRvbUV2ZW50RW1pdHRlclByb3h5IiwiaXNEZWxlZ2F0ZUV2ZW50XyIsImluZGV4Iiwic3Vic3RyIiwiYmFiZWxIZWxwZXJzLmdldCIsImlzU3VwcG9ydGVkRG9tRXZlbnRfIiwiZmVhdHVyZXMiLCJhbmltYXRpb25FdmVudE5hbWVfIiwiY2hlY2tBbmltYXRpb25FdmVudE5hbWVfIiwicHJlZml4ZXMiLCJ0eXBlVGl0bGVDYXNlIiwicmVwbGFjZUludGVydmFsIiwidG9VcHBlckNhc2UiLCJzdWZmaXhlcyIsImFuaW1hdGlvbkVsZW1lbnRfIiwiYXR0ck9yZGVyQ2hhbmdlXyIsIm9yaWdpbmFsQ29udGVudCIsImdsb2JhbEV2YWwiLCJ0ZXh0IiwiYXBwZW5kRm4iLCJkZWZhdWx0Rm4iLCJydW5GaWxlIiwic2NyaXB0cyIsInJ1blNjcmlwdHNJbk9yZGVyIiwicnVuU2NyaXB0IiwiZ2xvYmFsRXZhbFN0eWxlcyIsImhyZWYiLCJsaW5rIiwicmVsIiwicnVuU3R5bGUiLCJzdHlsZXMiLCJsb2FkQ291bnQiLCJyZWdpc3RlckV2ZW50cyIsIm1vdXNlRXZlbnRNYXAiLCJyZWxhdGVkIiwicmVsYXRlZFRhcmdldCIsImN1c3RvbVR5cGUiLCJhbmltYXRpb25FdmVudE1hcCIsImV2ZW50VHlwZSIsImNoZWNrQW5pbWF0aW9uRXZlbnROYW1lIiwiZ2xvYmFscyIsInBhcnNlRnJvbUFuY2hvciIsIm9wdF91cmkiLCJ0ZXN0IiwiaG9zdG5hbWUiLCJwYXNzd29yZCIsInBhdGhuYW1lIiwicG9ydCIsInNlYXJjaCIsInVzZXJuYW1lIiwicGFyc2UiLCJVUkwiLCJ1cmwiLCJjcmVhdGUiLCJNdWx0aU1hcCIsInZhbHVlcyIsInNpemUiLCJuYW1lcyIsIkpTT04iLCJzdHJpbmdpZnkiLCJzZXQiLCJUcmVlTm9kZSIsInZhbHVlXyIsInBhcmVudF8iLCJjaGlsZHJlbl8iLCJzZXRQYXJlbnQiLCJjdXJyZW50IiwiZ2V0UGFyZW50IiwiYW5jZXN0b3JzIiwiZ2V0Q2hpbGRyZW4iLCJFTVBUWV9BUlJBWSIsImRlcHRoIiwicm9vdCIsImdldENoaWxkQ291bnQiLCJvcHRfcHJlb3JkZXJGbiIsIm9wdF9wb3N0b3JkZXJGbiIsInRyYXZlcnNlIiwiYXNzZXJ0Q2hpbGRIYXNOb1BhcmVudCIsInBhcnNlRm5fIiwiVXJpIiwibWF5YmVBZGRQcm90b2NvbEFuZEhvc3RuYW1lXyIsIm11bHRpbWFwIiwiZ2V0QWxsIiwiYWRkUGFyYW1ldGVyVmFsdWUiLCJlbnN1cmVRdWVyeUluaXRpYWxpemVkXyIsInF1ZXJ5IiwicGFyYW0iLCJ1cmxEZWNvZGUiLCJnZXRIb3N0bmFtZSIsImdldFBvcnQiLCJIT1NUTkFNRV9QTEFDRUhPTERFUiIsImdldEhvc3QiLCJnZXRQcm90b2NvbCIsInF1ZXJ5c3RyaW5nIiwiZ2V0UGFyYW1ldGVyTmFtZXMiLCJnZXRQYXJhbWV0ZXJWYWx1ZXMiLCJlbmNvZGVVUklDb21wb25lbnQiLCJzZXRQYXJhbWV0ZXJWYWx1ZSIsIlJBTkRPTV9QQVJBTSIsImdldFJhbmRvbVN0cmluZyIsIkRFRkFVTFRfUFJPVE9DT0wiLCJjaGFyQXQiLCJyZW1vdmVQYXJhbWV0ZXIiLCJnZXRQYXRobmFtZSIsImdldFNlYXJjaCIsImdldEhhc2giLCJwYXJzZUZuIiwiYmFzZVBhdGgiLCJwYXRocyIsInBhdGgiLCJqb2luIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwiaXNTZWN1cmUiLCJ1dGlscyIsImF0dHJpYnV0ZXMiLCJhdHRyaWJ1dGUiLCJzZXRBdHRyaWJ1dGUiLCJnZXRDdXJyZW50QnJvd3NlclBhdGhXaXRob3V0SGFzaCIsIm9mZnNldExlZnQiLCJvZmZzZXRUb3AiLCJvZmZzZXRQYXJlbnQiLCJ1cmkiLCJjdXJyZW50QnJvd3NlclBhdGgiLCJnZXRVcmxQYXRoV2l0aG91dEhhc2giLCJnZXRVcmxQYXRoIiwiaGlzdG9yeSIsInB1c2hTdGF0ZSIsImVyciIsImVycm9yIiwicmVtb3ZlQXR0cmlidXRlIiwicmVmZXJyZXIiLCJkZWZpbmVQcm9wZXJ0eSIsIlRoZW5hYmxlIiwiSU1QTEVNRU5URURfQllfUFJPUCIsImFkZEltcGxlbWVudGF0aW9uIiwiJGdvb2dfVGhlbmFibGUiLCJpc0ltcGxlbWVudGVkQnkiLCJwYXJ0aWFsIiwibmV3QXJncyIsIkNhbmNlbGxhYmxlUHJvbWlzZSIsInJlc29sdmVyIiwib3B0X2NvbnRleHQiLCJzdGF0ZV8iLCJTdGF0ZV8iLCJQRU5ESU5HIiwicmVzdWx0XyIsImNhbGxiYWNrRW50cmllc18iLCJleGVjdXRpbmdfIiwiVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSIsInVuaGFuZGxlZFJlamVjdGlvbklkXyIsImhhZFVuaGFuZGxlZFJlamVjdGlvbl8iLCJyZXNvbHZlXyIsIkZVTEZJTExFRCIsInJlYXNvbiIsIlJFSkVDVEVEIiwiQ2FsbGJhY2tFbnRyeV8iLCJyZXNvbHZlIiwib3B0X3ZhbHVlIiwicmVqZWN0Iiwib3B0X3JlYXNvbiIsInJhY2UiLCJwcm9taXNlcyIsInByb21pc2UiLCJhbGwiLCJ0b0Z1bGZpbGwiLCJvbkZ1bGZpbGwiLCJvblJlamVjdCIsImZpcnN0RnVsZmlsbGVkIiwidG9SZWplY3QiLCJyZWFzb25zIiwib3B0X29uRnVsZmlsbGVkIiwib3B0X29uUmVqZWN0ZWQiLCJhZGRDaGlsZFByb21pc2VfIiwidGhlbkFsd2F5cyIsIm9uUmVzb2x2ZWQiLCJoYW5kbGVSZWplY3Rpb25fIiwiYWRkQ2FsbGJhY2tFbnRyeV8iLCJ0aGVuQ2F0Y2giLCJvblJlamVjdGVkIiwiY2F0Y2giLCJjYW5jZWwiLCJvcHRfbWVzc2FnZSIsIkNhbmNlbGxhdGlvbkVycm9yIiwiSVNfQ0FOQ0VMTEFUSU9OX0VSUk9SIiwiY2FuY2VsSW50ZXJuYWxfIiwiY2FuY2VsQ2hpbGRfIiwiY2hpbGRQcm9taXNlIiwiY2hpbGRDb3VudCIsImNoaWxkSW5kZXgiLCJlbnRyeSIsImNhbGxiYWNrRW50cnkiLCJleGVjdXRlQ2FsbGJhY2tfIiwic2NoZWR1bGVDYWxsYmFja3NfIiwib25GdWxmaWxsZWQiLCJyZXN1bHQiLCJ1bmJsb2NrQW5kRnVsZmlsbF8iLCJCTE9DS0VEIiwidW5ibG9ja0FuZFJlamVjdF8iLCJzdGF0ZSIsInRyeVRoZW5fIiwiYWRkVW5oYW5kbGVkUmVqZWN0aW9uXyIsInRoZW5hYmxlIiwiY2FsbGVkIiwiZXhlY3V0ZUNhbGxiYWNrc18iLCJlbnRyaWVzIiwicmVtb3ZlVW5oYW5kbGVkUmVqZWN0aW9uXyIsInNldFRpbWVvdXQiLCJzZXRVbmhhbmRsZWRSZWplY3Rpb25IYW5kbGVyIiwiZGVib3VuY2UiLCJkZWxheSIsImRlYm91bmNlZCIsImNhbmNlbERlYm91bmNlIiwiUkVHRVgiLCJjb252ZXJ0TWF0Y2hlc1RvT2JqIiwiY29udmVydFRva2Vuc1RvUmVnZXgiLCJ0b2tlbnMiLCJyZWdleCIsImNvcmUiLCJlc2NhcGUiLCJlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAiLCJwYXR0ZXJuIiwicmVwZWF0IiwicHJlZml4Iiwib3B0aW9uYWwiLCJSZWdFeHAiLCJtYWtlVHJhaWxpbmdTbGFzaE9wdGlvbmFsIiwicm91dGVPclRva2VucyIsInJvdXRlIiwidW5uYW1lZENvdW50IiwiY3VyclBhdGgiLCJleGVjIiwicGFyYW1QYXR0ZXJuIiwidW5uYW1lZFBhdHRlcm4iLCJtb2RpZmllciIsInRvUmVnZXgiLCJleHRyYWN0RGF0YSIsInBhcmFtSW5kZXgiLCJSb3V0ZSIsInBhcnNlZERhdGFfIiwiYnVpbGRQYXJzZWREYXRhXyIsIkNhY2hlYWJsZSIsImNhY2hlIiwiY2FjaGVhYmxlIiwiY29udGVudCIsImNsZWFyQ2FjaGUiLCJTY3JlZW4iLCJtYWtlSWRfIiwibWV0YXMiLCJsb2ciLCJzdXJmYWNlcyIsInNJZCIsImFjdGl2ZUNoaWxkIiwicnVuU2NyaXB0c0luRWxlbWVudCIsInRyYW5zaXRpb25zIiwic3VyZmFjZSIsImRlZmVycmVkIiwic2hvdyIsIlN1cmZhY2UiLCJkZWZhdWx0Q2hpbGQiLCJ0cmFuc2l0aW9uRm4iLCJnZXRDaGlsZCIsIkRFRkFVTFQiLCJtYXliZVdyYXBDb250ZW50QXNEZWZhdWx0XyIsInNjcmVlbklkIiwib3B0X2NvbnRlbnQiLCJjcmVhdGVDaGlsZCIsInRyYW5zaXRpb24iLCJnZXRFbGVtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJhZGRDb250ZW50IiwiZnJvbSIsInRvIiwiZGVmYXVsdFRyYW5zaXRpb24iLCJOYXZpZ2F0aW9uU3RyYXRlZ3kiLCJBcHAiLCJhY3RpdmVTY3JlZW4iLCJhY3RpdmVQYXRoIiwiYWxsb3dQcmV2ZW50TmF2aWdhdGUiLCJicm93c2VyUGF0aEJlZm9yZU5hdmlnYXRlIiwiY2FwdHVyZVNjcm9sbFBvc2l0aW9uRnJvbVNjcm9sbEV2ZW50IiwiZGVmYXVsdFRpdGxlIiwiZm9ybVNlbGVjdG9yIiwiaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoIiwibGlua1NlbGVjdG9yIiwibG9hZGluZ0Nzc0NsYXNzIiwibmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25TdXBwb3J0ZWQiLCJuYXZpZ2F0aW9uU3RyYXRlZ3kiLCJJTU1FRElBVEUiLCJpc05hdmlnYXRpb25QZW5kaW5nIiwicGVuZGluZ05hdmlnYXRlIiwicG9wc3RhdGVTY3JvbGxMZWZ0IiwicG9wc3RhdGVTY3JvbGxUb3AiLCJyZWRpcmVjdFBhdGgiLCJyb3V0ZXMiLCJzY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUiLCJzY3JlZW5zIiwic2tpcExvYWRQb3BzdGF0ZSIsInVwZGF0ZVNjcm9sbFBvc2l0aW9uIiwiYXBwRXZlbnRIYW5kbGVyc18iLCJvblNjcm9sbF8iLCJvbkxvYWRfIiwib25Qb3BzdGF0ZV8iLCJvblN0YXJ0TmF2aWdhdGVfIiwib25CZWZvcmVOYXZpZ2F0ZV8iLCJvbkJlZm9yZU5hdmlnYXRlRGVmYXVsdF8iLCJvbkJlZm9yZVVubG9hZERlZmF1bHRfIiwic2V0TGlua1NlbGVjdG9yIiwic2V0Rm9ybVNlbGVjdG9yIiwibWF5YmVPdmVybG9hZEJlZm9yZVVubG9hZF8iLCJnZXRJZCIsImlzV2ViVXJpIiwiaXNMaW5rU2FtZU9yaWdpbl8iLCJpc1NhbWVCYXNlUGF0aF8iLCJpc0N1cnJlbnRCcm93c2VyUGF0aCIsImZpbmRSb3V0ZSIsInJlbW92ZVNjcmVlbiIsInNjcmVlbiIsImdldEhhbmRsZXIiLCJjbGVhclNjcmVlbnNDYWNoZSIsImZvcm1FdmVudEhhbmRsZXJfIiwibGlua0V2ZW50SGFuZGxlcl8iLCJyZW1vdmVBbGxMaXN0ZW5lcnMiLCJuYXZpZ2F0ZSIsImdldEN1cnJlbnRCcm93c2VyUGF0aCIsIm9wdF9yZXBsYWNlSGlzdG9yeSIsInN0b3BQZW5kaW5nTmF2aWdhdGVfIiwibmV4dFNjcmVlbiIsImNyZWF0ZVNjcmVlbkluc3RhbmNlIiwibWF5YmVQcmV2ZW50RGVhY3RpdmF0ZV8iLCJtYXliZVByZXZlbnRBY3RpdmF0ZV8iLCJsb2FkIiwiU0NIRURVTEVfTEFTVCIsImRlYWN0aXZhdGUiLCJwcmVwYXJlTmF2aWdhdGVIaXN0b3J5XyIsInByZXBhcmVOYXZpZ2F0ZVN1cmZhY2VzXyIsImV4dHJhY3RQYXJhbXMiLCJldmFsdWF0ZVN0eWxlcyIsImZsaXAiLCJldmFsdWF0ZVNjcmlwdHMiLCJtYXliZVVwZGF0ZVNjcm9sbFBvc2l0aW9uU3RhdGVfIiwic3luY1Njcm9sbFBvc2l0aW9uU3luY1RoZW5Bc3luY18iLCJmaW5hbGl6ZU5hdmlnYXRlXyIsImhhbmRsZU5hdmlnYXRlRXJyb3JfIiwic2NoZWR1bGVkTmF2aWdhdGlvbiIsInNoaWZ0IiwibWF5YmVOYXZpZ2F0ZV8iLCJnZXRSb3V0ZVBhdGgiLCJhY3RpdmF0ZSIsImlzQ2FjaGVhYmxlIiwiY2FwdHVyZWRGb3JtRWxlbWVudCIsImNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQiLCJtYXRjaGVzUGF0aCIsImdldElnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCIsImdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaCIsInN0YWNrIiwiaG9zdFVyaSIsImxvY2F0aW9uSG9zdFVyaSIsIndpbm5lciIsInN3aXRjaFNjcm9sbFBvc2l0aW9uUmFjZSIsInNjcm9sbFRvIiwic2Nyb2xsTGVmdCIsInNjcm9sbFRvcCIsIm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uXyIsInNjcm9sbFJlc3RvcmF0aW9uIiwibWl4aW4iLCJjYW5OYXZpZ2F0ZSIsImlzTmF2aWdhdGlvblNjaGVkdWxlZCIsIm1heWJlU2NoZWR1bGVOYXZpZ2F0aW9uXyIsInByZXZlbnREZWZhdWx0IiwibmF2aWdhdGVGYWlsZWQiLCJpc1NjaGVkdWxlZE5hdmlnYXRpb24iLCJvbmJlZm9yZXVubG9hZCIsIl9vbmJlZm9yZXVubG9hZCIsIl9vdmVybG9hZGVkIiwiYmVmb3JlQWN0aXZhdGUiLCJwcmV2ZW50IiwiYmVmb3JlRGVhY3RpdmF0ZSIsImFuY2hvckVsZW1lbnQiLCJnZXROb2RlT2Zmc2V0Iiwic2F2ZUhpc3RvcnlDdXJyZW50UGFnZVNjcm9sbFBvc2l0aW9uXyIsIm9wdF9ldmVudCIsImlzSHRtbDVIaXN0b3J5U3VwcG9ydGVkIiwiZm9ybSIsInJlcGxhY2VIaXN0b3J5IiwiZnVuYyIsImFsdEtleSIsImN0cmxLZXkiLCJtZXRhS2V5Iiwic2hpZnRLZXkiLCJtZXRob2QiLCJidXR0b25TZWxlY3RvciIsImFjdGl2ZUVsZW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwiYWN0aW9uIiwibWF5YmVSZXBvc2l0aW9uU2Nyb2xsVG9IYXNoZWRBbmNob3IiLCJyZWxvYWRQYWdlIiwic2VubmEiLCJsb2NrSGlzdG9yeVNjcm9sbFBvc2l0aW9uXyIsInNldFJlZmVycmVyIiwic2V0SG9zdG5hbWUiLCJzZXRQb3J0IiwicGFnZVlPZmZzZXQiLCJwYWdlWE9mZnNldCIsIm1heWJlRGlzYWJsZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uIiwiZW5kTmF2aWdhdGVQYXlsb2FkIiwiZG9OYXZpZ2F0ZV8iLCJtYXliZVJlc3RvcmVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbiIsImdldFRpdGxlIiwiZ2V0RGVmYXVsdFRpdGxlIiwiYmVmb3JlVXBkYXRlSGlzdG9yeVBhdGgiLCJoaXN0b3J5U3RhdGUiLCJtYXliZVJlc3RvcmVSZWRpcmVjdFBhdGhIYXNoXyIsInVwZGF0ZUhpc3RvcnlfIiwiYmVmb3JlVXBkYXRlSGlzdG9yeVN0YXRlIiwicGFyYW1zIiwic3VyZmFjZUNvbnRlbnQiLCJnZXRTdXJmYWNlQ29udGVudCIsInJlbG9hZCIsInN1cmZhY2VJZCIsImRpc3Bvc2UiLCJyZXBsYWNlU3RhdGUiLCJyZW1vdmVQYXRoVHJhaWxpbmdTbGFzaCIsIm9uRG9jU3VibWl0RGVsZWdhdGVfIiwib25Eb2NDbGlja0RlbGVnYXRlXyIsInN5bmMiLCJ0aXRsZU5vZGUiLCJBamF4IiwiYWxsSGVhZGVycyIsImhlYWRlcnMiLCJwYWlycyIsImJvZHkiLCJvcHRfaGVhZGVycyIsIm9wdF9wYXJhbXMiLCJvcHRfdGltZW91dCIsIm9wdF9zeW5jIiwib3B0X3dpdGhDcmVkZW50aWFscyIsInJlcXVlc3QiLCJYTUxIdHRwUmVxdWVzdCIsInByZXZpb3VzUmVhZHlTdGF0ZSIsIlByb21pc2UiLCJvbmxvYWQiLCJhYm9ydGVkIiwib25lcnJvciIsInJlYWR5U3RhdGUiLCJ0ZXJtaW5hdGVkUHJlbWF0dXJlbHkiLCJhYm9ydCIsInRpbWVvdXQiLCJhZGRQYXJhbWV0ZXJzRnJvbU11bHRpTWFwIiwid2l0aENyZWRlbnRpYWxzIiwic2V0UmVxdWVzdEhlYWRlciIsInNlbmQiLCJlcnJvcnMiLCJJTlZBTElEX1NUQVRVUyIsIlJFUVVFU1RfRVJST1IiLCJSRVFVRVNUX1RJTUVPVVQiLCJSRVFVRVNUX1BSRU1BVFVSRV9URVJNSU5BVElPTiIsIlVBIiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwicGxhdGZvcm0iLCJpc01hYyIsIm1hdGNoUGxhdGZvcm0iLCJpc1dpbiIsImlzT3BlcmEiLCJtYXRjaFVzZXJBZ2VudCIsImlzSWUiLCJpc0VkZ2UiLCJpc0llT3JFZGdlIiwiaXNDaHJvbWUiLCJpc1NhZmFyaSIsImlzRmlyZWZveCIsInRlc3RVc2VyQWdlbnQiLCJnZXROYXRpdmVVc2VyQWdlbnQiLCJnZXROYXRpdmVQbGF0Zm9ybSIsIlJlcXVlc3RTY3JlZW4iLCJodHRwSGVhZGVycyIsImh0dHBNZXRob2QiLCJHRVQiLCJzdGF0dXMiLCJpc1ZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlIiwiaW52YWxpZFN0YXR1cyIsInN0YXR1c0NvZGUiLCJnZXRSZXF1ZXN0UGF0aCIsInNldFByb3RvY29sIiwibWFrZVVuaXF1ZSIsImdldFJlcXVlc3QiLCJyZXF1ZXN0UGF0aCIsInJlc3BvbnNlVXJsIiwibWF5YmVFeHRyYWN0UmVzcG9uc2VVcmxGcm9tUmVxdWVzdCIsInJlbW92ZVVuaXF1ZSIsImdldENhY2hlIiwiaGVhZGVyIiwiYWRkU2FmYXJpWEhSUG9seWZpbGwiLCJGb3JtRGF0YSIsIm1heWJlQXBwZW5kU3VibWl0QnV0dG9uVmFsdWVfIiwiUE9TVCIsImZvcm1hdExvYWRQYXRoIiwicmVtb3ZlU2FmYXJpWEhSUG9seWZpbGwiLCJzZXRSZXF1ZXN0IiwieGhyIiwiYXNzZXJ0VmFsaWRSZXNwb25zZVN0YXR1c0NvZGUiLCJhZGRDYWNoZSIsInJlc3BvbnNlVGV4dCIsInJlcXVlc3RFcnJvciIsInJlcXVlc3RQcmVtYXR1cmVUZXJtaW5hdGlvbiIsInJlc3BvbnNlVVJMIiwiZ2V0UmVzcG9uc2VIZWFkZXIiLCJYX1JFUVVFU1RfVVJMX0hFQURFUiIsImlucHV0cyIsImlucHV0IiwiZmlsZXMiLCJIdG1sU2NyZWVuIiwibWV0YVRhZ3NTZWxlY3RvciIsInRpdGxlU2VsZWN0b3IiLCJyZWxlYXNlVmlydHVhbERvY3VtZW50IiwicGVuZGluZ1N0eWxlcyIsInZpcnR1YWxEb2N1bWVudCIsImNvcHlOb2RlQXR0cmlidXRlc0Zyb21Db250ZW50XyIsIm5ld1N0eWxlIiwiaXNUZW1wb3JhcnlTdHlsZSIsInN0eWxlc1RlbXBvcmFyeSIsInN0eWxlSW5Eb2MiLCJpbnNlcnRCZWZvcmUiLCJuZXh0U2libGluZyIsImJvZHlTdXJmYWNlIiwicGxhY2Vob2xkZXIiLCJ0ZW1wTm9kZSIsImNyZWF0ZVJhbmdlIiwiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiwiY2xlYXJOb2RlQXR0cmlidXRlcyIsImNvcHlOb2RlQXR0cmlidXRlcyIsImRpc3Bvc2VQZW5kaW5nU3R5bGVzIiwicmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQiLCJldmFsdWF0ZVRyYWNrZWRTY3JpcHRzIiwiZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyIsInNjcmlwdHNUZW1wb3JhcnkiLCJzY3JpcHRzUGVybWFuZW50IiwiZXZhbHVhdGVUcmFja2VkU3R5bGVzIiwicnVuU3R5bGVzSW5FbGVtZW50Iiwic3R5bGVzUGVybWFuZW50IiwiYXBwZW5kU3R5bGVJbnRvRG9jdW1lbnRfIiwicmVzb3VyY2VzSW5WaXJ0dWFsIiwidmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfIiwiZmF2aWNvbiIsInJlc291cmNlc0luRG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yQWxsXyIsInJ1bkZhdmljb25JbkVsZW1lbnRfIiwiZXZhbHVhdG9yRm4iLCJzZWxlY3RvclRlbXBvcmFyeSIsInNlbGVjdG9yUGVybWFuZW50Iiwib3B0X2FwcGVuZFJlc291cmNlRm4iLCJ0cmFja2VkIiwidGVtcG9yYXJpZXNJbkRvYyIsInBlcm1hbmVudHNJbkRvYyIsInJlc291cmNlIiwicmVzb3VyY2VLZXkiLCJnZXRSZXNvdXJjZUtleV8iLCJwZXJtYW5lbnRSZXNvdXJjZXNJbkRvYyIsImZyYWciLCJldmFsdWF0ZUZhdmljb25fIiwidXBkYXRlTWV0YVRhZ3NfIiwiY3VycmVudE1ldGFOb2RlcyIsIm1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudCIsIm1ldGEiLCJhbGxvY2F0ZVZpcnR1YWxEb2N1bWVudEZvckNvbnRlbnQiLCJyZXNvbHZlVGl0bGVGcm9tVmlydHVhbERvY3VtZW50IiwicmVzb2x2ZU1ldGFUYWdzRnJvbVZpcnR1YWxEb2N1bWVudCIsImFzc2VydFNhbWVCb2R5SWRJblZpcnR1YWxEb2N1bWVudCIsIm1ha2VUZW1wb3JhcnlTdHlsZXNIcmVmc1VuaXF1ZV8iLCJyZXBsYWNlU3R5bGVBbmRNYWtlVW5pcXVlXyIsInJlcGxhY2VDaGlsZCIsInNldEVsZW1lbnRXaXRoUmFuZG9tSHJlZiIsInNldFRpdGxlIiwidGV4dENvbnRlbnQiLCJzZXRNZXRhcyIsImlnbm9yZUZhdmljb24iLCJBcHBEYXRhQXR0cmlidXRlSGFuZGxlciIsImFwcCIsImJhc2VFbGVtZW50IiwiaGFzQXR0cmlidXRlIiwiZGF0YUF0dHJpYnV0ZXMiLCJtYXliZUFkZFJvdXRlc18iLCJtYXliZUFkZFN1cmZhY2VzXyIsIm1heWJlU2V0QmFzZVBhdGhfIiwibWF5YmVTZXRMaW5rU2VsZWN0b3JfIiwibWF5YmVTZXRMb2FkaW5nQ3NzQ2xhc3NfIiwibWF5YmVTZXRVcGRhdGVTY3JvbGxQb3NpdGlvbl8iLCJtYXliZURpc3BhdGNoXyIsInJvdXRlc1NlbGVjdG9yIiwicXVlcnlTZWxlY3RvckFsbEFzQXJyYXlfIiwibWF5YmVQYXJzZUxpbmtSb3V0ZV8iLCJoYXNSb3V0ZXMiLCJhZGRSb3V0ZXMiLCJzdXJmYWNlc1NlbGVjdG9yIiwic3VyZmFjZUVsZW1lbnQiLCJ1cGRhdGVFbGVtZW50SWRJZlNwZWNpYWxTdXJmYWNlXyIsImFkZFN1cmZhY2VzIiwiZGlzcGF0Y2giLCJtYXliZVBhcnNlTGlua1JvdXRlUGF0aF8iLCJtYXliZVBhcnNlTGlua1JvdXRlSGFuZGxlcl8iLCJnZXRQYXRoIiwiZ2V0QXR0cmlidXRlIiwiZ2V0T2JqZWN0QnlOYW1lIiwic2V0QmFzZVBhdGgiLCJzZXRMb2FkaW5nQ3NzQ2xhc3MiLCJzZXRVcGRhdGVTY3JvbGxQb3NpdGlvbiIsImRhdGFBdHRyaWJ1dGVIYW5kbGVyIiwic2V0QmFzZUVsZW1lbnQiLCJoYW5kbGUiLCJ2ZXJzaW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQTs7Ozs7QUFLQSxJQUFJQSwrQkFBSjs7Ozs7OztBQU9BLElBQUlDLG1CQUFtQixDQUF2Qjs7Ozs7OztBQU9BLEFBQU8sSUFBTUMsMEJBQXdCQyxLQUFLQyxNQUFMLEtBQWdCLEdBQWpCLEtBQTBCLENBQWpELENBQU47Ozs7Ozs7Ozs7OztBQVlQLEFBQU8sU0FBU0MsY0FBVCxHQUEwQjtRQUMxQkMsTUFBTSwrQkFBTixDQUFOOzs7Ozs7QUFN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"} \ No newline at end of file +{"version":3,"file":"senna.js","sources":["node_modules/metal/src/coreNamed.js","node_modules/metal/src/core.js","node_modules/metal/src/array/array.js","node_modules/metal/src/async/async.js","node_modules/metal/src/disposable/Disposable.js","node_modules/metal/src/object/object.js","node_modules/metal/src/string/string.js","node_modules/metal-dom/src/domData.js","node_modules/metal-events/src/EventHandle.js","node_modules/metal-events/src/EventEmitter.js","node_modules/metal-events/src/EventEmitterProxy.js","node_modules/metal-events/src/EventHandler.js","node_modules/metal-dom/src/DomDelegatedEventHandle.js","node_modules/metal-dom/src/DomEventHandle.js","node_modules/metal-dom/src/domNamed.js","node_modules/metal-dom/src/dom.js","node_modules/metal-dom/src/DomEventEmitterProxy.js","node_modules/metal-dom/src/features.js","node_modules/metal-dom/src/globalEval.js","node_modules/metal-dom/src/globalEvalStyles.js","node_modules/metal-dom/src/events.js","src/globals/globals.js","node_modules/metal-uri/src/parseFromAnchor.js","node_modules/metal-uri/src/parse.js","node_modules/metal-structs/src/MultiMap.js","node_modules/metal-structs/src/TreeNode.js","node_modules/metal-uri/src/Uri.js","src/utils/utils.js","src/app/dataAttributes.js","node_modules/metal-promise/src/promise/Promise.js","node_modules/metal-debounce/src/debounce.js","node_modules/metal-path-parser/src/pathParser.js","src/route/Route.js","src/cacheable/Cacheable.js","src/screen/Screen.js","src/surface/Surface.js","src/app/App.js","node_modules/metal-ajax/src/Ajax.js","src/errors/errors.js","node_modules/metal-useragent/src/UA.js","src/screen/RequestScreen.js","src/screen/HtmlScreen.js","src/app/AppDataAttributeHandler.js","src/app/dataAttributeHandler.js","src/app/version.js"],"sourcesContent":["'use strict';\n\n/**\n * A collection of core utility functions.\n * @const\n */\n\nlet compatibilityModeData_;\n\n/**\n * Counter for unique id.\n * @type {Number}\n * @private\n */\nlet uniqueIdCounter_ = 1;\n\n/**\n * Unique id property prefix.\n * @type {String}\n * @protected\n */\nexport const UID_PROPERTY = `core_${(Math.random() * 1e9) >>> 0}`;\n\n/**\n * When defining a class Foo with an abstract method bar(), you can do:\n * Foo.prototype.bar = abstractMethod\n *\n * Now if a subclass of Foo fails to override bar(), an error will be thrown\n * when bar() is invoked.\n *\n * @type {!Function}\n * @throws {Error} when invoked to indicate the method should be overridden.\n */\nexport function abstractMethod() {\n\tthrow Error('Unimplemented abstract method');\n}\n\n/**\n * Disables Metal.js's compatibility mode.\n */\nexport function disableCompatibilityMode() {\n\tcompatibilityModeData_ = undefined;\n}\n\n/**\n * Enables Metal.js's compatibility mode with the following features from rc\n * and 1.x versions:\n * - Using \"key\" to reference component instances. In the current version\n * this should be done via \"ref\" instead. This allows old code still\n * using \"key\" to keep working like before. NOTE: this may cause\n * problems, since \"key\" is meant to be used differently. Only use this\n * if it's not possible to upgrade the code to use \"ref\" instead.\n * @param {Object=} data Optional object with data to specify more\n * details, such as:\n * - renderers {Array} the template renderers that should be in\n * compatibility mode, either their constructors or strings\n * representing them (e.g. 'soy' or 'jsx'). By default, all the ones\n * that extend from IncrementalDomRenderer.\n * @type {Object}\n */\nexport function enableCompatibilityMode(data = {}) {\n\tcompatibilityModeData_ = data;\n}\n\n/**\n * Returns the data used for compatibility mode, or nothing if it hasn't been\n * enabled.\n * @return {Object}\n */\nexport function getCompatibilityModeData() {\n\t// Compatibility mode can be set via the __METAL_COMPATIBILITY__ global var.\n\tif (compatibilityModeData_ === undefined) {\n\t\tif (typeof window !== 'undefined' && window.__METAL_COMPATIBILITY__) {\n\t\t\tenableCompatibilityMode(window.__METAL_COMPATIBILITY__);\n\t\t}\n\t}\n\treturn compatibilityModeData_;\n}\n\n/**\n * Returns the first argument if it's truthy, or the second otherwise.\n * @param {*} a\n * @param {*} b\n * @return {*}\n * @protected\n */\nfunction getFirstTruthy_(a, b) {\n\treturn a || b;\n}\n\n/**\n * Gets the name of the given function. If the current browser doesn't\n * support the `name` property, this will calculate it from the function's\n * content string.\n * @param {!function()} fn\n * @return {string}\n */\nexport function getFunctionName(fn) {\n\tif (!fn.name) {\n\t\tconst str = fn.toString();\n\t\tfn.name = str.substring(9, str.indexOf('('));\n\t}\n\treturn fn.name;\n}\n\n/**\n * Gets the value of a static property in the given class. The value will be\n * inherited from ancestors as expected, unless a custom merge function is given,\n * which can change how the super classes' value for that property will be merged\n * together.\n * The final merged value will be stored in another property, so that it won't\n * be recalculated even if this function is called multiple times.\n * @param {!function()} ctor Class constructor.\n * @param {string} propertyName Property name to be merged.\n * @param {function(*, *):*=} mergeFn Function that receives the merged\n * value of the property so far and the next value to be merged to it.\n * Should return these two merged together. If not passed the final property\n * will be the first truthy value among ancestors.\n * @return {Object}\n */\nexport function getStaticProperty(\n\tctor,\n\tpropertyName,\n\tmergeFn = getFirstTruthy_\n) {\n\tconst mergedName = propertyName + '_MERGED';\n\tif (!ctor.hasOwnProperty(mergedName)) {\n\t\t// eslint-disable-next-line\n\t\tlet merged = ctor.hasOwnProperty(propertyName)\n\t\t\t? ctor[propertyName]\n\t\t\t: null;\n\t\tif (ctor.__proto__ && !ctor.__proto__.isPrototypeOf(Function)) {\n\t\t\tmerged = mergeFn(\n\t\t\t\tmerged,\n\t\t\t\tgetStaticProperty(ctor.__proto__, propertyName, mergeFn)\n\t\t\t);\n\t\t}\n\t\tctor[mergedName] = merged;\n\t}\n\treturn ctor[mergedName];\n}\n\n/**\n * Gets an unique id. If `object` argument is passed, the object is\n * mutated with an unique id. Consecutive calls with the same object\n * reference won't mutate the object again, instead the current object uid\n * returns. See {@link UID_PROPERTY}.\n * @param {Object=} object Optional object to be mutated with the uid. If\n * not specified this method only returns the uid.\n * @param {boolean=} noInheritance Optional flag indicating if this\n * object's uid property can be inherited from parents or not.\n * @throws {Error} when invoked to indicate the method should be overridden.\n * @return {number}\n */\nexport function getUid(object, noInheritance) {\n\tif (object) {\n\t\tlet id = object[UID_PROPERTY];\n\t\tif (noInheritance && !object.hasOwnProperty(UID_PROPERTY)) {\n\t\t\tid = null;\n\t\t}\n\t\treturn id || (object[UID_PROPERTY] = uniqueIdCounter_++);\n\t}\n\treturn uniqueIdCounter_++;\n}\n\n/**\n * The identity function. Returns its first argument.\n * @param {*=} returnValue The single value that will be returned.\n * @return {?} The first argument.\n */\nexport function identityFunction(returnValue) {\n\treturn returnValue;\n}\n\n/**\n * Returns true if the specified value is a boolean.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is boolean.\n */\nexport function isBoolean(val) {\n\treturn typeof val === 'boolean';\n}\n\n/**\n * Returns true if the specified value is not undefined.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is defined.\n */\nexport function isDef(val) {\n\treturn val !== undefined;\n}\n\n/**\n * Returns true if value is not undefined or null.\n * @param {*} val\n * @return {boolean}\n */\nexport function isDefAndNotNull(val) {\n\treturn isDef(val) && !isNull(val);\n}\n\n/**\n * Returns true if value is a document.\n * @param {*} val\n * @return {boolean}\n */\nexport function isDocument(val) {\n\treturn val && typeof val === 'object' && val.nodeType === 9;\n}\n\n/**\n * Returns true if value is a document-fragment.\n * @param {*} val\n * @return {boolean}\n */\nexport function isDocumentFragment(val) {\n\treturn val && typeof val === 'object' && val.nodeType === 11;\n}\n\n/**\n * Returns true if value is a dom element.\n * @param {*} val\n * @return {boolean}\n */\nexport function isElement(val) {\n\treturn val && typeof val === 'object' && val.nodeType === 1;\n}\n\n/**\n * Returns true if the specified value is a function.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a function.\n */\nexport function isFunction(val) {\n\treturn typeof val === 'function';\n}\n\n/**\n * Returns true if value is null.\n * @param {*} val\n * @return {boolean}\n */\nexport function isNull(val) {\n\treturn val === null;\n}\n\n/**\n * Returns true if the specified value is a number.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is a number.\n */\nexport function isNumber(val) {\n\treturn typeof val === 'number';\n}\n\n/**\n * Returns true if value is a window.\n * @param {*} val\n * @return {boolean}\n */\nexport function isWindow(val) {\n\treturn val !== null && val === val.window;\n}\n\n/**\n * Returns true if the specified value is an object. This includes arrays\n * and functions.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is an object.\n */\nexport function isObject(val) {\n\tconst type = typeof val;\n\treturn (type === 'object' && val !== null) || type === 'function';\n}\n\n/**\n * Returns true if value is a Promise.\n * @param {*} val\n * @return {boolean}\n */\nexport function isPromise(val) {\n\treturn val && typeof val === 'object' && typeof val.then === 'function';\n}\n\n/**\n * Returns true if value is a string.\n * @param {*} val\n * @return {boolean}\n */\nexport function isString(val) {\n\treturn typeof val === 'string' || val instanceof String;\n}\n\n/**\n * Sets to true if running inside Node.js environment with extra check for\n * `process.browser` to skip Karma runner environment. Karma environment has\n * `process` defined even though it runs on the browser.\n * @param {?Object} options Contains `checkEnv` property which if true, checks\n * the NODE_ENV variable. If NODE_ENV equals 'test', the function returns false.\n * @return {boolean}\n */\nexport function isServerSide(options = {checkEnv: true}) {\n\tlet serverSide = typeof process !== 'undefined' && !process.browser;\n\tif (serverSide && options.checkEnv) {\n\t\tserverSide =\n\t\t\ttypeof process.env !== 'undefined' &&\n\t\t\tprocess.env.NODE_ENV !== 'test';\n\t}\n\treturn serverSide;\n}\n\n/**\n * Null function used for default values of callbacks, etc.\n * @return {void} Nothing.\n */\nexport function nullFunction() {}\n","'use strict';\n\n// This file exists just for backwards compatibility, making sure that old\n// default imports for this file still work. It's best to use the named exports\n// for each function instead though, since that allows bundlers like Rollup to\n// reduce the bundle size by removing unused code.\nimport * as core from './coreNamed';\n\nexport default core;\nexport {core};\nexport * from './coreNamed';\n","'use strict';\n\n/**\n * Set of utilities for array operations\n */\nclass array {\n\t/**\n\t * Checks if the given arrays have the same content.\n\t * @param {!Array<*>} arr1\n\t * @param {!Array<*>} arr2\n\t * @return {boolean}\n\t */\n\tstatic equal(arr1, arr2) {\n\t\tif (arr1 === arr2) {\n\t\t\treturn true;\n\t\t}\n\t\tif (arr1.length !== arr2.length) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (let i = 0; i < arr1.length; i++) {\n\t\t\tif (arr1[i] !== arr2[i]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the first value in the given array that isn't undefined.\n\t * @param {!Array} arr\n\t * @return {*}\n\t */\n\tstatic firstDefinedValue(arr) {\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\tif (arr[i] !== undefined) {\n\t\t\t\treturn arr[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Transforms the input nested array to become flat.\n\t * @param {Array.<*|Array.<*>>} arr Nested array to flatten.\n\t * @param {Array.<*>=} output Optional output array.\n\t * @return {Array.<*>} Flat array.\n\t */\n\tstatic flatten(arr, output = []) {\n\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\tif (Array.isArray(arr[i])) {\n\t\t\t\tarray.flatten(arr[i], output);\n\t\t\t} else {\n\t\t\t\toutput.push(arr[i]);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Removes the first occurrence of a particular value from an array.\n\t * @param {Array.<T>} arr Array from which to remove value.\n\t * @param {T} obj Object to remove.\n\t * @return {boolean} True if an element was removed.\n\t * @template T\n\t */\n\tstatic remove(arr, obj) {\n\t\tconst i = arr.indexOf(obj);\n\t\tlet rv;\n\t\tif ((rv = i >= 0)) {\n\t\t\tarray.removeAt(arr, i);\n\t\t}\n\t\treturn rv;\n\t}\n\n\t/**\n\t * Removes from an array the element at index i\n\t * @param {Array} arr Array or array like object from which to remove value.\n\t * @param {number} i The index to remove.\n\t * @return {boolean} True if an element was removed.\n\t */\n\tstatic removeAt(arr, i) {\n\t\treturn Array.prototype.splice.call(arr, i, 1).length === 1;\n\t}\n\n\t/**\n\t * Slices the given array, just like Array.prototype.slice, but this\n\t * is faster and working on all array-like objects (like arguments).\n\t * @param {!Object} arr Array-like object to slice.\n\t * @param {number} start The index that should start the slice.\n\t * @param {number=} end The index where the slice should end, not\n\t * included in the final array. If not given, all elements after the\n\t * start index will be included.\n\t * @return {!Array}\n\t */\n\tstatic slice(arr, start, end = arr.length) {\n\t\tconst sliced = [];\n\t\tfor (let i = start; i < end; i++) {\n\t\t\tsliced.push(arr[i]);\n\t\t}\n\t\treturn sliced;\n\t}\n}\n\nexport default array;\n","/* !\n * Polyfill from Google's Closure Library.\n * Copyright 2013 The Closure Library Authors. All Rights Reserved.\n */\n\n'use strict';\n\nimport {isServerSide} from '../coreNamed';\n\nconst async = {};\n\n/**\n * Throw an item without interrupting the current execution context. For\n * example, if processing a group of items in a loop, sometimes it is useful\n * to report an error while still allowing the rest of the batch to be\n * processed.\n * @param {*} exception\n */\nasync.throwException = function(exception) {\n\t// Each throw needs to be in its own context.\n\tasync.nextTick(function() {\n\t\tthrow exception;\n\t});\n};\n\n/**\n * Fires the provided callback just before the current callstack unwinds, or as\n * soon as possible after the current JS execution context.\n * @param {function(this:THIS)} callback\n * @param {THIS=} context Object to use as the \"this value\" when calling\n * the provided function.\n * @template THIS\n */\nasync.run = function(callback, context) {\n\tif (!async.run.workQueueScheduled_) {\n\t\t// Nothing is currently scheduled, schedule it now.\n\t\tasync.nextTick(async.run.processWorkQueue);\n\t\tasync.run.workQueueScheduled_ = true;\n\t}\n\n\tasync.run.workQueue_.push(new async.run.WorkItem_(callback, context));\n};\n\n/** @private {boolean} */\nasync.run.workQueueScheduled_ = false;\n\n/** @private {!Array.<!async.run.WorkItem_>} */\nasync.run.workQueue_ = [];\n\n/**\n * Run any pending async.run work items. This function is not intended\n * for general use, but for use by entry point handlers to run items ahead of\n * async.nextTick.\n */\nasync.run.processWorkQueue = function() {\n\t// NOTE: additional work queue items may be pushed while processing.\n\twhile (async.run.workQueue_.length) {\n\t\t// Don't let the work queue grow indefinitely.\n\t\tconst workItems = async.run.workQueue_;\n\t\tasync.run.workQueue_ = [];\n\t\tfor (let i = 0; i < workItems.length; i++) {\n\t\t\tconst workItem = workItems[i];\n\t\t\ttry {\n\t\t\t\tworkItem.fn.call(workItem.scope);\n\t\t\t} catch (e) {\n\t\t\t\tasync.throwException(e);\n\t\t\t}\n\t\t}\n\t}\n\n\t// There are no more work items, reset the work queue.\n\tasync.run.workQueueScheduled_ = false;\n};\n\n/**\n * @constructor\n * @final\n * @struct\n * @private\n *\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\nasync.run.WorkItem_ = function(fn, scope) {\n\t/** @const */\n\tthis.fn = fn;\n\t/** @const */\n\tthis.scope = scope;\n};\n\n/**\n * Fires the provided callbacks as soon as possible after the current JS\n * execution context. setTimeout(…, 0) always takes at least 5ms for legacy\n * reasons.\n * @param {function(this:SCOPE)} callback Callback function to fire as soon as\n * possible.\n * @param {SCOPE=} context Object in whose scope to call the listener.\n * @template SCOPE\n */\nasync.nextTick = function(callback, context) {\n\tlet cb = callback;\n\tif (context) {\n\t\tcb = callback.bind(context);\n\t}\n\tcb = async.nextTick.wrapCallback_(cb);\n\t// Look for and cache the custom fallback version of setImmediate.\n\tif (!async.nextTick.setImmediate_) {\n\t\tif (\n\t\t\ttypeof setImmediate === 'function' &&\n\t\t\tisServerSide({checkEnv: false})\n\t\t) {\n\t\t\tasync.nextTick.setImmediate_ = setImmediate;\n\t\t} else {\n\t\t\t// eslint-disable-next-line\n\t\t\tasync.nextTick.setImmediate_ = async.nextTick.getSetImmediateEmulator_();\n\t\t}\n\t}\n\tasync.nextTick.setImmediate_(cb);\n};\n\n/**\n * Cache for the setImmediate implementation.\n * @type {function(function())}\n * @private\n */\nasync.nextTick.setImmediate_ = null;\n\n/**\n * Determines the best possible implementation to run a function as soon as\n * the JS event loop is idle.\n * @return {function(function())} The \"setImmediate\" implementation.\n * @private\n */\nasync.nextTick.getSetImmediateEmulator_ = function() {\n\t// Create a private message channel and use it to postMessage empty messages\n\t// to ourselves.\n\tlet Channel;\n\n\t// Verify if variable is defined on the current runtime (i.e., node, browser).\n\t// Can't use typeof enclosed in a function (such as core.isFunction) or an\n\t// exception will be thrown when the function is called on an environment\n\t// where the variable is undefined.\n\tif (typeof MessageChannel === 'function') {\n\t\tChannel = MessageChannel;\n\t}\n\n\t// If MessageChannel is not available and we are in a browser, implement\n\t// an iframe based polyfill in browsers that have postMessage and\n\t// document.addEventListener. The latter excludes IE8 because it has a\n\t// synchronous postMessage implementation.\n\tif (\n\t\ttypeof Channel === 'undefined' &&\n\t\ttypeof window !== 'undefined' &&\n\t\twindow.postMessage &&\n\t\twindow.addEventListener\n\t) {\n\t\t/** @constructor */\n\t\tChannel = function() {\n\t\t\t// Make an empty, invisible iframe.\n\t\t\tconst iframe = document.createElement('iframe');\n\t\t\tiframe.style.display = 'none';\n\t\t\tiframe.src = '';\n\t\t\tiframe.title = '';\n\t\t\tdocument.documentElement.appendChild(iframe);\n\t\t\tconst win = iframe.contentWindow;\n\t\t\tconst doc = win.document;\n\t\t\tdoc.open();\n\t\t\tdoc.write('');\n\t\t\tdoc.close();\n\t\t\tconst message = 'callImmediate' + Math.random();\n\t\t\tconst origin = win.location.protocol + '//' + win.location.host;\n\t\t\tconst onmessage = function(e) {\n\t\t\t\t// Validate origin and message to make sure that this message was\n\t\t\t\t// intended for us.\n\t\t\t\tif (e.origin !== origin && e.data !== message) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.port1.onmessage();\n\t\t\t}.bind(this);\n\t\t\twin.addEventListener('message', onmessage, false);\n\t\t\tthis.port1 = {};\n\t\t\tthis.port2 = {\n\t\t\t\tpostMessage: function() {\n\t\t\t\t\twin.postMessage(message, origin);\n\t\t\t\t},\n\t\t\t};\n\t\t};\n\t}\n\tif (typeof Channel !== 'undefined') {\n\t\tconst channel = new Channel();\n\t\t// Use a fifo linked list to call callbacks in the right order.\n\t\tlet head = {};\n\t\tlet tail = head;\n\t\tchannel.port1.onmessage = function() {\n\t\t\thead = head.next;\n\t\t\tconst cb = head.cb;\n\t\t\thead.cb = null;\n\t\t\tcb();\n\t\t};\n\t\treturn function(cb) {\n\t\t\ttail.next = {\n\t\t\t\tcb: cb,\n\t\t\t};\n\t\t\ttail = tail.next;\n\t\t\tchannel.port2.postMessage(0);\n\t\t};\n\t}\n\t// Implementation for IE6-8: Script elements fire an asynchronous\n\t// onreadystatechange event when inserted into the DOM.\n\tif (\n\t\ttypeof document !== 'undefined' &&\n\t\t'onreadystatechange' in document.createElement('script')\n\t) {\n\t\treturn function(cb) {\n\t\t\tlet script = document.createElement('script');\n\t\t\tscript.onreadystatechange = function() {\n\t\t\t\t// Clean up and call the callback.\n\t\t\t\tscript.onreadystatechange = null;\n\t\t\t\tscript.parentNode.removeChild(script);\n\t\t\t\tscript = null;\n\t\t\t\tcb();\n\t\t\t\tcb = null;\n\t\t\t};\n\t\t\tdocument.documentElement.appendChild(script);\n\t\t};\n\t}\n\t// Fall back to setTimeout with 0. In browsers this creates a delay of 5ms\n\t// or more.\n\treturn function(cb) {\n\t\tsetTimeout(cb, 0);\n\t};\n};\n\n/**\n * Helper function that is overrided to protect callbacks with entry point\n * monitor if the application monitors entry points.\n * @param {function()} callback Callback function to fire as soon as possible.\n * @return {function()} The wrapped callback.\n * @private\n */\nasync.nextTick.wrapCallback_ = function(callback) {\n\treturn callback;\n};\n\nexport default async;\n","'use strict';\n\n/**\n * Disposable utility. When inherited provides the `dispose` function to its\n * subclass, which is responsible for disposing of any object references\n * when an instance won't be used anymore. Subclasses should override\n * `disposeInternal` to implement any specific disposing logic.\n * @constructor\n */\nclass Disposable {\n\t/**\n\t * Disposable constructor\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Flag indicating if this instance has already been disposed.\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.disposed_ = false;\n\t}\n\n\t/**\n\t * Disposes of this instance's object references. Calls `disposeInternal`.\n\t */\n\tdispose() {\n\t\tif (!this.disposed_) {\n\t\t\tthis.disposeInternal();\n\t\t\tthis.disposed_ = true;\n\t\t}\n\t}\n\n\t/**\n\t * Subclasses should override this method to implement any specific\n\t * disposing logic (like clearing references and calling `dispose` on other\n\t * disposables).\n\t */\n\tdisposeInternal() {}\n\n\t/**\n\t * Checks if this instance has already been disposed.\n\t * @return {boolean}\n\t */\n\tisDisposed() {\n\t\treturn this.disposed_;\n\t}\n}\n\nexport default Disposable;\n","'use strict';\n\n/**\n * Set of utilities for object operations\n */\nclass object {\n\t/**\n\t * Copies all the members of a source object to a target object.\n\t * @param {Object} target Target object.\n\t * @param {...Object} var_args The objects from which values will be copied.\n\t * @return {Object} Returns the target object reference.\n\t */\n\tstatic mixin(target, ...args) {\n\t\tlet key;\n\t\tlet source;\n\t\tfor (let i = 0; i < args.length; i++) {\n\t\t\tsource = args[i];\n\t\t\t// Possible prototype chain leak, breaks 1 metal-dom and\n\t\t\t// 1 metal-incremental-dom test if guard-for-in rule is addressed\n\t\t\t// eslint-disable-next-line\n\t\t\tfor (key in source) {\n\t\t\t\ttarget[key] = source[key];\n\t\t\t}\n\t\t}\n\t\treturn target;\n\t}\n\n\t/**\n\t * Returns an object based on its fully qualified external name.\n\t * @param {string} name The fully qualified name.\n\t * @param {object=} scope The object within which to look; default is\n\t * <code>window</code>.\n\t * @return {?} The value (object or primitive) or, if not found, undefined.\n\t */\n\tstatic getObjectByName(name, scope = window) {\n\t\tconst parts = name.split('.');\n\t\treturn parts.reduce((part, key) => part[key], scope);\n\t}\n\n\t/**\n\t * Returns a new object with the same keys as the given one, but with\n\t * their values set to the return values of the specified function.\n\t * @param {!Object} obj\n\t * @param {!function(string, *)} fn\n\t * @return {!Object}\n\t */\n\tstatic map(obj, fn) {\n\t\tconst mappedObj = {};\n\t\tconst keys = Object.keys(obj);\n\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\tmappedObj[keys[i]] = fn(keys[i], obj[keys[i]]);\n\t\t}\n\t\treturn mappedObj;\n\t}\n\n\t/**\n\t * Checks if the two given objects are equal. This is done via a shallow\n\t * check, including only the keys directly contained by the 2 objects.\n\t * @param {Object} obj1\n\t * @param {Object} obj2\n\t * @return {boolean}\n\t */\n\tstatic shallowEqual(obj1, obj2) {\n\t\tif (obj1 === obj2) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst keys1 = Object.keys(obj1);\n\t\tconst keys2 = Object.keys(obj2);\n\t\tif (keys1.length !== keys2.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = 0; i < keys1.length; i++) {\n\t\t\tif (obj1[keys1[i]] !== obj2[keys1[i]]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport default object;\n","'use strict';\n\n/**\n * Set of utilities for string operations\n */\nclass string {\n\t/**\n\t * Compares the given strings without taking the case into account.\n\t * @param {string|number} str1\n\t * @param {string|number} str2\n\t * @return {number} Either -1, 0 or 1, according to if the first string is\n\t * \"smaller\", equal or \"bigger\" than the second given string.\n\t */\n\tstatic caseInsensitiveCompare(str1, str2) {\n\t\tconst test1 = String(str1).toLowerCase();\n\t\tconst test2 = String(str2).toLowerCase();\n\n\t\tif (test1 < test2) {\n\t\t\treturn -1;\n\t\t} else if (test1 === test2) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t/**\n\t * Removes the breaking spaces from the left and right of the string and\n\t * collapses the sequences of breaking spaces in the middle into single spaces.\n\t * The original and the result strings render the same way in HTML.\n\t * @param {string} str A string in which to collapse spaces.\n\t * @return {string} Copy of the string with normalized breaking spaces.\n\t */\n\tstatic collapseBreakingSpaces(str) {\n\t\treturn str\n\t\t\t.replace(/[\\t\\r\\n ]+/g, ' ')\n\t\t\t.replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g, '');\n\t}\n\n\t/**\n\t * Escapes characters in the string that are not safe to use in a RegExp.\n\t * @param {*} str The string to escape. If not a string, it will be casted\n\t * to one.\n\t * @return {string} A RegExp safe, escaped copy of {@code s}.\n\t */\n\tstatic escapeRegex(str) {\n\t\treturn String(str)\n\t\t\t.replace(/([-()[\\]{}+?*.$^|,:#<!\\\\])/g, '\\\\$1')\n\t\t\t.replace(/\\x08/g, '\\\\x08'); // eslint-disable-line\n\t}\n\n\t/**\n\t * Returns a string with at least 64-bits of randomness.\n\t * @return {string} A random string, e.g. sn1s7vb4gcic.\n\t */\n\tstatic getRandomString() {\n\t\tconst x = 2147483648;\n\t\treturn (\n\t\t\tMath.floor(Math.random() * x).toString(36) +\n\t\t\tMath.abs(Math.floor(Math.random() * x) ^ Date.now()).toString(36)\n\t\t);\n\t}\n\n\t/**\n\t * Calculates the hashcode for a string. The hashcode value is computed by\n\t * the sum algorithm: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]. A nice\n\t * property of using 31 prime is that the multiplication can be replaced by\n\t * a shift and a subtraction for better performance: 31*i == (i<<5)-i.\n\t * Modern VMs do this sort of optimization automatically.\n\t * @param {String} val Target string.\n\t * @return {Number} Returns the string hashcode.\n\t */\n\tstatic hashCode(val) {\n\t\tlet hash = 0;\n\t\tfor (let i = 0, len = val.length; i < len; i++) {\n\t\t\thash = 31 * hash + val.charCodeAt(i);\n\t\t\thash %= 0x100000000;\n\t\t}\n\t\treturn hash;\n\t}\n\n\t/**\n\t * Replaces interval into the string with specified value, e.g.\n\t * `replaceInterval(\"abcde\", 1, 4, \"\")` returns \"ae\".\n\t * @param {string} str The input string.\n\t * @param {Number} start Start interval position to be replaced.\n\t * @param {Number} end End interval position to be replaced.\n\t * @param {string} value The value that replaces the specified interval.\n\t * @return {string}\n\t */\n\tstatic replaceInterval(str, start, end, value) {\n\t\treturn str.substring(0, start) + value + str.substring(end);\n\t}\n}\n\nexport default string;\n","'use strict';\n\nimport {isDef} from 'metal';\n\nconst METAL_DATA = '__metal_data__';\n\n/**\n * Set of utilities for dom data operations\n */\nclass domData {\n\t/**\n\t * Gets Metal.js's data for the given element.\n\t * @param {!Element} element\n\t * @param {string=} name Optional property from the data to be returned.\n\t * @param {*=} initialValue Optional value to the set the requested property\n\t * to if it doesn't exist yet in the data.\n\t * @return {!Object}\n\t */\n\tstatic get(element, name, initialValue) {\n\t\tif (!element[METAL_DATA]) {\n\t\t\telement[METAL_DATA] = {};\n\t\t}\n\t\tif (!name) {\n\t\t\treturn element[METAL_DATA];\n\t\t}\n\t\tif (!isDef(element[METAL_DATA][name]) && isDef(initialValue)) {\n\t\t\telement[METAL_DATA][name] = initialValue;\n\t\t}\n\t\treturn element[METAL_DATA][name];\n\t}\n\n\t/**\n\t * Checks if the given element has data stored in it.\n\t * @param {!Element} element\n\t * @return {boolean}\n\t */\n\tstatic has(element) {\n\t\treturn !!element[METAL_DATA];\n\t}\n\n\t/**\n\t * Sets Metal.js's data for the given element.\n\t * @param {!Element} element\n\t * @param {string=} name Property from the data to be set.\n\t * @param {*=} value Value to be set on the element.\n\t * @return {!Object|*}\n\t */\n\tstatic set(element, name, value) {\n\t\tif (!element[METAL_DATA]) {\n\t\t\telement[METAL_DATA] = {};\n\t\t}\n\t\tif (!name || !isDef(value)) {\n\t\t\treturn element[METAL_DATA];\n\t\t}\n\t\telement[METAL_DATA][name] = value;\n\t\treturn element[METAL_DATA][name];\n\t}\n}\n\nexport default domData;\n","'use strict';\n\nimport {Disposable} from 'metal';\n\n/**\n * EventHandle utility. Holds information about an event subscription, and\n * allows removing them easily.\n * EventHandle is a Disposable, but it's important to note that the\n * EventEmitter that created it is not the one responsible for disposing it.\n * That responsibility is for the code that holds a reference to it.\n * @extends {Disposable}\n */\nclass EventHandle extends Disposable {\n\t/**\n\t * EventHandle constructor\n\t * @param {!EventEmitter} emitter Emitter the event was subscribed to.\n\t * @param {string} event The name of the event that was subscribed to.\n\t * @param {!Function} listener The listener subscribed to the event.\n\t */\n\tconstructor(emitter, event, listener) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The EventEmitter instance that the event was subscribed to.\n\t\t * @type {EventEmitter}\n\t\t * @protected\n\t\t */\n\t\tthis.emitter_ = emitter;\n\n\t\t/**\n\t\t * The name of the event that was subscribed to.\n\t\t * @type {string}\n\t\t * @protected\n\t\t */\n\t\tthis.event_ = event;\n\n\t\t/**\n\t\t * The listener subscribed to the event.\n\t\t * @type {Function}\n\t\t * @protected\n\t\t */\n\t\tthis.listener_ = listener;\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.removeListener();\n\t\tthis.emitter_ = null;\n\t\tthis.listener_ = null;\n\t}\n\n\t/**\n\t * Removes the listener subscription from the emitter.\n\t */\n\tremoveListener() {\n\t\tif (!this.emitter_.isDisposed()) {\n\t\t\tthis.emitter_.removeListener(this.event_, this.listener_);\n\t\t}\n\t}\n}\n\nexport default EventHandle;\n","'use strict';\n\nimport {array, Disposable, isFunction, isString} from 'metal';\nimport EventHandle from './EventHandle';\n\nconst singleArray_ = [0];\n\n/**\n * EventEmitter utility.\n * @extends {Disposable}\n */\nclass EventEmitter extends Disposable {\n\t/**\n\t * EventEmitter constructor\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds event listeners scoped by event type.\n\t\t * @type {Object<string, !Array<!function()>>}\n\t\t * @protected\n\t\t */\n\t\tthis.events_ = null;\n\n\t\t/**\n\t\t * Handlers that are triggered when an event is listened to.\n\t\t * @type {Array}\n\t\t */\n\t\tthis.listenerHandlers_ = null;\n\n\t\t/**\n\t\t * Configuration option which determines if an event facade should be sent\n\t\t * as a param of listeners when emitting events. If set to true, the facade\n\t\t * will be passed as the first argument of the listener.\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.shouldUseFacade_ = false;\n\t}\n\n\t/**\n\t * Adds a handler to given holder variable. If the holder doesn't have a\n\t * value yet, it will receive the handler directly. If the holder is an array,\n\t * the value will just be added to it. Otherwise, the holder will be set to a\n\t * new array containing its previous value plus the new handler.\n\t * @param {*} holder\n\t * @param {!function()|Object} handler\n\t * @return {*} The holder's new value.\n\t * @protected\n\t */\n\taddHandler_(holder, handler) {\n\t\tif (!holder) {\n\t\t\tholder = handler;\n\t\t} else {\n\t\t\tif (!Array.isArray(holder)) {\n\t\t\t\tholder = [holder];\n\t\t\t}\n\t\t\tholder.push(handler);\n\t\t}\n\t\treturn holder;\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for the specified events.\n\t * @param {!(Array|string)} event\n\t * @param {!Function} listener\n\t * @param {boolean} defaultListener Flag indicating if this listener is a default\n\t * action for this event. Default actions are run last, and only if no previous\n\t * listener call `preventDefault()` on the received event facade.\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\taddListener(event, listener, defaultListener) {\n\t\tthis.validateListener_(listener);\n\n\t\tconst events = this.toEventsArray_(event);\n\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\tthis.addSingleListener_(events[i], listener, defaultListener);\n\t\t}\n\n\t\treturn new EventHandle(this, event, listener);\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for a single event.\n\t * @param {string} event\n\t * @param {!Function} listener\n\t * @param {boolean} defaultListener Flag indicating if this listener is a default\n\t * action for this event. Default actions are run last, and only if no previous\n\t * listener call `preventDefault()` on the received event facade.\n\t * @param {Function=} origin The original function that was added as a\n\t * listener, if there is any.\n\t * @protected\n\t */\n\taddSingleListener_(event, listener, defaultListener, origin) {\n\t\tthis.runListenerHandlers_(event);\n\t\tif (defaultListener || origin) {\n\t\t\tlistener = {\n\t\t\t\tdefault: defaultListener,\n\t\t\t\tfn: listener,\n\t\t\t\torigin: origin,\n\t\t\t};\n\t\t}\n\t\tthis.events_ = this.events_ || {};\n\t\tthis.events_[event] = this.addHandler_(this.events_[event], listener);\n\t}\n\n\t/**\n\t * Builds facade for the given event.\n\t * @param {string} event\n\t * @return {Object}\n\t * @protected\n\t */\n\tbuildFacade_(event) {\n\t\tif (this.getShouldUseFacade()) {\n\t\t\tconst facade = {\n\t\t\t\tpreventDefault: function() {\n\t\t\t\t\tfacade.preventedDefault = true;\n\t\t\t\t},\n\t\t\t\ttarget: this,\n\t\t\t\ttype: event,\n\t\t\t};\n\t\t\treturn facade;\n\t\t}\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.events_ = null;\n\t}\n\n\t/**\n\t * Execute each of the listeners in order with the supplied arguments.\n\t * @param {string} event\n\t * @param {*} opt_args [arg1], [arg2], [...]\n\t * @return {boolean} Returns true if event had listeners, false otherwise.\n\t */\n\temit(event) {\n\t\tconst listeners = this.getRawListeners_(event);\n\t\tif (listeners.length === 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst args = array.slice(arguments, 1); // eslint-disable-line\n\t\tthis.runListeners_(listeners, args, this.buildFacade_(event));\n\t\treturn true;\n\t}\n\n\t/**\n\t * Gets the listener objects for the given event, if there are any.\n\t * @param {string} event\n\t * @return {!Array}\n\t * @protected\n\t */\n\tgetRawListeners_(event) {\n\t\tconst directListeners = toArray(this.events_ && this.events_[event]);\n\t\treturn directListeners.concat(\n\t\t\ttoArray(this.events_ && this.events_['*'])\n\t\t);\n\t}\n\n\t/**\n\t * Gets the configuration option which determines if an event facade should\n\t * be sent as a param of listeners when emitting events. If set to true, the\n\t * facade will be passed as the first argument of the listener.\n\t * @return {boolean}\n\t */\n\tgetShouldUseFacade() {\n\t\treturn this.shouldUseFacade_;\n\t}\n\n\t/**\n\t * Returns an array of listeners for the specified event.\n\t * @param {string} event\n\t * @return {Array} Array of listeners.\n\t */\n\tlisteners(event) {\n\t\treturn this.getRawListeners_(event).map(\n\t\t\tlistener => (listener.fn ? listener.fn : listener)\n\t\t);\n\t}\n\n\t/**\n\t * Adds a listener that will be invoked a fixed number of times for the\n\t * events. After each event is triggered the specified amount of times, the\n\t * listener is removed for it.\n\t * @param {!(Array|string)} event\n\t * @param {number} amount The amount of times this event should be listened\n\t * to.\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\tmany(event, amount, listener) {\n\t\tconst events = this.toEventsArray_(event);\n\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\tthis.many_(events[i], amount, listener);\n\t\t}\n\n\t\treturn new EventHandle(this, event, listener);\n\t}\n\n\t/**\n\t * Adds a listener that will be invoked a fixed number of times for a single\n\t * event. After the event is triggered the specified amount of times, the\n\t * listener is removed.\n\t * @param {string} event\n\t * @param {number} amount The amount of times this event should be listened\n\t * to.\n\t * @param {!Function} listener\n\t * @protected\n\t */\n\tmany_(event, amount, listener) {\n\t\tconst self = this;\n\n\t\tif (amount <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t *\n\t\t */\n\t\tfunction handlerInternal() {\n\t\t\tif (--amount === 0) {\n\t\t\t\tself.removeListener(event, handlerInternal);\n\t\t\t}\n\t\t\tlistener.apply(self, arguments); // eslint-disable-line\n\t\t}\n\n\t\tself.addSingleListener_(event, handlerInternal, false, listener);\n\t}\n\n\t/**\n\t * Checks if a listener object matches the given listener function. To match,\n\t * it needs to either point to that listener or have it as its origin.\n\t * @param {!Object} listenerObj\n\t * @param {!Function} listener\n\t * @return {boolean}\n\t * @protected\n\t */\n\tmatchesListener_(listenerObj, listener) {\n\t\tconst fn = listenerObj.fn || listenerObj;\n\t\treturn (\n\t\t\tfn === listener ||\n\t\t\t(listenerObj.origin && listenerObj.origin === listener) // eslint-disable-line\n\t\t);\n\t}\n\n\t/**\n\t * Removes a listener for the specified events.\n\t * Caution: changes array indices in the listener array behind the listener.\n\t * @param {!(Array|string)} event\n\t * @param {!Function} listener\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\toff(event, listener) {\n\t\tthis.validateListener_(listener);\n\t\tif (!this.events_) {\n\t\t\treturn this;\n\t\t}\n\n\t\tconst events = this.toEventsArray_(event);\n\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\tthis.events_[events[i]] = this.removeMatchingListenerObjs_(\n\t\t\t\ttoArray(this.events_[events[i]]),\n\t\t\t\tlistener\n\t\t\t);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for the specified events.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\ton() {\n\t\treturn this.addListener.apply(this, arguments); // eslint-disable-line\n\t}\n\n\t/**\n\t * Adds handler that gets triggered when an event is listened to on this\n\t * instance.\n\t * @param {!function()} handler\n\t */\n\tonListener(handler) {\n\t\tthis.listenerHandlers_ = this.addHandler_(\n\t\t\tthis.listenerHandlers_,\n\t\t\thandler\n\t\t); // eslint-disable-line\n\t}\n\n\t/**\n\t * Adds a one time listener for the events. This listener is invoked only the\n\t * next time each event is fired, after which it is removed.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\tonce(events, listener) {\n\t\treturn this.many(events, 1, listener);\n\t}\n\n\t/**\n\t * Removes all listeners, or those of the specified events. It's not a good\n\t * idea to remove listeners that were added elsewhere in the code,\n\t * especially when it's on an emitter that you didn't create.\n\t * @param {(Array|string)=} event\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\tremoveAllListeners(event) {\n\t\tif (this.events_) {\n\t\t\tif (event) {\n\t\t\t\tconst events = this.toEventsArray_(event);\n\t\t\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\t\t\tthis.events_[events[i]] = null;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.events_ = null;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes all listener objects from the given array that match the given\n\t * listener function.\n\t * @param {Array.<Object>} listenerObjs\n\t * @param {!Function} listener\n\t * @return {Array.<Object>|Object} The new listeners array for this event.\n\t * @protected\n\t */\n\tremoveMatchingListenerObjs_(listenerObjs, listener) {\n\t\tconst finalListeners = [];\n\t\tfor (let i = 0; i < listenerObjs.length; i++) {\n\t\t\tif (!this.matchesListener_(listenerObjs[i], listener)) {\n\t\t\t\tfinalListeners.push(listenerObjs[i]);\n\t\t\t}\n\t\t}\n\t\treturn finalListeners.length > 0 ? finalListeners : null;\n\t}\n\n\t/**\n\t * Removes a listener for the specified events.\n\t * Caution: changes array indices in the listener array behind the listener.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\tremoveListener() {\n\t\treturn this.off.apply(this, arguments); // eslint-disable-line\n\t}\n\n\t/**\n\t * Runs the handlers when an event is listened to.\n\t * @param {string} event\n\t * @protected\n\t */\n\trunListenerHandlers_(event) {\n\t\tlet handlers = this.listenerHandlers_;\n\t\tif (handlers) {\n\t\t\thandlers = toArray(handlers);\n\t\t\tfor (let i = 0; i < handlers.length; i++) {\n\t\t\t\thandlers[i](event);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Runs the given listeners.\n\t * @param {!Array} listeners\n\t * @param {!Array} args\n\t * @param {Object} facade\n\t * @protected\n\t */\n\trunListeners_(listeners, args, facade) {\n\t\tif (facade) {\n\t\t\targs.push(facade);\n\t\t}\n\n\t\tconst defaultListeners = [];\n\t\tfor (let i = 0; i < listeners.length; i++) {\n\t\t\tconst listener = listeners[i].fn || listeners[i];\n\t\t\tif (listeners[i].default) {\n\t\t\t\tdefaultListeners.push(listener);\n\t\t\t} else {\n\t\t\t\tlistener.apply(this, args);\n\t\t\t}\n\t\t}\n\t\tif (!facade || !facade.preventedDefault) {\n\t\t\tfor (let j = 0; j < defaultListeners.length; j++) {\n\t\t\t\tdefaultListeners[j].apply(this, args);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sets the configuration option which determines if an event facade should\n\t * be sent as a param of listeners when emitting events. If set to true, the\n\t * facade will be passed as the first argument of the listener.\n\t * @param {boolean} shouldUseFacade\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\tsetShouldUseFacade(shouldUseFacade) {\n\t\tthis.shouldUseFacade_ = shouldUseFacade;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Converts the parameter to an array if only one event is given. Reuses the\n\t * same array each time this conversion is done, to avoid using more memory\n\t * than necessary.\n\t * @param {!(Array|string)} events\n\t * @return {!Array}\n\t * @protected\n\t */\n\ttoEventsArray_(events) {\n\t\tif (isString(events)) {\n\t\t\tsingleArray_[0] = events;\n\t\t\tevents = singleArray_;\n\t\t}\n\t\treturn events;\n\t}\n\n\t/**\n\t * Checks if the given listener is valid, throwing an exception when it's not.\n\t * @param {*} listener\n\t * @protected\n\t */\n\tvalidateListener_(listener) {\n\t\tif (!isFunction(listener)) {\n\t\t\tthrow new TypeError('Listener must be a function');\n\t\t}\n\t}\n}\n\n/**\n * Converts to an array\n * @param {Object} val\n * @return {Array}\n */\nfunction toArray(val) {\n\tval = val || [];\n\treturn Array.isArray(val) ? val : [val];\n}\n\nexport default EventEmitter;\n","'use strict';\n\nimport {Disposable} from 'metal';\n\n/**\n * EventEmitterProxy utility. It's responsible for linking two EventEmitter\n * instances together, emitting events from the first emitter through the\n * second one. That means that listening to a supported event on the target\n * emitter will mean listening to it on the origin emitter as well.\n * @extends {Disposable}\n */\nclass EventEmitterProxy extends Disposable {\n\t/**\n\t * @param {EventEmitter} originEmitter Events originated on this emitter\n\t * will be fired for the target emitter's listeners as well.\n\t * @param {EventEmitter} targetEmitter Event listeners attached to this emitter\n\t * will also be triggered when the event is fired by the origin emitter.\n\t * @param {Object} blacklist Optional blacklist of events that should not be\n\t * proxied.\n\t * @param {Object} whitelist\n\t */\n\tconstructor(originEmitter, targetEmitter, blacklist, whitelist) {\n\t\tsuper();\n\n\t\t/**\n\t\t * Map of events that should not be proxied.\n\t\t * @type {Object}\n\t\t * @protected\n\t\t */\n\t\tthis.blacklist_ = blacklist;\n\n\t\t/**\n\t\t * The origin emitter. This emitter's events will be proxied through the\n\t\t * target emitter.\n\t\t * @type {EventEmitter}\n\t\t * @protected\n\t\t */\n\t\tthis.originEmitter_ = originEmitter;\n\n\t\t/**\n\t\t * A list of events that are pending to be listened by an actual origin\n\t\t * emitter. Events are stored here when the origin doesn't exist, so they\n\t\t * can be set on a new origin when one is set.\n\t\t * @type {Array}\n\t\t * @protected\n\t\t */\n\t\tthis.pendingEvents_ = null;\n\n\t\t/**\n\t\t * Holds a map of events from the origin emitter that are already being proxied.\n\t\t * @type {Object<string, !EventHandle>}\n\t\t * @protected\n\t\t */\n\t\tthis.proxiedEvents_ = null;\n\n\t\t/**\n\t\t * The target emitter. This emitter will emit all events that come from\n\t\t * the origin emitter.\n\t\t * @type {EventEmitter}\n\t\t * @protected\n\t\t */\n\t\tthis.targetEmitter_ = targetEmitter;\n\n\t\t/**\n\t\t * Map of events that should be proxied. If whitelist is set blacklist is ignored.\n\t\t * @type {Object}\n\t\t * @protected\n\t\t */\n\t\tthis.whitelist_ = whitelist;\n\n\t\tthis.startProxy_();\n\t}\n\n\t/**\n\t * Adds the given listener for the given event.\n\t * @param {string} event\n\t * @param {!function()} listener\n\t * @return {!EventHandle} The listened event's handle.\n\t * @protected\n\t */\n\taddListener_(event, listener) {\n\t\treturn this.originEmitter_.on(event, listener);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tthis.removeListeners_();\n\t\tthis.proxiedEvents_ = null;\n\t\tthis.originEmitter_ = null;\n\t\tthis.targetEmitter_ = null;\n\t}\n\n\t/**\n\t * Emits the specified event type on the target emitter.\n\t * @protected\n\t */\n\temitOnTarget_(...args) {\n\t\tthis.targetEmitter_.emit(...args);\n\t}\n\n\t/**\n\t * Proxies the given event from the origin to the target emitter.\n\t * @param {string} event\n\t */\n\tproxyEvent(event) {\n\t\tif (this.shouldProxyEvent_(event)) {\n\t\t\tthis.tryToAddListener_(event);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the proxy listener for all events.\n\t * @protected\n\t */\n\tremoveListeners_() {\n\t\tif (this.proxiedEvents_) {\n\t\t\tconst events = Object.keys(this.proxiedEvents_);\n\t\t\tfor (let i = 0; i < events.length; i++) {\n\t\t\t\tthis.proxiedEvents_[events[i]].removeListener();\n\t\t\t}\n\t\t\tthis.proxiedEvents_ = null;\n\t\t}\n\t\tthis.pendingEvents_ = null;\n\t}\n\n\t/**\n\t * Changes the origin emitter. This automatically detaches any events that\n\t * were already being proxied from the previous emitter, and starts proxying\n\t * them on the new emitter instead.\n\t * @param {!EventEmitter} originEmitter\n\t */\n\tsetOriginEmitter(originEmitter) {\n\t\tconst events =\n\t\t\tthis.originEmitter_ && this.proxiedEvents_\n\t\t\t\t? Object.keys(this.proxiedEvents_)\n\t\t\t\t: this.pendingEvents_;\n\t\tthis.originEmitter_ = originEmitter;\n\t\tif (events) {\n\t\t\tthis.removeListeners_();\n\t\t\tevents.forEach(event => this.proxyEvent(event));\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given event should be proxied.\n\t * @param {string} event\n\t * @return {boolean}\n\t * @protected\n\t */\n\tshouldProxyEvent_(event) {\n\t\tif (this.whitelist_ && !this.whitelist_[event]) {\n\t\t\treturn false;\n\t\t}\n\t\tif (this.blacklist_ && this.blacklist_[event]) {\n\t\t\treturn false;\n\t\t}\n\t\treturn !this.proxiedEvents_ || !this.proxiedEvents_[event];\n\t}\n\n\t/**\n\t * Starts proxying all events from the origin to the target emitter.\n\t * @protected\n\t */\n\tstartProxy_() {\n\t\tthis.targetEmitter_.onListener(this.proxyEvent.bind(this));\n\t}\n\n\t/**\n\t * Adds a listener to the origin emitter, if it exists. Otherwise, stores\n\t * the pending listener so it can be used on a future origin emitter.\n\t * @param {string} event\n\t * @protected\n\t */\n\ttryToAddListener_(event) {\n\t\tif (this.originEmitter_) {\n\t\t\tthis.proxiedEvents_ = this.proxiedEvents_ || {};\n\t\t\tthis.proxiedEvents_[event] = this.addListener_(\n\t\t\t\tevent,\n\t\t\t\tthis.emitOnTarget_.bind(this, event)\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pendingEvents_ = this.pendingEvents_ || [];\n\t\t\tthis.pendingEvents_.push(event);\n\t\t}\n\t}\n}\n\nexport default EventEmitterProxy;\n","'use strict';\n\nimport {Disposable} from 'metal';\n\n/**\n * EventHandler utility. It's useful for easily removing a group of\n * listeners from different EventEmitter instances.\n * @extends {Disposable}\n */\nclass EventHandler extends Disposable {\n\t/**\n\t * EventHandler constructor\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * An array that holds the added event handles, so the listeners can be\n\t\t * removed later.\n\t\t * @type {Array.<EventHandle>}\n\t\t * @protected\n\t\t */\n\t\tthis.eventHandles_ = [];\n\t}\n\n\t/**\n\t * Adds event handles to be removed later through the `removeAllListeners`\n\t * method.\n\t * @param {...(!EventHandle)} var_args\n\t */\n\tadd(...args) {\n\t\tfor (let i = 0; i < arguments.length; i++) {\n\t\t\tthis.eventHandles_.push(args[i]);\n\t\t}\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.eventHandles_ = null;\n\t}\n\n\t/**\n\t * Removes all listeners that have been added through the `add` method.\n\t */\n\tremoveAllListeners() {\n\t\tfor (let i = 0; i < this.eventHandles_.length; i++) {\n\t\t\tthis.eventHandles_[i].removeListener();\n\t\t}\n\n\t\tthis.eventHandles_ = [];\n\t}\n}\n\nexport default EventHandler;\n","'use strict';\n\nimport {array, isString} from 'metal';\nimport domData from './domData';\nimport {EventHandle} from 'metal-events';\n\n/**\n * This is a special EventHandle, that is responsible for dom delegated events\n * (only the ones that receive a target element, not a selector string).\n * @extends {EventHandle}\n */\nclass DomDelegatedEventHandle extends EventHandle {\n\t/**\n\t * The constructor for `DomDelegatedEventHandle`.\n\t * @param {!Event} emitter Element the event was subscribed to.\n\t * @param {string} event The name of the event that was subscribed to.\n\t * @param {!Function} listener The listener subscribed to the event.\n\t * @param {string=} selector An optional selector used when delegating\n\t * the event.\n\t * @constructor\n\t */\n\tconstructor(emitter, event, listener, selector) {\n\t\tsuper(emitter, event, listener);\n\t\tthis.selector_ = selector;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tremoveListener() {\n\t\tconst delegating = domData.get(this.emitter_, 'delegating', {});\n\t\tconst listeners = domData.get(this.emitter_, 'listeners', {});\n\t\tconst selector = this.selector_;\n\t\tconst arr = isString(selector)\n\t\t\t? delegating[this.event_].selectors\n\t\t\t: listeners;\n\t\tconst key = isString(selector) ? selector : this.event_;\n\n\t\tarray.remove(arr[key] || [], this.listener_);\n\t\tif (arr[key] && arr[key].length === 0) {\n\t\t\tdelete arr[key];\n\t\t}\n\t}\n}\n\nexport default DomDelegatedEventHandle;\n","'use strict';\n\nimport {EventHandle} from 'metal-events';\n\n/**\n * This is a special EventHandle, that is responsible for dom events, instead\n * of EventEmitter events.\n * @extends {EventHandle}\n */\nclass DomEventHandle extends EventHandle {\n\t/**\n\t * The constructor for `DomEventHandle`.\n\t * @param {!EventEmitter} emitter Emitter the event was subscribed to.\n\t * @param {string} event The name of the event that was subscribed to.\n\t * @param {!Function} listener The listener subscribed to the event.\n\t * @param {boolean} capture Flag indicating if listener should be triggered\n\t * during capture phase, instead of during the bubbling phase. Defaults to false.\n\t * @constructor\n\t */\n\tconstructor(emitter, event, listener, capture) {\n\t\tsuper(emitter, event, listener);\n\t\tthis.capture_ = capture;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tremoveListener() {\n\t\tthis.emitter_.removeEventListener(\n\t\t\tthis.event_,\n\t\t\tthis.listener_,\n\t\t\tthis.capture_\n\t\t);\n\t}\n}\n\nexport default DomEventHandle;\n","'use strict';\n\nimport {\n\tisDef,\n\tisDefAndNotNull,\n\tisDocument,\n\tisDocumentFragment,\n\tisElement,\n\tisObject,\n\tisString,\n\tobject,\n} from 'metal';\nimport domData from './domData';\nimport DomDelegatedEventHandle from './DomDelegatedEventHandle';\nimport DomEventHandle from './DomEventHandle';\n\nconst elementsByTag_ = {};\nconst supportCache_ = {};\nexport const customEvents = {};\n\nconst LAST_CONTAINER = '__metal_last_container__';\nconst USE_CAPTURE = {\n\tblur: true,\n\terror: true,\n\tfocus: true,\n\tinvalid: true,\n\tload: true,\n\tscroll: true,\n};\n\n/**\n * Adds the requested CSS classes to an element.\n * @param {!Element|!Nodelist} elements The element or elements to add CSS classes to.\n * @param {string} classes CSS classes to add.\n */\nexport function addClasses(elements, classes) {\n\tif (!isObject(elements) || !isString(classes)) {\n\t\treturn;\n\t}\n\n\tif (!elements.length) {\n\t\telements = [elements];\n\t}\n\n\tfor (let i = 0; i < elements.length; i++) {\n\t\tif ('classList' in elements[i]) {\n\t\t\taddClassesWithNative_(elements[i], classes);\n\t\t} else {\n\t\t\taddClassesWithoutNative_(elements[i], classes);\n\t\t}\n\t}\n}\n\n/**\n * Adds the requested CSS classes to an element using classList.\n * @param {!Element} element The element to add CSS classes to.\n * @param {string} classes CSS classes to add.\n * @private\n */\nfunction addClassesWithNative_(element, classes) {\n\tclasses.split(' ').forEach(function(className) {\n\t\tif (className) {\n\t\t\telement.classList.add(className);\n\t\t}\n\t});\n}\n\n/**\n * Adds the requested CSS classes to an element without using classList.\n * @param {!Element} element The element to add CSS classes to.\n * @param {string} classes CSS classes to add.\n * @private\n */\nfunction addClassesWithoutNative_(element, classes) {\n\tconst elementClassName = ` ${element.className} `;\n\tlet classesToAppend = '';\n\n\tclasses = classes.split(' ');\n\n\tfor (let i = 0; i < classes.length; i++) {\n\t\tconst className = classes[i];\n\n\t\tif (elementClassName.indexOf(` ${className} `) === -1) {\n\t\t\tclassesToAppend += ` ${className}`;\n\t\t}\n\t}\n\n\tif (classesToAppend) {\n\t\telement.className = element.className + classesToAppend;\n\t}\n}\n\n/**\n * Adds an event listener to the given element, to be triggered via delegate.\n * @param {!Element} element\n * @param {string} eventName\n * @param {!function()} listener\n * @private\n */\nfunction addElementListener_(element, eventName, listener) {\n\taddToArr_(domData.get(element, 'listeners', {}), eventName, listener);\n}\n\n/**\n * Adds an event listener to the given element, to be triggered via delegate\n * selectors.\n * @param {!Element} element\n * @param {string} eventName\n * @param {string} selector\n * @param {!function()} listener\n * @private\n */\nfunction addSelectorListener_(element, eventName, selector, listener) {\n\tconst delegatingData = domData.get(element, 'delegating', {});\n\taddToArr_(delegatingData[eventName].selectors, selector, listener);\n}\n\n/**\n * Adds a value to an array inside an object, creating it first if it doesn't\n * yet exist.\n * @param {!Array} arr\n * @param {string} key\n * @param {*} value\n * @private\n */\nfunction addToArr_(arr, key, value) {\n\tif (!arr[key]) {\n\t\tarr[key] = [];\n\t}\n\tarr[key].push(value);\n}\n\n/**\n * Attaches a delegate listener, unless there's already one attached.\n * @param {!Element} element\n * @param {string} eventName\n * @private\n */\nfunction attachDelegateEvent_(element, eventName) {\n\tlet delegatingData = domData.get(element, 'delegating', {});\n\tif (!delegatingData[eventName]) {\n\t\tdelegatingData[eventName] = {\n\t\t\thandle: on(\n\t\t\t\telement,\n\t\t\t\teventName,\n\t\t\t\thandleDelegateEvent_,\n\t\t\t\t!!USE_CAPTURE[eventName]\n\t\t\t),\n\t\t\tselectors: {},\n\t\t};\n\t}\n}\n\n/**\n * Gets the closest element up the tree from the given element (including\n * itself) that matches the specified selector, or null if none match.\n * @param {Element} element\n * @param {string} selector\n * @return {Element}\n */\nexport function closest(element, selector) {\n\twhile (element && !match(element, selector)) {\n\t\telement = element.parentNode;\n\t}\n\treturn element;\n}\n\n/**\n * Appends a child node with text or other nodes to a parent node. If\n * child is a HTML string it will be automatically converted to a document\n * fragment before appending it to the parent.\n * @param {!Element} parent The node to append nodes to.\n * @param {!(Element|NodeList|string)} child The thing to append to the parent.\n * @return {!Element} The appended child.\n */\nexport function append(parent, child) {\n\tif (isString(child)) {\n\t\tchild = buildFragment(child);\n\t}\n\tif (isNodeListLike(child)) {\n\t\tconst childArr = Array.prototype.slice.call(child);\n\t\tfor (let i = 0; i < childArr.length; i++) {\n\t\t\tparent.appendChild(childArr[i]);\n\t\t}\n\t} else {\n\t\tparent.appendChild(child);\n\t}\n\treturn child;\n}\n\n/**\n * Helper for converting a HTML string into a document fragment.\n * @param {string} htmlString The HTML string to convert.\n * @return {!Element} The resulting document fragment.\n */\nexport function buildFragment(htmlString) {\n\tconst tempDiv = document.createElement('div');\n\ttempDiv.innerHTML = `<br>${htmlString}`;\n\ttempDiv.removeChild(tempDiv.firstChild);\n\n\tconst fragment = document.createDocumentFragment();\n\twhile (tempDiv.firstChild) {\n\t\tfragment.appendChild(tempDiv.firstChild);\n\t}\n\treturn fragment;\n}\n\n/**\n * Checks if the first element contains the second one.\n * @param {!Element} element1\n * @param {!Element} element2\n * @return {boolean}\n */\nexport function contains(element1, element2) {\n\tif (isDocument(element1)) {\n\t\t// document.contains is not defined on IE9, so call it on documentElement instead.\n\t\treturn element1.documentElement.contains(element2);\n\t} else {\n\t\treturn element1.contains(element2);\n\t}\n}\n\n/**\n * Listens to the specified event on the given DOM element, but only calls the\n * given callback listener when it's triggered by elements that match the\n * given selector or target element.\n * @param {!Element} element The DOM element the event should be listened on.\n * @param {string} eventName The name of the event to listen to.\n * @param {!Element|string} selectorOrTarget Either an element or css selector\n * that should match the event for the listener to be triggered.\n * @param {!function(!Object)} callback Function to be called when the event\n * is triggered. It will receive the normalized event object.\n * @param {boolean=} defaultListener Optional flag indicating if this is a default\n * listener. That means that it would only be executed after all non\n * default listeners, and only if the event isn't prevented via\n * `preventDefault`.\n * @return {!EventHandle} Can be used to remove the listener.\n */\nexport function delegate(\n\telement,\n\teventName,\n\tselectorOrTarget,\n\tcallback,\n\tdefaultListener\n) {\n\tconst customConfig = customEvents[eventName];\n\tif (customConfig && customConfig.delegate) {\n\t\teventName = customConfig.originalEvent;\n\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t}\n\n\tif (defaultListener) {\n\t\t// Wrap callback so we don't set property directly on it.\n\t\tcallback = callback.bind();\n\t\tcallback.defaultListener_ = true;\n\t}\n\n\tattachDelegateEvent_(element, eventName);\n\tif (isString(selectorOrTarget)) {\n\t\taddSelectorListener_(element, eventName, selectorOrTarget, callback);\n\t} else {\n\t\taddElementListener_(selectorOrTarget, eventName, callback);\n\t}\n\n\treturn new DomDelegatedEventHandle(\n\t\tisString(selectorOrTarget) ? element : selectorOrTarget,\n\t\teventName,\n\t\tcallback,\n\t\tisString(selectorOrTarget) ? selectorOrTarget : null\n\t);\n}\n\n/**\n * Verifies if the element is able to trigger the Click event,\n * simulating browsers behaviour, avoiding event listeners to be called by triggerEvent method.\n * @param {Element} node Element to be checked.\n * @param {string} eventName The event name.\n * @param {Object=} eventObj\n * @private\n * @return {boolean}\n */\nfunction isAbleToInteractWith_(node, eventName, eventObj) {\n\tif (eventObj && eventName === 'click' && eventObj.button === 2) {\n\t\t// Firefox triggers \"click\" events on the document for right clicks. This\n\t\t// causes our delegate logic to trigger it for regular elements too, which\n\t\t// shouldn't happen. Ignoring them here.\n\t\treturn false;\n\t}\n\n\tconst matchesSelector = [\n\t\t'BUTTON',\n\t\t'INPUT',\n\t\t'SELECT',\n\t\t'TEXTAREA',\n\t\t'FIELDSET',\n\t];\n\tif (eventName === 'click' && matchesSelector.indexOf(node.tagName) > -1) {\n\t\treturn !(node.disabled || parent(node, 'fieldset[disabled]'));\n\t}\n\treturn true;\n}\n\n/**\n * Returns true if the specified value is a NodeList or like one.\n * @param {?} val Variable to test.\n * @return {boolean} Whether variable is like a NodeList.\n */\nexport function isNodeListLike(val) {\n\treturn (\n\t\tisDefAndNotNull(val) &&\n\t\ttypeof val.length === 'number' &&\n\t\ttypeof val.item === 'function'\n\t);\n}\n\n/**\n * Inserts node in document as last element.\n * @param {Element} node Element to remove children from.\n */\nexport function enterDocument(node) {\n\tnode && append(document.body, node);\n}\n\n/**\n * Removes node from document.\n * @param {Element} node Element to remove children from.\n */\nexport function exitDocument(node) {\n\tif (node && node.parentNode) {\n\t\tnode.parentNode.removeChild(node);\n\t}\n}\n\n/**\n * This is called when an event is triggered by a delegate listener. All\n * matching listeners of this event type from `target` to `currentTarget` will\n * be triggered.\n * @param {!Event} event The event payload.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction handleDelegateEvent_(event) {\n\tnormalizeDelegateEvent_(event);\n\tlet ret = true;\n\tconst container = event.currentTarget;\n\tconst defFns = [];\n\n\tret &= triggerDelegatedListeners_(container, event, defFns);\n\tret &= triggerDefaultDelegatedListeners_(defFns, event);\n\n\tevent.delegateTarget = null;\n\tevent[LAST_CONTAINER] = container;\n\treturn ret;\n}\n\n/**\n * Checks if the given element has the requested css class.\n * @param {!Element} element\n * @param {string} className\n * @return {boolean}\n */\nexport function hasClass(element, className) {\n\tif ('classList' in element) {\n\t\treturn hasClassWithNative_(element, className);\n\t} else {\n\t\treturn hasClassWithoutNative_(element, className);\n\t}\n}\n\n/**\n * Checks if the given element has the requested css class using classList.\n * @param {!Element} element\n * @param {string} className\n * @return {boolean}\n * @private\n */\nfunction hasClassWithNative_(element, className) {\n\treturn (\n\t\tclassName.indexOf(' ') === -1 && element.classList.contains(className)\n\t);\n}\n\n/**\n * Checks if the given element has the requested css class without using classList.\n * @param {!Element} element\n * @param {string} className\n * @return {boolean}\n * @private\n */\nfunction hasClassWithoutNative_(element, className) {\n\treturn (\n\t\t` ${element.className} `.indexOf(` ${className} `) >= 0 &&\n\t\tclassName.split(' ').length === 1\n\t);\n}\n\n/**\n * Checks if the given element is empty or not.\n * @param {!Element} element\n * @return {boolean}\n */\nexport function isEmpty(element) {\n\treturn element.childNodes.length === 0;\n}\n\n/**\n * Check if an element matches a given selector.\n * @param {Element} element\n * @param {string} selector\n * @return {boolean}\n */\nexport function match(element, selector) {\n\tif (!element || element.nodeType !== 1) {\n\t\treturn false;\n\t}\n\n\tconst p = Element.prototype;\n\tconst m =\n\t\tp.matches ||\n\t\tp.webkitMatchesSelector ||\n\t\tp.mozMatchesSelector ||\n\t\tp.msMatchesSelector ||\n\t\tp.oMatchesSelector;\n\tif (m) {\n\t\treturn m.call(element, selector);\n\t}\n\n\treturn matchFallback_(element, selector);\n}\n\n/**\n * Check if an element matches a given selector, using an internal implementation\n * instead of calling existing javascript functions.\n * @param {Element} element\n * @param {string} selector\n * @return {boolean}\n * @private\n */\nfunction matchFallback_(element, selector) {\n\tconst parentNode = element.parentNode;\n\n\tif (parentNode) {\n\t\tconst nodes = parentNode.querySelectorAll(selector);\n\n\t\tfor (let i = 0; i < nodes.length; ++i) {\n\t\t\tif (nodes[i] === element) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Returns the next sibling of the given element that matches the specified\n * selector, or null if there is none.\n * @param {!Element} element\n * @param {?string} selector\n * @return {Element|null}\n */\nexport function next(element, selector) {\n\tdo {\n\t\telement = element.nextSibling;\n\t\tif (element && match(element, selector)) {\n\t\t\treturn element;\n\t\t}\n\t} while (element);\n\treturn null;\n}\n\n/**\n * Normalizes the event payload for delegate listeners.\n * @param {!Event} event\n * @private\n */\nfunction normalizeDelegateEvent_(event) {\n\tevent.stopPropagation = stopPropagation_;\n\tevent.stopImmediatePropagation = stopImmediatePropagation_;\n}\n\n/**\n * Listens to the specified event on the given DOM element. This function normalizes\n * DOM event payloads and functions so they'll work the same way on all supported\n * browsers.\n * @param {!Element|string} element The DOM element to listen to the event on, or\n * a selector that should be delegated on the entire document.\n * @param {string} eventName The name of the event to listen to.\n * @param {!function(!Object)} callback Function to be called when the event is\n * triggered. It will receive the normalized event object.\n * @param {boolean} capture Flag indicating if listener should be triggered\n * during capture phase, instead of during the bubbling phase. Defaults to false.\n * @return {!DomEventHandle} Can be used to remove the listener.\n */\nexport function on(element, eventName, callback, capture) {\n\tif (isString(element)) {\n\t\treturn delegate(document, eventName, element, callback);\n\t}\n\tconst customConfig = customEvents[eventName];\n\tif (customConfig && customConfig.event) {\n\t\teventName = customConfig.originalEvent;\n\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t}\n\telement.addEventListener(eventName, callback, capture);\n\treturn new DomEventHandle(element, eventName, callback, capture);\n}\n\n/**\n * Listens to the specified event on the given DOM element once. This\n * function normalizes DOM event payloads and functions so they'll work the\n * same way on all supported browsers.\n * @param {!Element} element The DOM element to listen to the event on.\n * @param {string} eventName The name of the event to listen to.\n * @param {!function(!Object)} callback Function to be called when the event\n * is triggered. It will receive the normalized event object.\n * @return {!DomEventHandle} Can be used to remove the listener.\n */\nexport function once(element, eventName, callback) {\n\tconst domEventHandle = on(element, eventName, function() {\n\t\tdomEventHandle.removeListener();\n\t\treturn callback.apply(this, arguments); // eslint-disable-line\n\t});\n\treturn domEventHandle;\n}\n\n/**\n * Gets the first parent from the given element that matches the specified\n * selector, or null if none match.\n * @param {!Element} element\n * @param {string} selector\n * @return {Element}\n */\nexport function parent(element, selector) {\n\treturn closest(element.parentNode, selector);\n}\n\n/**\n * Inserts a node before first child of the parent. If child is a HTML string\n * it will be converted to document fragment before prepending it to the parent.\n * @param {!Element} parent The node to prepend to.\n * @param {!(Element|NodeList|string)} child The thing to prepend to the parent.\n * @return {!Element} The prepended child.\n */\nexport function prepend(parent, child) {\n\tif (isString(child)) {\n\t\tchild = buildFragment(child);\n\t}\n\n\tif (!isNodeListLike(child) && !isDefAndNotNull(parent.firstChild)) {\n\t\treturn append(parent, child);\n\t}\n\n\tif (isNodeListLike(child)) {\n\t\tconst childArr = Array.prototype.slice.call(child);\n\t\tfor (let i = childArr.length - 1; i >= 0; i--) {\n\t\t\tparent.insertBefore(childArr[i], parent.firstChild);\n\t\t}\n\t} else {\n\t\tparent.insertBefore(child, parent.firstChild);\n\t}\n\n\treturn child;\n}\n\n/**\n * Registers a custom event.\n * @param {string} eventName The name of the custom event.\n * @param {!Object} customConfig An object with information about how the event\n * should be handled.\n */\nexport function registerCustomEvent(eventName, customConfig) {\n\tcustomEvents[eventName] = customConfig;\n}\n\n/**\n * Removes all the child nodes on a DOM node.\n * @param {Element} node Element to remove children from.\n */\nexport function removeChildren(node) {\n\tlet child;\n\twhile ((child = node.firstChild)) {\n\t\tnode.removeChild(child);\n\t}\n}\n\n/**\n * Removes the requested CSS classes from an element.\n * @param {!Element|!NodeList} elements The element or elements to remove CSS classes from.\n * @param {string} classes CSS classes to remove.\n */\nexport function removeClasses(elements, classes) {\n\tif (!isObject(elements) || !isString(classes)) {\n\t\treturn;\n\t}\n\n\tif (!elements.length) {\n\t\telements = [elements];\n\t}\n\n\tfor (let i = 0; i < elements.length; i++) {\n\t\tif ('classList' in elements[i]) {\n\t\t\tremoveClassesWithNative_(elements[i], classes);\n\t\t} else {\n\t\t\tremoveClassesWithoutNative_(elements[i], classes);\n\t\t}\n\t}\n}\n\n/**\n * Removes the requested CSS classes from an element using classList.\n * @param {!Element} element The element to remove CSS classes from.\n * @param {string} classes CSS classes to remove.\n * @private\n */\nfunction removeClassesWithNative_(element, classes) {\n\tclasses.split(' ').forEach(function(className) {\n\t\tif (className) {\n\t\t\telement.classList.remove(className);\n\t\t}\n\t});\n}\n\n/**\n * Removes the requested CSS classes from an element without using classList.\n * @param {!Element} element The element to remove CSS classes from.\n * @param {string} classes CSS classes to remove.\n * @private\n */\nfunction removeClassesWithoutNative_(element, classes) {\n\tlet elementClassName = ` ${element.className} `;\n\n\tclasses = classes.split(' ');\n\n\tfor (let i = 0; i < classes.length; i++) {\n\t\telementClassName = elementClassName.replace(` ${classes[i]} `, ' ');\n\t}\n\n\telement.className = elementClassName.trim();\n}\n\n/**\n * Replaces the first element with the second.\n * @param {Element} element1\n * @param {Element} element2\n */\nexport function replace(element1, element2) {\n\tif (element1 && element2 && element1 !== element2 && element1.parentNode) {\n\t\telement1.parentNode.insertBefore(element2, element1);\n\t\telement1.parentNode.removeChild(element1);\n\t}\n}\n\n/**\n * The function that replaces `stopImmediatePropagation_` for events.\n * @private\n */\nfunction stopImmediatePropagation_() {\n\tconst event = this; // eslint-disable-line\n\tevent.stopped = true;\n\tevent.stoppedImmediate = true;\n\tEvent.prototype.stopImmediatePropagation.call(event);\n}\n\n/**\n * The function that replaces `stopPropagation` for events.\n * @private\n */\nfunction stopPropagation_() {\n\tconst event = this; // eslint-disable-line\n\tevent.stopped = true;\n\tEvent.prototype.stopPropagation.call(event);\n}\n\n/**\n * Checks if the given element supports the given event type.\n * @param {!Element|string} element The DOM element or element tag name to check.\n * @param {string} eventName The name of the event to check.\n * @return {boolean}\n */\nexport function supportsEvent(element, eventName) {\n\tif (customEvents[eventName]) {\n\t\treturn true;\n\t}\n\n\tif (isString(element)) {\n\t\tif (!elementsByTag_[element]) {\n\t\t\telementsByTag_[element] = document.createElement(element);\n\t\t}\n\t\telement = elementsByTag_[element];\n\t}\n\n\tconst tag = element.tagName;\n\tif (!supportCache_[tag] || !supportCache_[tag].hasOwnProperty(eventName)) {\n\t\tsupportCache_[tag] = supportCache_[tag] || {};\n\t\tsupportCache_[tag][eventName] = 'on' + eventName in element;\n\t}\n\treturn supportCache_[tag][eventName];\n}\n\n/**\n * This triggers all default matched delegated listeners of a given event type.\n * @param {!Array} defFns Array to collect default listeners in, instead\n * @param {!Event} event\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerDefaultDelegatedListeners_(defFns, event) {\n\tlet ret = true;\n\n\tfor (let i = 0; i < defFns.length && !event.defaultPrevented; i++) {\n\t\tevent.delegateTarget = defFns[i].element;\n\t\tret &= defFns[i].fn(event);\n\t}\n\n\treturn ret;\n}\n\n/**\n * This triggers all matched delegated listeners of a given event type when its\n * delegated target is able to interact.\n * @param {!Element} container\n * @param {!Event} event\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerDelegatedListeners_(container, event, defaultFns) {\n\tlet ret = true;\n\tlet currElement = event.target;\n\tconst limit = container.parentNode;\n\n\twhile (currElement && currElement !== limit && !event.stopped) {\n\t\tif (isAbleToInteractWith_(currElement, event.type, event)) {\n\t\t\tevent.delegateTarget = currElement;\n\t\t\tret &= triggerElementListeners_(currElement, event, defaultFns);\n\t\t\tret &= triggerSelectorListeners_(\n\t\t\t\tcontainer,\n\t\t\t\tcurrElement,\n\t\t\t\tevent,\n\t\t\t\tdefaultFns\n\t\t\t);\n\t\t}\n\t\tcurrElement = currElement.parentNode;\n\t}\n\n\treturn ret;\n}\n\n/**\n * Converts the given argument to a DOM element. Strings are assumed to\n * be selectors, and so a matched element will be returned. If the arg\n * is already a DOM element it will be the return value.\n * @param {string|Element|Document} selectorOrElement\n * @return {Element} The converted element, or null if none was found.\n */\nexport function toElement(selectorOrElement) {\n\tif (\n\t\tisElement(selectorOrElement) ||\n\t\tisDocument(selectorOrElement) ||\n\t\tisDocumentFragment(selectorOrElement)\n\t) {\n\t\treturn selectorOrElement;\n\t} else if (isString(selectorOrElement)) {\n\t\tif (\n\t\t\tselectorOrElement[0] === '#' &&\n\t\t\tselectorOrElement.indexOf(' ') === -1\n\t\t) {\n\t\t\treturn document.getElementById(selectorOrElement.substr(1));\n\t\t} else {\n\t\t\treturn document.querySelector(selectorOrElement);\n\t\t}\n\t} else {\n\t\treturn null;\n\t}\n}\n\n/**\n * Adds or removes one or more classes from an element. If any of the classes\n * is present, it will be removed from the element, or added otherwise.\n * @param {!Element} element The element which classes will be toggled.\n * @param {string} classes The classes which have to added or removed from the element.\n */\nexport function toggleClasses(element, classes) {\n\tif (!isObject(element) || !isString(classes)) {\n\t\treturn;\n\t}\n\n\tif ('classList' in element) {\n\t\ttoggleClassesWithNative_(element, classes);\n\t} else {\n\t\ttoggleClassesWithoutNative_(element, classes);\n\t}\n}\n\n/**\n * Adds or removes one or more classes from an element using classList.\n * If any of the classes is present, it will be removed from the element,\n * or added otherwise.\n * @param {!Element} element The element which classes will be toggled.\n * @param {string} classes The classes which have to added or removed from the element.\n * @private\n */\nfunction toggleClassesWithNative_(element, classes) {\n\tclasses.split(' ').forEach(function(className) {\n\t\telement.classList.toggle(className);\n\t});\n}\n\n/**\n * Adds or removes one or more classes from an element without using classList.\n * If any of the classes is present, it will be removed from the element,\n * or added otherwise.\n * @param {!Element} element The element which classes will be toggled.\n * @param {string} classes The classes which have to added or removed from the element.\n * @private\n */\nfunction toggleClassesWithoutNative_(element, classes) {\n\tlet elementClassName = ` ${element.className} `;\n\n\tclasses = classes.split(' ');\n\n\tfor (let i = 0; i < classes.length; i++) {\n\t\tconst className = ` ${classes[i]} `;\n\t\tconst classIndex = elementClassName.indexOf(className);\n\n\t\tif (classIndex === -1) {\n\t\t\telementClassName = `${elementClassName}${classes[i]} `;\n\t\t} else {\n\t\t\tconst before = elementClassName.substring(0, classIndex);\n\t\t\tconst after = elementClassName.substring(\n\t\t\t\tclassIndex + className.length\n\t\t\t); // eslint-disable-line\n\t\t\telementClassName = `${before} ${after}`;\n\t\t}\n\t}\n\n\telement.className = elementClassName.trim();\n}\n\n/**\n * Triggers all listeners for the given event type that are stored in the\n * specified element.\n * @param {!Element} element\n * @param {!Event} event\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerElementListeners_(element, event, defaultFns) {\n\tconst lastContainer = event[LAST_CONTAINER];\n\tif (!isDef(lastContainer) || !contains(lastContainer, element)) {\n\t\tconst listeners = domData.get(element, 'listeners', {})[event.type];\n\t\treturn triggerListeners_(listeners, event, element, defaultFns);\n\t}\n\treturn true;\n}\n\n/**\n * Triggers the specified event on the given element.\n * NOTE: This should mostly be used for testing, not on real code.\n * @param {!Element} element The node that should trigger the event.\n * @param {string} eventName The name of the event to be triggred.\n * @param {Object=} eventObj An object with data that should be on the\n * triggered event's payload.\n */\nexport function triggerEvent(element, eventName, eventObj) {\n\tif (isAbleToInteractWith_(element, eventName, eventObj)) {\n\t\tconst payload = document.createEvent('HTMLEvents');\n\t\tpayload.initEvent(eventName, true, true);\n\t\tobject.mixin(payload, eventObj);\n\t\telement.dispatchEvent(payload);\n\t}\n}\n\n/**\n * Triggers the given listeners array.\n * @param {Array<!function()>} listeners\n * @param {!Event} event\n * @param {!Element} element\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerListeners_(listeners, event, element, defaultFns) {\n\tlet ret = true;\n\tlisteners = listeners || [];\n\tfor (let i = 0; i < listeners.length && !event.stoppedImmediate; i++) {\n\t\tif (listeners[i].defaultListener_) {\n\t\t\tdefaultFns.push({\n\t\t\t\telement,\n\t\t\t\tfn: listeners[i],\n\t\t\t});\n\t\t} else {\n\t\t\tret &= listeners[i](event);\n\t\t}\n\t}\n\treturn ret;\n}\n\n/**\n * Triggers all selector listeners for the given event.\n * @param {!Element} container\n * @param {!Element} element\n * @param {!Event} event\n * @param {!Array} defaultFns Array to collect default listeners in, instead\n * of running them.\n * @return {boolean} False if at least one of the triggered callbacks returns\n * false, or true otherwise.\n * @private\n */\nfunction triggerSelectorListeners_(container, element, event, defaultFns) {\n\tlet ret = true;\n\tconst data = domData.get(container, 'delegating', {});\n\tconst map = data[event.type].selectors;\n\tconst selectors = Object.keys(map);\n\tfor (let i = 0; i < selectors.length && !event.stoppedImmediate; i++) {\n\t\tif (match(element, selectors[i])) {\n\t\t\tconst listeners = map[selectors[i]];\n\t\t\tret &= triggerListeners_(listeners, event, element, defaultFns);\n\t\t}\n\t}\n\treturn ret;\n}\n","'use strict';\n\n// This file exists just for backwards compatibility, making sure that old\n// default imports for this file still work. It's best to use the named exports\n// for each function instead though, since that allows bundlers like Rollup to\n// reduce the bundle size by removing unused code.\nimport * as dom from './domNamed';\n\nexport default dom;\nexport {dom};\nexport * from './domNamed';\n","'use strict';\n\nimport {delegate, on, supportsEvent} from './dom';\nimport {EventEmitterProxy} from 'metal-events';\n\n/**\n * DomEventEmitterProxy utility. It extends `EventEmitterProxy` to also accept\n * dom elements as origin emitters.\n * @extends {EventEmitterProxy}\n */\nclass DomEventEmitterProxy extends EventEmitterProxy {\n\t/**\n\t * Adds the given listener for the given event.\n\t * @param {string} event\n\t * @param {!function()} listener\n\t * @return {!EventHandle} The listened event's handle.\n\t * @protected\n\t * @override\n\t */\n\taddListener_(event, listener) {\n\t\tif (this.originEmitter_.addEventListener) {\n\t\t\tif (this.isDelegateEvent_(event)) {\n\t\t\t\tconst index = event.indexOf(':', 9);\n\t\t\t\tconst eventName = event.substring(9, index);\n\t\t\t\tconst selector = event.substring(index + 1);\n\t\t\t\treturn delegate(\n\t\t\t\t\tthis.originEmitter_,\n\t\t\t\t\teventName,\n\t\t\t\t\tselector,\n\t\t\t\t\tlistener\n\t\t\t\t); // eslint-disable-line\n\t\t\t} else {\n\t\t\t\treturn on(this.originEmitter_, event, listener);\n\t\t\t}\n\t\t} else {\n\t\t\treturn super.addListener_(event, listener);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given event is of the delegate type.\n\t * @param {string} event\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisDelegateEvent_(event) {\n\t\treturn event.substr(0, 9) === 'delegate:';\n\t}\n\n\t/**\n\t * Checks if the given event is supported by the origin element.\n\t * @param {string} event\n\t * @protected\n\t * @return {boolean}\n\t */\n\tisSupportedDomEvent_(event) {\n\t\tif (!this.originEmitter_ || !this.originEmitter_.addEventListener) {\n\t\t\treturn true;\n\t\t}\n\t\treturn (\n\t\t\t(this.isDelegateEvent_(event) && event.indexOf(':', 9) !== -1) ||\n\t\t\tsupportsEvent(this.originEmitter_, event)\n\t\t);\n\t}\n\n\t/**\n\t * Checks if the given event should be proxied.\n\t * @param {string} event\n\t * @return {boolean}\n\t * @protected\n\t * @override\n\t */\n\tshouldProxyEvent_(event) {\n\t\treturn (\n\t\t\tsuper.shouldProxyEvent_(event) && this.isSupportedDomEvent_(event)\n\t\t); // eslint-disable-line\n\t}\n}\n\nexport default DomEventEmitterProxy;\n","'use strict';\n\nimport {append} from './dom';\nimport {string} from 'metal';\n\n/**\n * Class with static methods responsible for doing browser feature checks.\n */\nclass features {\n\t/**\n\t * Some browsers still supports prefixed animation events. This method can\n\t * be used to retrieve the current browser event name for both, animation\n\t * and transition.\n\t * @return {object}\n\t */\n\tstatic checkAnimationEventName() {\n\t\tif (features.animationEventName_ === undefined) {\n\t\t\tfeatures.animationEventName_ = {\n\t\t\t\tanimation: features.checkAnimationEventName_('animation'),\n\t\t\t\ttransition: features.checkAnimationEventName_('transition'),\n\t\t\t};\n\t\t}\n\t\treturn features.animationEventName_;\n\t}\n\n\t/**\n\t * @protected\n\t * @param {string} type Type to test: animation, transition.\n\t * @return {string} Browser event name.\n\t */\n\tstatic checkAnimationEventName_(type) {\n\t\tconst prefixes = ['Webkit', 'MS', 'O', ''];\n\t\tconst typeTitleCase = string.replaceInterval(\n\t\t\ttype,\n\t\t\t0,\n\t\t\t1,\n\t\t\ttype.substring(0, 1).toUpperCase()\n\t\t);\n\t\tconst suffixes = [\n\t\t\t`${typeTitleCase}End`,\n\t\t\t`${typeTitleCase}End`,\n\t\t\t`${typeTitleCase}End`,\n\t\t\t`${type}end`,\n\t\t];\n\t\tif (!features.animationElement_) {\n\t\t\tfeatures.animationElement_ = document.createElement('div');\n\t\t}\n\t\tfor (let i = 0; i < prefixes.length; i++) {\n\t\t\tif (\n\t\t\t\tfeatures.animationElement_.style[\n\t\t\t\t\tprefixes[i] + typeTitleCase\n\t\t\t\t] !== undefined // eslint-disable-line\n\t\t\t) {\n\t\t\t\treturn prefixes[i].toLowerCase() + suffixes[i];\n\t\t\t}\n\t\t}\n\t\treturn `${type}end`;\n\t}\n\n\t/**\n\t * Some browsers (like IE9) change the order of element attributes, when html\n\t * is rendered. This method can be used to check if this behavior happens on\n\t * the current browser.\n\t * @return {boolean}\n\t */\n\tstatic checkAttrOrderChange() {\n\t\tif (features.attrOrderChange_ === undefined) {\n\t\t\tconst originalContent = '<div data-component=\"\" data-ref=\"\"></div>';\n\t\t\tconst element = document.createElement('div');\n\t\t\tappend(element, originalContent);\n\t\t\tfeatures.attrOrderChange_ = originalContent !== element.innerHTML;\n\t\t}\n\t\treturn features.attrOrderChange_;\n\t}\n}\n\nfeatures.animationElement_ = undefined;\nfeatures.animationEventName_ = undefined;\nfeatures.attrOrderChange_ = undefined;\n\nexport default features;\n","'use strict';\n\nimport {async} from 'metal';\nimport {exitDocument, once} from './dom';\n\n/**\n * Utility functions for running javascript code in the global scope.\n */\nclass globalEval {\n\t/**\n\t * Evaluates the given string in the global scope.\n\t * @param {string} text\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} script\n\t */\n\tstatic run(text, appendFn) {\n\t\tconst script = document.createElement('script');\n\t\tscript.text = text;\n\t\tif (appendFn) {\n\t\t\tappendFn(script);\n\t\t} else {\n\t\t\tdocument.head.appendChild(script);\n\t\t}\n\t\texitDocument(script);\n\t\treturn script;\n\t}\n\n\t/**\n\t * Evaluates the given javascript file in the global scope.\n\t * @param {string} src The file's path.\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} script\n\t */\n\tstatic runFile(src, defaultFn, appendFn) {\n\t\tconst script = document.createElement('script');\n\t\tscript.src = src;\n\n\t\tconst callback = function() {\n\t\t\texitDocument(script);\n\t\t\tdefaultFn && defaultFn();\n\t\t};\n\t\tonce(script, 'load', callback);\n\t\tonce(script, 'error', callback);\n\n\t\tif (appendFn) {\n\t\t\tappendFn(script);\n\t\t} else {\n\t\t\tdocument.head.appendChild(script);\n\t\t}\n\n\t\treturn script;\n\t}\n\n\t/**\n\t * Evaluates the code referenced by the given script element.\n\t * @param {!Element} script\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} script\n\t */\n\tstatic runScript(script, defaultFn, appendFn) {\n\t\tconst callback = function() {\n\t\t\tdefaultFn && defaultFn();\n\t\t};\n\t\tif (script.type && script.type !== 'text/javascript') {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn;\n\t\t}\n\t\texitDocument(script);\n\t\tif (script.src) {\n\t\t\treturn globalEval.runFile(script.src, defaultFn, appendFn);\n\t\t} else {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn globalEval.run(script.text, appendFn);\n\t\t}\n\t}\n\n\t/**\n\t * Evaluates any script tags present in the given element.\n\t * @param {!Element} element\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t */\n\tstatic runScriptsInElement(element, defaultFn, appendFn) {\n\t\tconst scripts = element.querySelectorAll('script');\n\t\tif (scripts.length) {\n\t\t\tglobalEval.runScriptsInOrder(scripts, 0, defaultFn, appendFn);\n\t\t} else if (defaultFn) {\n\t\t\tasync.nextTick(defaultFn);\n\t\t}\n\t}\n\n\t/**\n\t * Runs the given scripts elements in the order that they appear.\n\t * @param {!NodeList} scripts\n\t * @param {number} index\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t */\n\tstatic runScriptsInOrder(scripts, index, defaultFn, appendFn) {\n\t\tglobalEval.runScript(\n\t\t\tscripts.item(index),\n\t\t\tfunction() {\n\t\t\t\tif (index < scripts.length - 1) {\n\t\t\t\t\tglobalEval.runScriptsInOrder(\n\t\t\t\t\t\tscripts,\n\t\t\t\t\t\tindex + 1,\n\t\t\t\t\t\tdefaultFn,\n\t\t\t\t\t\tappendFn\n\t\t\t\t\t); // eslint-disable-line\n\t\t\t\t} else if (defaultFn) {\n\t\t\t\t\tasync.nextTick(defaultFn);\n\t\t\t\t}\n\t\t\t},\n\t\t\tappendFn\n\t\t);\n\t}\n}\n\nexport default globalEval;\n","'use strict';\n\nimport {async} from 'metal';\nimport {once} from './dom';\n\n/**\n * Utility functions for running styles.\n */\nclass globalEvalStyles {\n\t/**\n\t * Evaluates the given style.\n\t * @param {string} text\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} style\n\t */\n\tstatic run(text, appendFn) {\n\t\tconst style = document.createElement('style');\n\t\tstyle.innerHTML = text;\n\t\tif (appendFn) {\n\t\t\tappendFn(style);\n\t\t} else {\n\t\t\tdocument.head.appendChild(style);\n\t\t}\n\t\treturn style;\n\t}\n\n\t/**\n\t * Evaluates the given style file.\n\t * @param {string} href The file's path.\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the styles has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} style\n\t */\n\tstatic runFile(href, defaultFn, appendFn) {\n\t\tconst link = document.createElement('link');\n\t\tlink.rel = 'stylesheet';\n\t\tlink.href = href;\n\t\tglobalEvalStyles.runStyle(link, defaultFn, appendFn);\n\t\treturn link;\n\t}\n\n\t/**\n\t * Evaluates the code referenced by the given style/link element.\n\t * @param {!Element} style\n\t * @param {function()=} defaultFn Optional function to be called\n\t * when the script has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t * @return {Element} style\n\t */\n\tstatic runStyle(style, defaultFn, appendFn) {\n\t\tconst callback = function() {\n\t\t\tdefaultFn && defaultFn();\n\t\t};\n\t\tif (style.rel && style.rel !== 'stylesheet') {\n\t\t\tasync.nextTick(callback);\n\t\t\treturn;\n\t\t}\n\n\t\tif (style.tagName === 'STYLE') {\n\t\t\tasync.nextTick(callback);\n\t\t} else {\n\t\t\tonce(style, 'load', callback);\n\t\t\tonce(style, 'error', callback);\n\t\t}\n\n\t\tif (appendFn) {\n\t\t\tappendFn(style);\n\t\t} else {\n\t\t\tdocument.head.appendChild(style);\n\t\t}\n\n\t\treturn style;\n\t}\n\n\t/**\n\t * Evaluates any style present in the given element.\n\t * @param {!Element} element\n\t * @param {function()=} defaultFn Optional function to be called when the\n\t * style has been run.\n\t * @param {function()=} appendFn Optional function to append the node\n\t * into document.\n\t */\n\tstatic runStylesInElement(element, defaultFn, appendFn) {\n\t\tconst styles = element.querySelectorAll('style,link');\n\t\tif (styles.length === 0 && defaultFn) {\n\t\t\tasync.nextTick(defaultFn);\n\t\t\treturn;\n\t\t}\n\n\t\tlet loadCount = 0;\n\t\tconst callback = function() {\n\t\t\tif (defaultFn && ++loadCount === styles.length) {\n\t\t\t\tasync.nextTick(defaultFn);\n\t\t\t}\n\t\t};\n\t\tfor (let i = 0; i < styles.length; i++) {\n\t\t\tglobalEvalStyles.runStyle(styles[i], callback, appendFn);\n\t\t}\n\t}\n}\n\nexport default globalEvalStyles;\n","'use strict';\n\nimport {isServerSide} from 'metal';\nimport {registerCustomEvent, contains} from './dom';\nimport features from './features';\n\n/**\n * Register custom events for event delegation.\n */\nfunction registerEvents() {\n\tconst mouseEventMap = {\n\t\tmouseenter: 'mouseover',\n\t\tmouseleave: 'mouseout',\n\t\tpointerenter: 'pointerover',\n\t\tpointerleave: 'pointerout',\n\t};\n\tObject.keys(mouseEventMap).forEach(function(eventName) {\n\t\tregisterCustomEvent(eventName, {\n\t\t\tdelegate: true,\n\t\t\thandler: function(callback, event) {\n\t\t\t\tconst related = event.relatedTarget;\n\t\t\t\tconst target = event.delegateTarget;\n\t\t\t\t// eslint-disable-next-line\n\t\t\t\tif (\n\t\t\t\t\t!related ||\n\t\t\t\t\t(related !== target && !contains(target, related))\n\t\t\t\t) {\n\t\t\t\t\tevent.customType = eventName;\n\t\t\t\t\treturn callback(event);\n\t\t\t\t}\n\t\t\t},\n\t\t\toriginalEvent: mouseEventMap[eventName],\n\t\t});\n\t});\n\n\tconst animationEventMap = {\n\t\tanimation: 'animationend',\n\t\ttransition: 'transitionend',\n\t};\n\tObject.keys(animationEventMap).forEach(function(eventType) {\n\t\tconst eventName = animationEventMap[eventType];\n\t\tregisterCustomEvent(eventName, {\n\t\t\tevent: true,\n\t\t\tdelegate: true,\n\t\t\thandler: function(callback, event) {\n\t\t\t\tevent.customType = eventName;\n\t\t\t\treturn callback(event);\n\t\t\t},\n\t\t\toriginalEvent: features.checkAnimationEventName()[eventType],\n\t\t});\n\t});\n}\n\nif (!isServerSide()) {\n\tregisterEvents();\n}\n","var globals = globals || {};\n\nif (typeof window !== 'undefined') {\n\tglobals.window = window;\n}\n\nif (typeof document !== 'undefined') {\n\tglobals.document = document;\n}\n\nexport default globals;\n","'use strict';\n\n/**\n * Parses the given uri string into an object.\n * @param {*=} opt_uri Optional string URI to parse\n */\nfunction parseFromAnchor(opt_uri) {\n\tvar link = document.createElement('a');\n\tlink.href = opt_uri;\n\n\tif(link.protocol === ':' || !/:/.test(link.href)) {\n\t\tthrow new TypeError(`${opt_uri} is not a valid URL`);\n\t}\n\n\treturn {\n\t\thash: link.hash,\n\t\thostname: link.hostname,\n\t\tpassword: link.password,\n\t\tpathname: link.pathname[0] === '/' ? link.pathname : '/' + link.pathname,\n\t\tport: link.port,\n\t\tprotocol: link.protocol,\n\t\tsearch: link.search,\n\t\tusername: link.username\n\t};\n}\n\nexport default parseFromAnchor;\n","'use strict';\n\nimport { isFunction } from 'metal';\nimport parseFromAnchor from './parseFromAnchor';\n\n/**\n * Parses the given uri string into an object. The URL function will be used\n * when present, otherwise we'll fall back to the anchor node element.\n * @param {*=} opt_uri Optional string URI to parse\n */\nfunction parse(opt_uri) {\n\tif (isFunction(URL) && URL.length) {\n\t\tconst url = new URL(opt_uri);\n\n\t\t// Safari Browsers will cap port to the max 16-bit unsigned integer (65535) instead\n\t\t// of throwing a TypeError as per spec. It will still keep the port number in the\n\t\t// href attribute, so we can use this mismatch to raise the expected exception.\n\t\tif (url.port && url.href.indexOf(url.port) === -1) {\n\t\t\tthrow new TypeError(`${opt_uri} is not a valid URL`);\n\t\t}\n\n\t\treturn url;\n\t} else {\n\t\treturn parseFromAnchor(opt_uri);\n\t}\n}\n\nexport default parse;\n","'use strict';\n\nimport { Disposable } from 'metal';\n\n/**\n * A cached reference to the create function.\n */\nvar create = Object.create;\n\n/**\n * Case insensitive string Multimap implementation. Allows multiple values for\n * the same key name.\n * @extends {Disposable}\n */\nclass MultiMap extends Disposable {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.keys = create(null);\n\t\tthis.values = create(null);\n\t}\n\n\t/**\n\t * Adds value to a key name.\n\t * @param {string} name\n\t * @param {*} value\n\t * @chainable\n\t */\n\tadd(name, value) {\n\t\tthis.keys[name.toLowerCase()] = name;\n\t\tthis.values[name.toLowerCase()] = this.values[name.toLowerCase()] || [];\n\t\tthis.values[name.toLowerCase()].push(value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Clears map names and values.\n\t * @chainable\n\t */\n\tclear() {\n\t\tthis.keys = create(null);\n\t\tthis.values = create(null);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Checks if map contains a value to the key name.\n\t * @param {string} name\n\t * @return {boolean}\n\t * @chainable\n\t */\n\tcontains(name) {\n\t\treturn name.toLowerCase() in this.values;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tthis.values = null;\n\t}\n\n\t/**\n\t * Creates a `MultiMap` instance from the given object.\n\t * @param {!Object} obj\n\t * @return {!MultiMap}\n\t */\n\tstatic fromObject(obj) {\n\t\tvar map = new MultiMap();\n\t\tvar keys = Object.keys(obj);\n\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\tmap.set(keys[i], obj[keys[i]]);\n\t\t}\n\t\treturn map;\n\t}\n\n\t/**\n\t * Gets the first added value from a key name.\n\t * @param {string} name\n\t * @return {*}\n\t * @chainable\n\t */\n\tget(name) {\n\t\tvar values = this.values[name.toLowerCase()];\n\t\tif (values) {\n\t\t\treturn values[0];\n\t\t}\n\t}\n\n\t/**\n\t * Gets all values from a key name.\n\t * @param {string} name\n\t * @return {Array.<*>}\n\t */\n\tgetAll(name) {\n\t\treturn this.values[name.toLowerCase()];\n\t}\n\n\t/**\n\t * Returns true if the map is empty, false otherwise.\n\t * @return {boolean}\n\t */\n\tisEmpty() {\n\t\treturn this.size() === 0;\n\t}\n\n\t/**\n\t * Gets array of key names.\n\t * @return {Array.<string>}\n\t */\n\tnames() {\n\t\treturn Object.keys(this.values).map((key) => this.keys[key]);\n\t}\n\n\t/**\n\t * Removes all values from a key name.\n\t * @param {string} name\n\t * @chainable\n\t */\n\tremove(name) {\n\t\tdelete this.keys[name.toLowerCase()];\n\t\tdelete this.values[name.toLowerCase()];\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of a key name. Relevant to replace the current values with\n\t * a new one.\n\t * @param {string} name\n\t * @param {*} value\n\t * @chainable\n\t */\n\tset(name, value) {\n\t\tthis.keys[name.toLowerCase()] = name;\n\t\tthis.values[name.toLowerCase()] = [value];\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the size of the map key names.\n\t * @return {number}\n\t */\n\tsize() {\n\t\treturn this.names().length;\n\t}\n\n\t/**\n\t * Returns the parsed values as a string.\n\t * @return {string}\n\t */\n\ttoString() {\n\t\treturn JSON.stringify(this.values);\n\t}\n}\n\nexport default MultiMap;\n","'use strict';\n\nimport { array } from 'metal';\n\n/**\n * Generic tree node data structure with arbitrary number of child nodes.\n * @param {V} value Value.\n * @constructor\n */\nclass TreeNode {\n\n\tconstructor(value) {\n\t\t/**\n\t\t * The value.\n\t\t * @private {V}\n\t\t */\n\t\tthis.value_ = value;\n\n\t\t/**\n\t\t * Reference to the parent node or null if it has no parent.\n\t\t * @private {TreeNode}\n\t\t */\n\t\tthis.parent_ = null;\n\n\t\t/**\n\t\t * Child nodes or null in case of leaf node.\n\t\t * @private {Array<!TreeNode>}\n\t\t */\n\t\tthis.children_ = null;\n\t}\n\n\t/**\n\t * Appends a child node to this node.\n\t * @param {!TreeNode} child Orphan child node.\n\t */\n\taddChild(child) {\n\t\tassertChildHasNoParent(child);\n\t\tchild.setParent(this);\n\t\tthis.children_ = this.children_ || [];\n\t\tthis.children_.push(child);\n\t}\n\n\t/**\n\t * Tells whether this node is the ancestor of the given node.\n\t * @param {!TreeNode} node A node.\n\t * @return {boolean} Whether this node is the ancestor of {@code node}.\n\t */\n\tcontains(node) {\n\t\tlet current = node.getParent();\n\t\twhile (current) {\n\t\t\tif (current === this) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcurrent = current.getParent();\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * @return {!Array<TreeNode>} All ancestor nodes in bottom-up order.\n\t */\n\tgetAncestors() {\n\t\tlet ancestors = [];\n\t\tlet node = this.getParent();\n\t\twhile (node) {\n\t\t\tancestors.push(node);\n\t\t\tnode = node.getParent();\n\t\t}\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Gets the child node of this node at the given index.\n\t * @param {number} index Child index.\n\t * @return {?TreeNode} The node at the given index\n\t * or null if not found.\n\t */\n\tgetChildAt(index) {\n\t\treturn this.getChildren()[index] || null;\n\t}\n\n\t/**\n\t * @return {?Array<!TreeNode>} Child nodes or null in case of leaf node.\n\t */\n\tgetChildren() {\n\t\treturn this.children_ || TreeNode.EMPTY_ARRAY;\n\t}\n\n\t/**\n\t * @return {number} The number of children.\n\t */\n\tgetChildCount() {\n\t\treturn this.getChildren().length;\n\t}\n\n\t/**\n\t * @return {number} The number of ancestors of the node.\n\t */\n\tgetDepth() {\n\t\tlet depth = 0;\n\t\tlet node = this;\n\t\twhile (node.getParent()) {\n\t\t\tdepth++;\n\t\t\tnode = node.getParent();\n\t\t}\n\t\treturn depth;\n\t}\n\n\t/**\n\t * @return {?TreeNode} Parent node or null if it has no parent.\n\t */\n\tgetParent() {\n\t\treturn this.parent_;\n\t}\n\n\t/**\n\t * @return {!TreeNode} The root of the tree structure, i.e. the farthest\n\t * ancestor of the node or the node itself if it has no parents.\n\t */\n\tgetRoot() {\n\t\tlet root = this;\n\t\twhile (root.getParent()) {\n\t\t\troot = root.getParent();\n\t\t}\n\t\treturn root;\n\t}\n\n\t/**\n\t * Gets the value.\n\t * @return {V} The value.\n\t */\n\tgetValue() {\n\t\treturn this.value_;\n\t}\n\n\t/**\n\t * @return {boolean} Whether the node is a leaf node.\n\t */\n\tisLeaf() {\n\t\treturn !this.getChildCount();\n\t}\n\n\t/**\n\t * Removes the given child node of this node.\n\t * @param {TreeNode} child The node to remove.\n\t * @return {TreeNode} The removed node if any, null otherwise.\n\t */\n\tremoveChild(child) {\n\t\tif (array.remove(this.getChildren(), child)) {\n\t\t\treturn child;\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Sets the parent node of this node. The callers must ensure that the\n\t * parent node and only that has this node among its children.\n\t * @param {TreeNode} parent The parent to set. If null, the node will be\n\t * detached from the tree.\n\t * @protected\n\t */\n\tsetParent(parent) {\n\t\tthis.parent_ = parent;\n\t}\n\n\t/**\n\t * Traverses the subtree. The first callback starts with this node,\n\t * and visits the descendant nodes depth-first, in preorder.\n\t * The second callback, starts with deepest child then visits\n\t * the ancestor nodes depth-first, in postorder. E.g.\n\t *\n\t * \t A\n\t * / \\\n\t * B C\n\t * / / \\\n\t * D E F\n\t *\n\t * preorder -> ['A', 'B', 'D', 'C', 'E', 'F']\n\t * postorder -> ['D', 'B', 'E', 'F', 'C', 'A']\n\t *\n\t * @param {function=} opt_preorderFn The callback to execute when visiting a node.\n\t * @param {function=} opt_postorderFn The callback to execute before leaving a node.\n\t */\n\ttraverse(opt_preorderFn, opt_postorderFn) {\n\t\tif (opt_preorderFn) {\n\t\t\topt_preorderFn(this);\n\t\t}\n\t\tthis.getChildren().forEach((child) => child.traverse(opt_preorderFn, opt_postorderFn));\n\t\tif (opt_postorderFn) {\n\t\t\topt_postorderFn(this);\n\t\t}\n\t}\n\n}\n\n/**\n * Constant for empty array to avoid unnecessary allocations.\n * @private\n */\nTreeNode.EMPTY_ARRAY = [];\n\n/**\n * Asserts that child has no parent.\n * @param {TreeNode} child A child.\n * @private\n */\nconst assertChildHasNoParent = function(child) {\n\tif (child.getParent()) {\n\t\tthrow new Error('Cannot add child with parent.');\n\t}\n};\n\nexport default TreeNode;\n","'use strict';\n\nimport { isDef, string } from 'metal';\nimport parse from './parse';\nimport { MultiMap } from 'metal-structs';\n\nvar parseFn_ = parse;\n\nclass Uri {\n\n\t/**\n\t * This class contains setters and getters for the parts of the URI.\n\t * The following figure displays an example URIs and their component parts.\n\t *\n\t * path\n\t *\t ┌───┴────┐\n\t *\t abc://example.com:123/path/data?key=value#fragid1\n\t *\t └┬┘ └────┬────┘ └┬┘ └───┬───┘ └──┬──┘\n\t * protocol hostname port search hash\n\t * └──────┬───────┘\n\t * host\n\t *\n\t * @param {*=} opt_uri Optional string URI to parse\n\t * @constructor\n\t */\n\tconstructor(opt_uri = '') {\n\t\tthis.url = Uri.parse(this.maybeAddProtocolAndHostname_(opt_uri));\n\t}\n\n\t/**\n\t * Adds parameters to uri from a <code>MultiMap</code> as source.\n\t * @param {MultiMap} multimap The <code>MultiMap</code> containing the\n\t * parameters.\n\t * @protected\n\t * @chainable\n\t */\n\taddParametersFromMultiMap(multimap) {\n\t\tmultimap.names().forEach((name) => {\n\t\t\tmultimap.getAll(name).forEach((value) => {\n\t\t\t\tthis.addParameterValue(name, value);\n\t\t\t});\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds the value of the named query parameters.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value. Will be explicitly casted to String.\n\t * @chainable\n\t */\n\taddParameterValue(name, value) {\n\t\tthis.ensureQueryInitialized_();\n\t\tif (isDef(value)) {\n\t\t\tvalue = String(value);\n\t\t}\n\t\tthis.query.add(name, value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds the values of the named query parameter.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value.\n\t * @chainable\n\t */\n\taddParameterValues(name, values) {\n\t\tvalues.forEach((value) => this.addParameterValue(name, value));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Ensures query internal map is initialized and synced with initial value\n\t * extracted from URI search part.\n\t * @protected\n\t */\n\tensureQueryInitialized_() {\n\t\tif (this.query) {\n\t\t\treturn;\n\t\t}\n\t\tthis.query = new MultiMap();\n\t\tvar search = this.url.search;\n\t\tif (search) {\n\t\t\tsearch.substring(1).split('&').forEach((param) => {\n\t\t\t\tvar [key, value] = param.split('=');\n\t\t\t\tif (isDef(value)) {\n\t\t\t\t\tvalue = Uri.urlDecode(value);\n\t\t\t\t}\n\t\t\t\tthis.addParameterValue(key, value);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets the hash part of uri.\n\t * @return {string}\n\t */\n\tgetHash() {\n\t\treturn this.url.hash || '';\n\t}\n\n\t/**\n\t * Gets the host part of uri. E.g. <code>[hostname]:[port]</code>.\n\t * @return {string}\n\t */\n\tgetHost() {\n\t\tvar host = this.getHostname();\n\t\tif (host) {\n\t\t\tvar port = this.getPort();\n\t\t\tif (port && port !== '80') {\n\t\t\t\thost += ':' + port;\n\t\t\t}\n\t\t}\n\t\treturn host;\n\t}\n\n\t/**\n\t * Gets the hostname part of uri without protocol and port.\n\t * @return {string}\n\t */\n\tgetHostname() {\n\t\tvar hostname = this.url.hostname;\n\t\tif (hostname === Uri.HOSTNAME_PLACEHOLDER) {\n\t\t\treturn '';\n\t\t}\n\t\treturn hostname;\n\t}\n\n\t/**\n\t * Gets the origin part of uri. E.g. <code>http://[hostname]:[port]</code>.\n\t * @return {string}\n\t */\n\tgetOrigin() {\n\t\tvar host = this.getHost();\n\t\tif (host) {\n\t\t\treturn this.getProtocol() + '//' + host;\n\t\t}\n\t\treturn '';\n\t}\n\n\t/**\n\t * Returns the first value for a given parameter or undefined if the given\n\t * parameter name does not appear in the query string.\n\t * @param {string} paramName Unescaped parameter name.\n\t * @return {string|undefined} The first value for a given parameter or\n\t * undefined if the given parameter name does not appear in the query\n\t * string.\n\t */\n\tgetParameterValue(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.get(name);\n\t}\n\n\t/**\n\t * Returns the value<b>s</b> for a given parameter as a list of decoded\n\t * query parameter values.\n\t * @param {string} name The parameter to get values for.\n\t * @return {!Array<?>} The values for a given parameter as a list of decoded\n\t * query parameter values.\n\t */\n\tgetParameterValues(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.getAll(name);\n\t}\n\n\t/**\n\t * Returns the name<b>s</b> of the parameters.\n\t * @return {!Array<string>} The names for the parameters as a list of\n\t * strings.\n\t */\n\tgetParameterNames() {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.names();\n\t}\n\n\t/**\n\t * Gets the function currently being used to parse URIs.\n\t * @return {!function()}\n\t */\n\tstatic getParseFn() {\n\t\treturn parseFn_;\n\t}\n\n\t/**\n\t * Gets the pathname part of uri.\n\t * @return {string}\n\t */\n\tgetPathname() {\n\t\treturn this.url.pathname;\n\t}\n\n\t/**\n\t * Gets the port number part of uri as string.\n\t * @return {string}\n\t */\n\tgetPort() {\n\t\treturn this.url.port;\n\t}\n\n\t/**\n\t * Gets the protocol part of uri. E.g. <code>http:</code>.\n\t * @return {string}\n\t */\n\tgetProtocol() {\n\t\treturn this.url.protocol;\n\t}\n\n\t/**\n\t * Gets the search part of uri. Search value is retrieved from query\n\t * parameters.\n\t * @return {string}\n\t */\n\tgetSearch() {\n\t\tvar search = '';\n\t\tvar querystring = '';\n\t\tthis.getParameterNames().forEach((name) => {\n\t\t\tthis.getParameterValues(name).forEach((value) => {\n\t\t\t\tquerystring += name;\n\t\t\t\tif (isDef(value)) {\n\t\t\t\t\tquerystring += '=' + encodeURIComponent(value);\n\t\t\t\t}\n\t\t\t\tquerystring += '&';\n\t\t\t});\n\t\t});\n\t\tquerystring = querystring.slice(0, -1);\n\t\tif (querystring) {\n\t\t\tsearch += '?' + querystring;\n\t\t}\n\t\treturn search;\n\t}\n\n\t/**\n\t * Checks if uri contains the parameter.\n\t * @param {string} name\n\t * @return {boolean}\n\t */\n\thasParameter(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\treturn this.query.contains(name);\n\t}\n\n\t/**\n\t * Makes this URL unique by adding a random param to it. Useful for avoiding\n\t * cache.\n\t */\n\tmakeUnique() {\n\t\tthis.setParameterValue(Uri.RANDOM_PARAM, string.getRandomString());\n\t\treturn this;\n\t}\n\n\t/**\n\t * Maybe adds protocol and a hostname placeholder on a parial URI if needed.\n\t * Relevent for compatibility with <code>URL</code> native object.\n\t * @param {string=} opt_uri\n\t * @return {string} URI with protocol and hostname placeholder.\n\t */\n\tmaybeAddProtocolAndHostname_(opt_uri) {\n\t\tvar url = opt_uri;\n\t\tif (opt_uri.indexOf('://') === -1 &&\n\t\t\topt_uri.indexOf('javascript:') !== 0) { // jshint ignore:line\n\n\t\t\turl = Uri.DEFAULT_PROTOCOL;\n\t\t\tif (opt_uri[0] !== '/' || opt_uri[1] !== '/') {\n\t\t\t\turl += '//';\n\t\t\t}\n\n\t\t\tswitch (opt_uri.charAt(0)) {\n\t\t\t\tcase '.':\n\t\t\t\tcase '?':\n\t\t\t\tcase '#':\n\t\t\t\t\turl += Uri.HOSTNAME_PLACEHOLDER;\n\t\t\t\t\turl += '/';\n\t\t\t\t\turl += opt_uri;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '':\n\t\t\t\tcase '/':\n\t\t\t\t\tif (opt_uri[1] !== '/') {\n\t\t\t\t\t\turl += Uri.HOSTNAME_PLACEHOLDER;\n\t\t\t\t\t}\n\t\t\t\t\turl += opt_uri;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\turl += opt_uri;\n\t\t\t}\n\t\t}\n\t\treturn url;\n\t}\n\n\t/**\n\t * Parses the given uri string into an object.\n\t * @param {*=} opt_uri Optional string URI to parse\n\t */\n\tstatic parse(opt_uri) {\n\t\treturn parseFn_(opt_uri);\n\t}\n\n\t/**\n\t * Removes the named query parameter.\n\t * @param {string} name The parameter to remove.\n\t * @chainable\n\t */\n\tremoveParameter(name) {\n\t\tthis.ensureQueryInitialized_();\n\t\tthis.query.remove(name);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes uniqueness parameter of the uri.\n\t * @chainable\n\t */\n\tremoveUnique() {\n\t\tthis.removeParameter(Uri.RANDOM_PARAM);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the hash.\n\t * @param {string} hash\n\t * @chainable\n\t */\n\tsetHash(hash) {\n\t\tthis.url.hash = hash;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the hostname.\n\t * @param {string} hostname\n\t * @chainable\n\t */\n\tsetHostname(hostname) {\n\t\tthis.url.hostname = hostname;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the value of the named query parameters, clearing previous values\n\t * for that key.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value.\n\t * @chainable\n\t */\n\tsetParameterValue(name, value) {\n\t\tthis.removeParameter(name);\n\t\tthis.addParameterValue(name, value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the values of the named query parameters, clearing previous values\n\t * for that key.\n\t * @param {string} key The parameter to set.\n\t * @param {*} value The new value.\n\t * @chainable\n\t */\n\tsetParameterValues(name, values) {\n\t\tthis.removeParameter(name);\n\t\tvalues.forEach((value) => this.addParameterValue(name, value));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the pathname.\n\t * @param {string} pathname\n\t * @chainable\n\t */\n\tsetPathname(pathname) {\n\t\tthis.url.pathname = pathname;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the port number.\n\t * @param {*} port Port number.\n\t * @chainable\n\t */\n\tsetPort(port) {\n\t\tthis.url.port = port;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the function that will be used for parsing the original string uri\n\t * into an object.\n\t * @param {!function()} parseFn\n\t */\n\tstatic setParseFn(parseFn) {\n\t\tparseFn_ = parseFn;\n\t}\n\n\t/**\n\t * Sets the protocol. If missing <code>http:</code> is used as default.\n\t * @param {string} protocol\n\t * @chainable\n\t */\n\tsetProtocol(protocol) {\n\t\tthis.url.protocol = protocol;\n\t\tif (this.url.protocol[this.url.protocol.length - 1] !== ':') {\n\t\t\tthis.url.protocol += ':';\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * @return {string} The string form of the url.\n\t * @override\n\t */\n\ttoString() {\n\t\tvar href = '';\n\t\tvar host = this.getHost();\n\t\tif (host) {\n\t\t\thref += this.getProtocol() + '//';\n\t\t}\n\t\thref += host + this.getPathname() + this.getSearch() + this.getHash();\n\t\treturn href;\n\t}\n\n\t/**\n\t * Joins the given paths.\n\t * @param {string} basePath\n\t * @param {...string} ...paths Any number of paths to be joined with the base url.\n\t * @static\n\t */\n\tstatic joinPaths(basePath, ...paths) {\n\t\tif (basePath.charAt(basePath.length - 1) === '/') {\n\t\t\tbasePath = basePath.substring(0, basePath.length - 1);\n\t\t}\n\t\tpaths = paths.map(path => path.charAt(0) === '/' ? path.substring(1) : path);\n\t\treturn [basePath].concat(paths).join('/').replace(/\\/$/, '');\n\t}\n\n\t/**\n\t * URL-decodes the string. We need to specially handle '+'s because\n\t * the javascript library doesn't convert them to spaces.\n\t * @param {string} str The string to url decode.\n\t * @return {string} The decoded {@code str}.\n\t */\n\tstatic urlDecode(str) {\n\t\treturn decodeURIComponent(str.replace(/\\+/g, ' '));\n\t}\n\n}\n\n/**\n * Default protocol value.\n * @type {string}\n * @default http:\n * @static\n */\nconst isSecure = () =>\n\t(typeof window !== 'undefined' &&\n\t\twindow.location &&\n\t\twindow.location.protocol &&\n\t\twindow.location.protocol.indexOf('https') === 0);\n\nUri.DEFAULT_PROTOCOL = isSecure() ? 'https:' : 'http:';\n\n/**\n * Hostname placeholder. Relevant to internal usage only.\n * @type {string}\n * @static\n */\nUri.HOSTNAME_PLACEHOLDER = 'hostname' + Date.now();\n\n/**\n * Name used by the param generated by `makeUnique`.\n * @type {string}\n * @static\n */\nUri.RANDOM_PARAM = 'zx';\n\nexport default Uri;\n","'use strict';\n\nimport { exitDocument } from 'metal-dom';\nimport globals from '../globals/globals';\nimport Uri from 'metal-uri';\n\n/**\n * A collection of static utility functions.\n * @const\n */\nclass utils {\n\n\t/**\n\t * Copies attributes form source node to target node.\n\t * @return {void}\n\t * @static\n\t */\n\tstatic copyNodeAttributes(source, target) {\n\t\tArray.prototype.slice.call(source.attributes).forEach((attribute) => target.setAttribute(attribute.name, attribute.value));\n\t}\n\n\t/**\n\t * Gets the current browser path including hashbang.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getCurrentBrowserPath() {\n\t\treturn this.getCurrentBrowserPathWithoutHash() + globals.window.location.hash;\n\t}\n\n\t/**\n\t * Gets the current browser path excluding hashbang.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getCurrentBrowserPathWithoutHash() {\n\t\treturn globals.window.location.pathname + globals.window.location.search;\n\t}\n\n\t/**\n\t * Gets the given node offset coordinates.\n\t * @return {!object}\n\t * @static\n\t */\n\tstatic getNodeOffset(node) {\n\t\tlet [offsetLeft, offsetTop] = [0, 0];\n\t\tdo {\n\t\t\toffsetLeft += node.offsetLeft;\n\t\t\toffsetTop += node.offsetTop;\n\t\t\tnode = node.offsetParent;\n\t\t} while (node);\n\t\treturn {\n\t\t\toffsetLeft,\n\t\t\toffsetTop\n\t\t};\n\t}\n\n\t/**\n\t * Extracts the path part of an url.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getUrlPath(url) {\n\t\tvar uri = new Uri(url);\n\t\treturn uri.getPathname() + uri.getSearch() + uri.getHash();\n\t}\n\n\t/**\n\t * Extracts the path part of an url without hashbang.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getUrlPathWithoutHash(url) {\n\t\tvar uri = new Uri(url);\n\t\treturn uri.getPathname() + uri.getSearch();\n\t}\n\n\t/**\n\t * Extracts the path part of an url without hashbang and query search.\n\t * @return {!string}\n\t * @static\n\t */\n\tstatic getUrlPathWithoutHashAndSearch(url) {\n\t\tvar uri = new Uri(url);\n\t\treturn uri.getPathname();\n\t}\n\n\t/**\n\t * Checks if url is in the same browser current url excluding the hashbang.\n\t * @param {!string} url\n\t * @return {boolean}\n\t * @static\n\t */\n\tstatic isCurrentBrowserPath(url) {\n\t\tif (url) {\n\t\t\tconst currentBrowserPath = this.getCurrentBrowserPathWithoutHash();\n\t\t\t// the getUrlPath will create a Uri and will normalize the path and\n\t\t\t// remove the trailling '/' for properly comparing paths.\n\t\t\treturn utils.getUrlPathWithoutHash(url) === this.getUrlPath(currentBrowserPath);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns true if HTML5 History api is supported.\n\t * @return {boolean}\n\t * @static\n\t */\n\tstatic isHtml5HistorySupported() {\n\t\treturn !!(globals.window.history && globals.window.history.pushState);\n\t}\n\n\t/**\n\t * Checks if a given url is a valid http(s) uri and returns the formed Uri\n\t * or false if the parsing failed\n\t * @return {Uri|boolean}\n\t * @static\n\t */\n\tstatic isWebUri(url) {\n\t\ttry {\n\t\t\treturn new Uri(url);\n\t\t} catch (err) {\n\t\t\tconsole.error(`${err.message} ${url}`);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Removes all attributes form node.\n\t * @return {void}\n\t * @static\n\t */\n\tstatic clearNodeAttributes(node) {\n\t\tArray.prototype.slice.call(node.attributes).forEach((attribute) => node.removeAttribute(attribute.name));\n\t}\n\n\t/**\n\t * Remove elements from the document.\n\t * @param {!Array<Element>} elements\n\t */\n\tstatic removeElementsFromDocument(elements) {\n\t\telements.forEach((element) => exitDocument(element));\n\t}\n\n\t/**\n\t* Removes trailing slash in path.\n\t* @param {!string}\n\t* @return {string}\n\t*/\n\tstatic removePathTrailingSlash(path) {\n\t\tvar length = path ? path.length : 0;\n\t\tif (length > 1 && path[length - 1] === '/') {\n\t\t\tpath = path.substr(0, length - 1);\n\t\t}\n\t\treturn path;\n\t}\n\n\t/**\n\t * Adds a random suffix to the href attribute of the element.\n\t * @param {!element} element\n\t * @return {element}\n\t */\n\tstatic setElementWithRandomHref(element) {\n\t\telement.href = element.href + '?q=' + Math.random();\n\t\treturn element;\n\t}\n\n\t/**\n\t * Overrides document referrer\n\t * @param {string} referrer\n\t * @static\n\t */\n\tstatic setReferrer(referrer) {\n\t\tObject.defineProperty(globals.document, 'referrer', {\n\t\t\tconfigurable: true,\n\t\t\tget: function() {\n\t\t\t\treturn referrer;\n\t\t\t}\n\t\t});\n\t}\n}\n\nexport default utils;\n","'use strict';\n\nexport default {\n\tbasePath: 'data-senna-base-path',\n\tlinkSelector: 'data-senna-link-selector',\n\tloadingCssClass: 'data-senna-loading-css-class',\n\tsenna: 'data-senna',\n\tdispatch: 'data-senna-dispatch',\n\tsurface: 'data-senna-surface',\n\tupdateScrollPosition: 'data-senna-update-scroll-position'\n};","/*!\n * Promises polyfill from Google's Closure Library.\n *\n * Copyright 2013 The Closure Library Authors. All Rights Reserved.\n *\n * NOTE(eduardo): Promise support is not ready on all supported browsers,\n * therefore metal-promise is temporarily using Google's promises as polyfill.\n * It supports cancellable promises and has clean and fast implementation.\n */\n\n'use strict';\n\nimport { isDef, isFunction, isObject } from 'metal';\nimport { async } from 'metal';\n\n/**\n * Provides a more strict interface for Thenables in terms of\n * http://promisesaplus.com for interop with {@see CancellablePromise}.\n *\n * @interface\n * @extends {IThenable.<TYPE>}\n * @template TYPE\n */\nvar Thenable = function() {};\n\n/**\n * Adds callbacks that will operate on the result of the Thenable, returning a\n * new child Promise.\n *\n * If the Thenable is fulfilled, the {@code onFulfilled} callback will be\n * invoked with the fulfillment value as argument, and the child Promise will\n * be fulfilled with the return value of the callback. If the callback throws\n * an exception, the child Promise will be rejected with the thrown value\n * instead.\n *\n * If the Thenable is rejected, the {@code onRejected} callback will be invoked\n * with the rejection reason as argument, and the child Promise will be rejected\n * with the return value of the callback or thrown value.\n *\n * @param {?(function(this:THIS, TYPE):\n * (RESULT|IThenable.<RESULT>|Thenable))=} opt_onFulfilled A\n * function that will be invoked with the fulfillment value if the Promise\n * is fullfilled.\n * @param {?(function(*): *)=} opt_onRejected A function that will be invoked\n * with the rejection reason if the Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * with the default this.\n * @return {!CancellablePromise.<RESULT>} A new Promise that will receive the\n * result of the fulfillment or rejection callback.\n * @template RESULT,THIS\n */\nThenable.prototype.then = function() {};\n\n\n/**\n * An expando property to indicate that an object implements\n * {@code Thenable}.\n *\n * {@see addImplementation}.\n *\n * @const\n */\nThenable.IMPLEMENTED_BY_PROP = '$goog_Thenable';\n\n\n/**\n * Marks a given class (constructor) as an implementation of Thenable, so\n * that we can query that fact at runtime. The class must have already\n * implemented the interface.\n * Exports a 'then' method on the constructor prototype, so that the objects\n * also implement the extern {@see Thenable} interface for interop with\n * other Promise implementations.\n * @param {function(new:Thenable,...[?])} ctor The class constructor. The\n * corresponding class must have already implemented the interface.\n */\nThenable.addImplementation = function(ctor) {\n ctor.prototype.then = ctor.prototype.then;\n ctor.prototype.$goog_Thenable = true;\n};\n\n\n/**\n * @param {*} object\n * @return {boolean} Whether a given instance implements {@code Thenable}.\n * The class/superclass of the instance must call {@code addImplementation}.\n */\nThenable.isImplementedBy = function(object) {\n if (!object) {\n return false;\n }\n try {\n return !!object.$goog_Thenable;\n } catch (e) {\n // Property access seems to be forbidden.\n return false;\n }\n};\n\n\n/**\n * Like bind(), except that a 'this object' is not required. Useful when the\n * target function is already bound.\n *\n * Usage:\n * var g = partial(f, arg1, arg2);\n * g(arg3, arg4);\n *\n * @param {Function} fn A function to partially apply.\n * @param {...*} var_args Additional arguments that are partially applied to fn.\n * @return {!Function} A partially-applied form of the function bind() was\n * invoked as a method of.\n */\nvar partial = function(fn) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function() {\n // Clone the array (with slice()) and append additional arguments\n // to the existing arguments.\n var newArgs = args.slice();\n newArgs.push.apply(newArgs, arguments);\n return fn.apply(this, newArgs);\n };\n};\n\n/**\n * Promises provide a result that may be resolved asynchronously. A Promise may\n * be resolved by being fulfilled or rejected with a value, which will be known\n * as the fulfillment value or the rejection reason. Whether fulfilled or\n * rejected, the Promise result is immutable once it is set.\n *\n * Promises may represent results of any type, including undefined. Rejection\n * reasons are typically Errors, but may also be of any type. Closure Promises\n * allow for optional type annotations that enforce that fulfillment values are\n * of the appropriate types at compile time.\n *\n * The result of a Promise is accessible by calling {@code then} and registering\n * {@code onFulfilled} and {@code onRejected} callbacks. Once the Promise\n * resolves, the relevant callbacks are invoked with the fulfillment value or\n * rejection reason as argument. Callbacks are always invoked in the order they\n * were registered, even when additional {@code then} calls are made from inside\n * another callback. A callback is always run asynchronously sometime after the\n * scope containing the registering {@code then} invocation has returned.\n *\n * If a Promise is resolved with another Promise, the first Promise will block\n * until the second is resolved, and then assumes the same result as the second\n * Promise. This allows Promises to depend on the results of other Promises,\n * linking together multiple asynchronous operations.\n *\n * This implementation is compatible with the Promises/A+ specification and\n * passes that specification's conformance test suite. A Closure Promise may be\n * resolved with a Promise instance (or sufficiently compatible Promise-like\n * object) created by other Promise implementations. From the specification,\n * Promise-like objects are known as \"Thenables\".\n *\n * @see http://promisesaplus.com/\n *\n * @param {function(\n * this:RESOLVER_CONTEXT,\n * function((TYPE|IThenable.<TYPE>|Thenable)),\n * function(*)): void} resolver\n * Initialization function that is invoked immediately with {@code resolve}\n * and {@code reject} functions as arguments. The Promise is resolved or\n * rejected with the first argument passed to either function.\n * @param {RESOLVER_CONTEXT=} opt_context An optional context for executing the\n * resolver function. If unspecified, the resolver function will be executed\n * in the default scope.\n * @constructor\n * @struct\n * @final\n * @implements {Thenable.<TYPE>}\n * @template TYPE,RESOLVER_CONTEXT\n */\nvar CancellablePromise = function(resolver, opt_context) {\n /**\n * The internal state of this Promise. Either PENDING, FULFILLED, REJECTED, or\n * BLOCKED.\n * @private {CancellablePromise.State_}\n */\n this.state_ = CancellablePromise.State_.PENDING;\n\n /**\n * The resolved result of the Promise. Immutable once set with either a\n * fulfillment value or rejection reason.\n * @private {*}\n */\n this.result_ = undefined;\n\n /**\n * For Promises created by calling {@code then()}, the originating parent.\n * @private {CancellablePromise}\n */\n this.parent_ = null;\n\n /**\n * The list of {@code onFulfilled} and {@code onRejected} callbacks added to\n * this Promise by calls to {@code then()}.\n * @private {Array.<CancellablePromise.CallbackEntry_>}\n */\n this.callbackEntries_ = null;\n\n /**\n * Whether the Promise is in the queue of Promises to execute.\n * @private {boolean}\n */\n this.executing_ = false;\n\n if (CancellablePromise.UNHANDLED_REJECTION_DELAY > 0) {\n /**\n * A timeout ID used when the {@code UNHANDLED_REJECTION_DELAY} is greater\n * than 0 milliseconds. The ID is set when the Promise is rejected, and\n * cleared only if an {@code onRejected} callback is invoked for the\n * Promise (or one of its descendants) before the delay is exceeded.\n *\n * If the rejection is not handled before the timeout completes, the\n * rejection reason is passed to the unhandled rejection handler.\n * @private {number}\n */\n this.unhandledRejectionId_ = 0;\n } else if (CancellablePromise.UNHANDLED_REJECTION_DELAY === 0) {\n /**\n * When the {@code UNHANDLED_REJECTION_DELAY} is set to 0 milliseconds, a\n * boolean that is set if the Promise is rejected, and reset to false if an\n * {@code onRejected} callback is invoked for the Promise (or one of its\n * descendants). If the rejection is not handled before the next timestep,\n * the rejection reason is passed to the unhandled rejection handler.\n * @private {boolean}\n */\n this.hadUnhandledRejection_ = false;\n }\n\n try {\n var self = this;\n resolver.call(\n opt_context, function(value) {\n self.resolve_(CancellablePromise.State_.FULFILLED, value);\n }, function(reason) {\n self.resolve_(CancellablePromise.State_.REJECTED, reason);\n });\n } catch (e) {\n this.resolve_(CancellablePromise.State_.REJECTED, e);\n }\n};\n\n/**\n * The delay in milliseconds before a rejected Promise's reason is passed to\n * the rejection handler. By default, the rejection handler rethrows the\n * rejection reason so that it appears in the developer console or\n * {@code window.onerror} handler.\n * Rejections are rethrown as quickly as possible by default. A negative value\n * disables rejection handling entirely.\n * @type {number}\n */\nCancellablePromise.UNHANDLED_REJECTION_DELAY = 0;\n\n\n/**\n * The possible internal states for a Promise. These states are not directly\n * observable to external callers.\n * @enum {number}\n * @private\n */\nCancellablePromise.State_ = {\n /** The Promise is waiting for resolution. */\n PENDING: 0,\n\n /** The Promise is blocked waiting for the result of another Thenable. */\n BLOCKED: 1,\n\n /** The Promise has been resolved with a fulfillment value. */\n FULFILLED: 2,\n\n /** The Promise has been resolved with a rejection reason. */\n REJECTED: 3\n};\n\n\n/**\n * Typedef for entries in the callback chain. Each call to {@code then},\n * {@code thenCatch}, or {@code thenAlways} creates an entry containing the\n * functions that may be invoked once the Promise is resolved.\n *\n * @typedef {{\n * child: CancellablePromise,\n * onFulfilled: function(*),\n * onRejected: function(*)\n * }}\n * @private\n */\nCancellablePromise.CallbackEntry_ = null;\n\n\n/**\n * @param {(TYPE|Thenable.<TYPE>|Thenable)=} opt_value\n * @return {!CancellablePromise.<TYPE>} A new Promise that is immediately resolved\n * with the given value.\n * @template TYPE\n */\nCancellablePromise.resolve = function(opt_value) {\n return new CancellablePromise(function(resolve) {\n resolve(opt_value);\n });\n};\n\n\n/**\n * @param {*=} opt_reason\n * @return {!CancellablePromise} A new Promise that is immediately rejected with the\n * given reason.\n */\nCancellablePromise.reject = function(opt_reason) {\n return new CancellablePromise(function(resolve, reject) {\n reject(opt_reason);\n });\n};\n\n\n/**\n * @param {!Array.<!(Thenable.<TYPE>|Thenable)>} promises\n * @return {!CancellablePromise.<TYPE>} A Promise that receives the result of the\n * first Promise (or Promise-like) input to complete.\n * @template TYPE\n */\nCancellablePromise.race = function(promises) {\n return new CancellablePromise(function(resolve, reject) {\n if (!promises.length) {\n resolve(undefined);\n }\n for (var i = 0, promise; (promise = promises[i]); i++) {\n promise.then(resolve, reject);\n }\n });\n};\n\n\n/**\n * @param {!Array.<!(Thenable.<TYPE>|Thenable)>} promises\n * @return {!CancellablePromise.<!Array.<TYPE>>} A Promise that receives a list of\n * every fulfilled value once every input Promise (or Promise-like) is\n * successfully fulfilled, or is rejected by the first rejection result.\n * @template TYPE\n */\nCancellablePromise.all = function(promises) {\n return new CancellablePromise(function(resolve, reject) {\n var toFulfill = promises.length;\n var values = [];\n\n if (!toFulfill) {\n resolve(values);\n return;\n }\n\n var onFulfill = function(index, value) {\n toFulfill--;\n values[index] = value;\n if (toFulfill === 0) {\n resolve(values);\n }\n };\n\n var onReject = function(reason) {\n reject(reason);\n };\n\n for (var i = 0, promise; (promise = promises[i]); i++) {\n promise.then(partial(onFulfill, i), onReject);\n }\n });\n};\n\n\n/**\n * @param {!Array.<!(Thenable.<TYPE>|Thenable)>} promises\n * @return {!CancellablePromise.<TYPE>} A Promise that receives the value of\n * the first input to be fulfilled, or is rejected with a list of every\n * rejection reason if all inputs are rejected.\n * @template TYPE\n */\nCancellablePromise.firstFulfilled = function(promises) {\n return new CancellablePromise(function(resolve, reject) {\n var toReject = promises.length;\n var reasons = [];\n\n if (!toReject) {\n resolve(undefined);\n return;\n }\n\n var onFulfill = function(value) {\n resolve(value);\n };\n\n var onReject = function(index, reason) {\n toReject--;\n reasons[index] = reason;\n if (toReject === 0) {\n reject(reasons);\n }\n };\n\n for (var i = 0, promise; (promise = promises[i]); i++) {\n promise.then(onFulfill, partial(onReject, i));\n }\n });\n};\n\n\n/**\n * Adds callbacks that will operate on the result of the Promise, returning a\n * new child Promise.\n *\n * If the Promise is fulfilled, the {@code onFulfilled} callback will be invoked\n * with the fulfillment value as argument, and the child Promise will be\n * fulfilled with the return value of the callback. If the callback throws an\n * exception, the child Promise will be rejected with the thrown value instead.\n *\n * If the Promise is rejected, the {@code onRejected} callback will be invoked\n * with the rejection reason as argument, and the child Promise will be rejected\n * with the return value (or thrown value) of the callback.\n *\n * @override\n */\nCancellablePromise.prototype.then = function(opt_onFulfilled, opt_onRejected, opt_context) {\n return this.addChildPromise_(\n isFunction(opt_onFulfilled) ? opt_onFulfilled : null,\n isFunction(opt_onRejected) ? opt_onRejected : null,\n opt_context);\n};\nThenable.addImplementation(CancellablePromise);\n\n\n/**\n * Adds a callback that will be invoked whether the Promise is fulfilled or\n * rejected. The callback receives no argument, and no new child Promise is\n * created. This is useful for ensuring that cleanup takes place after certain\n * asynchronous operations. Callbacks added with {@code thenAlways} will be\n * executed in the same order with other calls to {@code then},\n * {@code thenAlways}, or {@code thenCatch}.\n *\n * Since it does not produce a new child Promise, cancellation propagation is\n * not prevented by adding callbacks with {@code thenAlways}. A Promise that has\n * a cleanup handler added with {@code thenAlways} will be canceled if all of\n * its children created by {@code then} (or {@code thenCatch}) are canceled.\n *\n * @param {function(this:THIS): void} onResolved A function that will be invoked\n * when the Promise is resolved.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * in the global scope.\n * @return {!CancellablePromise.<TYPE>} This Promise, for chaining additional calls.\n * @template THIS\n */\nCancellablePromise.prototype.thenAlways = function(onResolved, opt_context) {\n var callback = function() {\n try {\n // Ensure that no arguments are passed to onResolved.\n onResolved.call(opt_context);\n } catch (err) {\n CancellablePromise.handleRejection_.call(null, err);\n }\n };\n\n this.addCallbackEntry_({\n child: null,\n onRejected: callback,\n onFulfilled: callback\n });\n return this;\n};\n\n\n/**\n * Adds a callback that will be invoked only if the Promise is rejected. This\n * is equivalent to {@code then(null, onRejected)}.\n *\n * @param {!function(this:THIS, *): *} onRejected A function that will be\n * invoked with the rejection reason if the Promise is rejected.\n * @param {THIS=} opt_context An optional context object that will be the\n * execution context for the callbacks. By default, functions are executed\n * in the global scope.\n * @return {!CancellablePromise} A new Promise that will receive the result of the\n * callback.\n * @template THIS\n */\nCancellablePromise.prototype.thenCatch = function(onRejected, opt_context) {\n return this.addChildPromise_(null, onRejected, opt_context);\n};\n\n/**\n * Alias of {@link CancellablePromise.prototype.thenCatch}\n */\nCancellablePromise.prototype.catch = CancellablePromise.prototype.thenCatch;\n\n\n/**\n * Cancels the Promise if it is still pending by rejecting it with a cancel\n * Error. No action is performed if the Promise is already resolved.\n *\n * All child Promises of the canceled Promise will be rejected with the same\n * cancel error, as with normal Promise rejection. If the Promise to be canceled\n * is the only child of a pending Promise, the parent Promise will also be\n * canceled. Cancellation may propagate upward through multiple generations.\n *\n * @param {string=} opt_message An optional debugging message for describing the\n * cancellation reason.\n */\nCancellablePromise.prototype.cancel = function(opt_message) {\n if (this.state_ === CancellablePromise.State_.PENDING) {\n async.run(function() {\n var err = new CancellablePromise.CancellationError(opt_message);\n err.IS_CANCELLATION_ERROR = true;\n this.cancelInternal_(err);\n }, this);\n }\n};\n\n\n/**\n * Cancels this Promise with the given error.\n *\n * @param {!Error} err The cancellation error.\n * @private\n */\nCancellablePromise.prototype.cancelInternal_ = function(err) {\n if (this.state_ === CancellablePromise.State_.PENDING) {\n if (this.parent_) {\n // Cancel the Promise and remove it from the parent's child list.\n this.parent_.cancelChild_(this, err);\n } else {\n this.resolve_(CancellablePromise.State_.REJECTED, err);\n }\n }\n};\n\n\n/**\n * Cancels a child Promise from the list of callback entries. If the Promise has\n * not already been resolved, reject it with a cancel error. If there are no\n * other children in the list of callback entries, propagate the cancellation\n * by canceling this Promise as well.\n *\n * @param {!CancellablePromise} childPromise The Promise to cancel.\n * @param {!Error} err The cancel error to use for rejecting the Promise.\n * @private\n */\nCancellablePromise.prototype.cancelChild_ = function(childPromise, err) {\n if (!this.callbackEntries_) {\n return;\n }\n var childCount = 0;\n var childIndex = -1;\n\n // Find the callback entry for the childPromise, and count whether there are\n // additional child Promises.\n for (var i = 0, entry; (entry = this.callbackEntries_[i]); i++) {\n var child = entry.child;\n if (child) {\n childCount++;\n if (child === childPromise) {\n childIndex = i;\n }\n if (childIndex >= 0 && childCount > 1) {\n break;\n }\n }\n }\n\n // If the child Promise was the only child, cancel this Promise as well.\n // Otherwise, reject only the child Promise with the cancel error.\n if (childIndex >= 0) {\n if (this.state_ === CancellablePromise.State_.PENDING && childCount === 1) {\n this.cancelInternal_(err);\n } else {\n var callbackEntry = this.callbackEntries_.splice(childIndex, 1)[0];\n this.executeCallback_(\n callbackEntry, CancellablePromise.State_.REJECTED, err);\n }\n }\n};\n\n\n/**\n * Adds a callback entry to the current Promise, and schedules callback\n * execution if the Promise has already been resolved.\n *\n * @param {CancellablePromise.CallbackEntry_} callbackEntry Record containing\n * {@code onFulfilled} and {@code onRejected} callbacks to execute after\n * the Promise is resolved.\n * @private\n */\nCancellablePromise.prototype.addCallbackEntry_ = function(callbackEntry) {\n if ((!this.callbackEntries_ || !this.callbackEntries_.length) &&\n (this.state_ === CancellablePromise.State_.FULFILLED ||\n this.state_ === CancellablePromise.State_.REJECTED)) {\n this.scheduleCallbacks_();\n }\n if (!this.callbackEntries_) {\n this.callbackEntries_ = [];\n }\n this.callbackEntries_.push(callbackEntry);\n};\n\n\n/**\n * Creates a child Promise and adds it to the callback entry list. The result of\n * the child Promise is determined by the state of the parent Promise and the\n * result of the {@code onFulfilled} or {@code onRejected} callbacks as\n * specified in the Promise resolution procedure.\n *\n * @see http://promisesaplus.com/#the__method\n *\n * @param {?function(this:THIS, TYPE):\n * (RESULT|CancellablePromise.<RESULT>|Thenable)} onFulfilled A callback that\n * will be invoked if the Promise is fullfilled, or null.\n * @param {?function(this:THIS, *): *} onRejected A callback that will be\n * invoked if the Promise is rejected, or null.\n * @param {THIS=} opt_context An optional execution context for the callbacks.\n * in the default calling context.\n * @return {!CancellablePromise} The child Promise.\n * @template RESULT,THIS\n * @private\n */\nCancellablePromise.prototype.addChildPromise_ = function(\nonFulfilled, onRejected, opt_context) {\n\n var callbackEntry = {\n child: null,\n onFulfilled: null,\n onRejected: null\n };\n\n callbackEntry.child = new CancellablePromise(function(resolve, reject) {\n // Invoke onFulfilled, or resolve with the parent's value if absent.\n callbackEntry.onFulfilled = onFulfilled ? function(value) {\n try {\n var result = onFulfilled.call(opt_context, value);\n resolve(result);\n } catch (err) {\n reject(err);\n }\n } : resolve;\n\n // Invoke onRejected, or reject with the parent's reason if absent.\n callbackEntry.onRejected = onRejected ? function(reason) {\n try {\n var result = onRejected.call(opt_context, reason);\n if (!isDef(result) && reason.IS_CANCELLATION_ERROR) {\n // Propagate cancellation to children if no other result is returned.\n reject(reason);\n } else {\n resolve(result);\n }\n } catch (err) {\n reject(err);\n }\n } : reject;\n });\n\n callbackEntry.child.parent_ = this;\n this.addCallbackEntry_(\n /** @type {CancellablePromise.CallbackEntry_} */ (callbackEntry));\n return callbackEntry.child;\n};\n\n\n/**\n * Unblocks the Promise and fulfills it with the given value.\n *\n * @param {TYPE} value\n * @private\n */\nCancellablePromise.prototype.unblockAndFulfill_ = function(value) {\n if (this.state_ !== CancellablePromise.State_.BLOCKED) {\n throw new Error('CancellablePromise is not blocked.');\n }\n this.state_ = CancellablePromise.State_.PENDING;\n this.resolve_(CancellablePromise.State_.FULFILLED, value);\n};\n\n\n/**\n * Unblocks the Promise and rejects it with the given rejection reason.\n *\n * @param {*} reason\n * @private\n */\nCancellablePromise.prototype.unblockAndReject_ = function(reason) {\n if (this.state_ !== CancellablePromise.State_.BLOCKED) {\n throw new Error('CancellablePromise is not blocked.');\n }\n this.state_ = CancellablePromise.State_.PENDING;\n this.resolve_(CancellablePromise.State_.REJECTED, reason);\n};\n\n\n/**\n * Attempts to resolve a Promise with a given resolution state and value. This\n * is a no-op if the given Promise has already been resolved.\n *\n * If the given result is a Thenable (such as another Promise), the Promise will\n * be resolved with the same state and result as the Thenable once it is itself\n * resolved.\n *\n * If the given result is not a Thenable, the Promise will be fulfilled or\n * rejected with that result based on the given state.\n *\n * @see http://promisesaplus.com/#the_promise_resolution_procedure\n *\n * @param {CancellablePromise.State_} state\n * @param {*} x The result to apply to the Promise.\n * @private\n */\nCancellablePromise.prototype.resolve_ = function(state, x) {\n if (this.state_ !== CancellablePromise.State_.PENDING) {\n return;\n }\n\n if (this === x) {\n state = CancellablePromise.State_.REJECTED;\n x = new TypeError('CancellablePromise cannot resolve to itself');\n\n } else if (Thenable.isImplementedBy(x)) {\n x = /** @type {!Thenable} */ (x);\n this.state_ = CancellablePromise.State_.BLOCKED;\n x.then(this.unblockAndFulfill_, this.unblockAndReject_, this);\n return;\n\n } else if (isObject(x)) {\n try {\n var then = x.then;\n if (isFunction(then)) {\n this.tryThen_(x, then);\n return;\n }\n } catch (e) {\n state = CancellablePromise.State_.REJECTED;\n x = e;\n }\n }\n\n this.result_ = x;\n this.state_ = state;\n this.scheduleCallbacks_();\n\n if (state === CancellablePromise.State_.REJECTED && !x.IS_CANCELLATION_ERROR) {\n CancellablePromise.addUnhandledRejection_(this, x);\n }\n};\n\n\n/**\n * Attempts to call the {@code then} method on an object in the hopes that it is\n * a Promise-compatible instance. This allows interoperation between different\n * Promise implementations, however a non-compliant object may cause a Promise\n * to hang indefinitely. If the {@code then} method throws an exception, the\n * dependent Promise will be rejected with the thrown value.\n *\n * @see http://promisesaplus.com/#point-70\n *\n * @param {Thenable} thenable An object with a {@code then} method that may be\n * compatible with the Promise/A+ specification.\n * @param {!Function} then The {@code then} method of the Thenable object.\n * @private\n */\nCancellablePromise.prototype.tryThen_ = function(thenable, then) {\n this.state_ = CancellablePromise.State_.BLOCKED;\n var promise = this;\n var called = false;\n\n var resolve = function(value) {\n if (!called) {\n called = true;\n promise.unblockAndFulfill_(value);\n }\n };\n\n var reject = function(reason) {\n if (!called) {\n called = true;\n promise.unblockAndReject_(reason);\n }\n };\n\n try {\n then.call(thenable, resolve, reject);\n } catch (e) {\n reject(e);\n }\n};\n\n\n/**\n * Executes the pending callbacks of a resolved Promise after a timeout.\n *\n * Section 2.2.4 of the Promises/A+ specification requires that Promise\n * callbacks must only be invoked from a call stack that only contains Promise\n * implementation code, which we accomplish by invoking callback execution after\n * a timeout. If {@code startExecution_} is called multiple times for the same\n * Promise, the callback chain will be evaluated only once. Additional callbacks\n * may be added during the evaluation phase, and will be executed in the same\n * event loop.\n *\n * All Promises added to the waiting list during the same browser event loop\n * will be executed in one batch to avoid using a separate timeout per Promise.\n *\n * @private\n */\nCancellablePromise.prototype.scheduleCallbacks_ = function() {\n if (!this.executing_) {\n this.executing_ = true;\n async.run(this.executeCallbacks_, this);\n }\n};\n\n\n/**\n * Executes all pending callbacks for this Promise.\n *\n * @private\n */\nCancellablePromise.prototype.executeCallbacks_ = function() {\n while (this.callbackEntries_ && this.callbackEntries_.length) {\n var entries = this.callbackEntries_;\n this.callbackEntries_ = [];\n\n for (var i = 0; i < entries.length; i++) {\n this.executeCallback_(entries[i], this.state_, this.result_);\n }\n }\n this.executing_ = false;\n};\n\n\n/**\n * Executes a pending callback for this Promise. Invokes an {@code onFulfilled}\n * or {@code onRejected} callback based on the resolved state of the Promise.\n *\n * @param {!CancellablePromise.CallbackEntry_} callbackEntry An entry containing the\n * onFulfilled and/or onRejected callbacks for this step.\n * @param {CancellablePromise.State_} state The resolution status of the Promise,\n * either FULFILLED or REJECTED.\n * @param {*} result The resolved result of the Promise.\n * @private\n */\nCancellablePromise.prototype.executeCallback_ = function(\ncallbackEntry, state, result) {\n if (state === CancellablePromise.State_.FULFILLED) {\n callbackEntry.onFulfilled(result);\n } else {\n this.removeUnhandledRejection_();\n callbackEntry.onRejected(result);\n }\n};\n\n\n/**\n * Marks this rejected Promise as having being handled. Also marks any parent\n * Promises in the rejected state as handled. The rejection handler will no\n * longer be invoked for this Promise (if it has not been called already).\n *\n * @private\n */\nCancellablePromise.prototype.removeUnhandledRejection_ = function() {\n var p;\n if (CancellablePromise.UNHANDLED_REJECTION_DELAY > 0) {\n for (p = this; p && p.unhandledRejectionId_; p = p.parent_) {\n clearTimeout(p.unhandledRejectionId_);\n p.unhandledRejectionId_ = 0;\n }\n } else if (CancellablePromise.UNHANDLED_REJECTION_DELAY === 0) {\n for (p = this; p && p.hadUnhandledRejection_; p = p.parent_) {\n p.hadUnhandledRejection_ = false;\n }\n }\n};\n\n\n/**\n * Marks this rejected Promise as unhandled. If no {@code onRejected} callback\n * is called for this Promise before the {@code UNHANDLED_REJECTION_DELAY}\n * expires, the reason will be passed to the unhandled rejection handler. The\n * handler typically rethrows the rejection reason so that it becomes visible in\n * the developer console.\n *\n * @param {!CancellablePromise} promise The rejected Promise.\n * @param {*} reason The Promise rejection reason.\n * @private\n */\nCancellablePromise.addUnhandledRejection_ = function(promise, reason) {\n if (CancellablePromise.UNHANDLED_REJECTION_DELAY > 0) {\n promise.unhandledRejectionId_ = setTimeout(function() {\n CancellablePromise.handleRejection_.call(null, reason);\n }, CancellablePromise.UNHANDLED_REJECTION_DELAY);\n\n } else if (CancellablePromise.UNHANDLED_REJECTION_DELAY === 0) {\n promise.hadUnhandledRejection_ = true;\n async.run(function() {\n if (promise.hadUnhandledRejection_) {\n CancellablePromise.handleRejection_.call(null, reason);\n }\n });\n }\n};\n\n\n/**\n * A method that is invoked with the rejection reasons for Promises that are\n * rejected but have no {@code onRejected} callbacks registered yet.\n * @type {function(*)}\n * @private\n */\nCancellablePromise.handleRejection_ = async.throwException;\n\n\n/**\n * Sets a handler that will be called with reasons from unhandled rejected\n * Promises. If the rejected Promise (or one of its descendants) has an\n * {@code onRejected} callback registered, the rejection will be considered\n * handled, and the rejection handler will not be called.\n *\n * By default, unhandled rejections are rethrown so that the error may be\n * captured by the developer console or a {@code window.onerror} handler.\n *\n * @param {function(*)} handler A function that will be called with reasons from\n * rejected Promises. Defaults to {@code async.throwException}.\n */\nCancellablePromise.setUnhandledRejectionHandler = function(handler) {\n CancellablePromise.handleRejection_ = handler;\n};\n\n\n\n/**\n * Error used as a rejection reason for canceled Promises.\n *\n * @param {string=} opt_message\n * @constructor\n * @extends {Error}\n * @final\n */\nCancellablePromise.CancellationError = class extends Error {\n constructor(opt_message) {\n super(opt_message);\n\n if (opt_message) {\n this.message = opt_message;\n }\n }\n};\n\n/** @override */\nCancellablePromise.CancellationError.prototype.name = 'cancel';\n\nexport {CancellablePromise};\nexport default CancellablePromise;\n","'use strict';\n\n/**\n * Debounces function execution.\n * @param {!function()} fn\n * @param {number} delay\n * @return {!function()}\n */\nfunction debounce(fn, delay) {\n\treturn function debounced() {\n\t\tvar args = arguments;\n\t\tcancelDebounce(debounced);\n\t\tdebounced.id = setTimeout(function() {\n\t\t\tfn.apply(null, args);\n\t\t}, delay);\n\t};\n}\n\n/**\n * Cancels the scheduled debounced function.\n */\nfunction cancelDebounce(debounced) {\n\tclearTimeout(debounced.id);\n}\n\nexport default debounce;\nexport { cancelDebounce, debounce };\n","'use strict';\n\nimport core from 'metal';\n\nconst REGEX = /([\\/])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])*)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?)/g;\n\n/**\n * Converts the given array of regex matches to a more readable object format.\n * @param {!Array<string>} matches\n * @return {!Object}\n */\nfunction convertMatchesToObj(matches) {\n\treturn {\n\t\tmatch: matches[0],\n\t\tprefix: matches[1],\n\t\tname: matches[2],\n\t\tparamPattern: matches[3],\n\t\tunnamedPattern: matches[4],\n\t\tmodifier: matches[5]\n\t};\n}\n\n/**\n * Converts the given tokens parsed from a route format string to a regex.\n * @param {!Array<string|!Object>} tokens\n * @return {!RegExp}\n */\nfunction convertTokensToRegex(tokens) {\n\tlet regex = '';\n\tfor (let i = 0; i < tokens.length; i++) {\n\t\tif (core.isString(tokens[i])) {\n\t\t\tregex += escape(tokens[i]);\n\t\t} else {\n\t\t\tlet capture = encloseNonCapturingGroup(tokens[i].pattern);\n\t\t\tif (tokens[i].repeat) {\n\t\t\t\tcapture += encloseNonCapturingGroup('\\\\/' + capture) + '*';\n\t\t\t}\n\t\t\tcapture = escape(tokens[i].prefix) + `(${capture})`;\n\t\t\tif (tokens[i].optional) {\n\t\t\t\tif (!tokens[i].partial) {\n\t\t\t\t\tcapture = encloseNonCapturingGroup(capture);\n\t\t\t\t}\n\t\t\t\tcapture += '?';\n\t\t\t}\n\t\t\tregex += capture;\n\t\t}\n\t}\n\treturn new RegExp('^' + makeTrailingSlashOptional(regex) + '$');\n}\n\n/**\n * Encloses the given regex pattern into a non capturing group.\n * @param {string} pattern\n * @return {string}\n */\nfunction encloseNonCapturingGroup(pattern) {\n\treturn `(?:${pattern})`;\n}\n\n/**\n * Escapes the given string to show up in the path regex.\n * @param {string} str\n * @return {string}\n */\nfunction escape(str) {\n\treturn str.replace(/([.+*?=^!:${}()[\\]|\\/\\\\])/g, '\\\\$1');\n}\n\n/**\n * Makes trailing slash optional on paths.\n * @param {string} regex\n * @param {string}\n */\nfunction makeTrailingSlashOptional(regex) {\n\tif (/\\/$/.test(regex)) {\n\t\tregex += '?';\n\t} else {\n\t\tregex += '\\\\/?';\n\t}\n\treturn regex;\n}\n\n/**\n * Parses the given route format string into tokens representing its contents.\n * @param {!Array|string} routeOrTokens Either a route format string or tokens\n * previously parsed via the `parse` function.\n * @return {!Array<string|!Object>} An array of tokens that can be either plain\n * strings (part of the route) or objects containing informations on params.\n */\nexport function parse(routeOrTokens) {\n\tif (!core.isString(routeOrTokens)) {\n\t\treturn routeOrTokens;\n\t}\n\n\tconst route = routeOrTokens;\n\tlet unnamedCount = 0;\n\tconst tokens = [];\n\tlet currPath = '';\n\tlet index = 0;\n\n\tlet matches = REGEX.exec(route);\n\twhile (matches) {\n\t\tconst data = convertMatchesToObj(matches);\n\n\t\tcurrPath = route.slice(index, matches.index);\n\t\tindex = matches.index + data.match.length;\n\t\ttokens.push(currPath);\n\n\t\ttokens.push({\n\t\t\tname: data.name ? data.name : '' + unnamedCount++,\n\t\t\tpartial: route[index] && route[index] !== data.prefix,\n\t\t\tprefix: data.prefix || '',\n\t\t\tpattern: data.paramPattern || data.unnamedPattern || '[^\\\\/]+',\n\t\t\trepeat: data.modifier === '*' || data.modifier === '+',\n\t\t\toptional: data.modifier === '*' || data.modifier === '?'\n\t\t});\n\n\t\tmatches = REGEX.exec(route);\n\t}\n\n\tif (index < route.length) {\n\t\ttokens.push(route.substr(index));\n\t}\n\treturn tokens;\n}\n\n/**\n * Converts the given route format string to a regex that can extract param\n * data from paths matching it.\n * @param {!Array|string} routeOrTokens Either a route format string or tokens\n * previously parsed via the `parse` function.\n * @return {!RegExp}\n */\nexport function toRegex(routeOrTokens) {\n\treturn convertTokensToRegex(parse(routeOrTokens));\n}\n\n/**\n * Extracts data from the given path according to the specified route format.\n * @param {!Array|string} routeOrTokens Either a route format string or tokens\n * previously parsed via the `parse` function.\n * @param {string} The path to extract param data from.\n * @return {Object<string, string>} The data object, or null if the path doesn't\n * match the given format.\n */\nexport function extractData(routeOrTokens, path) {\n\tconst data = {};\n\tconst tokens = parse(routeOrTokens);\n\tconst match = path.match(convertTokensToRegex(tokens));\n\n\tif (!match) {\n\t\treturn null;\n\t}\n\n\tlet paramIndex = 1;\n\tfor (let i = 0; i < tokens.length; i++) {\n\t\tif (!core.isString(tokens[i])) {\n\t\t\tlet value = match[paramIndex++];\n\t\t\tif (core.isDef(value)) {\n\t\t\t\tif (tokens[i].repeat) {\n\t\t\t\t\tvalue = value.split('/');\n\t\t\t\t}\n\t\t\t\tdata[tokens[i].name] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn data;\n}\n","'use strict';\n\nimport { isDefAndNotNull, isFunction, isString } from 'metal';\nimport { extractData, parse, toRegex } from 'metal-path-parser';\n\nclass Route {\n\n\t/**\n\t * Route class.\n\t * @param {!string|RegExp|Function} path\n\t * @param {!Function} handler\n\t * @constructor\n\t */\n\tconstructor(path, handler) {\n\t\tif (!isDefAndNotNull(path)) {\n\t\t\tthrow new Error('Route path not specified.');\n\t\t}\n\t\tif (!isFunction(handler)) {\n\t\t\tthrow new Error('Route handler is not a function.');\n\t\t}\n\n\t\t/**\n\t\t * Defines the handler which will execute once a URL in the application\n\t\t * matches the path.\n\t\t * @type {!Function}\n\t\t * @protected\n\t\t */\n\t\tthis.handler = handler;\n\n\t\t/**\n\t\t * Defines the path which will trigger the route handler.\n\t\t * @type {!string|RegExp|Function}\n\t\t * @protected\n\t\t */\n\t\tthis.path = path;\n\t}\n\n\t/**\n\t* Builds parsed data (regex and tokens) for this route.\n\t* @return {!Object}\n\t* @protected\n\t*/\n\tbuildParsedData_() {\n\t\tif (!this.parsedData_) {\n\t\t\tvar tokens = parse(this.path);\n\t\t\tvar regex = toRegex(tokens);\n\t\t\tthis.parsedData_ = {\n\t\t\t\tregex,\n\t\t\t\ttokens\n\t\t\t};\n\t\t}\n\t\treturn this.parsedData_;\n\t}\n\n\t/**\n\t * Extracts param data from the given path, according to this route.\n\t * @param {string} path The url path to extract params from.\n\t * @return {Object} The extracted data, if the path matches this route, or\n\t * null otherwise.\n\t */\n\textractParams(path) {\n\t\tif (isString(this.path)) {\n\t\t\treturn extractData(this.buildParsedData_().tokens, path);\n\t\t}\n\t\treturn {};\n\t}\n\n\t/**\n\t * Gets the route handler.\n\t * @return {!Function}\n\t */\n\tgetHandler() {\n\t\treturn this.handler;\n\t}\n\n\t/**\n\t * Gets the route path.\n\t * @return {!string|RegExp|Function}\n\t */\n\tgetPath() {\n\t\treturn this.path;\n\t}\n\n\t/**\n \t * Matches if the router can handle the tested path.\n \t * @param {!string} value Path to test (may contain the querystring part).\n\t * @return {boolean} Returns true if matches any route.\n\t */\n\tmatchesPath(value) {\n\t\tvar path = this.path;\n\n\t\tif (isFunction(path)) {\n\t\t\treturn path(value);\n\t\t}\n\t\tif (isString(path)) {\n\t\t\tpath = this.buildParsedData_().regex;\n\t\t}\n\t\tif (path instanceof RegExp) {\n\t\t\treturn value.search(path) > -1;\n\t\t}\n\n\t\treturn false;\n\t}\n\n}\n\nexport default Route;\n","'use strict';\n\nimport { Disposable } from 'metal';\n\nclass Cacheable extends Disposable {\n\n\t/**\n\t * Abstract class for defining cacheable behavior.\n\t * @constructor\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the cached data.\n\t\t * @type {!Object}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.cache = null;\n\n\t\t/**\n\t\t * Holds whether class is cacheable.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.cacheable = false;\n\t}\n\n\t/**\n\t * Adds content to the cache.\n\t * @param {string} content Content to be cached.\n\t * @chainable\n\t */\n\taddCache(content) {\n\t\tif (this.cacheable) {\n\t\t\tthis.cache = content;\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Clears the cache.\n\t * @chainable\n\t */\n\tclearCache() {\n\t\tthis.cache = null;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.clearCache();\n\t}\n\n\t/**\n\t * Gets the cached content.\n\t * @return {Object} Cached content.\n\t * @protected\n\t */\n\tgetCache() {\n\t\treturn this.cache;\n\t}\n\n\t/**\n\t * Whether the class is cacheable.\n\t * @return {boolean} Returns true when class is cacheable, false otherwise.\n\t */\n\tisCacheable() {\n\t\treturn this.cacheable;\n\t}\n\n\t/**\n\t * Sets whether the class is cacheable.\n\t * @param {boolean} cacheable\n\t */\n\tsetCacheable(cacheable) {\n\t\tif (!cacheable) {\n\t\t\tthis.clearCache();\n\t\t}\n\t\tthis.cacheable = cacheable;\n\t}\n\n}\n\nexport default Cacheable;\n","'use strict';\n\nimport { getUid } from 'metal';\nimport { globalEval } from 'metal-dom';\nimport Cacheable from '../cacheable/Cacheable';\nimport CancellablePromise from 'metal-promise';\n\nclass Screen extends Cacheable {\n\n\t/**\n\t * Screen class is a special type of route handler that provides helper\n\t * utilities that adds lifecycle and methods to provide content to each\n\t * registered surface.\n\t * @constructor\n\t * @extends {Cacheable}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the screen id.\n\t\t * @type {string}\n\t\t * @protected\n\t\t */\n\t\tthis.id = this.makeId_(getUid());\n\n\t\t/**\n\t\t * Holds the screen meta tags. Relevant when the meta tags\n\t\t * should be updated when screen is rendered.\n\t\t */\n\t\tthis.metas = null;\n\n\t\t/**\n\t\t * Holds the screen title. Relevant when the page title should be\n\t\t * upadated when screen is rendered.\n\t\t * @type {?string=}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.title = null;\n\t}\n\n\t/**\n\t * Fires when the screen is active. Allows a screen to perform any setup\n\t * that requires its DOM to be visible. Lifecycle.\n\t */\n\tactivate() {\n\t\tconsole.log('Screen [' + this + '] activate');\n\t}\n\n\t/**\n\t * Gives the Screen a chance to cancel the navigation and stop itself from\n\t * activating. Can be used, for example, to prevent navigation if a user\n\t * is not authenticated. Lifecycle.\n\t * @return {boolean=|?CancellablePromise=} If returns or resolves to true,\n\t * the current screen is locked and the next nagivation interrupted.\n\t */\n\tbeforeActivate() {\n\t\tconsole.log('Screen [' + this + '] beforeActivate');\n\t}\n\n\t/**\n\t * Gives the Screen a chance to cancel the navigation and stop itself from\n\t * being deactivated. Can be used, for example, if the screen has unsaved\n\t * state. Lifecycle. Clean-up should not be preformed here, since the\n\t * navigation may still be cancelled. Do clean-up in deactivate.\n\t * @return {boolean=|?CancellablePromise=} If returns or resolves to true,\n\t * the current screen is locked and the next nagivation interrupted.\n\t */\n\tbeforeDeactivate() {\n\t\tconsole.log('Screen [' + this + '] beforeDeactivate');\n\t}\n\n\t/**\n\t * Gives the Screen a chance format the path before history update.\n\t * @path {!string} path Navigation path.\n\t * @return {!string} Navigation path to use on history.\n\t */\n\tbeforeUpdateHistoryPath(path) {\n\t\treturn path;\n\t}\n\n\t/**\n\t * Gives the Screen a chance format the state before history update.\n\t * @path {!object} state History state.\n\t * @return {!object} History state to use on history.\n\t */\n\tbeforeUpdateHistoryState(state) {\n\t\treturn state;\n\t}\n\n\t/**\n\t * Allows a screen to do any cleanup necessary after it has been\n\t * deactivated, for example cancelling outstanding requests or stopping\n\t * timers. Lifecycle.\n\t */\n\tdeactivate() {\n\t\tconsole.log('Screen [' + this + '] deactivate');\n\t}\n\n\t/**\n\t * Dispose a screen, either after it is deactivated (in the case of a\n\t * non-cacheable view) or when the App is itself disposed for whatever\n\t * reason. Lifecycle.\n\t */\n\tdisposeInternal() {\n\t\tsuper.disposeInternal();\n\t\tconsole.log('Screen [' + this + '] dispose');\n\t}\n\n\t/**\n\t * Allows a screen to evaluate scripts before the element is made visible.\n\t * Lifecycle.\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @return {?CancellablePromise=} This can return a promise, which will\n\t * pause the navigation until it is resolved.\n\t */\n\tevaluateScripts(surfaces) {\n\t\tObject.keys(surfaces).forEach(sId => {\n\t\t\tif (surfaces[sId].activeChild) {\n\t\t\t\tglobalEval.runScriptsInElement(surfaces[sId].activeChild);\n\t\t\t}\n\t\t});\n\t\treturn CancellablePromise.resolve();\n\t}\n\n\t/**\n\t * Allows a screen to evaluate styles before the element is made visible.\n\t * Lifecycle.\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @return {?CancellablePromise=} This can return a promise, which will\n\t * pause the navigation until it is resolved.\n\t */\n\tevaluateStyles() {\n\t\treturn CancellablePromise.resolve();\n\t}\n\n\t/**\n\t * Allows a screen to perform any setup immediately before the element is\n\t * made visible. Lifecycle.\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @return {?CancellablePromise=} This can return a promise, which will pause the\n\t * navigation until it is resolved.\n\t */\n\tflip(surfaces) {\n\t\tconsole.log('Screen [' + this + '] flip');\n\n\t\tvar transitions = [];\n\n\t\tObject.keys(surfaces).forEach(sId => {\n\t\t\tvar surface = surfaces[sId];\n\t\t\tvar deferred = surface.show(this.id);\n\t\t\ttransitions.push(deferred);\n\t\t});\n\n\t\treturn CancellablePromise.all(transitions);\n\t}\n\n\t/**\n\t * Gets the screen id.\n\t * @return {string}\n\t */\n\tgetId() {\n\t\treturn this.id;\n\t}\n\n\t/**\n\t * Gets the screen meta tags.\n\t * @return {NodeList|Node}\n\t */\n\tgetMetas() {\n\t\treturn this.metas;\n\t}\n\n\t/**\n\t * Returns the content for the given surface, or null if the surface isn't\n\t * used by this screen. This will be called when a screen is initially\n\t * constructed or, if a screen is non-cacheable, when navigated.\n\t * @param {!string} surfaceId The id of the surface DOM element.\n\t * @param {!Object} params Params extracted from the current path.\n\t * @return {?string|Element=} This can return a string or node representing\n\t * the content of the surface. If returns falsy values surface default\n\t * content is restored.\n\t */\n\tgetSurfaceContent() {\n\t\tconsole.log('Screen [' + this + '] getSurfaceContent');\n\t}\n\n\t/**\n\t * Gets the screen title.\n\t * @return {?string=}\n\t */\n\tgetTitle() {\n\t\treturn this.title;\n\t}\n\n\t/**\n\t * Returns all contents for the surfaces. This will pass the loaded content\n\t * to <code>Screen.load</code> with all information you\n\t * need to fulfill the surfaces. Lifecycle.\n\t * @param {!string=} path The requested path.\n\t * @return {!CancellablePromise} This can return a string representing the\n\t * contents of the surfaces or a promise, which will pause the navigation\n\t * until it is resolved. This is useful for loading async content.\n\t */\n\tload() {\n\t\tconsole.log('Screen [' + this + '] load');\n\t\treturn CancellablePromise.resolve();\n\t}\n\n\t/**\n\t * Makes the id for the screen.\n\t * @param {!string} id The screen id the content belongs too.\n\t * @return {string}\n\t * @private\n\t */\n\tmakeId_(id) {\n\t\treturn 'screen_' + id;\n\t}\n\n\t/**\n\t * Sets the screen id.\n\t * @param {!string} id\n\t */\n\tsetId(id) {\n\t\tthis.id = id;\n\t}\n\n\t/**\n\t * Sets the screen meta tags.\n\t * @param {NodeList|Node} metas\n\t */\n\tsetMetas(metas) {\n\t\tthis.metas = metas;\n\t}\n\n\t/**\n\t * Sets the screen title.\n\t * @param {?string=} title\n\t */\n\tsetTitle(title) {\n\t\tthis.title = title;\n\t}\n\n\t/**\n\t * @return {string}\n\t */\n\ttoString() {\n\t\treturn this.id;\n\t}\n\n}\n\n/**\n * @param {*} object\n * @return {boolean} Whether a given instance implements\n * <code>Screen</code>.\n */\nScreen.isImplementedBy = function(object) {\n\treturn object instanceof Screen;\n};\n\nexport default Screen;\n","'use strict';\n\nimport globals from '../globals/globals';\nimport { Disposable, isDefAndNotNull } from 'metal';\nimport { append, removeChildren, exitDocument } from 'metal-dom';\nimport CancellablePromise from 'metal-promise';\n\nclass Surface extends Disposable {\n\n\t/**\n\t * Surface class representing the references to elements on the page that\n\t * can potentially be updated by <code>App</code>.\n\t * @param {string} id\n\t * @constructor\n\t */\n\tconstructor(id) {\n\t\tsuper();\n\n\t\tif (!id) {\n\t\t\tthrow new Error('Surface element id not specified. A surface element requires a valid id.');\n\t\t}\n\n\t\t/**\n\t\t * Holds the active child element.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.activeChild = null;\n\n\t\t/**\n\t\t * Holds the default child element.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.defaultChild = null;\n\n\t\t/**\n\t\t * Holds the element with the specified surface id, if not found creates a\n\t\t * new element with the specified id.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.element = null;\n\n\t\t/**\n\t\t * Holds the surface id.\n\t\t * @type {String}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.id = id;\n\n\t\t/**\n\t\t * Holds the default transitionFn for the surfaces.\n\t\t * @param {?Element=} from The visible surface element.\n\t\t * @param {?Element=} to The surface element to be flipped.\n\t\t * @default null\n\t\t */\n\t\tthis.transitionFn = null;\n\n\t\tthis.defaultChild = this.getChild(Surface.DEFAULT);\n\t\tthis.maybeWrapContentAsDefault_();\n\t\tthis.activeChild = this.defaultChild;\n\t}\n\n\t/**\n\t * Adds screen content to a surface. If content hasn't been passed, see if\n\t * an element exists in the DOM that matches the id. By convention, the\n\t * element should already be nested in the right element and should have an\n\t * id that is a concatentation of the surface id + '-' + the screen id.\n\t * @param {!string} screenId The screen id the content belongs too.\n\t * @param {?string|Element=} opt_content The string content or element to\n\t * add be added as surface content.\n\t * @return {Element}\n\t */\n\taddContent(screenId, opt_content) {\n\t\tvar child = this.defaultChild;\n\n\t\tif (isDefAndNotNull(opt_content)) {\n\t\t\tchild = this.getChild(screenId);\n\t\t\tif (child) {\n\t\t\t\tremoveChildren(child);\n\t\t\t} else {\n\t\t\t\tchild = this.createChild(screenId);\n\t\t\t\tthis.transition(child, null);\n\t\t\t}\n\t\t\tappend(child, opt_content);\n\t\t}\n\n\t\tvar element = this.getElement();\n\n\t\tif (element && child) {\n\t\t\tappend(element, child);\n\t\t}\n\n\t\treturn child;\n\t}\n\n\t/**\n\t * Creates child node for the surface.\n\t * @param {!string} screenId The screen id.\n\t * @return {Element}\n\t */\n\tcreateChild(screenId) {\n\t\tvar child = globals.document.createElement('div');\n\t\tchild.setAttribute('id', this.makeId_(screenId));\n\t\treturn child;\n\t}\n\n\t/**\n\t * Gets child node of the surface.\n\t * @param {!string} screenId The screen id.\n\t * @return {?Element}\n\t */\n\tgetChild(screenId) {\n\t\treturn globals.document.getElementById(this.makeId_(screenId));\n\t}\n\n\t/**\n\t * Gets the surface element from element, and sets it to the el property of\n\t * the current instance.\n\t * <code>this.element</code> will be used.\n\t * @return {?Element} The current surface element.\n\t */\n\tgetElement() {\n\t\tif (this.element) {\n\t\t\treturn this.element;\n\t\t}\n\t\tthis.element = globals.document.getElementById(this.id);\n\t\treturn this.element;\n\t}\n\n\t/**\n\t * Gets the surface id.\n\t * @return {String}\n\t */\n\tgetId() {\n\t\treturn this.id;\n\t}\n\n\t/**\n\t * Gets the surface transition function.\n\t * See <code>Surface.defaultTransition</code>.\n\t * @return {?Function=} The transition function.\n\t */\n\tgetTransitionFn() {\n\t\treturn this.transitionFn;\n\t}\n\n\t/**\n\t * Makes the id for the element that holds content for a screen.\n\t * @param {!string} screenId The screen id the content belongs too.\n\t * @return {String}\n\t * @private\n\t */\n\tmakeId_(screenId) {\n\t\treturn this.id + '-' + screenId;\n\t}\n\n\t/**\n\t * If default child is missing, wraps surface content as default child. If\n\t * surface have static content, make sure to place a\n\t * <code>surfaceId-default</code> element inside surface, only contents\n\t * inside the default child will be replaced by navigation.\n\t */\n\tmaybeWrapContentAsDefault_() {\n\t\tvar element = this.getElement();\n\t\tif (element && !this.defaultChild) {\n\t\t\tvar fragment = globals.document.createDocumentFragment();\n\t\t\twhile (element.firstChild) {\n\t\t\t\tfragment.appendChild(element.firstChild);\n\t\t\t}\n\t\t\tthis.defaultChild = this.addContent(Surface.DEFAULT, fragment);\n\t\t\tthis.transition(null, this.defaultChild);\n\t\t}\n\t}\n\n\t/**\n\t * Sets the surface id.\n\t * @param {!string} id\n\t */\n\tsetId(id) {\n\t\tthis.id = id;\n\t}\n\n\t/**\n\t * Sets the surface transition function.\n\t * See <code>Surface.defaultTransition</code>.\n\t * @param {?Function=} transitionFn The transition function.\n\t */\n\tsetTransitionFn(transitionFn) {\n\t\tthis.transitionFn = transitionFn;\n\t}\n\n\t/**\n\t * Shows screen content from a surface.\n\t * @param {String} screenId The screen id to show.\n\t * @return {CancellablePromise} Pauses the navigation until it is resolved.\n\t */\n\tshow(screenId) {\n\t\tvar from = this.activeChild;\n\t\tvar to = this.getChild(screenId);\n\t\tif (!to) {\n\t\t\tto = this.defaultChild;\n\t\t}\n\t\tthis.activeChild = to;\n\t\treturn this.transition(from, to).thenAlways(() => {\n\t\t\tif (from && from !== to) {\n\t\t\t\texitDocument(from);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Removes screen content from a surface.\n\t * @param {!string} screenId The screen id to remove.\n\t */\n\tremove(screenId) {\n\t\tvar child = this.getChild(screenId);\n\t\tif (child) {\n\t\t\texitDocument(child);\n\t\t}\n\t}\n\n\t/**\n\t * @return {String}\n\t */\n\ttoString() {\n\t\treturn this.id;\n\t}\n\n\t/**\n\t * Invokes the transition function specified on <code>transition</code> attribute.\n\t * @param {?Element=} from\n\t * @param {?Element=} to\n\t * @return {?CancellablePromise=} This can return a promise, which will pause the\n\t * navigation until it is resolved.\n\t */\n\ttransition(from, to) {\n\t\tvar transitionFn = this.transitionFn || Surface.defaultTransition;\n\t\treturn CancellablePromise.resolve(transitionFn.call(this, from, to));\n\t}\n\n}\n\n/**\n * Holds the default surface name. Elements on the page must contain a child\n * element containing the default content, this element must be as following:\n *\n * Example:\n * <code>\n * <div id=\"mysurface\">\n * <div id=\"mysurface-default\">Default surface content.</div>\n * </div>\n * </code>\n *\n * The default content is relevant for the initial page content. When a\n * screen doesn't provide content for the surface the default content is\n * restored into the page.\n *\n * @type {!String}\n * @default default\n * @static\n */\nSurface.DEFAULT = 'default';\n\n/**\n * Holds the default transition for all surfaces. Each surface could have its\n * own transition.\n *\n * Example:\n *\n * <code>\n * surface.setTransitionFn(function(from, to) {\n * if (from) {\n * from.style.display = 'none';\n * from.classList.remove('flipped');\n * }\n * if (to) {\n * to.style.display = 'block';\n * to.classList.add('flipped');\n * }\n * return null;\n * });\n * </code>\n *\n * @param {?Element=} from The visible surface element.\n * @param {?Element=} to The surface element to be flipped.\n * @static\n */\nSurface.defaultTransition = function(from, to) {\n\tif (from) {\n\t\tfrom.style.display = 'none';\n\t\tfrom.classList.remove('flipped');\n\t}\n\tif (to) {\n\t\tto.style.display = 'block';\n\t\tto.classList.add('flipped');\n\t}\n};\n\nexport default Surface;\n","'use strict';\n\nimport { addClasses, delegate, match, on, removeClasses } from 'metal-dom';\nimport { array, async, isDefAndNotNull, isString, object } from 'metal';\nimport { EventEmitter, EventHandler } from 'metal-events';\nimport CancellablePromise from 'metal-promise';\nimport debounce from 'metal-debounce';\nimport globals from '../globals/globals';\nimport Route from '../route/Route';\nimport Screen from '../screen/Screen';\nimport Surface from '../surface/Surface';\nimport Uri from 'metal-uri';\nimport utils from '../utils/utils';\n\nconst NavigationStrategy = {\n\tIMMEDIATE: 'immediate',\n\tSCHEDULE_LAST: 'scheduleLast'\n};\n\nclass App extends EventEmitter {\n\n\t/**\n\t * App class that handle routes and screens lifecycle.\n\t * @constructor\n\t * @extends {EventEmitter}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the active screen.\n\t\t * @type {?Screen}\n\t\t * @protected\n\t\t */\n\t\tthis.activeScreen = null;\n\n\t\t/**\n\t\t * Holds the active path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.activePath = null;\n\n\t\t/**\n\t\t * Allows prevent navigate from dom prevented event.\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.allowPreventNavigate = true;\n\n\t\t/**\n\t\t * Holds link base path.\n\t\t * @type {!string}\n\t\t * @default ''\n\t\t * @protected\n\t\t */\n\t\tthis.basePath = '';\n\n\t\t/**\n\t\t * Holds the value of the browser path before a navigation is performed.\n\t\t * @type {!string}\n\t\t * @default the current browser path.\n\t\t * @protected\n\t\t */\n\t\tthis.browserPathBeforeNavigate = utils.getCurrentBrowserPathWithoutHash();\n\n\t\t/**\n\t\t * Captures scroll position from scroll event.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.captureScrollPositionFromScrollEvent = true;\n\n\t\t/**\n\t\t * Holds the default page title.\n\t\t * @type {string}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.defaultTitle = globals.document.title;\n\n\t\t/**\n\t\t * Holds the form selector to define forms that are routed.\n\t\t * @type {!string}\n\t\t * @default form[enctype=\"multipart/form-data\"]:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.formSelector = 'form[enctype=\"multipart/form-data\"]:not([data-senna-off])';\n\n\t\t/**\n\t\t * When enabled, the route matching ignores query string from the path.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.ignoreQueryStringFromRoutePath = false;\n\n\t\t/**\n\t\t * Holds the link selector to define links that are routed.\n\t\t * @type {!string}\n\t\t * @default a:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.linkSelector = 'a:not([data-senna-off]):not([target=\"_blank\"])';\n\n\t\t/**\n\t\t * Holds the loading css class.\n\t\t * @type {!string}\n\t\t * @default senna-loading\n\t\t * @protected\n\t\t */\n\t\tthis.loadingCssClass = 'senna-loading';\n\n\t\t/**\n\t\t * Using the History API to manage your URLs is awesome and, as it happens,\n\t\t * a crucial feature of good web apps. One of its downsides, however, is\n\t\t * that scroll positions are stored and then, more importantly, restored\n\t\t * whenever you traverse the history. This often means unsightly jumps as\n\t\t * the scroll position changes automatically, and especially so if your app\n\t\t * does transitions, or changes the contents of the page in any way.\n\t\t * Ultimately this leads to an horrible user experience. The good news is,\n\t\t * however, that there’s a potential fix: history.scrollRestoration.\n\t\t * https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.nativeScrollRestorationSupported = ('scrollRestoration' in globals.window.history);\n\n\t\t/**\n\t\t * When set to NavigationStrategy.SCHEDULE_LAST means that the current navigation\n\t\t * cannot be Cancelled to start another and will be queued in\n\t\t * scheduledNavigationQueue. When NavigationStrategy.IMMEDIATE means that all\n\t\t * navigation will be cancelled to start another.\n\t\t * @type {!string}\n\t\t * @default immediate\n\t\t * @protected\n\t\t */\n\t\tthis.navigationStrategy = NavigationStrategy.IMMEDIATE;\n\n\t\t/**\n\t\t * When set to true there is a pendingNavigate that has not yet been\n\t\t * resolved or rejected.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.isNavigationPending = false;\n\n\t\t/**\n\t\t * Holds a deferred with the current navigation.\n\t\t * @type {?CancellablePromise}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.pendingNavigate = null;\n\n\t\t/**\n\t\t * Holds the window horizontal scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollLeft = 0;\n\n\t\t/**\n\t\t * Holds the window vertical scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollTop = 0;\n\n\t\t/**\n\t\t * Holds the redirect path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.redirectPath = null;\n\n\t\t/**\n\t\t * Holds the screen routes configuration.\n\t\t * @type {?Array}\n\t\t * @default []\n\t\t * @protected\n\t\t */\n\t\tthis.routes = [];\n\n\t\t/**\n\t\t * Holds a queue that stores every DOM event that can initiate a navigation.\n\t\t * @type {!Event}\n\t\t * @default []\n\t\t * @protected\n\t\t */\n\t\tthis.scheduledNavigationQueue = [];\n\n\t\t/**\n\t\t * Maps the screen instances by the url containing the parameters.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.screens = {};\n\n\t\t/**\n\t\t * When set to true the first erroneous popstate fired on page load will be\n\t\t * ignored, only if <code>globals.window.history.state</code> is also\n\t\t * <code>null</code>.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.skipLoadPopstate = false;\n\n\t\t/**\n\t\t * Maps that index the surfaces instances by the surface id.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.surfaces = {};\n\n\t\t/**\n\t\t * When set to true, moves the scroll position after popstate, or to the\n\t\t * top of the viewport for new navigation. If false, the browser will\n\t\t * take care of scroll restoration.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.updateScrollPosition = true;\n\n\t\tthis.appEventHandlers_ = new EventHandler();\n\n\t\tthis.appEventHandlers_.add(\n\t\t\ton(globals.window, 'scroll', debounce(this.onScroll_.bind(this), 100)),\n\t\t\ton(globals.window, 'load', this.onLoad_.bind(this)),\n\t\t\ton(globals.window, 'popstate', this.onPopstate_.bind(this))\n\t\t);\n\n\t\tthis.on('startNavigate', this.onStartNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigateDefault_, true);\n\t\tthis.on('beforeUnload', this.onBeforeUnloadDefault_);\n\n\t\tthis.setLinkSelector(this.linkSelector);\n\t\tthis.setFormSelector(this.formSelector);\n\n\t\tthis.maybeOverloadBeforeUnload_();\n\t}\n\n\t/**\n\t * Adds one or more screens to the application.\n\t *\n\t * Example:\n\t *\n\t * <code>\n\t * app.addRoutes({ path: '/foo', handler: FooScreen });\n\t * or\n\t * app.addRoutes([{ path: '/foo', handler: function(route) { return new FooScreen(); } }]);\n\t * </code>\n\t *\n\t * @param {Object} or {Array} routes Single object or an array of object.\n\t * Each object should contain <code>path</code> and <code>screen</code>.\n\t * The <code>path</code> should be a string or a regex that maps the\n\t * navigation route to a screen class definition (not an instance), e.g:\n\t * <code>{ path: \"/home:param1\", handler: MyScreen }</code>\n\t * <code>{ path: /foo.+/, handler: MyScreen }</code>\n\t * @chainable\n\t */\n\taddRoutes(routes) {\n\t\tif (!Array.isArray(routes)) {\n\t\t\troutes = [routes];\n\t\t}\n\t\troutes.forEach((route) => {\n\t\t\tif (!(route instanceof Route)) {\n\t\t\t\troute = new Route(route.path, route.handler);\n\t\t\t}\n\t\t\tthis.routes.push(route);\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds one or more surfaces to the application.\n\t * @param {Surface|String|Array.<Surface|String>} surfaces\n\t * Surface element id or surface instance. You can also pass an Array\n\t * whichcontains surface instances or id. In case of ID, these should be\n\t * the id of surface element.\n\t * @chainable\n\t */\n\taddSurfaces(surfaces) {\n\t\tif (!Array.isArray(surfaces)) {\n\t\t\tsurfaces = [surfaces];\n\t\t}\n\t\tsurfaces.forEach((surface) => {\n\t\t\tif (isString(surface)) {\n\t\t\t\tsurface = new Surface(surface);\n\t\t\t}\n\t\t\tthis.surfaces[surface.getId()] = surface;\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns if can navigate to path.\n\t * @param {!string} url\n\t * @return {boolean}\n\t */\n\tcanNavigate(url) {\n\t\tconst uri = utils.isWebUri(url);\n\n\t\tif (!uri) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst path = utils.getUrlPath(url);\n\n\t\tif (!this.isLinkSameOrigin_(uri.getHost())) {\n\t\t\tconsole.log('Offsite link clicked');\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.isSameBasePath_(path)) {\n\t\t\tconsole.log('Link clicked outside app\\'s base path');\n\t\t\treturn false;\n\t\t}\n\t\t// Prevents navigation if it's a hash change on the same url.\n\t\tif (uri.getHash() && utils.isCurrentBrowserPath(path)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.findRoute(path)) {\n\t\t\tconsole.log('No route for ' + path);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear screens cache.\n\t * @chainable\n\t */\n\tclearScreensCache() {\n\t\tObject.keys(this.screens).forEach((path) => {\n\t\t\tif (path === this.activePath) {\n\t\t\t\tthis.activeScreen.clearCache();\n\t\t\t} else if (!(this.isNavigationPending && this.pendingNavigate.path === path)) {\n\t\t\t\tthis.removeScreen(path);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves or create a screen instance to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {Screen}\n\t */\n\tcreateScreenInstance(path, route) {\n\t\tif (!this.pendingNavigate && path === this.activePath) {\n\t\t\tconsole.log('Already at destination, refresh navigation');\n\t\t\treturn this.activeScreen;\n\t\t}\n\t\t/* jshint newcap: false */\n\t\tvar screen = this.screens[path];\n\t\tif (!screen) {\n\t\t\tvar handler = route.getHandler();\n\t\t\tif (handler === Screen || Screen.isImplementedBy(handler.prototype)) {\n\t\t\t\tscreen = new handler();\n\t\t\t} else {\n\t\t\t\tscreen = handler(route) || new Screen();\n\t\t\t}\n\t\t\tconsole.log('Create screen for [' + path + '] [' + screen + ']');\n\t\t}\n\t\treturn screen;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tif (this.activeScreen) {\n\t\t\tthis.removeScreen(this.activePath);\n\t\t}\n\t\tthis.clearScreensCache();\n\t\tthis.formEventHandler_.removeListener();\n\t\tthis.linkEventHandler_.removeListener();\n\t\tthis.appEventHandlers_.removeAllListeners();\n\t\tsuper.disposeInternal();\n\t}\n\n\t/**\n\t * Dispatches to the first route handler that matches the current path, if\n\t * any.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdispatch() {\n\t\treturn this.navigate(utils.getCurrentBrowserPath(), true);\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdoNavigate_(path, opt_replaceHistory) {\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t\treturn this.pendingNavigate;\n\t\t}\n\n\t\tconsole.log('Navigate to [' + path + ']');\n\n\t\tthis.stopPendingNavigate_();\n\t\tthis.isNavigationPending = true;\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn this.maybePreventDeactivate_()\n\t\t\t.then(() => this.maybePreventActivate_(nextScreen))\n\t\t\t.then(() => nextScreen.load(path))\n\t\t\t.then(() => {\n\t\t\t\t// At this point we cannot stop navigation and all received\n\t\t\t\t// navigate candidates will be queued at scheduledNavigationQueue.\n\t\t\t\tthis.navigationStrategy = NavigationStrategy.SCHEDULE_LAST;\n\n\t\t\t\tif (this.activeScreen) {\n\t\t\t\t\tthis.activeScreen.deactivate();\n\t\t\t\t}\n\t\t\t\tthis.prepareNavigateHistory_(path, nextScreen, opt_replaceHistory);\n\t\t\t\tthis.prepareNavigateSurfaces_(\n\t\t\t\t\tnextScreen,\n\t\t\t\t\tthis.surfaces,\n\t\t\t\t\tthis.extractParams(route, path)\n\t\t\t\t);\n\t\t\t})\n\t\t\t.then(() => nextScreen.evaluateStyles(this.surfaces))\n\t\t\t.then(() => nextScreen.flip(this.surfaces))\n\t\t\t.then(() => nextScreen.evaluateScripts(this.surfaces))\n\t\t\t.then(() => this.maybeUpdateScrollPositionState_())\n\t\t\t.then(() => this.syncScrollPositionSyncThenAsync_())\n\t\t\t.then(() => this.finalizeNavigate_(path, nextScreen))\n\t\t\t.then(() => this.maybeOverloadBeforeUnload_())\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.isNavigationPending = false;\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t})\n\t\t\t.thenAlways(() => {\n\t\t\t\tthis.navigationStrategy = NavigationStrategy.IMMEDIATE;\n\n\t\t\t\tif (this.scheduledNavigationQueue.length) {\n\t\t\t\t\tconst scheduledNavigation = this.scheduledNavigationQueue.shift();\n\t\t\t\t\tthis.maybeNavigate_(scheduledNavigation.href, scheduledNavigation);\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Extracts params according to the given path and route.\n\t * @param {!Route} route\n\t * @param {string} path\n\t * @param {!Object}\n\t */\n\textractParams(route, path) {\n\t\treturn route.extractParams(this.getRoutePath(path));\n\t}\n\n\t/**\n\t * Finalizes a screen navigation.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @protected\n\t */\n\tfinalizeNavigate_(path, nextScreen) {\n\t\tnextScreen.activate();\n\n\t\tif (this.activeScreen && !this.activeScreen.isCacheable()) {\n\t\t\tif (this.activeScreen !== nextScreen) {\n\t\t\t\tthis.removeScreen(this.activePath);\n\t\t\t}\n\t\t}\n\n\t\tthis.activePath = path;\n\t\tthis.activeScreen = nextScreen;\n\t\tthis.browserPathBeforeNavigate = utils.getCurrentBrowserPathWithoutHash();\n\t\tthis.screens[path] = nextScreen;\n\t\tthis.isNavigationPending = false;\n\t\tthis.pendingNavigate = null;\n\t\tglobals.capturedFormElement = null;\n\t\tglobals.capturedFormButtonElement = null;\n\t\tconsole.log('Navigation done');\n\t}\n\n\t/**\n\t * Finds a route for the test path. Returns true if matches has a route,\n\t * otherwise returns null.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {?Object} Route handler if match any or <code>null</code> if the\n\t * path is the same as the current url and the path contains a fragment.\n\t */\n\tfindRoute(path) {\n\t\tpath = this.getRoutePath(path);\n\t\tfor (var i = 0; i < this.routes.length; i++) {\n\t\t\tvar route = this.routes[i];\n\t\t\tif (route.matchesPath(path)) {\n\t\t\t\treturn route;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets allow prevent navigate.\n\t * @return {boolean}\n\t */\n\tgetAllowPreventNavigate() {\n\t\treturn this.allowPreventNavigate;\n\t}\n\n\t/**\n\t * Gets link base path.\n\t * @return {!string}\n\t */\n\tgetBasePath() {\n\t\treturn this.basePath;\n\t}\n\n\t/**\n\t * Gets the default page title.\n\t * @return {string} defaultTitle\n\t */\n\tgetDefaultTitle() {\n\t\treturn this.defaultTitle;\n\t}\n\n\t/**\n\t * Gets the form selector.\n\t * @return {!string}\n\t */\n\tgetFormSelector() {\n\t\treturn this.formSelector;\n\t}\n\n\t/**\n\t * Check if route matching is ignoring query string from the route path.\n\t * @return {boolean}\n\t */\n\tgetIgnoreQueryStringFromRoutePath() {\n\t\treturn this.ignoreQueryStringFromRoutePath;\n\t}\n\n\t/**\n\t * Gets the link selector.\n\t * @return {!string}\n\t */\n\tgetLinkSelector() {\n\t\treturn this.linkSelector;\n\t}\n\n\t/**\n\t * Gets the loading css class.\n\t * @return {!string}\n\t */\n\tgetLoadingCssClass() {\n\t\treturn this.loadingCssClass;\n\t}\n\n\t/**\n\t * Returns the given path formatted to be matched by a route. This will,\n\t * for example, remove the base path from it, but make sure it will end\n\t * with a '/'.\n\t * @param {string} path\n\t * @return {string}\n\t */\n\tgetRoutePath(path) {\n\t\tif (this.getIgnoreQueryStringFromRoutePath()) {\n\t\t\tpath = utils.getUrlPathWithoutHashAndSearch(path);\n\t\t\treturn utils.getUrlPathWithoutHashAndSearch(path.substr(this.basePath.length));\n\t\t}\n\n\t\tpath = utils.getUrlPathWithoutHash(path);\n\t\treturn utils.getUrlPathWithoutHash(path.substr(this.basePath.length));\n\t}\n\n\t/**\n\t * Gets the update scroll position value.\n\t * @return {boolean}\n\t */\n\tgetUpdateScrollPosition() {\n\t\treturn this.updateScrollPosition;\n\t}\n\n\t/**\n\t * Handle navigation error.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {!Error} error\n\t * @protected\n\t */\n\thandleNavigateError_(path, nextScreen, error) {\n\t\tconsole.log('Navigation error for [' + nextScreen + '] (' + error.stack + ')');\n\t\tthis.emit('navigationError', {\n\t\t\terror,\n\t\t\tnextScreen,\n\t\t\tpath\n\t\t});\n\t\tif (!utils.isCurrentBrowserPath(path)) {\n\t\t\tif (this.isNavigationPending && this.pendingNavigate) {\n\t\t\t\tthis.pendingNavigate.thenAlways(() => this.removeScreen(path), this);\n\t\t\t} else {\n\t\t\t\tthis.removeScreen(path);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if app has routes.\n\t * @return {boolean}\n\t */\n\thasRoutes() {\n\t\treturn this.routes.length > 0;\n\t}\n\n\t/**\n\t * Tests if host is an offsite link.\n\t * @param {!string} host Link host to compare with\n\t * <code>globals.window.location.host</code>.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisLinkSameOrigin_(host) {\n\t\tconst hostUri = new Uri(host);\n\t\tconst locationHostUri = new Uri(globals.window.location.host);\n\n\t\treturn hostUri.getPort() === locationHostUri.getPort() && hostUri.getHostname() === locationHostUri.getHostname();\n\t}\n\n\t/**\n\t * Tests if link element has the same app's base path.\n\t * @param {!string} path Link path containing the querystring part.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisSameBasePath_(path) {\n\t\treturn path.indexOf(this.basePath) === 0;\n\t}\n\n\t/**\n\t * Lock the document scroll in order to avoid the browser native back and\n\t * forward navigation to change the scroll position. In the end of\n\t * navigation lifecycle scroll is repositioned.\n\t * @protected\n\t */\n\tlockHistoryScrollPosition_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\t\t// Browsers are inconsistent when re-positioning the scroll history on\n\t\t// popstate. At some browsers, history scroll happens before popstate, then\n\t\t// lock the scroll on the last known position as soon as possible after the\n\t\t// current JS execution context and capture the current value. Some others,\n\t\t// history scroll happens after popstate, in this case, we bind an once\n\t\t// scroll event to lock the las known position. Lastly, the previous two\n\t\t// behaviors can happen even on the same browser, hence the race will decide\n\t\t// the winner.\n\t\tvar winner = false;\n\t\tvar switchScrollPositionRace = function() {\n\t\t\tglobals.document.removeEventListener('scroll', switchScrollPositionRace, false);\n\t\t\tif (!winner) {\n\t\t\t\tglobals.window.scrollTo(state.scrollLeft, state.scrollTop);\n\t\t\t\twinner = true;\n\t\t\t}\n\t\t};\n\t\tasync.nextTick(switchScrollPositionRace);\n\t\tglobals.document.addEventListener('scroll', switchScrollPositionRace, false);\n\t}\n\n\t/**\n\t * If supported by the browser, disables native scroll restoration and\n\t * stores current value.\n\t */\n\tmaybeDisableNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported) {\n\t\t\tthis.nativeScrollRestoration_ = globals.window.history.scrollRestoration;\n\t\t\tglobals.window.history.scrollRestoration = 'manual';\n\t\t}\n\t}\n\n\t/**\n\t * This method is used to evaluate if is possible to queue received\n\t * dom event to scheduleNavigationQueue and enqueue it.\n\t * @param {string} href Information about the link's href.\n\t * @param {Event} event Dom event that initiated the navigation.\n\t */\n\tmaybeScheduleNavigation_(href, event) {\n\t\tif (this.isNavigationPending && this.navigationStrategy === NavigationStrategy.SCHEDULE_LAST) {\n\t\t\tthis.scheduledNavigationQueue = [object.mixin({\n\t\t\t\thref,\n\t\t\t\tisScheduledNavigation: true\n\t\t\t}, event)];\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Maybe navigate to a path.\n\t * @param {string} href Information about the link's href.\n\t * @param {Event} event Dom event that initiated the navigation.\n\t */\n\tmaybeNavigate_(href, event) {\n\t\tif (!this.canNavigate(href)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isNavigationScheduled = this.maybeScheduleNavigation_(href, event);\n\n\t\tif (isNavigationScheduled) {\n\t\t\tevent.preventDefault();\n\t\t\treturn;\n\t\t}\n\n\t\tvar navigateFailed = false;\n\t\ttry {\n\t\t\tthis.navigate(utils.getUrlPath(href), false, event);\n\t\t} catch (err) {\n\t\t\t// Do not prevent link navigation in case some synchronous error occurs\n\t\t\tnavigateFailed = true;\n\t\t}\n\n\t\tif (!navigateFailed && !event.isScheduledNavigation) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether the onbeforeunload global event handler is overloaded\n\t * by client code. If so, it replaces with a function that halts the normal\n\t * event flow in relation with the client onbeforeunload function.\n\t * This can be in most part used to prematurely terminate navigation to other pages\n\t * according to the given constrait(s).\n\t * @protected\n\t */\n\tmaybeOverloadBeforeUnload_() {\n\t\tif ('function' === typeof window.onbeforeunload) {\n\t\t\twindow._onbeforeunload = window.onbeforeunload;\n\n\t\t\twindow.onbeforeunload = event => {\n\t\t\t\tthis.emit('beforeUnload', event);\n\t\t\t\tif (event && event.defaultPrevented) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// mark the updated handler due unwanted recursion\n\t\t\twindow.onbeforeunload._overloaded = true;\n\t\t}\n\t}\n\n\t/**\n\t * Cancels navigation if nextScreen's beforeActivate lifecycle method\n\t * resolves to true.\n\t * @param {!Screen} nextScreen\n\t * @return {!CancellablePromise}\n\t */\n\tmaybePreventActivate_(nextScreen) {\n\t\treturn CancellablePromise.resolve()\n\t\t\t.then(() => {\n\t\t\t\treturn nextScreen.beforeActivate();\n\t\t\t})\n\t\t\t.then(prevent => {\n\t\t\t\tif (prevent) {\n\t\t\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('Cancelled by next screen'));\n\t\t\t\t\treturn this.pendingNavigate;\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Cancels navigation if activeScreen's beforeDeactivate lifecycle\n\t * method resolves to true.\n\t * @return {!CancellablePromise}\n\t */\n\tmaybePreventDeactivate_() {\n\t\treturn CancellablePromise.resolve()\n\t\t\t.then(() => {\n\t\t\t\tif (this.activeScreen) {\n\t\t\t\t\treturn this.activeScreen.beforeDeactivate();\n\t\t\t\t}\n\t\t\t})\n\t\t\t.then(prevent => {\n\t\t\t\tif (prevent) {\n\t\t\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('Cancelled by active screen'));\n\t\t\t\t\treturn this.pendingNavigate;\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Maybe reposition scroll to hashed anchor.\n\t */\n\tmaybeRepositionScrollToHashedAnchor() {\n\t\tconst hash = globals.window.location.hash;\n\t\tif (hash) {\n\t\t\tlet anchorElement = globals.document.getElementById(hash.substring(1));\n\t\t\tif (anchorElement) {\n\t\t\t\tconst {offsetLeft, offsetTop} = utils.getNodeOffset(anchorElement);\n\t\t\t\tglobals.window.scrollTo(offsetLeft, offsetTop);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If supported by the browser, restores native scroll restoration to the\n\t * value captured by `maybeDisableNativeScrollRestoration`.\n\t */\n\tmaybeRestoreNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported && this.nativeScrollRestoration_) {\n\t\t\tglobals.window.history.scrollRestoration = this.nativeScrollRestoration_;\n\t\t}\n\t}\n\n\t/**\n\t * Maybe restore redirected path hash in case both the current path and\n\t * the given path are the same.\n\t * @param {!string} path Path before navigation.\n\t * @param {!string} redirectPath Path after navigation.\n\t * @param {!string} hash Hash to be added to the path.\n\t * @return {!string} Returns the path with the hash restored.\n\t */\n\tmaybeRestoreRedirectPathHash_(path, redirectPath, hash) {\n\t\tif (redirectPath === utils.getUrlPathWithoutHash(path)) {\n\t\t\treturn redirectPath + hash;\n\t\t}\n\t\treturn redirectPath;\n\t}\n\n\t/**\n\t * Maybe update scroll position in history state to anchor on path.\n\t * @param {!string} path Path containing anchor\n\t */\n\tmaybeUpdateScrollPositionState_() {\n\t\tvar hash = globals.window.location.hash;\n\t\tvar anchorElement = globals.document.getElementById(hash.substring(1));\n\t\tif (anchorElement) {\n\t\t\tconst {offsetLeft, offsetTop} = utils.getNodeOffset(anchorElement);\n\t\t\tthis.saveHistoryCurrentPageScrollPosition_(offsetTop, offsetLeft);\n\t\t}\n\t}\n\n\t/**\n\t * Navigates to the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @param {Event=} event Optional event object that triggered the navigation.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tnavigate(path, opt_replaceHistory, opt_event) {\n\t\tif (!utils.isHtml5HistorySupported()) {\n\t\t\tthrow new Error('HTML5 History is not supported. Senna will not intercept navigation.');\n\t\t}\n\n\t\tif (opt_event) {\n\t\t\tglobals.capturedFormElement = opt_event.capturedFormElement;\n\t\t\tglobals.capturedFormButtonElement = opt_event.capturedFormButtonElement;\n\t\t}\n\n\t\t// When reloading the same path do replaceState instead of pushState to\n\t\t// avoid polluting history with states with the same path.\n\t\tif (path === this.activePath) {\n\t\t\topt_replaceHistory = true;\n\t\t}\n\n\t\tthis.emit('beforeNavigate', {\n\t\t\tevent: opt_event,\n\t\t\tpath: path,\n\t\t\treplaceHistory: !!opt_replaceHistory\n\t\t});\n\n\t\treturn this.pendingNavigate;\n\t}\n\n\t/**\n\t * Befores navigation to a path.\n\t * @param {!Event} event Event facade containing <code>path</code> and\n\t * <code>replaceHistory</code>.\n\t * @protected\n\t */\n\tonBeforeNavigate_(event) {\n\t\tif (globals.capturedFormElement) {\n\t\t\tevent.form = globals.capturedFormElement;\n\t\t}\n\t}\n\n\t/**\n\t * Befores navigation to a path. Runs after external listeners.\n\t * @param {!Event} event Event facade containing <code>path</code> and\n\t * <code>replaceHistory</code>.\n\t * @protected\n\t */\n\tonBeforeNavigateDefault_(event) {\n\t\tif (this.pendingNavigate) {\n\t\t\tif (this.pendingNavigate.path === event.path || this.navigationStrategy === NavigationStrategy.SCHEDULE_LAST) {\n\t\t\t\tconsole.log('Waiting...');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.emit('beforeUnload', event);\n\n\t\tthis.emit('startNavigate', {\n\t\t\tform: event.form,\n\t\t\tpath: event.path,\n\t\t\treplaceHistory: event.replaceHistory\n\t\t});\n\t}\n\n\t/**\n\t * Custom event handler that executes the original listener that has been\n\t * added by the client code and terminates the navigation accordingly.\n\t * @param {!Event} event original Event facade.\n\t * @protected\n\t */\n\tonBeforeUnloadDefault_(event) {\n\t\tvar func = window._onbeforeunload;\n\t\tif (func && !func._overloaded && func()) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/**\n\t * Intercepts document clicks and test link elements in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocClickDelegate_(event) {\n\t\tif (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.button) {\n\t\t\tconsole.log('Navigate aborted, invalid mouse button or modifier key pressed.');\n\t\t\treturn;\n\t\t}\n\t\tthis.maybeNavigate_(event.delegateTarget.href, event);\n\t}\n\n\t/**\n\t * Intercepts document form submits and test action path in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocSubmitDelegate_(event) {\n\t\tvar form = event.delegateTarget;\n\t\tif (form.method === 'get') {\n\t\t\tconsole.log('GET method not supported');\n\t\t\treturn;\n\t\t}\n\t\tevent.capturedFormElement = form;\n\t\tconst buttonSelector = 'button:not([type]),button[type=submit],input[type=submit]';\n\t\tif (match(globals.document.activeElement, buttonSelector)) {\n\t\t\tevent.capturedFormButtonElement = globals.document.activeElement;\n\t\t} else {\n\t\t\tevent.capturedFormButtonElement = form.querySelector(buttonSelector);\n\t\t}\n\t\tthis.maybeNavigate_(form.action, event);\n\t}\n\n\t/**\n\t * Listens to the window's load event in order to avoid issues with some browsers\n\t * that trigger popstate calls on the first load. For more information see\n\t * http://stackoverflow.com/questions/6421769/popstate-on-pages-load-in-chrome.\n\t * @protected\n\t */\n\tonLoad_() {\n\t\tthis.skipLoadPopstate = true;\n\t\tsetTimeout(() => {\n\t\t\t// The timeout ensures that popstate events will be unblocked right\n\t\t\t// after the load event occured, but not in the same event-loop cycle.\n\t\t\tthis.skipLoadPopstate = false;\n\t\t}, 0);\n\t\t// Try to reposition scroll to the hashed anchor when page loads.\n\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t}\n\n\t/**\n\t * Handles browser history changes and fires app's navigation if the state\n\t * belows to us. If we detect a popstate and the state is <code>null</code>,\n\t * assume it is navigating to an external page or to a page we don't have\n\t * route, then <code>globals.window.location.reload()</code> is invoked in order to\n\t * reload the content to the current url.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonPopstate_(event) {\n\t\tif (this.skipLoadPopstate) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not navigate if the popstate was triggered by a hash change.\n\t\tif (utils.isCurrentBrowserPath(this.browserPathBeforeNavigate)) {\n\t\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t\t\treturn;\n\t\t}\n\n\t\tvar state = event.state;\n\n\t\tif (!state) {\n\t\t\tif (globals.window.location.hash) {\n\t\t\t\t// If senna is on an redirect path and a hash popstate happens\n\t\t\t\t// to a different url, reload the browser. This behavior doesn't\n\t\t\t\t// require senna to route hashed links and is closer to native\n\t\t\t\t// browser behavior.\n\t\t\t\tif (this.redirectPath && !utils.isCurrentBrowserPath(this.redirectPath)) {\n\t\t\t\t\tthis.reloadPage();\n\t\t\t\t}\n\t\t\t\t// Always try to reposition scroll to the hashed anchor when\n\t\t\t\t// hash popstate happens.\n\t\t\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t\t\t} else {\n\t\t\t\tthis.reloadPage();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (state.senna) {\n\t\t\tconsole.log('History navigation to [' + state.path + ']');\n\t\t\tthis.popstateScrollTop = state.scrollTop;\n\t\t\tthis.popstateScrollLeft = state.scrollLeft;\n\t\t\tif (!this.nativeScrollRestorationSupported) {\n\t\t\t\tthis.lockHistoryScrollPosition_();\n\t\t\t}\n\t\t\tthis.once('endNavigate', () => {\n\t\t\t\tif (state.referrer) {\n\t\t\t\t\tutils.setReferrer(state.referrer);\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst uri = new Uri(state.path);\n\t\t\turi.setHostname(globals.window.location.hostname);\n\t\t\turi.setPort(globals.window.location.port);\n\t\t\tconst isNavigationScheduled = this.maybeScheduleNavigation_(uri.toString(), {});\n\t\t\tif (isNavigationScheduled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.navigate(state.path, true);\n\t\t}\n\t}\n\n\t/**\n\t * Listens document scroll changes in order to capture the possible lock\n\t * scroll position for history scrolling.\n\t * @protected\n\t */\n\tonScroll_() {\n\t\tif (this.captureScrollPositionFromScrollEvent) {\n\t\t\tthis.saveHistoryCurrentPageScrollPosition_(globals.window.pageYOffset, globals.window.pageXOffset);\n\t\t}\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!Event} event Event facade containing <code>path</code> and\n\t * <code>replaceHistory</code>.\n\t * @protected\n\t */\n\tonStartNavigate_(event) {\n\t\tthis.maybeDisableNativeScrollRestoration();\n\t\tthis.captureScrollPositionFromScrollEvent = false;\n\t\taddClasses(globals.document.documentElement, this.loadingCssClass);\n\n\t\tvar endNavigatePayload = {\n\t\t\tform: event.form,\n\t\t\tpath: event.path\n\t\t};\n\n\t\tthis.pendingNavigate = this.doNavigate_(event.path, event.replaceHistory)\n\t\t\t.catch((reason) => {\n\t\t\t\tendNavigatePayload.error = reason;\n\t\t\t\tthrow reason;\n\t\t\t})\n\t\t\t.thenAlways(() => {\n\t\t\t\tif (!this.pendingNavigate && !this.scheduledNavigationQueue.length) {\n\t\t\t\t\tremoveClasses(globals.document.documentElement, this.loadingCssClass);\n\t\t\t\t\tthis.maybeRestoreNativeScrollRestoration();\n\t\t\t\t\tthis.captureScrollPositionFromScrollEvent = true;\n\t\t\t\t}\n\t\t\t\tthis.emit('endNavigate', endNavigatePayload);\n\t\t\t});\n\n\t\tthis.pendingNavigate.path = event.path;\n\t}\n\n\t/**\n\t * Prefetches the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tprefetch(path) {\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\treturn CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t}\n\n\t\tconsole.log('Prefetching [' + path + ']');\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn nextScreen.load(path)\n\t\t\t.then(() => this.screens[path] = nextScreen)\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t */\n\tprepareNavigateHistory_(path, nextScreen, opt_replaceHistory) {\n\t\tlet title = nextScreen.getTitle();\n\t\tif (!isString(title)) {\n\t\t\ttitle = this.getDefaultTitle();\n\t\t}\n\t\tlet redirectPath = nextScreen.beforeUpdateHistoryPath(path);\n\t\tconst historyState = {\n\t\t\tform: isDefAndNotNull(globals.capturedFormElement),\n\t\t\tpath,\n\t\t\tredirectPath,\n\t\t\tscrollLeft: 0,\n\t\t\tscrollTop: 0,\n\t\t\tsenna: true\n\t\t};\n\t\tif (opt_replaceHistory) {\n\t\t\thistoryState.scrollTop = this.popstateScrollTop;\n\t\t\thistoryState.scrollLeft = this.popstateScrollLeft;\n\t\t}\n\t\tconst hash = new Uri(path).getHash();\n\t\tredirectPath = this.maybeRestoreRedirectPathHash_(path, redirectPath, hash);\n\t\tthis.updateHistory_(title, redirectPath, nextScreen.beforeUpdateHistoryState(historyState), opt_replaceHistory);\n\t\tthis.redirectPath = redirectPath;\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!Screen} nextScreen\n\t * @param {!Object} surfaces Map of surfaces to flip keyed by surface id.\n\t * @param {!Object} params Params extracted from the current path.\n\t */\n\tprepareNavigateSurfaces_(nextScreen, surfaces, params) {\n\t\tObject.keys(surfaces).forEach((id) => {\n\t\t\tvar surfaceContent = nextScreen.getSurfaceContent(id, params);\n\t\t\tsurfaces[id].addContent(nextScreen.getId(), surfaceContent);\n\t\t\tconsole.log('Screen [' + nextScreen.getId() + '] add content to surface ' +\n\t\t\t\t'[' + surfaces[id] + '] [' + (isDefAndNotNull(surfaceContent) ? '...' : 'empty') + ']');\n\t\t});\n\t}\n\n\t/**\n\t * Reloads the page by performing `window.location.reload()`.\n\t */\n\treloadPage() {\n\t\tglobals.window.location.reload();\n\t}\n\n\t/**\n\t * Removes route instance from app routes.\n\t * @param {Route} route\n\t * @return {boolean} True if an element was removed.\n\t */\n\tremoveRoute(route) {\n\t\treturn array.remove(this.routes, route);\n\t}\n\n\t/**\n\t * Removes a screen.\n\t * @param {!string} path Path containing the querystring part.\n\t */\n\tremoveScreen(path) {\n\t\tvar screen = this.screens[path];\n\t\tif (screen) {\n\t\t\tObject.keys(this.surfaces).forEach((surfaceId) => this.surfaces[surfaceId].remove(screen.getId()));\n\t\t\tscreen.dispose();\n\t\t\tdelete this.screens[path];\n\t\t}\n\t}\n\n\t/**\n\t * Saves given scroll position into history state.\n\t * @param {!number} scrollTop Number containing the top scroll position to be saved.\n\t * @param {!number} scrollLeft Number containing the left scroll position to be saved.\n\t */\n\tsaveHistoryCurrentPageScrollPosition_(scrollTop, scrollLeft) {\n\t\tvar state = globals.window.history.state;\n\t\tif (state && state.senna) {\n\t\t\t[state.scrollTop, state.scrollLeft] = [scrollTop, scrollLeft];\n\t\t\tglobals.window.history.replaceState(state, null, null);\n\t\t}\n\t}\n\n\t/**\n\t * Sets allow prevent navigate.\n\t * @param {boolean} allowPreventNavigate\n\t */\n\tsetAllowPreventNavigate(allowPreventNavigate) {\n\t\tthis.allowPreventNavigate = allowPreventNavigate;\n\t}\n\n\t/**\n\t * Sets link base path.\n\t * @param {!string} path\n\t */\n\tsetBasePath(basePath) {\n\t\tthis.basePath = utils.removePathTrailingSlash(basePath);\n\t}\n\n\t/**\n\t * Sets the default page title.\n\t * @param {string} defaultTitle\n\t */\n\tsetDefaultTitle(defaultTitle) {\n\t\tthis.defaultTitle = defaultTitle;\n\t}\n\n\t/**\n\t * Sets the form selector.\n\t * @param {!string} formSelector\n\t */\n\tsetFormSelector(formSelector) {\n\t\tthis.formSelector = formSelector;\n\t\tif (this.formEventHandler_) {\n\t\t\tthis.formEventHandler_.removeListener();\n\t\t}\n\t\tthis.formEventHandler_ = delegate(document, 'submit', this.formSelector, this.onDocSubmitDelegate_.bind(this), this.allowPreventNavigate);\n\t}\n\n\t/**\n\t * Sets if route matching should ignore query string from the route path.\n\t * @param {boolean} ignoreQueryStringFromRoutePath\n\t */\n\tsetIgnoreQueryStringFromRoutePath(ignoreQueryStringFromRoutePath) {\n\t\tthis.ignoreQueryStringFromRoutePath = ignoreQueryStringFromRoutePath;\n\t}\n\n\t/**\n\t * Sets the link selector.\n\t * @param {!string} linkSelector\n\t */\n\tsetLinkSelector(linkSelector) {\n\t\tthis.linkSelector = linkSelector;\n\t\tif (this.linkEventHandler_) {\n\t\t\tthis.linkEventHandler_.removeListener();\n\t\t}\n\t\tthis.linkEventHandler_ = delegate(document, 'click', this.linkSelector, this.onDocClickDelegate_.bind(this), this.allowPreventNavigate);\n\t}\n\n\t/**\n\t * Sets the loading css class.\n\t * @param {!string} loadingCssClass\n\t */\n\tsetLoadingCssClass(loadingCssClass) {\n\t\tthis.loadingCssClass = loadingCssClass;\n\t}\n\n\t/**\n\t * Sets the update scroll position value.\n\t * @param {boolean} updateScrollPosition\n\t */\n\tsetUpdateScrollPosition(updateScrollPosition) {\n\t\tthis.updateScrollPosition = updateScrollPosition;\n\t}\n\n\t/**\n\t * Cancels pending navigate with <code>Cancel pending navigation</code> error.\n\t * @protected\n\t */\n\tstopPendingNavigate_() {\n\t\tif (this.pendingNavigate) {\n\t\t\tthis.pendingNavigate.cancel('Cancel pending navigation');\n\t\t}\n\t\tthis.pendingNavigate = null;\n\t}\n\n\t/**\n\t * Sync document scroll position twice, the first one synchronous and then\n\t * one inside <code>async.nextTick</code>. Relevant to browsers that fires\n\t * scroll restoration asynchronously after popstate.\n\t * @protected\n\t * @return {?CancellablePromise=}\n\t */\n\tsyncScrollPositionSyncThenAsync_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar scrollTop = state.scrollTop;\n\t\tvar scrollLeft = state.scrollLeft;\n\n\t\tvar sync = () => {\n\t\t\tif (this.updateScrollPosition) {\n\t\t\t\tglobals.window.scrollTo(scrollLeft, scrollTop);\n\t\t\t}\n\t\t};\n\n\t\treturn new CancellablePromise((resolve) => sync() & async.nextTick(() => sync() & resolve()));\n\t}\n\n\t/**\n\t * Updates or replace browser history.\n\t * @param {?string} title Document title.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!object} state\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @protected\n\t */\n\tupdateHistory_(title, path, state, opt_replaceHistory) {\n\t\tconst referrer = globals.window.location.href;\n\n\t\tif (state) {\n\t\t\tstate.referrer = referrer;\n\t\t}\n\n\t\tif (opt_replaceHistory) {\n\t\t\tglobals.window.history.replaceState(state, title, path);\n\t\t} else {\n\t\t\tglobals.window.history.pushState(state, title, path);\n\t\t}\n\n\t\tutils.setReferrer(referrer);\n\n\t\tlet titleNode = globals.document.querySelector('title');\n\t\tif (titleNode) {\n\t\t\ttitleNode.innerHTML = title;\n\t\t} else {\n\t\t\tglobals.document.title = title;\n\t\t}\n\t}\n\n}\n\nexport default App;\n","'use strict';\n\nimport { isDef, isDefAndNotNull } from 'metal';\nimport Uri from 'metal-uri';\nimport { CancellablePromise as Promise } from 'metal-promise';\n\nclass Ajax {\n\n\t/**\n\t * XmlHttpRequest's getAllResponseHeaders() method returns a string of\n\t * response headers according to the format described on the spec:\n\t * {@link http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders-method}.\n\t * This method parses that string into a user-friendly name/value pair\n\t * object.\n\t * @param {string} allHeaders All headers as string.\n\t * @return {!Array.<Object<string, string>>}\n\t */\n\tstatic parseResponseHeaders(allHeaders) {\n\t\tvar headers = [];\n\t\tif (!allHeaders) {\n\t\t\treturn headers;\n\t\t}\n\t\tvar pairs = allHeaders.split('\\u000d\\u000a');\n\t\tfor (var i = 0; i < pairs.length; i++) {\n\t\t\tvar index = pairs[i].indexOf('\\u003a\\u0020');\n\t\t\tif (index > 0) {\n\t\t\t\tvar name = pairs[i].substring(0, index);\n\t\t\t\tvar value = pairs[i].substring(index + 2);\n\t\t\t\theaders.push({\n\t\t\t\t\tname: name,\n\t\t\t\t\tvalue: value\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn headers;\n\t}\n\n\t/**\n\t * Requests the url using XMLHttpRequest.\n\t * @param {!string} url\n\t * @param {!string} method\n\t * @param {?string} body\n\t * @param {MultiMap=} opt_headers\n\t * @param {MultiMap=} opt_params\n\t * @param {number=} opt_timeout\n\t * @param {boolean=} opt_sync\n\t * @param {boolean=} opt_withCredentials\n\t * @return {Promise} Deferred ajax request.\n\t * @protected\n\t */\n\tstatic request(url, method, body, opt_headers, opt_params, opt_timeout, opt_sync, opt_withCredentials) {\n\t\turl = url || '';\n\t\tmethod = method || 'GET';\n\n\t\tvar request = new XMLHttpRequest();\n\t\tvar previousReadyState = 0;\n\n\t\tvar promise = new Promise(function(resolve, reject) {\n\t\t\trequest.onload = function() {\n\t\t\t\tif (request.aborted) {\n\t\t\t\t\trequest.onerror();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tresolve(request);\n\t\t\t};\n\t\t\trequest.onreadystatechange = function() {\n\t\t\t\tif (previousReadyState && previousReadyState < 3 && 4 === request.readyState) {\n\t\t\t\t\trequest.terminatedPrematurely = true;\n\t\t\t\t}\n\t\t\t\tpreviousReadyState = request.readyState;\n\t\t\t};\n\t\t\trequest.onerror = function() {\n\t\t\t\tvar message = 'Request error';\n\t\t\t\tif (request.terminatedPrematurely) {\n\t\t\t\t\tmessage = 'Request terminated prematurely';\n\t\t\t\t} \n\t\t\t\tvar error = new Error(message);\n\t\t\t\terror.request = request;\n\t\t\t\treject(error);\n\t\t\t};\n\t\t}).thenCatch(function(reason) {\n\t\t\trequest.abort();\n\t\t\tthrow reason;\n\t\t}).thenAlways(function() {\n\t\t\tclearTimeout(timeout);\n\t\t});\n\n\t\turl = new Uri(url);\n\n\t\tif (opt_params) {\n\t\t\turl.addParametersFromMultiMap(opt_params).toString();\n\t\t}\n\n\t\turl = url.toString();\n\n\t\trequest.open(method, url, !opt_sync);\n\n\t\tif (opt_withCredentials) {\n\t\t\trequest.withCredentials = true;\n\t\t}\n\n\t\tif (opt_headers) {\n\t\t\topt_headers.names().forEach(function(name) {\n\t\t\t\trequest.setRequestHeader(name, opt_headers.getAll(name).join(', '));\n\t\t\t});\n\t\t}\n\n\t\trequest.send(isDef(body) ? body : null);\n\n\t\tif (isDefAndNotNull(opt_timeout)) {\n\t\t\tvar timeout = setTimeout(function() {\n\t\t\t\tpromise.cancel('Request timeout');\n\t\t\t}, opt_timeout);\n\t\t}\n\n\t\treturn promise;\n\t}\n\n}\n\nexport default Ajax;\n","'use strict';\n\n/**\n * Holds value error messages.\n * @const\n */\nclass errors {\n}\n\n/**\n * Invalid status error message.\n * @type {string}\n * @static\n */\nerrors.INVALID_STATUS = 'Invalid status code';\n\n/**\n * Request error message.\n * @type {string}\n * @static\n */\nerrors.REQUEST_ERROR = 'Request error';\n\n/**\n * Request timeout error message.\n * @type {string}\n * @static\n */\nerrors.REQUEST_TIMEOUT = 'Request timeout';\n\n/**\n * Request is blocked by CORS issue message.\n * @type {string}\n * @static\n */\nerrors.REQUEST_PREMATURE_TERMINATION = 'Request terminated prematurely';\n\nexport default errors;\n","'use strict';\n\nimport {isServerSide} from 'metal';\n\n/**\n * Metal.js browser user agent detection. It's extremely recommended the usage\n * of feature checking over browser user agent sniffing. Unfortunately, in some\n * situations feature checking can be slow or even impossible, therefore use\n * this utility with caution.\n * @see <a href=\"http://www.useragentstring.com/\">User agent strings</a>.\n */\nclass UA {\n\t/**\n\t * Gets the native userAgent string from navigator if it exists. If\n\t * navigator or navigator.userAgent string is missing, returns an empty\n\t * string.\n\t * @return {string}\n\t * @private\n\t * @static\n\t */\n\tstatic getNativeUserAgent() {\n\t\tlet navigator = UA.globals.window && UA.globals.window.navigator;\n\t\tif (navigator) {\n\t\t\tlet userAgent = navigator.userAgent;\n\t\t\tif (userAgent) {\n\t\t\t\treturn userAgent;\n\t\t\t}\n\t\t}\n\t\treturn '';\n\t}\n\n\t/**\n\t * Gets the native platform string from navigator if it exists. If\n\t * navigator or navigator.platform string is missing, returns an empty\n\t * string.\n\t * @return {string}\n\t * @private\n\t * @static\n\t */\n\tstatic getNativePlatform() {\n\t\tlet navigator = UA.globals.window && UA.globals.window.navigator;\n\t\tif (navigator) {\n\t\t\tlet platform = navigator.platform;\n\t\t\tif (platform) {\n\t\t\t\treturn platform;\n\t\t\t}\n\t\t}\n\t\treturn '';\n\t}\n\n\t/**\n\t * Whether the platform contains the given string, ignoring case.\n\t * @param {string} str\n\t * @return {boolean}\n\t * @private\n\t * @static\n\t */\n\tstatic matchPlatform(str) {\n\t\treturn UA.platform.indexOf(str) !== -1;\n\t}\n\n\t/**\n\t * Whether the user agent contains the given string, ignoring case.\n\t * @param {string} str\n\t * @return {boolean}\n\t * @private\n\t * @static\n\t */\n\tstatic matchUserAgent(str) {\n\t\treturn UA.userAgent.indexOf(str) !== -1;\n\t}\n\n\t/**\n\t * Tests the user agent.\n\t * @param {string} userAgent The user agent string.\n\t * @param {string} platform\n\t * @static\n\t */\n\tstatic testUserAgent(userAgent = '', platform = '') {\n\t\t/**\n\t\t * Holds the user agent value extracted from browser native user agent.\n\t\t * @type {string}\n\t\t * @static\n\t\t */\n\t\tUA.userAgent = userAgent;\n\n\t\t/**\n\t\t * Holds the platform value extracted from browser native platform.\n\t\t * @type {string}\n\t\t * @static\n\t\t */\n\t\tUA.platform = platform;\n\n\t\t/**\n\t\t * Whether the user's OS is Mac.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isMac = UA.matchPlatform('Mac');\n\n\t\t/**\n\t\t * Whether the user's OS is Win.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isWin = UA.matchPlatform('Win');\n\n\t\t/**\n\t\t * Whether the user's browser is Opera.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isOpera = UA.matchUserAgent('Opera') || UA.matchUserAgent('OPR');\n\n\t\t/**\n\t\t * Whether the user's browser is IE.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isIe = UA.matchUserAgent('Trident') || UA.matchUserAgent('MSIE');\n\n\t\t/**\n\t\t * Whether the user's browser is Edge.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isEdge = UA.matchUserAgent('Edge');\n\n\t\t/**\n\t\t * Whether the user's browser is IE or Edge.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isIeOrEdge = UA.isIe || UA.isEdge;\n\n\t\t/**\n\t\t * Whether the user's browser is Chrome.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isChrome =\n\t\t\t(UA.matchUserAgent('Chrome') || UA.matchUserAgent('CriOS')) &&\n\t\t\t!UA.isOpera &&\n\t\t\t!UA.isEdge;\n\n\t\t/**\n\t\t * Whether the user's browser is Safari.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isSafari =\n\t\t\tUA.matchUserAgent('Safari') &&\n\t\t\t!(UA.isChrome || UA.isOpera || UA.isEdge);\n\n\t\t/**\n\t\t * Whether the user's browser is Firefox.\n\t\t * @type {boolean}\n\t\t * @static\n\t\t */\n\t\tUA.isFirefox = UA.matchUserAgent('Firefox');\n\t}\n}\n\n/**\n * Exposes global references.\n * @type {object}\n * @static\n */\nObject.defineProperty(UA, 'globals', {\n\twritable: true,\n\tvalue: {\n\t\twindow: isServerSide() ? null : window,\n\t},\n});\n\nUA.testUserAgent(UA.getNativeUserAgent(), UA.getNativePlatform());\n\nexport default UA;\n","'use strict';\n\nimport { isDefAndNotNull } from 'metal';\nimport Ajax from 'metal-ajax';\nimport { MultiMap } from 'metal-structs';\nimport CancellablePromise from 'metal-promise';\nimport errors from '../errors/errors';\nimport utils from '../utils/utils';\nimport globals from '../globals/globals';\nimport Screen from './Screen';\nimport Uri from 'metal-uri';\nimport UA from 'metal-useragent';\n\nclass RequestScreen extends Screen {\n\n\t/**\n\t * Request screen abstract class to perform io operations on descendant\n\t * screens.\n\t * @constructor\n\t * @extends {Screen}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t * @default true\n\t\t */\n\t\tthis.cacheable = true;\n\n\t\t/**\n\t\t * Holds default http headers to set on request.\n\t\t * @type {?Object=}\n\t\t * @default {\n\t\t * 'X-PJAX': 'true',\n\t\t * 'X-Requested-With': 'XMLHttpRequest'\n\t\t * }\n\t\t * @protected\n\t\t */\n\t\tthis.httpHeaders = {\n\t\t\t'X-PJAX': 'true',\n\t\t\t'X-Requested-With': 'XMLHttpRequest'\n\t\t};\n\n\t\t/**\n\t\t * Holds default http method to perform the request.\n\t\t * @type {!string}\n\t\t * @default RequestScreen.GET\n\t\t * @protected\n\t\t */\n\t\tthis.httpMethod = RequestScreen.GET;\n\n\t\t/**\n\t\t * Holds the XHR object responsible for the request.\n\t\t * @type {XMLHttpRequest}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.request = null;\n\n\t\t/**\n\t\t * Holds the request timeout in milliseconds.\n\t\t * @type {!number}\n\t\t * @default 30000\n\t\t * @protected\n\t\t */\n\t\tthis.timeout = 30000;\n\t}\n\n\t/**\n\t * Asserts that response status code is valid.\n\t * @param {number} status\n\t * @protected\n\t */\n\tassertValidResponseStatusCode(status) {\n\t\tif (!this.isValidResponseStatusCode(status)) {\n\t\t\tvar error = new Error(errors.INVALID_STATUS);\n\t\t\terror.invalidStatus = true;\n\t\t\terror.statusCode = status;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tbeforeUpdateHistoryPath(path) {\n\t\tvar redirectPath = this.getRequestPath();\n\t\tif (redirectPath && redirectPath !== path) {\n\t\t\treturn redirectPath;\n\t\t}\n\t\treturn path;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tbeforeUpdateHistoryState(state) {\n\t\t// If state is ours and navigate to post-without-redirect-get set\n\t\t// history state to null, that way Senna will reload the page on\n\t\t// popstate since it cannot predict post data.\n\t\tif (state.senna && state.form && state.redirectPath === state.path) {\n\t\t\treturn null;\n\t\t}\n\t\treturn state;\n\t}\n\n\t/**\n\t * Formats load path before invoking ajax call.\n\t * @param {string} path\n\t * @return {string} Formatted path;\n\t * @protected\n\t */\n\tformatLoadPath(path) {\n\t\tvar uri = new Uri(path);\n\n\t\turi.setHostname(globals.window.location.hostname);\n\t\turi.setProtocol(globals.window.location.protocol);\n\n\t\tif (globals.window.location.port) {\n\t\t\turi.setPort(globals.window.location.port);\n\t\t}\n\n\t\tif (UA.isIeOrEdge && this.httpMethod === RequestScreen.GET) {\n\t\t\treturn uri.makeUnique().toString();\n\t\t}\n\n\t\treturn uri.toString();\n\t}\n\n\t/**\n\t * Gets the http headers.\n\t * @return {?Object=}\n\t */\n\tgetHttpHeaders() {\n\t\treturn this.httpHeaders;\n\t}\n\n\t/**\n\t * Gets the http method.\n\t * @return {!string}\n\t */\n\tgetHttpMethod() {\n\t\treturn this.httpMethod;\n\t}\n\n\t/**\n\t * Gets request path.\n\t * @return {string=}\n\t */\n\tgetRequestPath() {\n\t\tvar request = this.getRequest();\n\t\tif (request) {\n\t\t\tvar requestPath = request.requestPath;\n\t\t\tvar responseUrl = this.maybeExtractResponseUrlFromRequest(request);\n\t\t\tif (responseUrl) {\n\t\t\t\trequestPath = responseUrl;\n\t\t\t}\n\t\t\tif (UA.isIeOrEdge && this.httpMethod === RequestScreen.GET) {\n\t\t\t\trequestPath = new Uri(requestPath).removeUnique().toString();\n\t\t\t}\n\t\t\treturn utils.getUrlPath(requestPath);\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets the request object.\n\t * @return {?Object}\n\t */\n\tgetRequest() {\n\t\treturn this.request;\n\t}\n\n\t/**\n\t * Gets the request timeout.\n\t * @return {!number}\n\t */\n\tgetTimeout() {\n\t\treturn this.timeout;\n\t}\n\n\t/**\n\t * Checks if response succeeded. Any status code 2xx or 3xx is considered\n\t * valid.\n\t * @param {number} statusCode\n\t */\n\tisValidResponseStatusCode(statusCode) {\n\t\treturn statusCode >= 200 && statusCode <= 399;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tload(path) {\n\t\tconst cache = this.getCache();\n\t\tif (isDefAndNotNull(cache)) {\n\t\t\treturn CancellablePromise.resolve(cache);\n\t\t}\n\t\tlet body = null;\n\t\tlet httpMethod = this.httpMethod;\n\t\tconst headers = new MultiMap();\n\t\tObject.keys(this.httpHeaders).forEach(header => headers.add(header, this.httpHeaders[header]));\n\t\tif (globals.capturedFormElement) {\n\t\t\tthis.addSafariXHRPolyfill();\n\t\t\tbody = new FormData(globals.capturedFormElement);\n\t\t\tthis.maybeAppendSubmitButtonValue_(body);\n\t\t\thttpMethod = RequestScreen.POST;\n\t\t\tif (UA.isIeOrEdge) {\n\t\t\t\theaders.add('If-None-Match', '\"0\"');\n\t\t\t}\n\t\t}\n\t\tconst requestPath = this.formatLoadPath(path);\n\t\treturn Ajax\n\t\t\t.request(requestPath, httpMethod, body, headers, null, this.timeout)\n\t\t\t.then(xhr => {\n\t\t\t\tthis.removeSafariXHRPolyfill();\n\t\t\t\tthis.setRequest(xhr);\n\t\t\t\tthis.assertValidResponseStatusCode(xhr.status);\n\t\t\t\tif (httpMethod === RequestScreen.GET && this.isCacheable()) {\n\t\t\t\t\tthis.addCache(xhr.responseText);\n\t\t\t\t}\n\t\t\t\txhr.requestPath = requestPath;\n\t\t\t\treturn xhr.responseText;\n\t\t\t})\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.removeSafariXHRPolyfill();\n\t\t\t\tswitch (reason.message) {\n\t\t\t\t\tcase errors.REQUEST_TIMEOUT:\n\t\t\t\t\t\treason.timeout = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase errors.REQUEST_ERROR:\n\t\t\t\t\t\treason.requestError = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase errors.REQUEST_PREMATURE_TERMINATION:\n\t\t\t\t\t\treason.requestError = true;\n\t\t\t\t\t\treason.requestPrematureTermination = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Adds aditional data to the body of the request in case a submit button\n\t * is captured during form submission.\n\t * @param {!FormData} body The FormData containing the request body.\n\t * @protected\n\t */\n\tmaybeAppendSubmitButtonValue_(body) {\n\t\tconst button = globals.capturedFormButtonElement;\n\t\tif (button && button.name) {\n\t\t\tbody.append(button.name, button.value);\n\t\t}\n\t}\n\n\t/**\n\t * The following method tries to extract the response url value by checking\n\t * the custom response header 'X-Request-URL' if proper value is not present\n\t * in XMLHttpRequest. The value of responseURL will be the final URL\n\t * obtained after any redirects. Internet Explorer, Edge and Safari <= 7\n\t * does not yet support the feature. For more information see:\n\t * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseURL\n\t * https://xhr.spec.whatwg.org/#the-responseurl-attribute\n\t * @param {XMLHttpRequest} request\n\t * @return {?string} Response url best match.\n\t */\n\tmaybeExtractResponseUrlFromRequest(request) {\n\t\tvar responseUrl = request.responseURL;\n\t\tif (responseUrl) {\n\t\t\treturn responseUrl;\n\t\t}\n\t\treturn request.getResponseHeader(RequestScreen.X_REQUEST_URL_HEADER);\n\t}\n\n\t/**\n\t * This function set attribute data-safari-temp-disabled to \n\t * true and set disable attribute of an input type=\"file\" tag\n\t * is used as a polyfill for iOS 11.3 Safari / macOS Safari 11.1 \n\t * empty <input type=\"file\"> XHR bug.\n\t * https://github.com/rails/rails/issues/32440\n\t * https://bugs.webkit.org/show_bug.cgi?id=184490\n\t */\n\taddSafariXHRPolyfill() {\n\t\tif (globals.capturedFormElement && UA.isSafari) {\n\t\t\tlet inputs = globals.capturedFormElement.querySelectorAll('input[type=\"file\"]:not([disabled])');\n\t\t\tfor (let index = 0; index < inputs.length; index++) {\n\t\t\t\tlet input = inputs[index];\n\t\t\t\tif (input.files.length > 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tinput.setAttribute('data-safari-temp-disabled', 'true');\n\t\t\t\tinput.setAttribute('disabled', '');\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * This function remove attribute data-safari-temp-disabled and disable attribute\n\t * of an input type=\"file\" tag is used as a polyfill for iOS 11.3 Safari / macOS Safari 11.1\n\t * empty <input type=\"file\"> XHR bug.\n\t * https://github.com/rails/rails/issues/32440\n\t * https://bugs.webkit.org/show_bug.cgi?id=184490\n\t */\n\tremoveSafariXHRPolyfill() {\n\t\tif (globals.capturedFormElement && UA.isSafari) {\n\t\t\tlet inputs = globals.capturedFormElement.querySelectorAll('input[type=\"file\"][data-safari-temp-disabled]');\n\t\t\tfor (let index = 0; index < inputs.length; index++) {\n\t\t\t\tconst input = inputs[index];\n\t\t\t\tinput.removeAttribute('data-safari-temp-disabled');\n\t\t\t\tinput.removeAttribute('disabled');\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sets the http headers.\n\t * @param {?Object=} httpHeaders\n\t */\n\tsetHttpHeaders(httpHeaders) {\n\t\tthis.httpHeaders = httpHeaders;\n\t}\n\n\t/**\n\t * Sets the http method.\n\t * @param {!string} httpMethod\n\t */\n\tsetHttpMethod(httpMethod) {\n\t\tthis.httpMethod = httpMethod.toLowerCase();\n\t}\n\n\t/**\n\t * Sets the request object.\n\t * @param {?Object} request\n\t */\n\tsetRequest(request) {\n\t\tthis.request = request;\n\t}\n\n\t/**\n\t * Sets the request timeout in milliseconds.\n\t * @param {!number} timeout\n\t */\n\tsetTimeout(timeout) {\n\t\tthis.timeout = timeout;\n\t}\n\n}\n\n/**\n * Holds value for method get.\n * @type {string}\n * @default 'get'\n * @static\n */\nRequestScreen.GET = 'get';\n\n/**\n * Holds value for method post.\n * @type {string}\n * @default 'post'\n * @static\n */\nRequestScreen.POST = 'post';\n\n/**\n * Fallback http header to retrieve response request url.\n * @type {string}\n * @default 'X-Request-URL'\n * @static\n */\nRequestScreen.X_REQUEST_URL_HEADER = 'X-Request-URL';\n\nexport default RequestScreen;\n","'use strict';\n\nimport { getUid } from 'metal';\nimport { buildFragment, globalEval, globalEvalStyles, match } from 'metal-dom';\nimport CancellablePromise from 'metal-promise';\nimport globals from '../globals/globals';\nimport RequestScreen from './RequestScreen';\nimport Surface from '../surface/Surface';\nimport UA from 'metal-useragent';\nimport Uri from 'metal-uri';\nimport utils from '../utils/utils';\n\nclass HtmlScreen extends RequestScreen {\n\n\t/**\n\t * Screen class that perform a request and extracts surface contents from\n\t * the response content.\n\t * @constructor\n\t * @extends {RequestScreen}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the meta selector. Relevant to extract <code>meta</code> tags\n\t\t * elements from request fragments to use as the screen.\n\t\t * @type {!string}\n\t\t * @default meta\n\t\t * @protected\n\t\t */\n\t\tthis.metaTagsSelector = 'meta';\n\n\t\t/**\n\t\t * Holds the title selector. Relevant to extract the <code><title></code>\n\t\t * element from request fragments to use as the screen title.\n\t\t * @type {!string}\n\t\t * @default title\n\t\t * @protected\n\t\t */\n\t\tthis.titleSelector = 'title';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tactivate() {\n\t\tsuper.activate();\n\t\tthis.releaseVirtualDocument();\n\t\tthis.pendingStyles = null;\n\t}\n\n\t/**\n\t * Allocates virtual document for content. After allocated virtual document\n\t * can be accessed by <code>this.virtualDocument</code>.\n\t * @param {!string} htmlString\n\t */\n\tallocateVirtualDocumentForContent(htmlString) {\n\t\tif (!this.virtualDocument) {\n\t\t\tthis.virtualDocument = globals.document.createElement('html');\n\t\t}\n\n\t\tthis.copyNodeAttributesFromContent_(htmlString, this.virtualDocument);\n\n\t\tthis.virtualDocument.innerHTML = htmlString;\n\t}\n\n\t/**\n\t * Customizes logic to append styles into document. Relevant to when\n\t * tracking a style by id make sure to re-positions the new style in the\n\t * same dom order.\n\t * @param {Element} newStyle\n\t */\n\tappendStyleIntoDocument_(newStyle) {\n\t\tvar isTemporaryStyle = match(newStyle, HtmlScreen.selectors.stylesTemporary);\n\t\tif (isTemporaryStyle) {\n\t\t\tthis.pendingStyles.push(newStyle);\n\t\t}\n\t\tif (newStyle.id) {\n\t\t\tvar styleInDoc = globals.document.getElementById(newStyle.id);\n\t\t\tif (styleInDoc) {\n\t\t\t\tstyleInDoc.parentNode.insertBefore(newStyle, styleInDoc.nextSibling);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tglobals.document.head.appendChild(newStyle);\n\t}\n\n\t/**\n\t * If body is used as surface forces the requested documents to have same id\n\t * of the initial page.\n\t */\n\tassertSameBodyIdInVirtualDocument() {\n\t\tvar bodySurface = this.virtualDocument.querySelector('body');\n\t\tif (!globals.document.body.id) {\n\t\t\tglobals.document.body.id = 'senna_surface_' + getUid();\n\t\t}\n\t\tif (bodySurface) {\n\t\t\tbodySurface.id = globals.document.body.id;\n\t\t}\n\t}\n\n\t/**\n\t * Copies attributes from the <html> tag of content to the given node.\n\t */\n\tcopyNodeAttributesFromContent_(content, node) {\n\t\tcontent = content.replace(/[<]\\s*html/ig, '<senna');\n\t\tcontent = content.replace(/\\/html\\s*\\>/ig, '/senna>');\n\t\tlet placeholder;\n\t\tif (UA.isIe) {\n\t\t\tconst tempNode = globals.document.createRange().createContextualFragment(content);\n\t\t\tplaceholder = tempNode.querySelector('senna');\n\t\t} else {\n\t\t\tnode.innerHTML = content;\n\t\t\tplaceholder = node.querySelector('senna');\n\t\t}\n\n\t\tif (placeholder) {\n\t\t\tutils.clearNodeAttributes(node);\n\t\t\tutils.copyNodeAttributes(placeholder, node);\n\t\t}\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tdisposeInternal() {\n\t\tthis.disposePendingStyles();\n\t\tsuper.disposeInternal();\n\t}\n\n\t/**\n\t * Disposes pending styles if screen get disposed prior to its loading.\n\t */\n\tdisposePendingStyles() {\n\t\tif (this.pendingStyles) {\n\t\t\tutils.removeElementsFromDocument(this.pendingStyles);\n\t\t}\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tevaluateScripts(surfaces) {\n\t\tvar evaluateTrackedScripts = this.evaluateTrackedResources_(\n\t\t\tglobalEval.runScriptsInElement, HtmlScreen.selectors.scripts,\n\t\t\tHtmlScreen.selectors.scriptsTemporary, HtmlScreen.selectors.scriptsPermanent);\n\n\t\treturn evaluateTrackedScripts.then(() => super.evaluateScripts(surfaces));\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tevaluateStyles(surfaces) {\n\t\tthis.pendingStyles = [];\n\t\tvar evaluateTrackedStyles = this.evaluateTrackedResources_(\n\t\t\tglobalEvalStyles.runStylesInElement, HtmlScreen.selectors.styles,\n\t\t\tHtmlScreen.selectors.stylesTemporary, HtmlScreen.selectors.stylesPermanent,\n\t\t\tthis.appendStyleIntoDocument_.bind(this));\n\n\t\treturn evaluateTrackedStyles.then(() => super.evaluateStyles(surfaces));\n\t}\n\n\t/**\n\t * Allows a screen to evaluate the favicon style before the screen becomes visible.\n\t * @return {CancellablePromise}\n\t */\n\tevaluateFavicon_() {\n\t\tconst resourcesInVirtual = this.virtualQuerySelectorAll_(HtmlScreen.selectors.favicon);\n\t\tconst resourcesInDocument = this.querySelectorAll_(HtmlScreen.selectors.favicon);\n\n\t\treturn new CancellablePromise((resolve) => {\n\t\t\tutils.removeElementsFromDocument(resourcesInDocument);\n\t\t\tthis.runFaviconInElement_(resourcesInVirtual).then(() => resolve());\n\t\t});\n\t}\n\n\t/**\n\t * Evaluates tracked resources inside incoming fragment and remove existing\n\t * temporary resources.\n\t * @param {?function()} appendFn Function to append the node into document.\n\t * @param {!string} selector Selector used to find resources to track.\n\t * @param {!string} selectorTemporary Selector used to find temporary\n\t * resources to track.\n\t * @param {!string} selectorPermanent Selector used to find permanent\n\t * resources to track.\n\t * @param {!function} opt_appendResourceFn Optional function used to\n\t * evaluate fragment containing resources.\n\t * @return {CancellablePromise} Deferred that waits resources evaluation to\n\t * complete.\n\t * @private\n\t */\n\tevaluateTrackedResources_(evaluatorFn, selector, selectorTemporary, selectorPermanent, opt_appendResourceFn) {\n\t\tvar tracked = this.virtualQuerySelectorAll_(selector);\n\t\tvar temporariesInDoc = this.querySelectorAll_(selectorTemporary);\n\t\tvar permanentsInDoc = this.querySelectorAll_(selectorPermanent);\n\n\t\t// Adds permanent resources in document to cache.\n\t\tpermanentsInDoc.forEach((resource) => {\n\t\t\tvar resourceKey = this.getResourceKey_(resource);\n\t\t\tif (resourceKey) {\n\t\t\t\tHtmlScreen.permanentResourcesInDoc[resourceKey] = true;\n\t\t\t}\n\t\t});\n\n\t\tvar frag = buildFragment();\n\t\ttracked.forEach((resource) => {\n\t\t\tvar resourceKey = this.getResourceKey_(resource);\n\t\t\t// Do not load permanent resources if already in document.\n\t\t\tif (!HtmlScreen.permanentResourcesInDoc[resourceKey]) {\n\t\t\t\tfrag.appendChild(resource);\n\t\t\t}\n\t\t\t// If resource has key and is permanent add to cache.\n\t\t\tif (resourceKey && match(resource, selectorPermanent)) {\n\t\t\t\tHtmlScreen.permanentResourcesInDoc[resourceKey] = true;\n\t\t\t}\n\t\t});\n\n\t\treturn new CancellablePromise((resolve) => {\n\t\t\tevaluatorFn(frag, () => {\n\t\t\t\tutils.removeElementsFromDocument(temporariesInDoc);\n\t\t\t\tresolve();\n\t\t\t}, opt_appendResourceFn);\n\t\t});\n\t}\n\n\t/**\n\t * @Override\n\t */\n\tflip(surfaces) {\n\t\treturn super.flip(surfaces).then(() => {\n\t\t\tutils.clearNodeAttributes(globals.document.documentElement);\n\t\t\tutils.copyNodeAttributes(this.virtualDocument, globals.document.documentElement);\n\t\t\tthis.evaluateFavicon_();\n\t\t\tthis.updateMetaTags_();\n\t\t});\n\t}\n\n\tupdateMetaTags_() {\n\t\tconst currentMetaNodes = this.querySelectorAll_('meta');\n\t\tconst metasFromVirtualDocument = this.metas;\n\t\tif (currentMetaNodes) {\n\t\t\tutils.removeElementsFromDocument(currentMetaNodes);\n\t\t\tif (metasFromVirtualDocument) {\n\t\t\t\tmetasFromVirtualDocument.forEach((meta) => globals.document.head.appendChild(meta));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Extracts a key to identify the resource based on its attributes.\n\t * @param {Element} resource\n\t * @return {string} Extracted key based on resource attributes in order of\n\t * preference: id, href, src.\n\t */\n\tgetResourceKey_(resource) {\n\t\treturn resource.id || resource.href || resource.src || '';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tgetSurfaceContent(surfaceId) {\n\t\tvar surface = this.virtualDocument.querySelector('#' + surfaceId);\n\t\tif (surface) {\n\t\t\tvar defaultChild = surface.querySelector('#' + surfaceId + '-' + Surface.DEFAULT);\n\t\t\tif (defaultChild) {\n\t\t\t\treturn defaultChild.innerHTML;\n\t\t\t}\n\t\t\treturn surface.innerHTML; // If default content not found, use surface content\n\t\t}\n\t}\n\n\t/**\n\t * Gets the title selector.\n\t * @return {!string}\n\t */\n\tgetTitleSelector() {\n\t\treturn this.titleSelector;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tload(path) {\n\t\treturn super.load(path)\n\t\t\t.then(content => {\n\t\t\t\tthis.allocateVirtualDocumentForContent(content);\n\t\t\t\tthis.resolveTitleFromVirtualDocument();\n\t\t\t\tthis.resolveMetaTagsFromVirtualDocument();\n\t\t\t\tthis.assertSameBodyIdInVirtualDocument();\n\t\t\t\tif (UA.isIe) {\n\t\t\t\t\tthis.makeTemporaryStylesHrefsUnique_();\n\t\t\t\t}\n\t\t\t\treturn content;\n\t\t\t});\n\t}\n\n\t/**\n\t * Queries temporary styles from virtual document, and makes them unique.\n\t * This is necessary for caching and load event firing issues specific to\n\t * IE11. https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7940171/\n\t */\n\tmakeTemporaryStylesHrefsUnique_() {\n\t\tvar temporariesInDoc = this.virtualQuerySelectorAll_(HtmlScreen.selectors.stylesTemporary);\n\t\ttemporariesInDoc.forEach((style) => this.replaceStyleAndMakeUnique_(style));\n\t}\n\n\t/**\n\t * Creates a new element from given, copies attributes, mutates href to be\n\t * unique to prevent caching and more than one load/error event from firing.\n\t */\n\treplaceStyleAndMakeUnique_(style) {\n\t\tif (style.href) {\n\t\t\tvar newStyle = globals.document.createElement(style.tagName);\n\t\t\tstyle.href = new Uri(style.href).makeUnique().toString();\n\t\t\tutils.copyNodeAttributes(style, newStyle);\n\t\t\tstyle.parentNode.replaceChild(newStyle, style);\n\t\t\tstyle.disabled = true;\n\t\t}\n\t}\n\n\t/**\n\t * Adds the favicon elements to the document.\n\t * @param {!Array<Element>} elements\n\t * @private\n\t * @return {CancellablePromise}\n\t */\n\trunFaviconInElement_(elements) {\n\t\treturn new CancellablePromise((resolve) => {\n\t\t\telements.forEach((element) => document.head.appendChild(\n\t\t\t\tUA.isIe ? element : utils.setElementWithRandomHref(element)\n\t\t\t));\n\t\t\tresolve();\n\t\t});\n\t}\n\n\t/**\n\t * Queries elements from virtual document and returns an array of elements.\n\t * @param {!string} selector\n\t * @return {array.<Element>}\n\t */\n\tvirtualQuerySelectorAll_(selector) {\n\t\treturn Array.prototype.slice.call(this.virtualDocument.querySelectorAll(selector));\n\t}\n\n\t/**\n\t * Queries elements from document and returns an array of elements.\n\t * @param {!string} selector\n\t * @return {array.<Element>}\n\t */\n\tquerySelectorAll_(selector) {\n\t\treturn Array.prototype.slice.call(globals.document.querySelectorAll(selector));\n\t}\n\n\t/**\n\t * Releases virtual document allocated for content.\n\t */\n\treleaseVirtualDocument() {\n\t\tthis.virtualDocument = null;\n\t}\n\n\t/**\n\t * Resolves title from allocated virtual document.\n\t */\n\tresolveTitleFromVirtualDocument() {\n\t\tconst title = this.virtualDocument.querySelector(this.titleSelector);\n\t\tif (title) {\n\t\t\tthis.setTitle(title.textContent.trim());\n\t\t}\n\t}\n\n\tresolveMetaTagsFromVirtualDocument() {\n\t\tconst metas = this.virtualQuerySelectorAll_(this.metaTagsSelector);\n\t\tif (metas) {\n\t\t\tthis.setMetas(metas);\n\t\t}\n\t}\n\n\t/**\n\t * Sets the title selector.\n\t * @param {!string} titleSelector\n\t */\n\tsetTitleSelector(titleSelector) {\n\t\tthis.titleSelector = titleSelector;\n\t}\n\n}\n\n/**\n * Helper selector for ignore favicon when exist data-senna-track.\n */\nconst ignoreFavicon = ':not([rel=\"Shortcut Icon\"]):not([rel=\"shortcut icon\"]):not([rel=\"icon\"]):not([href$=\"favicon.icon\"])';\n\n/**\n * Helper selectors for tracking resources.\n * @type {object}\n * @protected\n * @static\n */\nHtmlScreen.selectors = {\n\tfavicon: 'link[rel=\"Shortcut Icon\"],link[rel=\"shortcut icon\"],link[rel=\"icon\"],link[href$=\"favicon.icon\"]',\n\tscripts: 'script[data-senna-track]',\n\tscriptsPermanent: 'script[data-senna-track=\"permanent\"]',\n\tscriptsTemporary: 'script[data-senna-track=\"temporary\"]',\n\tstyles: `style[data-senna-track],link[data-senna-track]${ignoreFavicon}`,\n\tstylesPermanent: `style[data-senna-track=\"permanent\"],link[data-senna-track=\"permanent\"]${ignoreFavicon}`,\n\tstylesTemporary: `style[data-senna-track=\"temporary\"],link[data-senna-track=\"temporary\"]${ignoreFavicon}`\n};\n\n/**\n * Caches permanent resource keys.\n * @type {object}\n * @protected\n * @static\n */\nHtmlScreen.permanentResourcesInDoc = {};\n\nexport default HtmlScreen;\n","'use strict';\n\nimport { Disposable, getUid, isDefAndNotNull, isElement, object } from 'metal';\nimport dataAttributes from './dataAttributes';\nimport globals from '../globals/globals';\nimport App from './App';\nimport HtmlScreen from '../screen/HtmlScreen';\nimport Route from '../route/Route';\n\nclass AppDataAttributeHandler extends Disposable {\n\n\t/**\n\t * Initilizes App, register surfaces and routes from data attributes.\n\t * @constructor\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the app reference initialized by data attributes.\n\t\t * @type {App}\n\t\t * @default null\n\t\t */\n\t\tthis.app = null;\n\n\t\t/**\n\t\t * Holds the base element to search initialization data attributes. This\n\t\t * element is the container used to enable initialization based on the\n\t\t * presence of `data-senna` attribute.\n\t\t * @type {Element}\n\t\t * @default null\n\t\t */\n\t\tthis.baseElement = null;\n\t}\n\n\t/**\n\t * Inits application based on information scanned from document.\n\t */\n\thandle() {\n\t\tif (!isElement(this.baseElement)) {\n\t\t\tthrow new Error('Senna data attribute handler base element ' +\n\t\t\t\t'not set or invalid, try setting a valid element that ' +\n\t\t\t\t'contains a `data-senna` attribute.');\n\t\t}\n\n\t\tif (!this.baseElement.hasAttribute(dataAttributes.senna)) {\n\t\t\tconsole.log('Senna was not initialized from data attributes. ' +\n\t\t\t\t'In order to enable its usage from data attributes try setting ' +\n\t\t\t\t'in the base element, e.g. `<body data-senna>`.');\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.app) {\n\t\t\tthrow new Error('Senna app was already initialized.');\n\t\t}\n\n\t\tconsole.log('Senna initialized from data attribute.');\n\n\t\tthis.app = new App();\n\t\tthis.maybeAddRoutes_();\n\t\tthis.maybeAddSurfaces_();\n\t\tthis.maybeSetBasePath_();\n\t\tthis.maybeSetLinkSelector_();\n\t\tthis.maybeSetLoadingCssClass_();\n\t\tthis.maybeSetUpdateScrollPosition_();\n\t\tthis.maybeDispatch_();\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tif (this.app) {\n\t\t\tthis.app.dispose();\n\t\t}\n\t}\n\n\t/**\n\t * Gets the app reference.\n\t * @return {App}\n\t */\n\tgetApp() {\n\t\treturn this.app;\n\t}\n\n\t/**\n\t * Gets the base element.\n\t * @return {Element} baseElement\n\t */\n\tgetBaseElement() {\n\t\treturn this.baseElement;\n\t}\n\n\t/**\n\t * Maybe adds app routes from link elements that are `senna-route`.\n\t */\n\tmaybeAddRoutes_() {\n\t\tvar routesSelector = 'link[rel=\"senna-route\"]';\n\t\tthis.querySelectorAllAsArray_(routesSelector).forEach((link) => this.maybeParseLinkRoute_(link));\n\t\tif (!this.app.hasRoutes()) {\n\t\t\tthis.app.addRoutes(new Route(/.*/, HtmlScreen));\n\t\t\tconsole.log('Senna can\\'t find route elements, adding default.');\n\t\t}\n\t}\n\n\t/**\n\t * Maybe adds app surfaces by scanning `data-senna-surface` data attribute.\n\t */\n\tmaybeAddSurfaces_() {\n\t\tvar surfacesSelector = '[' + dataAttributes.surface + ']';\n\t\tthis.querySelectorAllAsArray_(surfacesSelector).forEach((surfaceElement) => {\n\t\t\tthis.updateElementIdIfSpecialSurface_(surfaceElement);\n\t\t\tthis.app.addSurfaces(surfaceElement.id);\n\t\t});\n\t}\n\n\t/**\n\t * Dispatches app navigation to the current path when initializes.\n\t */\n\tmaybeDispatch_() {\n\t\tif (this.baseElement.hasAttribute(dataAttributes.dispatch)) {\n\t\t\tthis.app.dispatch();\n\t\t}\n\t}\n\n\t/**\n\t * Adds app route by parsing valid link elements. A valid link element is of\n\t * the kind `rel=\"senna-route\"`.\n\t * @param {Element} link\n\t */\n\tmaybeParseLinkRoute_(link) {\n\t\tvar route = new Route(this.maybeParseLinkRoutePath_(link), this.maybeParseLinkRouteHandler_(link));\n\t\tthis.app.addRoutes(route);\n\t\tconsole.log('Senna scanned route ' + route.getPath());\n\t}\n\n\t/**\n\t * Maybe parse link route handler.\n\t * @param {Element} link\n\t * @return {?string}\n\t */\n\tmaybeParseLinkRouteHandler_(link) {\n\t\tvar handler = link.getAttribute('type');\n\t\tif (isDefAndNotNull(handler)) {\n\t\t\thandler = object.getObjectByName(handler);\n\t\t}\n\t\treturn handler;\n\t}\n\n\t/**\n\t * Maybe parse link route path.\n\t * @param {Element} link\n\t * @return {?string}\n\t */\n\tmaybeParseLinkRoutePath_(link) {\n\t\tvar path = link.getAttribute('href');\n\t\tif (isDefAndNotNull(path)) {\n\t\t\tif (path.indexOf('regex:') === 0) {\n\t\t\t\tpath = new RegExp(path.substring(6));\n\t\t\t}\n\t\t}\n\t\treturn path;\n\t}\n\n\t/**\n\t * Maybe sets app base path from `data-senna-base-path` data attribute.\n\t */\n\tmaybeSetBasePath_() {\n\t\tvar basePath = this.baseElement.getAttribute(dataAttributes.basePath);\n\t\tif (isDefAndNotNull(basePath)) {\n\t\t\tthis.app.setBasePath(basePath);\n\t\t\tconsole.log('Senna scanned base path ' + basePath);\n\t\t}\n\t}\n\n\t/**\n\t * Maybe sets app link selector from `data-senna-link-selector` data\n\t * attribute.\n\t */\n\tmaybeSetLinkSelector_() {\n\t\tvar linkSelector = this.baseElement.getAttribute(dataAttributes.linkSelector);\n\t\tif (isDefAndNotNull(linkSelector)) {\n\t\t\tthis.app.setLinkSelector(linkSelector);\n\t\t\tconsole.log('Senna scanned link selector ' + linkSelector);\n\t\t}\n\t}\n\n\t/**\n\t * Maybe sets app link loading css class from `data-senna-loading-css-class`\n\t * data attribute.\n\t */\n\tmaybeSetLoadingCssClass_() {\n\t\tvar loadingCssClass = this.baseElement.getAttribute(dataAttributes.loadingCssClass);\n\t\tif (isDefAndNotNull(loadingCssClass)) {\n\t\t\tthis.app.setLoadingCssClass(loadingCssClass);\n\t\t\tconsole.log('Senna scanned loading css class ' + loadingCssClass);\n\t\t}\n\t}\n\n\t/**\n\t * Maybe sets app update scroll position from\n\t * `data-senna-update-scroll-position` data attribute.\n\t */\n\tmaybeSetUpdateScrollPosition_() {\n\t\tvar updateScrollPosition = this.baseElement.getAttribute(dataAttributes.updateScrollPosition);\n\t\tif (isDefAndNotNull(updateScrollPosition)) {\n\t\t\tif (updateScrollPosition === 'false') {\n\t\t\t\tthis.app.setUpdateScrollPosition(false);\n\t\t\t} else {\n\t\t\t\tthis.app.setUpdateScrollPosition(true);\n\t\t\t}\n\t\t\tconsole.log('Senna scanned update scroll position ' + updateScrollPosition);\n\t\t}\n\t}\n\n\t/**\n\t * Queries elements from document and returns an array of elements.\n\t * @param {!string} selector\n\t * @return {array.<Element>}\n\t */\n\tquerySelectorAllAsArray_(selector) {\n\t\treturn Array.prototype.slice.call(globals.document.querySelectorAll(selector));\n\t}\n\n\t/**\n\t * Updates element id if handled as special surface element. Some surfaces\n\t * are slightly different from others, like when threating <code>body</code>\n\t * as surface.\n\t * @param {Element} element\n\t */\n\tupdateElementIdIfSpecialSurface_(element) {\n\t\tif (!element.id && element === globals.document.body) {\n\t\t\telement.id = 'senna_surface_' + getUid();\n\t\t}\n\t}\n\n\t/**\n\t * Sets the base element.\n\t * @param {Element} baseElement\n\t */\n\tsetBaseElement(baseElement) {\n\t\tthis.baseElement = baseElement;\n\t}\n\n}\n\nexport default AppDataAttributeHandler;\n","'use strict';\n\nimport globals from '../globals/globals';\nimport AppDataAttributeHandler from './AppDataAttributeHandler';\n\n/**\n * Data attribute handler.\n * @type {AppDataAttributeHandler}\n */\nvar dataAttributeHandler = new AppDataAttributeHandler();\n\nglobals.document.addEventListener('DOMContentLoaded', function() {\n\tdataAttributeHandler.setBaseElement(globals.document.body);\n\tdataAttributeHandler.handle();\n});\n\nexport default dataAttributeHandler;","/**\n * @returns String containing the current senna version\n */\n\nconst version = '<%= version %>';\n\nexport default version;"],"names":["compatibilityModeData_","uniqueIdCounter_","UID_PROPERTY","Math","random","abstractMethod","Error","disableCompatibilityMode","undefined","enableCompatibilityMode","data","getCompatibilityModeData","window","__METAL_COMPATIBILITY__","getFirstTruthy_","a","b","getFunctionName","fn","name","str","toString","substring","indexOf","getStaticProperty","ctor","propertyName","mergeFn","mergedName","hasOwnProperty","merged","__proto__","isPrototypeOf","Function","getUid","object","noInheritance","id","identityFunction","returnValue","isBoolean","val","isDef","isDefAndNotNull","isNull","isDocument","nodeType","isDocumentFragment","isElement","isFunction","isNumber","isWindow","isObject","type","isPromise","then","isString","String","isServerSide","options","checkEnv","serverSide","process","browser","env","NODE_ENV","nullFunction","array","arr1","arr2","length","i","arr","output","Array","isArray","flatten","push","obj","rv","removeAt","prototype","splice","call","start","end","sliced","async","throwException","exception","nextTick","run","callback","context","workQueueScheduled_","processWorkQueue","workQueue_","WorkItem_","workItems","workItem","scope","e","cb","bind","wrapCallback_","setImmediate_","setImmediate","getSetImmediateEmulator_","Channel","MessageChannel","postMessage","addEventListener","iframe","document","createElement","style","display","src","title","documentElement","appendChild","win","contentWindow","doc","open","write","close","message","origin","location","protocol","host","onmessage","port1","port2","channel","head","tail","next","script","onreadystatechange","parentNode","removeChild","Disposable","disposed_","disposeInternal","target","key","source","args","parts","split","reduce","part","mappedObj","keys","Object","obj1","obj2","keys1","keys2","string","str1","str2","test1","toLowerCase","test2","replace","x","floor","abs","Date","now","hash","len","charCodeAt","value","METAL_DATA","domData","element","initialValue","EventHandle","emitter","event","listener","emitter_","event_","listener_","removeListener","isDisposed","singleArray_","EventEmitter","events_","listenerHandlers_","shouldUseFacade_","holder","handler","defaultListener","validateListener_","events","toEventsArray_","addSingleListener_","runListenerHandlers_","addHandler_","getShouldUseFacade","facade","preventedDefault","listeners","getRawListeners_","slice","arguments","runListeners_","buildFacade_","directListeners","toArray","concat","map","amount","many_","self","handlerInternal","apply","listenerObj","removeMatchingListenerObjs_","addListener","many","listenerObjs","finalListeners","matchesListener_","off","handlers","defaultListeners","default","j","shouldUseFacade","TypeError","EventEmitterProxy","originEmitter","targetEmitter","blacklist","whitelist","blacklist_","originEmitter_","pendingEvents_","proxiedEvents_","targetEmitter_","whitelist_","startProxy_","on","removeListeners_","emit","shouldProxyEvent_","tryToAddListener_","forEach","proxyEvent","onListener","addListener_","emitOnTarget_","EventHandler","eventHandles_","DomDelegatedEventHandle","selector","selector_","delegating","get","selectors","remove","DomEventHandle","capture","capture_","removeEventListener","elementsByTag_","supportCache_","customEvents","LAST_CONTAINER","USE_CAPTURE","addClasses","elements","classes","addClassesWithNative_","className","classList","add","addClassesWithoutNative_","elementClassName","classesToAppend","addElementListener_","eventName","addSelectorListener_","delegatingData","addToArr_","attachDelegateEvent_","handleDelegateEvent_","closest","match","append","parent","child","buildFragment","isNodeListLike","childArr","htmlString","tempDiv","innerHTML","firstChild","fragment","createDocumentFragment","contains","element1","element2","delegate","selectorOrTarget","customConfig","originalEvent","defaultListener_","isAbleToInteractWith_","node","eventObj","button","matchesSelector","tagName","disabled","item","exitDocument","ret","container","currentTarget","defFns","triggerDelegatedListeners_","triggerDefaultDelegatedListeners_","delegateTarget","p","Element","m","matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","matchFallback_","nodes","querySelectorAll","normalizeDelegateEvent_","stopPropagation","stopPropagation_","stopImmediatePropagation","stopImmediatePropagation_","once","domEventHandle","registerCustomEvent","removeChildren","removeClasses","removeClassesWithNative_","removeClassesWithoutNative_","trim","stopped","stoppedImmediate","supportsEvent","tag","defaultPrevented","defaultFns","currElement","limit","triggerElementListeners_","triggerSelectorListeners_","lastContainer","triggerListeners_","DomEventEmitterProxy","isDelegateEvent_","index","substr","babelHelpers.get","isSupportedDomEvent_","features","animationEventName_","checkAnimationEventName_","prefixes","typeTitleCase","replaceInterval","toUpperCase","suffixes","animationElement_","attrOrderChange_","originalContent","globalEval","text","appendFn","defaultFn","runFile","scripts","runScriptsInOrder","runScript","globalEvalStyles","href","link","rel","runStyle","styles","loadCount","registerEvents","mouseEventMap","related","relatedTarget","customType","animationEventMap","eventType","checkAnimationEventName","globals","parseFromAnchor","opt_uri","test","hostname","password","pathname","port","search","username","parse","URL","url","create","MultiMap","values","size","names","JSON","stringify","set","TreeNode","value_","parent_","children_","setParent","current","getParent","ancestors","getChildren","EMPTY_ARRAY","depth","root","getChildCount","opt_preorderFn","opt_postorderFn","traverse","assertChildHasNoParent","parseFn_","Uri","maybeAddProtocolAndHostname_","multimap","getAll","addParameterValue","ensureQueryInitialized_","query","param","urlDecode","getHostname","getPort","HOSTNAME_PLACEHOLDER","getHost","getProtocol","querystring","getParameterNames","getParameterValues","encodeURIComponent","setParameterValue","RANDOM_PARAM","getRandomString","DEFAULT_PROTOCOL","charAt","removeParameter","getPathname","getSearch","getHash","parseFn","basePath","paths","path","join","decodeURIComponent","isSecure","utils","attributes","attribute","setAttribute","getCurrentBrowserPathWithoutHash","offsetLeft","offsetTop","offsetParent","uri","currentBrowserPath","getUrlPathWithoutHash","getUrlPath","history","pushState","err","error","removeAttribute","referrer","defineProperty","Thenable","IMPLEMENTED_BY_PROP","addImplementation","$goog_Thenable","isImplementedBy","partial","newArgs","CancellablePromise","resolver","opt_context","state_","State_","PENDING","result_","callbackEntries_","executing_","UNHANDLED_REJECTION_DELAY","unhandledRejectionId_","hadUnhandledRejection_","resolve_","FULFILLED","reason","REJECTED","CallbackEntry_","resolve","opt_value","reject","opt_reason","race","promises","promise","all","toFulfill","onFulfill","onReject","firstFulfilled","toReject","reasons","opt_onFulfilled","opt_onRejected","addChildPromise_","thenAlways","onResolved","handleRejection_","addCallbackEntry_","thenCatch","onRejected","catch","cancel","opt_message","CancellationError","IS_CANCELLATION_ERROR","cancelInternal_","cancelChild_","childPromise","childCount","childIndex","entry","callbackEntry","executeCallback_","scheduleCallbacks_","onFulfilled","result","unblockAndFulfill_","BLOCKED","unblockAndReject_","state","tryThen_","addUnhandledRejection_","thenable","called","executeCallbacks_","entries","removeUnhandledRejection_","setTimeout","setUnhandledRejectionHandler","debounce","delay","debounced","cancelDebounce","REGEX","convertMatchesToObj","convertTokensToRegex","tokens","regex","core","escape","encloseNonCapturingGroup","pattern","repeat","prefix","optional","RegExp","makeTrailingSlashOptional","routeOrTokens","route","unnamedCount","currPath","exec","paramPattern","unnamedPattern","modifier","toRegex","extractData","paramIndex","Route","parsedData_","buildParsedData_","Cacheable","cache","cacheable","content","clearCache","Screen","makeId_","metas","log","surfaces","sId","activeChild","runScriptsInElement","transitions","surface","deferred","show","Surface","defaultChild","transitionFn","getChild","DEFAULT","maybeWrapContentAsDefault_","screenId","opt_content","createChild","transition","getElement","getElementById","addContent","from","to","defaultTransition","NavigationStrategy","App","activeScreen","activePath","allowPreventNavigate","browserPathBeforeNavigate","captureScrollPositionFromScrollEvent","defaultTitle","formSelector","ignoreQueryStringFromRoutePath","linkSelector","loadingCssClass","nativeScrollRestorationSupported","navigationStrategy","IMMEDIATE","isNavigationPending","pendingNavigate","popstateScrollLeft","popstateScrollTop","redirectPath","routes","scheduledNavigationQueue","screens","skipLoadPopstate","updateScrollPosition","appEventHandlers_","onScroll_","onLoad_","onPopstate_","onStartNavigate_","onBeforeNavigate_","onBeforeNavigateDefault_","onBeforeUnloadDefault_","setLinkSelector","setFormSelector","maybeOverloadBeforeUnload_","getId","isWebUri","isLinkSameOrigin_","isSameBasePath_","isCurrentBrowserPath","findRoute","removeScreen","screen","getHandler","clearScreensCache","formEventHandler_","linkEventHandler_","removeAllListeners","navigate","getCurrentBrowserPath","opt_replaceHistory","stopPendingNavigate_","nextScreen","createScreenInstance","maybePreventDeactivate_","maybePreventActivate_","load","SCHEDULE_LAST","deactivate","prepareNavigateHistory_","prepareNavigateSurfaces_","extractParams","evaluateStyles","flip","evaluateScripts","maybeUpdateScrollPositionState_","syncScrollPositionSyncThenAsync_","finalizeNavigate_","handleNavigateError_","scheduledNavigation","shift","maybeNavigate_","getRoutePath","activate","isCacheable","capturedFormElement","capturedFormButtonElement","matchesPath","getIgnoreQueryStringFromRoutePath","getUrlPathWithoutHashAndSearch","stack","hostUri","locationHostUri","winner","switchScrollPositionRace","scrollTo","scrollLeft","scrollTop","nativeScrollRestoration_","scrollRestoration","mixin","canNavigate","isNavigationScheduled","maybeScheduleNavigation_","preventDefault","navigateFailed","isScheduledNavigation","onbeforeunload","_onbeforeunload","_overloaded","beforeActivate","prevent","beforeDeactivate","anchorElement","getNodeOffset","saveHistoryCurrentPageScrollPosition_","opt_event","isHtml5HistorySupported","form","replaceHistory","func","altKey","ctrlKey","metaKey","shiftKey","method","buttonSelector","activeElement","querySelector","action","maybeRepositionScrollToHashedAnchor","reloadPage","senna","lockHistoryScrollPosition_","setReferrer","setHostname","setPort","pageYOffset","pageXOffset","maybeDisableNativeScrollRestoration","endNavigatePayload","doNavigate_","maybeRestoreNativeScrollRestoration","getTitle","getDefaultTitle","beforeUpdateHistoryPath","historyState","maybeRestoreRedirectPathHash_","updateHistory_","beforeUpdateHistoryState","params","surfaceContent","getSurfaceContent","reload","surfaceId","dispose","replaceState","removePathTrailingSlash","onDocSubmitDelegate_","onDocClickDelegate_","sync","titleNode","Ajax","allHeaders","headers","pairs","body","opt_headers","opt_params","opt_timeout","opt_sync","opt_withCredentials","request","XMLHttpRequest","previousReadyState","Promise","onload","aborted","onerror","readyState","terminatedPrematurely","abort","timeout","addParametersFromMultiMap","withCredentials","setRequestHeader","send","errors","INVALID_STATUS","REQUEST_ERROR","REQUEST_TIMEOUT","REQUEST_PREMATURE_TERMINATION","UA","navigator","userAgent","platform","isMac","matchPlatform","isWin","isOpera","matchUserAgent","isIe","isEdge","isIeOrEdge","isChrome","isSafari","isFirefox","testUserAgent","getNativeUserAgent","getNativePlatform","RequestScreen","httpHeaders","httpMethod","GET","status","isValidResponseStatusCode","invalidStatus","statusCode","getRequestPath","setProtocol","makeUnique","getRequest","requestPath","responseUrl","maybeExtractResponseUrlFromRequest","removeUnique","getCache","header","addSafariXHRPolyfill","FormData","maybeAppendSubmitButtonValue_","POST","formatLoadPath","removeSafariXHRPolyfill","setRequest","xhr","assertValidResponseStatusCode","addCache","responseText","requestError","requestPrematureTermination","responseURL","getResponseHeader","X_REQUEST_URL_HEADER","inputs","input","files","HtmlScreen","metaTagsSelector","titleSelector","releaseVirtualDocument","pendingStyles","virtualDocument","copyNodeAttributesFromContent_","newStyle","isTemporaryStyle","stylesTemporary","styleInDoc","insertBefore","nextSibling","bodySurface","placeholder","tempNode","createRange","createContextualFragment","clearNodeAttributes","copyNodeAttributes","disposePendingStyles","removeElementsFromDocument","evaluateTrackedScripts","evaluateTrackedResources_","scriptsTemporary","scriptsPermanent","evaluateTrackedStyles","runStylesInElement","stylesPermanent","appendStyleIntoDocument_","resourcesInVirtual","virtualQuerySelectorAll_","favicon","resourcesInDocument","querySelectorAll_","runFaviconInElement_","evaluatorFn","selectorTemporary","selectorPermanent","opt_appendResourceFn","tracked","temporariesInDoc","permanentsInDoc","resource","resourceKey","getResourceKey_","permanentResourcesInDoc","frag","evaluateFavicon_","updateMetaTags_","currentMetaNodes","metasFromVirtualDocument","meta","allocateVirtualDocumentForContent","resolveTitleFromVirtualDocument","resolveMetaTagsFromVirtualDocument","assertSameBodyIdInVirtualDocument","makeTemporaryStylesHrefsUnique_","replaceStyleAndMakeUnique_","replaceChild","setElementWithRandomHref","setTitle","textContent","setMetas","ignoreFavicon","AppDataAttributeHandler","app","baseElement","hasAttribute","dataAttributes","maybeAddRoutes_","maybeAddSurfaces_","maybeSetBasePath_","maybeSetLinkSelector_","maybeSetLoadingCssClass_","maybeSetUpdateScrollPosition_","maybeDispatch_","routesSelector","querySelectorAllAsArray_","maybeParseLinkRoute_","hasRoutes","addRoutes","surfacesSelector","surfaceElement","updateElementIdIfSpecialSurface_","addSurfaces","dispatch","maybeParseLinkRoutePath_","maybeParseLinkRouteHandler_","getPath","getAttribute","getObjectByName","setBasePath","setLoadingCssClass","setUpdateScrollPosition","dataAttributeHandler","setBaseElement","handle","version"],"mappings":"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","preExistingComment":"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2NvcmVOYW1lZC5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2NvcmUuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsL3NyYy9hcnJheS9hcnJheS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL2FzeW5jL2FzeW5jLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvZGlzcG9zYWJsZS9EaXNwb3NhYmxlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC9zcmMvb2JqZWN0L29iamVjdC5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwvc3JjL3N0cmluZy9zdHJpbmcuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZG9tRGF0YS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZXZlbnRzL3NyYy9FdmVudEhhbmRsZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZXZlbnRzL3NyYy9FdmVudEVtaXR0ZXIuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRFbWl0dGVyUHJveHkuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWV2ZW50cy9zcmMvRXZlbnRIYW5kbGVyLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL0RvbURlbGVnYXRlZEV2ZW50SGFuZGxlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL0RvbUV2ZW50SGFuZGxlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2RvbU5hbWVkLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2RvbS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9Eb21FdmVudEVtaXR0ZXJQcm94eS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9mZWF0dXJlcy5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtZG9tL3NyYy9nbG9iYWxFdmFsLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1kb20vc3JjL2dsb2JhbEV2YWxTdHlsZXMuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRvbS9zcmMvZXZlbnRzLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9nbG9iYWxzL2dsb2JhbHMuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXVyaS9zcmMvcGFyc2VGcm9tQW5jaG9yLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC11cmkvc3JjL3BhcnNlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1zdHJ1Y3RzL3NyYy9NdWx0aU1hcC5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtc3RydWN0cy9zcmMvVHJlZU5vZGUuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXVyaS9zcmMvVXJpLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy91dGlscy91dGlscy5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvYXBwL2RhdGFBdHRyaWJ1dGVzLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL25vZGVfbW9kdWxlcy9tZXRhbC1wcm9taXNlL3NyYy9wcm9taXNlL1Byb21pc2UuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWRlYm91bmNlL3NyYy9kZWJvdW5jZS5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9ub2RlX21vZHVsZXMvbWV0YWwtcGF0aC1wYXJzZXIvc3JjL3BhdGhQYXJzZXIuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvc3JjL3JvdXRlL1JvdXRlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9jYWNoZWFibGUvQ2FjaGVhYmxlLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9zY3JlZW4vU2NyZWVuLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9zdXJmYWNlL1N1cmZhY2UuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvc3JjL2FwcC9BcHAuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLWFqYXgvc3JjL0FqYXguanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvc3JjL2Vycm9ycy9lcnJvcnMuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvbm9kZV9tb2R1bGVzL21ldGFsLXVzZXJhZ2VudC9zcmMvVUEuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvc3JjL3NjcmVlbi9SZXF1ZXN0U2NyZWVuLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9zY3JlZW4vSHRtbFNjcmVlbi5qcyIsIi9Vc2Vycy9tYXR1emFsZW10ZWxlcy9Qcm9qZWN0cy9zZW5uYS5qcy9zcmMvYXBwL0FwcERhdGFBdHRyaWJ1dGVIYW5kbGVyLmpzIiwiL1VzZXJzL21hdHV6YWxlbXRlbGVzL1Byb2plY3RzL3Nlbm5hLmpzL3NyYy9hcHAvZGF0YUF0dHJpYnV0ZUhhbmRsZXIuanMiLCIvVXNlcnMvbWF0dXphbGVtdGVsZXMvUHJvamVjdHMvc2VubmEuanMvc3JjL2FwcC92ZXJzaW9uLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBBIGNvbGxlY3Rpb24gb2YgY29yZSB1dGlsaXR5IGZ1bmN0aW9ucy5cbiAqIEBjb25zdFxuICovXG5cbmxldCBjb21wYXRpYmlsaXR5TW9kZURhdGFfO1xuXG4vKipcbiAqIENvdW50ZXIgZm9yIHVuaXF1ZSBpZC5cbiAqIEB0eXBlIHtOdW1iZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG5sZXQgdW5pcXVlSWRDb3VudGVyXyA9IDE7XG5cbi8qKlxuICogVW5pcXVlIGlkIHByb3BlcnR5IHByZWZpeC5cbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAcHJvdGVjdGVkXG4gKi9cbmV4cG9ydCBjb25zdCBVSURfUFJPUEVSVFkgPSBgY29yZV8keyhNYXRoLnJhbmRvbSgpICogMWU5KSA+Pj4gMH1gO1xuXG4vKipcbiAqIFdoZW4gZGVmaW5pbmcgYSBjbGFzcyBGb28gd2l0aCBhbiBhYnN0cmFjdCBtZXRob2QgYmFyKCksIHlvdSBjYW4gZG86XG4gKiBGb28ucHJvdG90eXBlLmJhciA9IGFic3RyYWN0TWV0aG9kXG4gKlxuICogTm93IGlmIGEgc3ViY2xhc3Mgb2YgRm9vIGZhaWxzIHRvIG92ZXJyaWRlIGJhcigpLCBhbiBlcnJvciB3aWxsIGJlIHRocm93blxuICogd2hlbiBiYXIoKSBpcyBpbnZva2VkLlxuICpcbiAqIEB0eXBlIHshRnVuY3Rpb259XG4gKiBAdGhyb3dzIHtFcnJvcn0gd2hlbiBpbnZva2VkIHRvIGluZGljYXRlIHRoZSBtZXRob2Qgc2hvdWxkIGJlIG92ZXJyaWRkZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhYnN0cmFjdE1ldGhvZCgpIHtcblx0dGhyb3cgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgYWJzdHJhY3QgbWV0aG9kJyk7XG59XG5cbi8qKlxuICogRGlzYWJsZXMgTWV0YWwuanMncyBjb21wYXRpYmlsaXR5IG1vZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNhYmxlQ29tcGF0aWJpbGl0eU1vZGUoKSB7XG5cdGNvbXBhdGliaWxpdHlNb2RlRGF0YV8gPSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRW5hYmxlcyBNZXRhbC5qcydzIGNvbXBhdGliaWxpdHkgbW9kZSB3aXRoIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgZnJvbSByY1xuICogYW5kIDEueCB2ZXJzaW9uczpcbiAqICAgICAtIFVzaW5nIFwia2V5XCIgdG8gcmVmZXJlbmNlIGNvbXBvbmVudCBpbnN0YW5jZXMuIEluIHRoZSBjdXJyZW50IHZlcnNpb25cbiAqICAgICAgIHRoaXMgc2hvdWxkIGJlIGRvbmUgdmlhIFwicmVmXCIgaW5zdGVhZC4gVGhpcyBhbGxvd3Mgb2xkIGNvZGUgc3RpbGxcbiAqICAgICAgIHVzaW5nIFwia2V5XCIgdG8ga2VlcCB3b3JraW5nIGxpa2UgYmVmb3JlLiBOT1RFOiB0aGlzIG1heSBjYXVzZVxuICogICAgICAgcHJvYmxlbXMsIHNpbmNlIFwia2V5XCIgaXMgbWVhbnQgdG8gYmUgdXNlZCBkaWZmZXJlbnRseS4gT25seSB1c2UgdGhpc1xuICogICAgICAgaWYgaXQncyBub3QgcG9zc2libGUgdG8gdXBncmFkZSB0aGUgY29kZSB0byB1c2UgXCJyZWZcIiBpbnN0ZWFkLlxuICogQHBhcmFtIHtPYmplY3Q9fSBkYXRhIE9wdGlvbmFsIG9iamVjdCB3aXRoIGRhdGEgdG8gc3BlY2lmeSBtb3JlXG4gKiAgICAgZGV0YWlscywgc3VjaCBhczpcbiAqICAgICAgICAgLSByZW5kZXJlcnMge0FycmF5fSB0aGUgdGVtcGxhdGUgcmVuZGVyZXJzIHRoYXQgc2hvdWxkIGJlIGluXG4gKiAgICAgICAgICAgY29tcGF0aWJpbGl0eSBtb2RlLCBlaXRoZXIgdGhlaXIgY29uc3RydWN0b3JzIG9yIHN0cmluZ3NcbiAqICAgICAgICAgICByZXByZXNlbnRpbmcgdGhlbSAoZS5nLiAnc295JyBvciAnanN4JykuIEJ5IGRlZmF1bHQsIGFsbCB0aGUgb25lc1xuICogICAgICAgICAgIHRoYXQgZXh0ZW5kIGZyb20gSW5jcmVtZW50YWxEb21SZW5kZXJlci5cbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmFibGVDb21wYXRpYmlsaXR5TW9kZShkYXRhID0ge30pIHtcblx0Y29tcGF0aWJpbGl0eU1vZGVEYXRhXyA9IGRhdGE7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZGF0YSB1c2VkIGZvciBjb21wYXRpYmlsaXR5IG1vZGUsIG9yIG5vdGhpbmcgaWYgaXQgaGFzbid0IGJlZW5cbiAqIGVuYWJsZWQuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb21wYXRpYmlsaXR5TW9kZURhdGEoKSB7XG5cdC8vIENvbXBhdGliaWxpdHkgbW9kZSBjYW4gYmUgc2V0IHZpYSB0aGUgX19NRVRBTF9DT01QQVRJQklMSVRZX18gZ2xvYmFsIHZhci5cblx0aWYgKGNvbXBhdGliaWxpdHlNb2RlRGF0YV8gPT09IHVuZGVmaW5lZCkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuX19NRVRBTF9DT01QQVRJQklMSVRZX18pIHtcblx0XHRcdGVuYWJsZUNvbXBhdGliaWxpdHlNb2RlKHdpbmRvdy5fX01FVEFMX0NPTVBBVElCSUxJVFlfXyk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBjb21wYXRpYmlsaXR5TW9kZURhdGFfO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGlmIGl0J3MgdHJ1dGh5LCBvciB0aGUgc2Vjb25kIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7Kn0gYVxuICogQHBhcmFtIHsqfSBiXG4gKiBAcmV0dXJuIHsqfVxuICogQHByb3RlY3RlZFxuICovXG5mdW5jdGlvbiBnZXRGaXJzdFRydXRoeV8oYSwgYikge1xuXHRyZXR1cm4gYSB8fCBiO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIG5hbWUgb2YgdGhlIGdpdmVuIGZ1bmN0aW9uLiBJZiB0aGUgY3VycmVudCBicm93c2VyIGRvZXNuJ3RcbiAqIHN1cHBvcnQgdGhlIGBuYW1lYCBwcm9wZXJ0eSwgdGhpcyB3aWxsIGNhbGN1bGF0ZSBpdCBmcm9tIHRoZSBmdW5jdGlvbidzXG4gKiBjb250ZW50IHN0cmluZy5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl9IGZuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoZm4pIHtcblx0aWYgKCFmbi5uYW1lKSB7XG5cdFx0Y29uc3Qgc3RyID0gZm4udG9TdHJpbmcoKTtcblx0XHRmbi5uYW1lID0gc3RyLnN1YnN0cmluZyg5LCBzdHIuaW5kZXhPZignKCcpKTtcblx0fVxuXHRyZXR1cm4gZm4ubmFtZTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIHN0YXRpYyBwcm9wZXJ0eSBpbiB0aGUgZ2l2ZW4gY2xhc3MuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gKiBpbmhlcml0ZWQgZnJvbSBhbmNlc3RvcnMgYXMgZXhwZWN0ZWQsIHVubGVzcyBhIGN1c3RvbSBtZXJnZSBmdW5jdGlvbiBpcyBnaXZlbixcbiAqIHdoaWNoIGNhbiBjaGFuZ2UgaG93IHRoZSBzdXBlciBjbGFzc2VzJyB2YWx1ZSBmb3IgdGhhdCBwcm9wZXJ0eSB3aWxsIGJlIG1lcmdlZFxuICogdG9nZXRoZXIuXG4gKiBUaGUgZmluYWwgbWVyZ2VkIHZhbHVlIHdpbGwgYmUgc3RvcmVkIGluIGFub3RoZXIgcHJvcGVydHksIHNvIHRoYXQgaXQgd29uJ3RcbiAqIGJlIHJlY2FsY3VsYXRlZCBldmVuIGlmIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG11bHRpcGxlIHRpbWVzLlxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gY3RvciBDbGFzcyBjb25zdHJ1Y3Rvci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWUgUHJvcGVydHkgbmFtZSB0byBiZSBtZXJnZWQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosICopOio9fSBtZXJnZUZuIEZ1bmN0aW9uIHRoYXQgcmVjZWl2ZXMgdGhlIG1lcmdlZFxuICogICAgIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBzbyBmYXIgYW5kIHRoZSBuZXh0IHZhbHVlIHRvIGJlIG1lcmdlZCB0byBpdC5cbiAqICAgICBTaG91bGQgcmV0dXJuIHRoZXNlIHR3byBtZXJnZWQgdG9nZXRoZXIuIElmIG5vdCBwYXNzZWQgdGhlIGZpbmFsIHByb3BlcnR5XG4gKiAgICAgd2lsbCBiZSB0aGUgZmlyc3QgdHJ1dGh5IHZhbHVlIGFtb25nIGFuY2VzdG9ycy5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0YXRpY1Byb3BlcnR5KFxuXHRjdG9yLFxuXHRwcm9wZXJ0eU5hbWUsXG5cdG1lcmdlRm4gPSBnZXRGaXJzdFRydXRoeV9cbikge1xuXHRjb25zdCBtZXJnZWROYW1lID0gcHJvcGVydHlOYW1lICsgJ19NRVJHRUQnO1xuXHRpZiAoIWN0b3IuaGFzT3duUHJvcGVydHkobWVyZ2VkTmFtZSkpIHtcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRsZXQgbWVyZ2VkID0gY3Rvci5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpXG5cdFx0XHQ/IGN0b3JbcHJvcGVydHlOYW1lXVxuXHRcdFx0OiBudWxsO1xuXHRcdGlmIChjdG9yLl9fcHJvdG9fXyAmJiAhY3Rvci5fX3Byb3RvX18uaXNQcm90b3R5cGVPZihGdW5jdGlvbikpIHtcblx0XHRcdG1lcmdlZCA9IG1lcmdlRm4oXG5cdFx0XHRcdG1lcmdlZCxcblx0XHRcdFx0Z2V0U3RhdGljUHJvcGVydHkoY3Rvci5fX3Byb3RvX18sIHByb3BlcnR5TmFtZSwgbWVyZ2VGbilcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGN0b3JbbWVyZ2VkTmFtZV0gPSBtZXJnZWQ7XG5cdH1cblx0cmV0dXJuIGN0b3JbbWVyZ2VkTmFtZV07XG59XG5cbi8qKlxuICogR2V0cyBhbiB1bmlxdWUgaWQuIElmIGBvYmplY3RgIGFyZ3VtZW50IGlzIHBhc3NlZCwgdGhlIG9iamVjdCBpc1xuICogbXV0YXRlZCB3aXRoIGFuIHVuaXF1ZSBpZC4gQ29uc2VjdXRpdmUgY2FsbHMgd2l0aCB0aGUgc2FtZSBvYmplY3RcbiAqIHJlZmVyZW5jZSB3b24ndCBtdXRhdGUgdGhlIG9iamVjdCBhZ2FpbiwgaW5zdGVhZCB0aGUgY3VycmVudCBvYmplY3QgdWlkXG4gKiByZXR1cm5zLiBTZWUge0BsaW5rIFVJRF9QUk9QRVJUWX0uXG4gKiBAcGFyYW0ge09iamVjdD19IG9iamVjdCBPcHRpb25hbCBvYmplY3QgdG8gYmUgbXV0YXRlZCB3aXRoIHRoZSB1aWQuIElmXG4gKiAgICAgbm90IHNwZWNpZmllZCB0aGlzIG1ldGhvZCBvbmx5IHJldHVybnMgdGhlIHVpZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vSW5oZXJpdGFuY2UgT3B0aW9uYWwgZmxhZyBpbmRpY2F0aW5nIGlmIHRoaXNcbiAqICAgICBvYmplY3QncyB1aWQgcHJvcGVydHkgY2FuIGJlIGluaGVyaXRlZCBmcm9tIHBhcmVudHMgb3Igbm90LlxuICogQHRocm93cyB7RXJyb3J9IHdoZW4gaW52b2tlZCB0byBpbmRpY2F0ZSB0aGUgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuLlxuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VWlkKG9iamVjdCwgbm9Jbmhlcml0YW5jZSkge1xuXHRpZiAob2JqZWN0KSB7XG5cdFx0bGV0IGlkID0gb2JqZWN0W1VJRF9QUk9QRVJUWV07XG5cdFx0aWYgKG5vSW5oZXJpdGFuY2UgJiYgIW9iamVjdC5oYXNPd25Qcm9wZXJ0eShVSURfUFJPUEVSVFkpKSB7XG5cdFx0XHRpZCA9IG51bGw7XG5cdFx0fVxuXHRcdHJldHVybiBpZCB8fCAob2JqZWN0W1VJRF9QUk9QRVJUWV0gPSB1bmlxdWVJZENvdW50ZXJfKyspO1xuXHR9XG5cdHJldHVybiB1bmlxdWVJZENvdW50ZXJfKys7XG59XG5cbi8qKlxuICogVGhlIGlkZW50aXR5IGZ1bmN0aW9uLiBSZXR1cm5zIGl0cyBmaXJzdCBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kj19IHJldHVyblZhbHVlIFRoZSBzaW5nbGUgdmFsdWUgdGhhdCB3aWxsIGJlIHJldHVybmVkLlxuICogQHJldHVybiB7P30gVGhlIGZpcnN0IGFyZ3VtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHlGdW5jdGlvbihyZXR1cm5WYWx1ZSkge1xuXHRyZXR1cm4gcmV0dXJuVmFsdWU7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBib29sZWFuLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYm9vbGVhbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbih2YWwpIHtcblx0cmV0dXJuIHR5cGVvZiB2YWwgPT09ICdib29sZWFuJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBub3QgdW5kZWZpbmVkLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmKHZhbCkge1xuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIG5vdCB1bmRlZmluZWQgb3IgbnVsbC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEZWZBbmROb3ROdWxsKHZhbCkge1xuXHRyZXR1cm4gaXNEZWYodmFsKSAmJiAhaXNOdWxsKHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgZG9jdW1lbnQuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRG9jdW1lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSA5O1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBhIGRvY3VtZW50LWZyYWdtZW50LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RvY3VtZW50RnJhZ21lbnQodmFsKSB7XG5cdHJldHVybiB2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLm5vZGVUeXBlID09PSAxMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBkb20gZWxlbWVudC5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbGVtZW50KHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbC5ub2RlVHlwZSA9PT0gMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIGZ1bmN0aW9uLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgYSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsKSB7XG5cdHJldHVybiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB2YWx1ZSBpcyBudWxsLlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bGwodmFsKSB7XG5cdHJldHVybiB2YWwgPT09IG51bGw7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBAcGFyYW0gez99IHZhbCBWYXJpYWJsZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB2YXJpYWJsZSBpcyBhIG51bWJlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtYmVyKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ251bWJlcic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgd2luZG93LlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1dpbmRvdyh2YWwpIHtcblx0cmV0dXJuIHZhbCAhPT0gbnVsbCAmJiB2YWwgPT09IHZhbC53aW5kb3c7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gb2JqZWN0LiBUaGlzIGluY2x1ZGVzIGFycmF5c1xuICogYW5kIGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7P30gdmFsIFZhcmlhYmxlIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHZhcmlhYmxlIGlzIGFuIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbCkge1xuXHRjb25zdCB0eXBlID0gdHlwZW9mIHZhbDtcblx0cmV0dXJuICh0eXBlID09PSAnb2JqZWN0JyAmJiB2YWwgIT09IG51bGwpIHx8IHR5cGUgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHZhbHVlIGlzIGEgUHJvbWlzZS5cbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQcm9taXNlKHZhbCkge1xuXHRyZXR1cm4gdmFsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWwudGhlbiA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdmFsdWUgaXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0geyp9IHZhbFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbCkge1xuXHRyZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgfHwgdmFsIGluc3RhbmNlb2YgU3RyaW5nO1xufVxuXG4vKipcbiAqIFNldHMgdG8gdHJ1ZSBpZiBydW5uaW5nIGluc2lkZSBOb2RlLmpzIGVudmlyb25tZW50IHdpdGggZXh0cmEgY2hlY2sgZm9yXG4gKiBgcHJvY2Vzcy5icm93c2VyYCB0byBza2lwIEthcm1hIHJ1bm5lciBlbnZpcm9ubWVudC4gS2FybWEgZW52aXJvbm1lbnQgaGFzXG4gKiBgcHJvY2Vzc2AgZGVmaW5lZCBldmVuIHRob3VnaCBpdCBydW5zIG9uIHRoZSBicm93c2VyLlxuICogQHBhcmFtIHs/T2JqZWN0fSBvcHRpb25zIENvbnRhaW5zIGBjaGVja0VudmAgcHJvcGVydHkgd2hpY2ggaWYgdHJ1ZSwgY2hlY2tzXG4gKiB0aGUgTk9ERV9FTlYgdmFyaWFibGUuIElmIE5PREVfRU5WIGVxdWFscyAndGVzdCcsIHRoZSBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2VydmVyU2lkZShvcHRpb25zID0ge2NoZWNrRW52OiB0cnVlfSkge1xuXHRsZXQgc2VydmVyU2lkZSA9IHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiAhcHJvY2Vzcy5icm93c2VyO1xuXHRpZiAoc2VydmVyU2lkZSAmJiBvcHRpb25zLmNoZWNrRW52KSB7XG5cdFx0c2VydmVyU2lkZSA9XG5cdFx0XHR0eXBlb2YgcHJvY2Vzcy5lbnYgIT09ICd1bmRlZmluZWQnICYmXG5cdFx0XHRwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnO1xuXHR9XG5cdHJldHVybiBzZXJ2ZXJTaWRlO1xufVxuXG4vKipcbiAqIE51bGwgZnVuY3Rpb24gdXNlZCBmb3IgZGVmYXVsdCB2YWx1ZXMgb2YgY2FsbGJhY2tzLCBldGMuXG4gKiBAcmV0dXJuIHt2b2lkfSBOb3RoaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVsbEZ1bmN0aW9uKCkge31cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gVGhpcyBmaWxlIGV4aXN0cyBqdXN0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgbWFraW5nIHN1cmUgdGhhdCBvbGRcbi8vIGRlZmF1bHQgaW1wb3J0cyBmb3IgdGhpcyBmaWxlIHN0aWxsIHdvcmsuIEl0J3MgYmVzdCB0byB1c2UgdGhlIG5hbWVkIGV4cG9ydHNcbi8vIGZvciBlYWNoIGZ1bmN0aW9uIGluc3RlYWQgdGhvdWdoLCBzaW5jZSB0aGF0IGFsbG93cyBidW5kbGVycyBsaWtlIFJvbGx1cCB0b1xuLy8gcmVkdWNlIHRoZSBidW5kbGUgc2l6ZSBieSByZW1vdmluZyB1bnVzZWQgY29kZS5cbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnLi9jb3JlTmFtZWQnO1xuXG5leHBvcnQgZGVmYXVsdCBjb3JlO1xuZXhwb3J0IHtjb3JlfTtcbmV4cG9ydCAqIGZyb20gJy4vY29yZU5hbWVkJztcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBhcnJheSBvcGVyYXRpb25zXG4gKi9cbmNsYXNzIGFycmF5IHtcblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJyYXlzIGhhdmUgdGhlIHNhbWUgY29udGVudC5cblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjFcblx0ICogQHBhcmFtIHshQXJyYXk8Kj59IGFycjJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBlcXVhbChhcnIxLCBhcnIyKSB7XG5cdFx0aWYgKGFycjEgPT09IGFycjIpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRpZiAoYXJyMS5sZW5ndGggIT09IGFycjIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycjFbaV0gIT09IGFycjJbaV0pIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgZ2l2ZW4gYXJyYXkgdGhhdCBpc24ndCB1bmRlZmluZWQuXG5cdCAqIEBwYXJhbSB7IUFycmF5fSBhcnJcblx0ICogQHJldHVybiB7Kn1cblx0ICovXG5cdHN0YXRpYyBmaXJzdERlZmluZWRWYWx1ZShhcnIpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycltpXSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBhcnJbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRyYW5zZm9ybXMgdGhlIGlucHV0IG5lc3RlZCBhcnJheSB0byBiZWNvbWUgZmxhdC5cblx0ICogQHBhcmFtIHtBcnJheS48KnxBcnJheS48Kj4+fSBhcnIgTmVzdGVkIGFycmF5IHRvIGZsYXR0ZW4uXG5cdCAqIEBwYXJhbSB7QXJyYXkuPCo+PX0gb3V0cHV0IE9wdGlvbmFsIG91dHB1dCBhcnJheS5cblx0ICogQHJldHVybiB7QXJyYXkuPCo+fSBGbGF0IGFycmF5LlxuXHQgKi9cblx0c3RhdGljIGZsYXR0ZW4oYXJyLCBvdXRwdXQgPSBbXSkge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoQXJyYXkuaXNBcnJheShhcnJbaV0pKSB7XG5cdFx0XHRcdGFycmF5LmZsYXR0ZW4oYXJyW2ldLCBvdXRwdXQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3V0cHV0LnB1c2goYXJyW2ldKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGEgcGFydGljdWxhciB2YWx1ZSBmcm9tIGFuIGFycmF5LlxuXHQgKiBAcGFyYW0ge0FycmF5LjxUPn0gYXJyIEFycmF5IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge1R9IG9iaiBPYmplY3QgdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqIEB0ZW1wbGF0ZSBUXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlKGFyciwgb2JqKSB7XG5cdFx0Y29uc3QgaSA9IGFyci5pbmRleE9mKG9iaik7XG5cdFx0bGV0IHJ2O1xuXHRcdGlmICgocnYgPSBpID49IDApKSB7XG5cdFx0XHRhcnJheS5yZW1vdmVBdChhcnIsIGkpO1xuXHRcdH1cblx0XHRyZXR1cm4gcnY7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBmcm9tIGFuIGFycmF5IHRoZSBlbGVtZW50IGF0IGluZGV4IGlcblx0ICogQHBhcmFtIHtBcnJheX0gYXJyIEFycmF5IG9yIGFycmF5IGxpa2Ugb2JqZWN0IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHZhbHVlLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gaSBUaGUgaW5kZXggdG8gcmVtb3ZlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGFuIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG5cdCAqL1xuXHRzdGF0aWMgcmVtb3ZlQXQoYXJyLCBpKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zcGxpY2UuY2FsbChhcnIsIGksIDEpLmxlbmd0aCA9PT0gMTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTbGljZXMgdGhlIGdpdmVuIGFycmF5LCBqdXN0IGxpa2UgQXJyYXkucHJvdG90eXBlLnNsaWNlLCBidXQgdGhpc1xuXHQgKiBpcyBmYXN0ZXIgYW5kIHdvcmtpbmcgb24gYWxsIGFycmF5LWxpa2Ugb2JqZWN0cyAobGlrZSBhcmd1bWVudHMpLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGFyciBBcnJheS1saWtlIG9iamVjdCB0byBzbGljZS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBpbmRleCB0aGF0IHNob3VsZCBzdGFydCB0aGUgc2xpY2UuXG5cdCAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIFRoZSBpbmRleCB3aGVyZSB0aGUgc2xpY2Ugc2hvdWxkIGVuZCwgbm90XG5cdCAqICAgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIGFycmF5LiBJZiBub3QgZ2l2ZW4sIGFsbCBlbGVtZW50cyBhZnRlciB0aGVcblx0ICogICBzdGFydCBpbmRleCB3aWxsIGJlIGluY2x1ZGVkLlxuXHQgKiBAcmV0dXJuIHshQXJyYXl9XG5cdCAqL1xuXHRzdGF0aWMgc2xpY2UoYXJyLCBzdGFydCwgZW5kID0gYXJyLmxlbmd0aCkge1xuXHRcdGNvbnN0IHNsaWNlZCA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG5cdFx0XHRzbGljZWQucHVzaChhcnJbaV0pO1xuXHRcdH1cblx0XHRyZXR1cm4gc2xpY2VkO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGFycmF5O1xuIiwiLyogIVxuICogUG9seWZpbGwgZnJvbSBHb29nbGUncyBDbG9zdXJlIExpYnJhcnkuXG4gKiBDb3B5cmlnaHQgMjAxMyBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2lzU2VydmVyU2lkZX0gZnJvbSAnLi4vY29yZU5hbWVkJztcblxuY29uc3QgYXN5bmMgPSB7fTtcblxuLyoqXG4gKiBUaHJvdyBhbiBpdGVtIHdpdGhvdXQgaW50ZXJydXB0aW5nIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBjb250ZXh0LiAgRm9yXG4gKiBleGFtcGxlLCBpZiBwcm9jZXNzaW5nIGEgZ3JvdXAgb2YgaXRlbXMgaW4gYSBsb29wLCBzb21ldGltZXMgaXQgaXMgdXNlZnVsXG4gKiB0byByZXBvcnQgYW4gZXJyb3Igd2hpbGUgc3RpbGwgYWxsb3dpbmcgdGhlIHJlc3Qgb2YgdGhlIGJhdGNoIHRvIGJlXG4gKiBwcm9jZXNzZWQuXG4gKiBAcGFyYW0geyp9IGV4Y2VwdGlvblxuICovXG5hc3luYy50aHJvd0V4Y2VwdGlvbiA9IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuXHQvLyBFYWNoIHRocm93IG5lZWRzIHRvIGJlIGluIGl0cyBvd24gY29udGV4dC5cblx0YXN5bmMubmV4dFRpY2soZnVuY3Rpb24oKSB7XG5cdFx0dGhyb3cgZXhjZXB0aW9uO1xuXHR9KTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrIGp1c3QgYmVmb3JlIHRoZSBjdXJyZW50IGNhbGxzdGFjayB1bndpbmRzLCBvciBhc1xuICogc29vbiBhcyBwb3NzaWJsZSBhZnRlciB0aGUgY3VycmVudCBKUyBleGVjdXRpb24gY29udGV4dC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpUSElTKX0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7VEhJUz19IGNvbnRleHQgT2JqZWN0IHRvIHVzZSBhcyB0aGUgXCJ0aGlzIHZhbHVlXCIgd2hlbiBjYWxsaW5nXG4gKiAgICAgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uLlxuICogQHRlbXBsYXRlIFRISVNcbiAqL1xuYXN5bmMucnVuID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0aWYgKCFhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXykge1xuXHRcdC8vIE5vdGhpbmcgaXMgY3VycmVudGx5IHNjaGVkdWxlZCwgc2NoZWR1bGUgaXQgbm93LlxuXHRcdGFzeW5jLm5leHRUaWNrKGFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlKTtcblx0XHRhc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IHRydWU7XG5cdH1cblxuXHRhc3luYy5ydW4ud29ya1F1ZXVlXy5wdXNoKG5ldyBhc3luYy5ydW4uV29ya0l0ZW1fKGNhbGxiYWNrLCBjb250ZXh0KSk7XG59O1xuXG4vKiogQHByaXZhdGUge2Jvb2xlYW59ICovXG5hc3luYy5ydW4ud29ya1F1ZXVlU2NoZWR1bGVkXyA9IGZhbHNlO1xuXG4vKiogQHByaXZhdGUgeyFBcnJheS48IWFzeW5jLnJ1bi5Xb3JrSXRlbV8+fSAqL1xuYXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblxuLyoqXG4gKiBSdW4gYW55IHBlbmRpbmcgYXN5bmMucnVuIHdvcmsgaXRlbXMuIFRoaXMgZnVuY3Rpb24gaXMgbm90IGludGVuZGVkXG4gKiBmb3IgZ2VuZXJhbCB1c2UsIGJ1dCBmb3IgdXNlIGJ5IGVudHJ5IHBvaW50IGhhbmRsZXJzIHRvIHJ1biBpdGVtcyBhaGVhZCBvZlxuICogYXN5bmMubmV4dFRpY2suXG4gKi9cbmFzeW5jLnJ1bi5wcm9jZXNzV29ya1F1ZXVlID0gZnVuY3Rpb24oKSB7XG5cdC8vIE5PVEU6IGFkZGl0aW9uYWwgd29yayBxdWV1ZSBpdGVtcyBtYXkgYmUgcHVzaGVkIHdoaWxlIHByb2Nlc3NpbmcuXG5cdHdoaWxlIChhc3luYy5ydW4ud29ya1F1ZXVlXy5sZW5ndGgpIHtcblx0XHQvLyBEb24ndCBsZXQgdGhlIHdvcmsgcXVldWUgZ3JvdyBpbmRlZmluaXRlbHkuXG5cdFx0Y29uc3Qgd29ya0l0ZW1zID0gYXN5bmMucnVuLndvcmtRdWV1ZV87XG5cdFx0YXN5bmMucnVuLndvcmtRdWV1ZV8gPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHdvcmtJdGVtcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgd29ya0l0ZW0gPSB3b3JrSXRlbXNbaV07XG5cdFx0XHR0cnkge1xuXHRcdFx0XHR3b3JrSXRlbS5mbi5jYWxsKHdvcmtJdGVtLnNjb3BlKTtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0YXN5bmMudGhyb3dFeGNlcHRpb24oZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gVGhlcmUgYXJlIG5vIG1vcmUgd29yayBpdGVtcywgcmVzZXQgdGhlIHdvcmsgcXVldWUuXG5cdGFzeW5jLnJ1bi53b3JrUXVldWVTY2hlZHVsZWRfID0gZmFsc2U7XG59O1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICogQGZpbmFsXG4gKiBAc3RydWN0XG4gKiBAcHJpdmF0ZVxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKX0gZm5cbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx8dW5kZWZpbmVkfSBzY29wZVxuICovXG5hc3luYy5ydW4uV29ya0l0ZW1fID0gZnVuY3Rpb24oZm4sIHNjb3BlKSB7XG5cdC8qKiBAY29uc3QgKi9cblx0dGhpcy5mbiA9IGZuO1xuXHQvKiogQGNvbnN0ICovXG5cdHRoaXMuc2NvcGUgPSBzY29wZTtcbn07XG5cbi8qKlxuICogRmlyZXMgdGhlIHByb3ZpZGVkIGNhbGxiYWNrcyBhcyBzb29uIGFzIHBvc3NpYmxlIGFmdGVyIHRoZSBjdXJyZW50IEpTXG4gKiBleGVjdXRpb24gY29udGV4dC4gc2V0VGltZW91dCjigKYsIDApIGFsd2F5cyB0YWtlcyBhdCBsZWFzdCA1bXMgZm9yIGxlZ2FjeVxuICogcmVhc29ucy5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpTQ09QRSl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhc1xuICogICAgIHBvc3NpYmxlLlxuICogQHBhcmFtIHtTQ09QRT19IGNvbnRleHQgT2JqZWN0IGluIHdob3NlIHNjb3BlIHRvIGNhbGwgdGhlIGxpc3RlbmVyLlxuICogQHRlbXBsYXRlIFNDT1BFXG4gKi9cbmFzeW5jLm5leHRUaWNrID0gZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcblx0bGV0IGNiID0gY2FsbGJhY2s7XG5cdGlmIChjb250ZXh0KSB7XG5cdFx0Y2IgPSBjYWxsYmFjay5iaW5kKGNvbnRleHQpO1xuXHR9XG5cdGNiID0gYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyhjYik7XG5cdC8vIExvb2sgZm9yIGFuZCBjYWNoZSB0aGUgY3VzdG9tIGZhbGxiYWNrIHZlcnNpb24gb2Ygc2V0SW1tZWRpYXRlLlxuXHRpZiAoIWFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8pIHtcblx0XHRpZiAoXG5cdFx0XHR0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHRpc1NlcnZlclNpZGUoe2NoZWNrRW52OiBmYWxzZX0pXG5cdFx0KSB7XG5cdFx0XHRhc3luYy5uZXh0VGljay5zZXRJbW1lZGlhdGVfID0gc2V0SW1tZWRpYXRlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRcdGFzeW5jLm5leHRUaWNrLnNldEltbWVkaWF0ZV8gPSBhc3luYy5uZXh0VGljay5nZXRTZXRJbW1lZGlhdGVFbXVsYXRvcl8oKTtcblx0XHR9XG5cdH1cblx0YXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyhjYik7XG59O1xuXG4vKipcbiAqIENhY2hlIGZvciB0aGUgc2V0SW1tZWRpYXRlIGltcGxlbWVudGF0aW9uLlxuICogQHR5cGUge2Z1bmN0aW9uKGZ1bmN0aW9uKCkpfVxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suc2V0SW1tZWRpYXRlXyA9IG51bGw7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB0aGUgYmVzdCBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbiB0byBydW4gYSBmdW5jdGlvbiBhcyBzb29uIGFzXG4gKiB0aGUgSlMgZXZlbnQgbG9vcCBpcyBpZGxlLlxuICogQHJldHVybiB7ZnVuY3Rpb24oZnVuY3Rpb24oKSl9IFRoZSBcInNldEltbWVkaWF0ZVwiIGltcGxlbWVudGF0aW9uLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2suZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfID0gZnVuY3Rpb24oKSB7XG5cdC8vIENyZWF0ZSBhIHByaXZhdGUgbWVzc2FnZSBjaGFubmVsIGFuZCB1c2UgaXQgdG8gcG9zdE1lc3NhZ2UgZW1wdHkgbWVzc2FnZXNcblx0Ly8gdG8gb3Vyc2VsdmVzLlxuXHRsZXQgQ2hhbm5lbDtcblxuXHQvLyBWZXJpZnkgaWYgdmFyaWFibGUgaXMgZGVmaW5lZCBvbiB0aGUgY3VycmVudCBydW50aW1lIChpLmUuLCBub2RlLCBicm93c2VyKS5cblx0Ly8gQ2FuJ3QgdXNlIHR5cGVvZiBlbmNsb3NlZCBpbiBhIGZ1bmN0aW9uIChzdWNoIGFzIGNvcmUuaXNGdW5jdGlvbikgb3IgYW5cblx0Ly8gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBhbiBlbnZpcm9ubWVudFxuXHQvLyB3aGVyZSB0aGUgdmFyaWFibGUgaXMgdW5kZWZpbmVkLlxuXHRpZiAodHlwZW9mIE1lc3NhZ2VDaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0Q2hhbm5lbCA9IE1lc3NhZ2VDaGFubmVsO1xuXHR9XG5cblx0Ly8gSWYgTWVzc2FnZUNoYW5uZWwgaXMgbm90IGF2YWlsYWJsZSBhbmQgd2UgYXJlIGluIGEgYnJvd3NlciwgaW1wbGVtZW50XG5cdC8vIGFuIGlmcmFtZSBiYXNlZCBwb2x5ZmlsbCBpbiBicm93c2VycyB0aGF0IGhhdmUgcG9zdE1lc3NhZ2UgYW5kXG5cdC8vIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIuIFRoZSBsYXR0ZXIgZXhjbHVkZXMgSUU4IGJlY2F1c2UgaXQgaGFzIGFcblx0Ly8gc3luY2hyb25vdXMgcG9zdE1lc3NhZ2UgaW1wbGVtZW50YXRpb24uXG5cdGlmIChcblx0XHR0eXBlb2YgQ2hhbm5lbCA9PT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuXHRcdHdpbmRvdy5wb3N0TWVzc2FnZSAmJlxuXHRcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG5cdCkge1xuXHRcdC8qKiBAY29uc3RydWN0b3IgKi9cblx0XHRDaGFubmVsID0gZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBNYWtlIGFuIGVtcHR5LCBpbnZpc2libGUgaWZyYW1lLlxuXHRcdFx0Y29uc3QgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG5cdFx0XHRpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdGlmcmFtZS5zcmMgPSAnJztcblx0XHRcdGlmcmFtZS50aXRsZSA9ICcnO1xuXHRcdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKGlmcmFtZSk7XG5cdFx0XHRjb25zdCB3aW4gPSBpZnJhbWUuY29udGVudFdpbmRvdztcblx0XHRcdGNvbnN0IGRvYyA9IHdpbi5kb2N1bWVudDtcblx0XHRcdGRvYy5vcGVuKCk7XG5cdFx0XHRkb2Mud3JpdGUoJycpO1xuXHRcdFx0ZG9jLmNsb3NlKCk7XG5cdFx0XHRjb25zdCBtZXNzYWdlID0gJ2NhbGxJbW1lZGlhdGUnICsgTWF0aC5yYW5kb20oKTtcblx0XHRcdGNvbnN0IG9yaWdpbiA9IHdpbi5sb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyB3aW4ubG9jYXRpb24uaG9zdDtcblx0XHRcdGNvbnN0IG9ubWVzc2FnZSA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0Ly8gVmFsaWRhdGUgb3JpZ2luIGFuZCBtZXNzYWdlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSB3YXNcblx0XHRcdFx0Ly8gaW50ZW5kZWQgZm9yIHVzLlxuXHRcdFx0XHRpZiAoZS5vcmlnaW4gIT09IG9yaWdpbiAmJiBlLmRhdGEgIT09IG1lc3NhZ2UpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5wb3J0MS5vbm1lc3NhZ2UoKTtcblx0XHRcdH0uYmluZCh0aGlzKTtcblx0XHRcdHdpbi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25tZXNzYWdlLCBmYWxzZSk7XG5cdFx0XHR0aGlzLnBvcnQxID0ge307XG5cdFx0XHR0aGlzLnBvcnQyID0ge1xuXHRcdFx0XHRwb3N0TWVzc2FnZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0d2luLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIG9yaWdpbik7XG5cdFx0XHRcdH0sXG5cdFx0XHR9O1xuXHRcdH07XG5cdH1cblx0aWYgKHR5cGVvZiBDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuXHRcdGNvbnN0IGNoYW5uZWwgPSBuZXcgQ2hhbm5lbCgpO1xuXHRcdC8vIFVzZSBhIGZpZm8gbGlua2VkIGxpc3QgdG8gY2FsbCBjYWxsYmFja3MgaW4gdGhlIHJpZ2h0IG9yZGVyLlxuXHRcdGxldCBoZWFkID0ge307XG5cdFx0bGV0IHRhaWwgPSBoZWFkO1xuXHRcdGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRoZWFkID0gaGVhZC5uZXh0O1xuXHRcdFx0Y29uc3QgY2IgPSBoZWFkLmNiO1xuXHRcdFx0aGVhZC5jYiA9IG51bGw7XG5cdFx0XHRjYigpO1xuXHRcdH07XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0XHR0YWlsLm5leHQgPSB7XG5cdFx0XHRcdGNiOiBjYixcblx0XHRcdH07XG5cdFx0XHR0YWlsID0gdGFpbC5uZXh0O1xuXHRcdFx0Y2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSgwKTtcblx0XHR9O1xuXHR9XG5cdC8vIEltcGxlbWVudGF0aW9uIGZvciBJRTYtODogU2NyaXB0IGVsZW1lbnRzIGZpcmUgYW4gYXN5bmNocm9ub3VzXG5cdC8vIG9ucmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aGVuIGluc2VydGVkIGludG8gdGhlIERPTS5cblx0aWYgKFxuXHRcdHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHQnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKVxuXHQpIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oY2IpIHtcblx0XHRcdGxldCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRcdHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0Ly8gQ2xlYW4gdXAgYW5kIGNhbGwgdGhlIGNhbGxiYWNrLlxuXHRcdFx0XHRzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcblx0XHRcdFx0c2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcblx0XHRcdFx0c2NyaXB0ID0gbnVsbDtcblx0XHRcdFx0Y2IoKTtcblx0XHRcdFx0Y2IgPSBudWxsO1xuXHRcdFx0fTtcblx0XHRcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH07XG5cdH1cblx0Ly8gRmFsbCBiYWNrIHRvIHNldFRpbWVvdXQgd2l0aCAwLiBJbiBicm93c2VycyB0aGlzIGNyZWF0ZXMgYSBkZWxheSBvZiA1bXNcblx0Ly8gb3IgbW9yZS5cblx0cmV0dXJuIGZ1bmN0aW9uKGNiKSB7XG5cdFx0c2V0VGltZW91dChjYiwgMCk7XG5cdH07XG59O1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGlzIG92ZXJyaWRlZCB0byBwcm90ZWN0IGNhbGxiYWNrcyB3aXRoIGVudHJ5IHBvaW50XG4gKiBtb25pdG9yIGlmIHRoZSBhcHBsaWNhdGlvbiBtb25pdG9ycyBlbnRyeSBwb2ludHMuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCl9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgYXMgc29vbiBhcyBwb3NzaWJsZS5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKCl9IFRoZSB3cmFwcGVkIGNhbGxiYWNrLlxuICogQHByaXZhdGVcbiAqL1xuYXN5bmMubmV4dFRpY2sud3JhcENhbGxiYWNrXyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG5cdHJldHVybiBjYWxsYmFjaztcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIERpc3Bvc2FibGUgdXRpbGl0eS4gV2hlbiBpbmhlcml0ZWQgcHJvdmlkZXMgdGhlIGBkaXNwb3NlYCBmdW5jdGlvbiB0byBpdHNcbiAqIHN1YmNsYXNzLCB3aGljaCBpcyByZXNwb25zaWJsZSBmb3IgZGlzcG9zaW5nIG9mIGFueSBvYmplY3QgcmVmZXJlbmNlc1xuICogd2hlbiBhbiBpbnN0YW5jZSB3b24ndCBiZSB1c2VkIGFueW1vcmUuIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlXG4gKiBgZGlzcG9zZUludGVybmFsYCB0byBpbXBsZW1lbnQgYW55IHNwZWNpZmljIGRpc3Bvc2luZyBsb2dpYy5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5jbGFzcyBEaXNwb3NhYmxlIHtcblx0LyoqXG5cdCAqIERpc3Bvc2FibGUgY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdC8qKlxuXHRcdCAqIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGluc3RhbmNlIGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZGlzcG9zZWRfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLiBDYWxscyBgZGlzcG9zZUludGVybmFsYC5cblx0ICovXG5cdGRpc3Bvc2UoKSB7XG5cdFx0aWYgKCF0aGlzLmRpc3Bvc2VkXykge1xuXHRcdFx0dGhpcy5kaXNwb3NlSW50ZXJuYWwoKTtcblx0XHRcdHRoaXMuZGlzcG9zZWRfID0gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gaW1wbGVtZW50IGFueSBzcGVjaWZpY1xuXHQgKiBkaXNwb3NpbmcgbG9naWMgKGxpa2UgY2xlYXJpbmcgcmVmZXJlbmNlcyBhbmQgY2FsbGluZyBgZGlzcG9zZWAgb24gb3RoZXJcblx0ICogZGlzcG9zYWJsZXMpLlxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge31cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoaXMgaW5zdGFuY2UgaGFzIGFscmVhZHkgYmVlbiBkaXNwb3NlZC5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzRGlzcG9zZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZGlzcG9zZWRfO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERpc3Bvc2FibGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3Igb2JqZWN0IG9wZXJhdGlvbnNcbiAqL1xuY2xhc3Mgb2JqZWN0IHtcblx0LyoqXG5cdCAqIENvcGllcyBhbGwgdGhlIG1lbWJlcnMgb2YgYSBzb3VyY2Ugb2JqZWN0IHRvIGEgdGFyZ2V0IG9iamVjdC5cblx0ICogQHBhcmFtIHtPYmplY3R9IHRhcmdldCBUYXJnZXQgb2JqZWN0LlxuXHQgKiBAcGFyYW0gey4uLk9iamVjdH0gdmFyX2FyZ3MgVGhlIG9iamVjdHMgZnJvbSB3aGljaCB2YWx1ZXMgd2lsbCBiZSBjb3BpZWQuXG5cdCAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyB0aGUgdGFyZ2V0IG9iamVjdCByZWZlcmVuY2UuXG5cdCAqL1xuXHRzdGF0aWMgbWl4aW4odGFyZ2V0LCAuLi5hcmdzKSB7XG5cdFx0bGV0IGtleTtcblx0XHRsZXQgc291cmNlO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0c291cmNlID0gYXJnc1tpXTtcblx0XHRcdC8vIFBvc3NpYmxlIHByb3RvdHlwZSBjaGFpbiBsZWFrLCBicmVha3MgMSBtZXRhbC1kb20gYW5kXG5cdFx0XHQvLyAxIG1ldGFsLWluY3JlbWVudGFsLWRvbSB0ZXN0IGlmIGd1YXJkLWZvci1pbiBydWxlIGlzIGFkZHJlc3NlZFxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cdFx0XHRmb3IgKGtleSBpbiBzb3VyY2UpIHtcblx0XHRcdFx0dGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRhcmdldDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGFuIG9iamVjdCBiYXNlZCBvbiBpdHMgZnVsbHkgcXVhbGlmaWVkIGV4dGVybmFsIG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZS5cblx0ICogQHBhcmFtIHtvYmplY3Q9fSBzY29wZSBUaGUgb2JqZWN0IHdpdGhpbiB3aGljaCB0byBsb29rOyBkZWZhdWx0IGlzXG5cdCAqICAgICA8Y29kZT53aW5kb3c8L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHs/fSBUaGUgdmFsdWUgKG9iamVjdCBvciBwcmltaXRpdmUpIG9yLCBpZiBub3QgZm91bmQsIHVuZGVmaW5lZC5cblx0ICovXG5cdHN0YXRpYyBnZXRPYmplY3RCeU5hbWUobmFtZSwgc2NvcGUgPSB3aW5kb3cpIHtcblx0XHRjb25zdCBwYXJ0cyA9IG5hbWUuc3BsaXQoJy4nKTtcblx0XHRyZXR1cm4gcGFydHMucmVkdWNlKChwYXJ0LCBrZXkpID0+IHBhcnRba2V5XSwgc2NvcGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUga2V5cyBhcyB0aGUgZ2l2ZW4gb25lLCBidXQgd2l0aFxuXHQgKiB0aGVpciB2YWx1ZXMgc2V0IHRvIHRoZSByZXR1cm4gdmFsdWVzIG9mIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24uXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gb2JqXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKHN0cmluZywgKil9IGZuXG5cdCAqIEByZXR1cm4geyFPYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgbWFwKG9iaiwgZm4pIHtcblx0XHRjb25zdCBtYXBwZWRPYmogPSB7fTtcblx0XHRjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdG1hcHBlZE9ialtrZXlzW2ldXSA9IGZuKGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXBwZWRPYmo7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSB0d28gZ2l2ZW4gb2JqZWN0cyBhcmUgZXF1YWwuIFRoaXMgaXMgZG9uZSB2aWEgYSBzaGFsbG93XG5cdCAqIGNoZWNrLCBpbmNsdWRpbmcgb25seSB0aGUga2V5cyBkaXJlY3RseSBjb250YWluZWQgYnkgdGhlIDIgb2JqZWN0cy5cblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajFcblx0ICogQHBhcmFtIHtPYmplY3R9IG9iajJcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBzaGFsbG93RXF1YWwob2JqMSwgb2JqMikge1xuXHRcdGlmIChvYmoxID09PSBvYmoyKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBrZXlzMSA9IE9iamVjdC5rZXlzKG9iajEpO1xuXHRcdGNvbnN0IGtleXMyID0gT2JqZWN0LmtleXMob2JqMik7XG5cdFx0aWYgKGtleXMxLmxlbmd0aCAhPT0ga2V5czIubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzMS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKG9iajFba2V5czFbaV1dICE9PSBvYmoyW2tleXMxW2ldXSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9iamVjdDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTZXQgb2YgdXRpbGl0aWVzIGZvciBzdHJpbmcgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBzdHJpbmcge1xuXHQvKipcblx0ICogQ29tcGFyZXMgdGhlIGdpdmVuIHN0cmluZ3Mgd2l0aG91dCB0YWtpbmcgdGhlIGNhc2UgaW50byBhY2NvdW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHN0cjFcblx0ICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdHIyXG5cdCAqIEByZXR1cm4ge251bWJlcn0gRWl0aGVyIC0xLCAwIG9yIDEsIGFjY29yZGluZyB0byBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzXG5cdCAqICAgICBcInNtYWxsZXJcIiwgZXF1YWwgb3IgXCJiaWdnZXJcIiB0aGFuIHRoZSBzZWNvbmQgZ2l2ZW4gc3RyaW5nLlxuXHQgKi9cblx0c3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbXBhcmUoc3RyMSwgc3RyMikge1xuXHRcdGNvbnN0IHRlc3QxID0gU3RyaW5nKHN0cjEpLnRvTG93ZXJDYXNlKCk7XG5cdFx0Y29uc3QgdGVzdDIgPSBTdHJpbmcoc3RyMikudG9Mb3dlckNhc2UoKTtcblxuXHRcdGlmICh0ZXN0MSA8IHRlc3QyKSB7XG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0fSBlbHNlIGlmICh0ZXN0MSA9PT0gdGVzdDIpIHtcblx0XHRcdHJldHVybiAwO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgYnJlYWtpbmcgc3BhY2VzIGZyb20gdGhlIGxlZnQgYW5kIHJpZ2h0IG9mIHRoZSBzdHJpbmcgYW5kXG5cdCAqIGNvbGxhcHNlcyB0aGUgc2VxdWVuY2VzIG9mIGJyZWFraW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlIGludG8gc2luZ2xlIHNwYWNlcy5cblx0ICogVGhlIG9yaWdpbmFsIGFuZCB0aGUgcmVzdWx0IHN0cmluZ3MgcmVuZGVyIHRoZSBzYW1lIHdheSBpbiBIVE1MLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIEEgc3RyaW5nIGluIHdoaWNoIHRvIGNvbGxhcHNlIHNwYWNlcy5cblx0ICogQHJldHVybiB7c3RyaW5nfSBDb3B5IG9mIHRoZSBzdHJpbmcgd2l0aCBub3JtYWxpemVkIGJyZWFraW5nIHNwYWNlcy5cblx0ICovXG5cdHN0YXRpYyBjb2xsYXBzZUJyZWFraW5nU3BhY2VzKHN0cikge1xuXHRcdHJldHVybiBzdHJcblx0XHRcdC5yZXBsYWNlKC9bXFx0XFxyXFxuIF0rL2csICcgJylcblx0XHRcdC5yZXBsYWNlKC9eW1xcdFxcclxcbiBdK3xbXFx0XFxyXFxuIF0rJC9nLCAnJyk7XG5cdH1cblxuXHQvKipcblx0ICogRXNjYXBlcyBjaGFyYWN0ZXJzIGluIHRoZSBzdHJpbmcgdGhhdCBhcmUgbm90IHNhZmUgdG8gdXNlIGluIGEgUmVnRXhwLlxuXHQgKiBAcGFyYW0geyp9IHN0ciBUaGUgc3RyaW5nIHRvIGVzY2FwZS4gSWYgbm90IGEgc3RyaW5nLCBpdCB3aWxsIGJlIGNhc3RlZFxuXHQgKiAgICAgdG8gb25lLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IEEgUmVnRXhwIHNhZmUsIGVzY2FwZWQgY29weSBvZiB7QGNvZGUgc30uXG5cdCAqL1xuXHRzdGF0aWMgZXNjYXBlUmVnZXgoc3RyKSB7XG5cdFx0cmV0dXJuIFN0cmluZyhzdHIpXG5cdFx0XHQucmVwbGFjZSgvKFstKClbXFxde30rPyouJF58LDojPCFcXFxcXSkvZywgJ1xcXFwkMScpXG5cdFx0XHQucmVwbGFjZSgvXFx4MDgvZywgJ1xcXFx4MDgnKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhdCBsZWFzdCA2NC1iaXRzIG9mIHJhbmRvbW5lc3MuXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQSByYW5kb20gc3RyaW5nLCBlLmcuIHNuMXM3dmI0Z2NpYy5cblx0ICovXG5cdHN0YXRpYyBnZXRSYW5kb21TdHJpbmcoKSB7XG5cdFx0Y29uc3QgeCA9IDIxNDc0ODM2NDg7XG5cdFx0cmV0dXJuIChcblx0XHRcdE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHgpLnRvU3RyaW5nKDM2KSArXG5cdFx0XHRNYXRoLmFicyhNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB4KSBeIERhdGUubm93KCkpLnRvU3RyaW5nKDM2KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogQ2FsY3VsYXRlcyB0aGUgaGFzaGNvZGUgZm9yIGEgc3RyaW5nLiBUaGUgaGFzaGNvZGUgdmFsdWUgaXMgY29tcHV0ZWQgYnlcblx0ICogdGhlIHN1bSBhbGdvcml0aG06IHNbMF0qMzFeKG4tMSkgKyBzWzFdKjMxXihuLTIpICsgLi4uICsgc1tuLTFdLiBBIG5pY2Vcblx0ICogcHJvcGVydHkgb2YgdXNpbmcgMzEgcHJpbWUgaXMgdGhhdCB0aGUgbXVsdGlwbGljYXRpb24gY2FuIGJlIHJlcGxhY2VkIGJ5XG5cdCAqIGEgc2hpZnQgYW5kIGEgc3VidHJhY3Rpb24gZm9yIGJldHRlciBwZXJmb3JtYW5jZTogMzEqaSA9PSAoaTw8NSktaS5cblx0ICogTW9kZXJuIFZNcyBkbyB0aGlzIHNvcnQgb2Ygb3B0aW1pemF0aW9uIGF1dG9tYXRpY2FsbHkuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB2YWwgVGFyZ2V0IHN0cmluZy5cblx0ICogQHJldHVybiB7TnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgaGFzaGNvZGUuXG5cdCAqL1xuXHRzdGF0aWMgaGFzaENvZGUodmFsKSB7XG5cdFx0bGV0IGhhc2ggPSAwO1xuXHRcdGZvciAobGV0IGkgPSAwLCBsZW4gPSB2YWwubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGhhc2ggPSAzMSAqIGhhc2ggKyB2YWwuY2hhckNvZGVBdChpKTtcblx0XHRcdGhhc2ggJT0gMHgxMDAwMDAwMDA7XG5cdFx0fVxuXHRcdHJldHVybiBoYXNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlcGxhY2VzIGludGVydmFsIGludG8gdGhlIHN0cmluZyB3aXRoIHNwZWNpZmllZCB2YWx1ZSwgZS5nLlxuXHQgKiBgcmVwbGFjZUludGVydmFsKFwiYWJjZGVcIiwgMSwgNCwgXCJcIilgIHJldHVybnMgXCJhZVwiLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBpbnB1dCBzdHJpbmcuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdGFydCBTdGFydCBpbnRlcnZhbCBwb3NpdGlvbiB0byBiZSByZXBsYWNlZC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IGVuZCBFbmQgaW50ZXJ2YWwgcG9zaXRpb24gdG8gYmUgcmVwbGFjZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdGhhdCByZXBsYWNlcyB0aGUgc3BlY2lmaWVkIGludGVydmFsLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRzdGF0aWMgcmVwbGFjZUludGVydmFsKHN0ciwgc3RhcnQsIGVuZCwgdmFsdWUpIHtcblx0XHRyZXR1cm4gc3RyLnN1YnN0cmluZygwLCBzdGFydCkgKyB2YWx1ZSArIHN0ci5zdWJzdHJpbmcoZW5kKTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBzdHJpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7aXNEZWZ9IGZyb20gJ21ldGFsJztcblxuY29uc3QgTUVUQUxfREFUQSA9ICdfX21ldGFsX2RhdGFfXyc7XG5cbi8qKlxuICogU2V0IG9mIHV0aWxpdGllcyBmb3IgZG9tIGRhdGEgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBkb21EYXRhIHtcblx0LyoqXG5cdCAqIEdldHMgTWV0YWwuanMncyBkYXRhIGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuXHQgKiBAcGFyYW0ge3N0cmluZz19IG5hbWUgT3B0aW9uYWwgcHJvcGVydHkgZnJvbSB0aGUgZGF0YSB0byBiZSByZXR1cm5lZC5cblx0ICogQHBhcmFtIHsqPX0gaW5pdGlhbFZhbHVlIE9wdGlvbmFsIHZhbHVlIHRvIHRoZSBzZXQgdGhlIHJlcXVlc3RlZCBwcm9wZXJ0eVxuXHQgKiAgICAgdG8gaWYgaXQgZG9lc24ndCBleGlzdCB5ZXQgaW4gdGhlIGRhdGEuXG5cdCAqIEByZXR1cm4geyFPYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgZ2V0KGVsZW1lbnQsIG5hbWUsIGluaXRpYWxWYWx1ZSkge1xuXHRcdGlmICghZWxlbWVudFtNRVRBTF9EQVRBXSkge1xuXHRcdFx0ZWxlbWVudFtNRVRBTF9EQVRBXSA9IHt9O1xuXHRcdH1cblx0XHRpZiAoIW5hbWUpIHtcblx0XHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdO1xuXHRcdH1cblx0XHRpZiAoIWlzRGVmKGVsZW1lbnRbTUVUQUxfREFUQV1bbmFtZV0pICYmIGlzRGVmKGluaXRpYWxWYWx1ZSkpIHtcblx0XHRcdGVsZW1lbnRbTUVUQUxfREFUQV1bbmFtZV0gPSBpbml0aWFsVmFsdWU7XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBoYXMgZGF0YSBzdG9yZWQgaW4gaXQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdHN0YXRpYyBoYXMoZWxlbWVudCkge1xuXHRcdHJldHVybiAhIWVsZW1lbnRbTUVUQUxfREFUQV07XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBNZXRhbC5qcydzIGRhdGEgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7c3RyaW5nPX0gbmFtZSBQcm9wZXJ0eSBmcm9tIHRoZSBkYXRhIHRvIGJlIHNldC5cblx0ICogQHBhcmFtIHsqPX0gdmFsdWUgVmFsdWUgdG8gYmUgc2V0IG9uIHRoZSBlbGVtZW50LlxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fCp9XG5cdCAqL1xuXHRzdGF0aWMgc2V0KGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG5cdFx0aWYgKCFlbGVtZW50W01FVEFMX0RBVEFdKSB7XG5cdFx0XHRlbGVtZW50W01FVEFMX0RBVEFdID0ge307XG5cdFx0fVxuXHRcdGlmICghbmFtZSB8fCAhaXNEZWYodmFsdWUpKSB7XG5cdFx0XHRyZXR1cm4gZWxlbWVudFtNRVRBTF9EQVRBXTtcblx0XHR9XG5cdFx0ZWxlbWVudFtNRVRBTF9EQVRBXVtuYW1lXSA9IHZhbHVlO1xuXHRcdHJldHVybiBlbGVtZW50W01FVEFMX0RBVEFdW25hbWVdO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRvbURhdGE7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlIHV0aWxpdHkuIEhvbGRzIGluZm9ybWF0aW9uIGFib3V0IGFuIGV2ZW50IHN1YnNjcmlwdGlvbiwgYW5kXG4gKiBhbGxvd3MgcmVtb3ZpbmcgdGhlbSBlYXNpbHkuXG4gKiBFdmVudEhhbmRsZSBpcyBhIERpc3Bvc2FibGUsIGJ1dCBpdCdzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhlXG4gKiBFdmVudEVtaXR0ZXIgdGhhdCBjcmVhdGVkIGl0IGlzIG5vdCB0aGUgb25lIHJlc3BvbnNpYmxlIGZvciBkaXNwb3NpbmcgaXQuXG4gKiBUaGF0IHJlc3BvbnNpYmlsaXR5IGlzIGZvciB0aGUgY29kZSB0aGF0IGhvbGRzIGEgcmVmZXJlbmNlIHRvIGl0LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdC8qKlxuXHQgKiBFdmVudEhhbmRsZSBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IGVtaXR0ZXIgRW1pdHRlciB0aGUgZXZlbnQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdGhhdCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgRXZlbnRFbWl0dGVyIGluc3RhbmNlIHRoYXQgdGhlIGV2ZW50IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZW1pdHRlcl8gPSBlbWl0dGVyO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRoYXQgd2FzIHN1YnNjcmliZWQgdG8uXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudF8gPSBldmVudDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBsaXN0ZW5lciBzdWJzY3JpYmVkIHRvIHRoZSBldmVudC5cblx0XHQgKiBAdHlwZSB7RnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubGlzdGVuZXJfID0gbGlzdGVuZXI7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0dGhpcy5lbWl0dGVyXyA9IG51bGw7XG5cdFx0dGhpcy5saXN0ZW5lcl8gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIHN1YnNjcmlwdGlvbiBmcm9tIHRoZSBlbWl0dGVyLlxuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0aWYgKCF0aGlzLmVtaXR0ZXJfLmlzRGlzcG9zZWQoKSkge1xuXHRcdFx0dGhpcy5lbWl0dGVyXy5yZW1vdmVMaXN0ZW5lcih0aGlzLmV2ZW50XywgdGhpcy5saXN0ZW5lcl8pO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBFdmVudEhhbmRsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcnJheSwgRGlzcG9zYWJsZSwgaXNGdW5jdGlvbiwgaXNTdHJpbmd9IGZyb20gJ21ldGFsJztcbmltcG9ydCBFdmVudEhhbmRsZSBmcm9tICcuL0V2ZW50SGFuZGxlJztcblxuY29uc3Qgc2luZ2xlQXJyYXlfID0gWzBdO1xuXG4vKipcbiAqIEV2ZW50RW1pdHRlciB1dGlsaXR5LlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50RW1pdHRlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRFbWl0dGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgZXZlbnQgbGlzdGVuZXJzIHNjb3BlZCBieSBldmVudCB0eXBlLlxuXHRcdCAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAhQXJyYXk8IWZ1bmN0aW9uKCk+Pn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhhbmRsZXJzIHRoYXQgYXJlIHRyaWdnZXJlZCB3aGVuIGFuIGV2ZW50IGlzIGxpc3RlbmVkIHRvLlxuXHRcdCAqIEB0eXBlIHtBcnJheX1cblx0XHQgKi9cblx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIENvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZCBiZSBzZW50XG5cdFx0ICogYXMgYSBwYXJhbSBvZiBsaXN0ZW5lcnMgd2hlbiBlbWl0dGluZyBldmVudHMuIElmIHNldCB0byB0cnVlLCB0aGUgZmFjYWRlXG5cdFx0ICogd2lsbCBiZSBwYXNzZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50IG9mIHRoZSBsaXN0ZW5lci5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zaG91bGRVc2VGYWNhZGVfID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIGhhbmRsZXIgdG8gZ2l2ZW4gaG9sZGVyIHZhcmlhYmxlLiBJZiB0aGUgaG9sZGVyIGRvZXNuJ3QgaGF2ZSBhXG5cdCAqIHZhbHVlIHlldCwgaXQgd2lsbCByZWNlaXZlIHRoZSBoYW5kbGVyIGRpcmVjdGx5LiBJZiB0aGUgaG9sZGVyIGlzIGFuIGFycmF5LFxuXHQgKiB0aGUgdmFsdWUgd2lsbCBqdXN0IGJlIGFkZGVkIHRvIGl0LiBPdGhlcndpc2UsIHRoZSBob2xkZXIgd2lsbCBiZSBzZXQgdG8gYVxuXHQgKiBuZXcgYXJyYXkgY29udGFpbmluZyBpdHMgcHJldmlvdXMgdmFsdWUgcGx1cyB0aGUgbmV3IGhhbmRsZXIuXG5cdCAqIEBwYXJhbSB7Kn0gaG9sZGVyXG5cdCAqIEBwYXJhbSB7IWZ1bmN0aW9uKCl8T2JqZWN0fSBoYW5kbGVyXG5cdCAqIEByZXR1cm4geyp9IFRoZSBob2xkZXIncyBuZXcgdmFsdWUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGFkZEhhbmRsZXJfKGhvbGRlciwgaGFuZGxlcikge1xuXHRcdGlmICghaG9sZGVyKSB7XG5cdFx0XHRob2xkZXIgPSBoYW5kbGVyO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIUFycmF5LmlzQXJyYXkoaG9sZGVyKSkge1xuXHRcdFx0XHRob2xkZXIgPSBbaG9sZGVyXTtcblx0XHRcdH1cblx0XHRcdGhvbGRlci5wdXNoKGhhbmRsZXIpO1xuXHRcdH1cblx0XHRyZXR1cm4gaG9sZGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBAcGFyYW0geyEoQXJyYXl8c3RyaW5nKX0gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG5cdCAqL1xuXHRhZGRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcikge1xuXHRcdHRoaXMudmFsaWRhdGVMaXN0ZW5lcl8obGlzdGVuZXIpO1xuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50c1tpXSwgbGlzdGVuZXIsIGRlZmF1bHRMaXN0ZW5lcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBFdmVudEhhbmRsZSh0aGlzLCBldmVudCwgbGlzdGVuZXIpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIGEgc2luZ2xlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gZGVmYXVsdExpc3RlbmVyIEZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGxpc3RlbmVyIGlzIGEgZGVmYXVsdFxuXHQgKiAgIGFjdGlvbiBmb3IgdGhpcyBldmVudC4gRGVmYXVsdCBhY3Rpb25zIGFyZSBydW4gbGFzdCwgYW5kIG9ubHkgaWYgbm8gcHJldmlvdXNcblx0ICogICBsaXN0ZW5lciBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiB0aGUgcmVjZWl2ZWQgZXZlbnQgZmFjYWRlLlxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9uPX0gb3JpZ2luIFRoZSBvcmlnaW5hbCBmdW5jdGlvbiB0aGF0IHdhcyBhZGRlZCBhcyBhXG5cdCAqICAgbGlzdGVuZXIsIGlmIHRoZXJlIGlzIGFueS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lciwgZGVmYXVsdExpc3RlbmVyLCBvcmlnaW4pIHtcblx0XHR0aGlzLnJ1bkxpc3RlbmVySGFuZGxlcnNfKGV2ZW50KTtcblx0XHRpZiAoZGVmYXVsdExpc3RlbmVyIHx8IG9yaWdpbikge1xuXHRcdFx0bGlzdGVuZXIgPSB7XG5cdFx0XHRcdGRlZmF1bHQ6IGRlZmF1bHRMaXN0ZW5lcixcblx0XHRcdFx0Zm46IGxpc3RlbmVyLFxuXHRcdFx0XHRvcmlnaW46IG9yaWdpbixcblx0XHRcdH07XG5cdFx0fVxuXHRcdHRoaXMuZXZlbnRzXyA9IHRoaXMuZXZlbnRzXyB8fCB7fTtcblx0XHR0aGlzLmV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRIYW5kbGVyXyh0aGlzLmV2ZW50c19bZXZlbnRdLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQnVpbGRzIGZhY2FkZSBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7T2JqZWN0fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRidWlsZEZhY2FkZV8oZXZlbnQpIHtcblx0XHRpZiAodGhpcy5nZXRTaG91bGRVc2VGYWNhZGUoKSkge1xuXHRcdFx0Y29uc3QgZmFjYWRlID0ge1xuXHRcdFx0XHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0ZmFjYWRlLnByZXZlbnRlZERlZmF1bHQgPSB0cnVlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0YXJnZXQ6IHRoaXMsXG5cdFx0XHRcdHR5cGU6IGV2ZW50LFxuXHRcdFx0fTtcblx0XHRcdHJldHVybiBmYWNhZGU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5ldmVudHNfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeGVjdXRlIGVhY2ggb2YgdGhlIGxpc3RlbmVycyBpbiBvcmRlciB3aXRoIHRoZSBzdXBwbGllZCBhcmd1bWVudHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyp9IG9wdF9hcmdzIFthcmcxXSwgW2FyZzJdLCBbLi4uXVxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgZXZlbnQgaGFkIGxpc3RlbmVycywgZmFsc2Ugb3RoZXJ3aXNlLlxuXHQgKi9cblx0ZW1pdChldmVudCkge1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCk7XG5cdFx0aWYgKGxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRjb25zdCBhcmdzID0gYXJyYXkuc2xpY2UoYXJndW1lbnRzLCAxKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdHRoaXMucnVuTGlzdGVuZXJzXyhsaXN0ZW5lcnMsIGFyZ3MsIHRoaXMuYnVpbGRGYWNhZGVfKGV2ZW50KSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbGlzdGVuZXIgb2JqZWN0cyBmb3IgdGhlIGdpdmVuIGV2ZW50LCBpZiB0aGVyZSBhcmUgYW55LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRnZXRSYXdMaXN0ZW5lcnNfKGV2ZW50KSB7XG5cdFx0Y29uc3QgZGlyZWN0TGlzdGVuZXJzID0gdG9BcnJheSh0aGlzLmV2ZW50c18gJiYgdGhpcy5ldmVudHNfW2V2ZW50XSk7XG5cdFx0cmV0dXJuIGRpcmVjdExpc3RlbmVycy5jb25jYXQoXG5cdFx0XHR0b0FycmF5KHRoaXMuZXZlbnRzXyAmJiB0aGlzLmV2ZW50c19bJyonXSlcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Z2V0U2hvdWxkVXNlRmFjYWRlKCkge1xuXHRcdHJldHVybiB0aGlzLnNob3VsZFVzZUZhY2FkZV87XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgbGlzdGVuZXJzLlxuXHQgKi9cblx0bGlzdGVuZXJzKGV2ZW50KSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0UmF3TGlzdGVuZXJzXyhldmVudCkubWFwKFxuXHRcdFx0bGlzdGVuZXIgPT4gKGxpc3RlbmVyLmZuID8gbGlzdGVuZXIuZm4gOiBsaXN0ZW5lcilcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIGZpeGVkIG51bWJlciBvZiB0aW1lcyBmb3IgdGhlXG5cdCAqIGV2ZW50cy4gQWZ0ZXIgZWFjaCBldmVudCBpcyB0cmlnZ2VyZWQgdGhlIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZXMsIHRoZVxuXHQgKiBsaXN0ZW5lciBpcyByZW1vdmVkIGZvciBpdC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFFdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cblx0ICovXG5cdG1hbnkoZXZlbnQsIGFtb3VudCwgbGlzdGVuZXIpIHtcblx0XHRjb25zdCBldmVudHMgPSB0aGlzLnRvRXZlbnRzQXJyYXlfKGV2ZW50KTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5tYW55XyhldmVudHNbaV0sIGFtb3VudCwgbGlzdGVuZXIpO1xuXHRcdH1cblxuXHRcdHJldHVybiBuZXcgRXZlbnRIYW5kbGUodGhpcywgZXZlbnQsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgYSBmaXhlZCBudW1iZXIgb2YgdGltZXMgZm9yIGEgc2luZ2xlXG5cdCAqIGV2ZW50LiBBZnRlciB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWVzLCB0aGVcblx0ICogbGlzdGVuZXIgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgVGhlIGFtb3VudCBvZiB0aW1lcyB0aGlzIGV2ZW50IHNob3VsZCBiZSBsaXN0ZW5lZFxuXHQgKiB0by5cblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG1hbnlfKGV2ZW50LCBhbW91bnQsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3Qgc2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoYW1vdW50IDw9IDApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKlxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGhhbmRsZXJJbnRlcm5hbCgpIHtcblx0XHRcdGlmICgtLWFtb3VudCA9PT0gMCkge1xuXHRcdFx0XHRzZWxmLnJlbW92ZUxpc3RlbmVyKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwpO1xuXHRcdFx0fVxuXHRcdFx0bGlzdGVuZXIuYXBwbHkoc2VsZiwgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdH1cblxuXHRcdHNlbGYuYWRkU2luZ2xlTGlzdGVuZXJfKGV2ZW50LCBoYW5kbGVySW50ZXJuYWwsIGZhbHNlLCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIGEgbGlzdGVuZXIgb2JqZWN0IG1hdGNoZXMgdGhlIGdpdmVuIGxpc3RlbmVyIGZ1bmN0aW9uLiBUbyBtYXRjaCxcblx0ICogaXQgbmVlZHMgdG8gZWl0aGVyIHBvaW50IHRvIHRoYXQgbGlzdGVuZXIgb3IgaGF2ZSBpdCBhcyBpdHMgb3JpZ2luLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IGxpc3RlbmVyT2JqXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXRjaGVzTGlzdGVuZXJfKGxpc3RlbmVyT2JqLCBsaXN0ZW5lcikge1xuXHRcdGNvbnN0IGZuID0gbGlzdGVuZXJPYmouZm4gfHwgbGlzdGVuZXJPYmo7XG5cdFx0cmV0dXJuIChcblx0XHRcdGZuID09PSBsaXN0ZW5lciB8fFxuXHRcdFx0KGxpc3RlbmVyT2JqLm9yaWdpbiAmJiBsaXN0ZW5lck9iai5vcmlnaW4gPT09IGxpc3RlbmVyKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudFxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IU9iamVjdH0gUmV0dXJucyBlbWl0dGVyLCBzbyBjYWxscyBjYW4gYmUgY2hhaW5lZC5cblx0ICovXG5cdG9mZihldmVudCwgbGlzdGVuZXIpIHtcblx0XHR0aGlzLnZhbGlkYXRlTGlzdGVuZXJfKGxpc3RlbmVyKTtcblx0XHRpZiAoIXRoaXMuZXZlbnRzXykge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRzX1tldmVudHNbaV1dID0gdGhpcy5yZW1vdmVNYXRjaGluZ0xpc3RlbmVyT2Jqc18oXG5cdFx0XHRcdHRvQXJyYXkodGhpcy5ldmVudHNfW2V2ZW50c1tpXV0pLFxuXHRcdFx0XHRsaXN0ZW5lclxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50cy5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgaGFuZGxlciB0aGF0IGdldHMgdHJpZ2dlcmVkIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8gb24gdGhpc1xuXHQgKiBpbnN0YW5jZS5cblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gaGFuZGxlclxuXHQgKi9cblx0b25MaXN0ZW5lcihoYW5kbGVyKSB7XG5cdFx0dGhpcy5saXN0ZW5lckhhbmRsZXJzXyA9IHRoaXMuYWRkSGFuZGxlcl8oXG5cdFx0XHR0aGlzLmxpc3RlbmVySGFuZGxlcnNfLFxuXHRcdFx0aGFuZGxlclxuXHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudHMuIFRoaXMgbGlzdGVuZXIgaXMgaW52b2tlZCBvbmx5IHRoZVxuXHQgKiBuZXh0IHRpbWUgZWFjaCBldmVudCBpcyBmaXJlZCwgYWZ0ZXIgd2hpY2ggaXQgaXMgcmVtb3ZlZC5cblx0ICogQHBhcmFtIHshKEFycmF5fHN0cmluZyl9IGV2ZW50c1xuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXJcblx0ICogQHJldHVybiB7IUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuXHQgKi9cblx0b25jZShldmVudHMsIGxpc3RlbmVyKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFueShldmVudHMsIDEsIGxpc3RlbmVyKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnRzLiBJdCdzIG5vdCBhIGdvb2Rcblx0ICogaWRlYSB0byByZW1vdmUgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZCBlbHNld2hlcmUgaW4gdGhlIGNvZGUsXG5cdCAqIGVzcGVjaWFsbHkgd2hlbiBpdCdzIG9uIGFuIGVtaXR0ZXIgdGhhdCB5b3UgZGlkbid0IGNyZWF0ZS5cblx0ICogQHBhcmFtIHsoQXJyYXl8c3RyaW5nKT19IGV2ZW50XG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnQpIHtcblx0XHRpZiAodGhpcy5ldmVudHNfKSB7XG5cdFx0XHRpZiAoZXZlbnQpIHtcblx0XHRcdFx0Y29uc3QgZXZlbnRzID0gdGhpcy50b0V2ZW50c0FycmF5XyhldmVudCk7XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0dGhpcy5ldmVudHNfW2V2ZW50c1tpXV0gPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmV2ZW50c18gPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lciBvYmplY3RzIGZyb20gdGhlIGdpdmVuIGFycmF5IHRoYXQgbWF0Y2ggdGhlIGdpdmVuXG5cdCAqIGxpc3RlbmVyIGZ1bmN0aW9uLlxuXHQgKiBAcGFyYW0ge0FycmF5LjxPYmplY3Q+fSBsaXN0ZW5lck9ianNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4ge0FycmF5LjxPYmplY3Q+fE9iamVjdH0gVGhlIG5ldyBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoaXMgZXZlbnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZU1hdGNoaW5nTGlzdGVuZXJPYmpzXyhsaXN0ZW5lck9ianMsIGxpc3RlbmVyKSB7XG5cdFx0Y29uc3QgZmluYWxMaXN0ZW5lcnMgPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVyT2Jqcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKCF0aGlzLm1hdGNoZXNMaXN0ZW5lcl8obGlzdGVuZXJPYmpzW2ldLCBsaXN0ZW5lcikpIHtcblx0XHRcdFx0ZmluYWxMaXN0ZW5lcnMucHVzaChsaXN0ZW5lck9ianNbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmluYWxMaXN0ZW5lcnMubGVuZ3RoID4gMCA/IGZpbmFsTGlzdGVuZXJzIDogbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnRzLlxuXHQgKiBDYXV0aW9uOiBjaGFuZ2VzIGFycmF5IGluZGljZXMgaW4gdGhlIGxpc3RlbmVyIGFycmF5IGJlaGluZCB0aGUgbGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHBhcmFtIHshRnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqIEByZXR1cm4geyFPYmplY3R9IFJldHVybnMgZW1pdHRlciwgc28gY2FsbHMgY2FuIGJlIGNoYWluZWQuXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGhhbmRsZXJzIHdoZW4gYW4gZXZlbnQgaXMgbGlzdGVuZWQgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRydW5MaXN0ZW5lckhhbmRsZXJzXyhldmVudCkge1xuXHRcdGxldCBoYW5kbGVycyA9IHRoaXMubGlzdGVuZXJIYW5kbGVyc187XG5cdFx0aWYgKGhhbmRsZXJzKSB7XG5cdFx0XHRoYW5kbGVycyA9IHRvQXJyYXkoaGFuZGxlcnMpO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBoYW5kbGVycy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRoYW5kbGVyc1tpXShldmVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJ1bnMgdGhlIGdpdmVuIGxpc3RlbmVycy5cblx0ICogQHBhcmFtIHshQXJyYXl9IGxpc3RlbmVyc1xuXHQgKiBAcGFyYW0geyFBcnJheX0gYXJnc1xuXHQgKiBAcGFyYW0ge09iamVjdH0gZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJ1bkxpc3RlbmVyc18obGlzdGVuZXJzLCBhcmdzLCBmYWNhZGUpIHtcblx0XHRpZiAoZmFjYWRlKSB7XG5cdFx0XHRhcmdzLnB1c2goZmFjYWRlKTtcblx0XHR9XG5cblx0XHRjb25zdCBkZWZhdWx0TGlzdGVuZXJzID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldLmZuIHx8IGxpc3RlbmVyc1tpXTtcblx0XHRcdGlmIChsaXN0ZW5lcnNbaV0uZGVmYXVsdCkge1xuXHRcdFx0XHRkZWZhdWx0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICghZmFjYWRlIHx8ICFmYWNhZGUucHJldmVudGVkRGVmYXVsdCkge1xuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBkZWZhdWx0TGlzdGVuZXJzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdGRlZmF1bHRMaXN0ZW5lcnNbal0uYXBwbHkodGhpcywgYXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgYW4gZXZlbnQgZmFjYWRlIHNob3VsZFxuXHQgKiBiZSBzZW50IGFzIGEgcGFyYW0gb2YgbGlzdGVuZXJzIHdoZW4gZW1pdHRpbmcgZXZlbnRzLiBJZiBzZXQgdG8gdHJ1ZSwgdGhlXG5cdCAqIGZhY2FkZSB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgb2YgdGhlIGxpc3RlbmVyLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFVzZUZhY2FkZVxuXHQgKiBAcmV0dXJuIHshT2JqZWN0fSBSZXR1cm5zIGVtaXR0ZXIsIHNvIGNhbGxzIGNhbiBiZSBjaGFpbmVkLlxuXHQgKi9cblx0c2V0U2hvdWxkVXNlRmFjYWRlKHNob3VsZFVzZUZhY2FkZSkge1xuXHRcdHRoaXMuc2hvdWxkVXNlRmFjYWRlXyA9IHNob3VsZFVzZUZhY2FkZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyB0aGUgcGFyYW1ldGVyIHRvIGFuIGFycmF5IGlmIG9ubHkgb25lIGV2ZW50IGlzIGdpdmVuLiBSZXVzZXMgdGhlXG5cdCAqIHNhbWUgYXJyYXkgZWFjaCB0aW1lIHRoaXMgY29udmVyc2lvbiBpcyBkb25lLCB0byBhdm9pZCB1c2luZyBtb3JlIG1lbW9yeVxuXHQgKiB0aGFuIG5lY2Vzc2FyeS5cblx0ICogQHBhcmFtICB7IShBcnJheXxzdHJpbmcpfSBldmVudHNcblx0ICogQHJldHVybiB7IUFycmF5fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0b0V2ZW50c0FycmF5XyhldmVudHMpIHtcblx0XHRpZiAoaXNTdHJpbmcoZXZlbnRzKSkge1xuXHRcdFx0c2luZ2xlQXJyYXlfWzBdID0gZXZlbnRzO1xuXHRcdFx0ZXZlbnRzID0gc2luZ2xlQXJyYXlfO1xuXHRcdH1cblx0XHRyZXR1cm4gZXZlbnRzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbGlzdGVuZXIgaXMgdmFsaWQsIHRocm93aW5nIGFuIGV4Y2VwdGlvbiB3aGVuIGl0J3Mgbm90LlxuXHQgKiBAcGFyYW0gIHsqfSBsaXN0ZW5lclxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR2YWxpZGF0ZUxpc3RlbmVyXyhsaXN0ZW5lcikge1xuXHRcdGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIENvbnZlcnRzIHRvIGFuIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gdmFsXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdG9BcnJheSh2YWwpIHtcblx0dmFsID0gdmFsIHx8IFtdO1xuXHRyZXR1cm4gQXJyYXkuaXNBcnJheSh2YWwpID8gdmFsIDogW3ZhbF07XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50RW1pdHRlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtEaXNwb3NhYmxlfSBmcm9tICdtZXRhbCc7XG5cbi8qKlxuICogRXZlbnRFbWl0dGVyUHJveHkgdXRpbGl0eS4gSXQncyByZXNwb25zaWJsZSBmb3IgbGlua2luZyB0d28gRXZlbnRFbWl0dGVyXG4gKiBpbnN0YW5jZXMgdG9nZXRoZXIsIGVtaXR0aW5nIGV2ZW50cyBmcm9tIHRoZSBmaXJzdCBlbWl0dGVyIHRocm91Z2ggdGhlXG4gKiBzZWNvbmQgb25lLiBUaGF0IG1lYW5zIHRoYXQgbGlzdGVuaW5nIHRvIGEgc3VwcG9ydGVkIGV2ZW50IG9uIHRoZSB0YXJnZXRcbiAqIGVtaXR0ZXIgd2lsbCBtZWFuIGxpc3RlbmluZyB0byBpdCBvbiB0aGUgb3JpZ2luIGVtaXR0ZXIgYXMgd2VsbC5cbiAqIEBleHRlbmRzIHtEaXNwb3NhYmxlfVxuICovXG5jbGFzcyBFdmVudEVtaXR0ZXJQcm94eSBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXIgRXZlbnRzIG9yaWdpbmF0ZWQgb24gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYmUgZmlyZWQgZm9yIHRoZSB0YXJnZXQgZW1pdHRlcidzIGxpc3RlbmVycyBhcyB3ZWxsLlxuXHQgKiBAcGFyYW0ge0V2ZW50RW1pdHRlcn0gdGFyZ2V0RW1pdHRlciBFdmVudCBsaXN0ZW5lcnMgYXR0YWNoZWQgdG8gdGhpcyBlbWl0dGVyXG5cdCAqIHdpbGwgYWxzbyBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgZXZlbnQgaXMgZmlyZWQgYnkgdGhlIG9yaWdpbiBlbWl0dGVyLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gYmxhY2tsaXN0IE9wdGlvbmFsIGJsYWNrbGlzdCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlXG5cdCAqIHByb3hpZWQuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB3aGl0ZWxpc3Rcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9yaWdpbkVtaXR0ZXIsIHRhcmdldEVtaXR0ZXIsIGJsYWNrbGlzdCwgd2hpdGVsaXN0KSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcCBvZiBldmVudHMgdGhhdCBzaG91bGQgbm90IGJlIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5ibGFja2xpc3RfID0gYmxhY2tsaXN0O1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG9yaWdpbiBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIncyBldmVudHMgd2lsbCBiZSBwcm94aWVkIHRocm91Z2ggdGhlXG5cdFx0ICogdGFyZ2V0IGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBBIGxpc3Qgb2YgZXZlbnRzIHRoYXQgYXJlIHBlbmRpbmcgdG8gYmUgbGlzdGVuZWQgYnkgYW4gYWN0dWFsIG9yaWdpblxuXHRcdCAqIGVtaXR0ZXIuIEV2ZW50cyBhcmUgc3RvcmVkIGhlcmUgd2hlbiB0aGUgb3JpZ2luIGRvZXNuJ3QgZXhpc3QsIHNvIHRoZXlcblx0XHQgKiBjYW4gYmUgc2V0IG9uIGEgbmV3IG9yaWdpbiB3aGVuIG9uZSBpcyBzZXQuXG5cdFx0ICogQHR5cGUge0FycmF5fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBlbmRpbmdFdmVudHNfID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGEgbWFwIG9mIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gZW1pdHRlciB0aGF0IGFyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQuXG5cdFx0ICogQHR5cGUge09iamVjdDxzdHJpbmcsICFFdmVudEhhbmRsZT59XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucHJveGllZEV2ZW50c18gPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIHRhcmdldCBlbWl0dGVyLiBUaGlzIGVtaXR0ZXIgd2lsbCBlbWl0IGFsbCBldmVudHMgdGhhdCBjb21lIGZyb21cblx0XHQgKiB0aGUgb3JpZ2luIGVtaXR0ZXIuXG5cdFx0ICogQHR5cGUge0V2ZW50RW1pdHRlcn1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy50YXJnZXRFbWl0dGVyXyA9IHRhcmdldEVtaXR0ZXI7XG5cblx0XHQvKipcblx0XHQgKiBNYXAgb2YgZXZlbnRzIHRoYXQgc2hvdWxkIGJlIHByb3hpZWQuIElmIHdoaXRlbGlzdCBpcyBzZXQgYmxhY2tsaXN0IGlzIGlnbm9yZWQuXG5cdFx0ICogQHR5cGUge09iamVjdH1cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy53aGl0ZWxpc3RfID0gd2hpdGVsaXN0O1xuXG5cdFx0dGhpcy5zdGFydFByb3h5XygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIGdpdmVuIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IFRoZSBsaXN0ZW5lZCBldmVudCdzIGhhbmRsZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0YWRkTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lcikge1xuXHRcdHJldHVybiB0aGlzLm9yaWdpbkVtaXR0ZXJfLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLnJlbW92ZUxpc3RlbmVyc18oKTtcblx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfID0gbnVsbDtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbWl0cyB0aGUgc3BlY2lmaWVkIGV2ZW50IHR5cGUgb24gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRlbWl0T25UYXJnZXRfKC4uLmFyZ3MpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLmVtaXQoLi4uYXJncyk7XG5cdH1cblxuXHQvKipcblx0ICogUHJveGllcyB0aGUgZ2l2ZW4gZXZlbnQgZnJvbSB0aGUgb3JpZ2luIHRvIHRoZSB0YXJnZXQgZW1pdHRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqL1xuXHRwcm94eUV2ZW50KGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuc2hvdWxkUHJveHlFdmVudF8oZXZlbnQpKSB7XG5cdFx0XHR0aGlzLnRyeVRvQWRkTGlzdGVuZXJfKGV2ZW50KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyB0aGUgcHJveHkgbGlzdGVuZXIgZm9yIGFsbCBldmVudHMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHJlbW92ZUxpc3RlbmVyc18oKSB7XG5cdFx0aWYgKHRoaXMucHJveGllZEV2ZW50c18pIHtcblx0XHRcdGNvbnN0IGV2ZW50cyA9IE9iamVjdC5rZXlzKHRoaXMucHJveGllZEV2ZW50c18pO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0dGhpcy5wcm94aWVkRXZlbnRzX1tldmVudHNbaV1dLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gbnVsbDtcblx0XHR9XG5cdFx0dGhpcy5wZW5kaW5nRXZlbnRzXyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQ2hhbmdlcyB0aGUgb3JpZ2luIGVtaXR0ZXIuIFRoaXMgYXV0b21hdGljYWxseSBkZXRhY2hlcyBhbnkgZXZlbnRzIHRoYXRcblx0ICogd2VyZSBhbHJlYWR5IGJlaW5nIHByb3hpZWQgZnJvbSB0aGUgcHJldmlvdXMgZW1pdHRlciwgYW5kIHN0YXJ0cyBwcm94eWluZ1xuXHQgKiB0aGVtIG9uIHRoZSBuZXcgZW1pdHRlciBpbnN0ZWFkLlxuXHQgKiBAcGFyYW0geyFFdmVudEVtaXR0ZXJ9IG9yaWdpbkVtaXR0ZXJcblx0ICovXG5cdHNldE9yaWdpbkVtaXR0ZXIob3JpZ2luRW1pdHRlcikge1xuXHRcdGNvbnN0IGV2ZW50cyA9XG5cdFx0XHR0aGlzLm9yaWdpbkVtaXR0ZXJfICYmIHRoaXMucHJveGllZEV2ZW50c19cblx0XHRcdFx0PyBPYmplY3Qua2V5cyh0aGlzLnByb3hpZWRFdmVudHNfKVxuXHRcdFx0XHQ6IHRoaXMucGVuZGluZ0V2ZW50c187XG5cdFx0dGhpcy5vcmlnaW5FbWl0dGVyXyA9IG9yaWdpbkVtaXR0ZXI7XG5cdFx0aWYgKGV2ZW50cykge1xuXHRcdFx0dGhpcy5yZW1vdmVMaXN0ZW5lcnNfKCk7XG5cdFx0XHRldmVudHMuZm9yRWFjaChldmVudCA9PiB0aGlzLnByb3h5RXZlbnQoZXZlbnQpKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBzaG91bGQgYmUgcHJveGllZC5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHNob3VsZFByb3h5RXZlbnRfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMud2hpdGVsaXN0XyAmJiAhdGhpcy53aGl0ZWxpc3RfW2V2ZW50XSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpZiAodGhpcy5ibGFja2xpc3RfICYmIHRoaXMuYmxhY2tsaXN0X1tldmVudF0pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuICF0aGlzLnByb3hpZWRFdmVudHNfIHx8ICF0aGlzLnByb3hpZWRFdmVudHNfW2V2ZW50XTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgcHJveHlpbmcgYWxsIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW4gdG8gdGhlIHRhcmdldCBlbWl0dGVyLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzdGFydFByb3h5XygpIHtcblx0XHR0aGlzLnRhcmdldEVtaXR0ZXJfLm9uTGlzdGVuZXIodGhpcy5wcm94eUV2ZW50LmJpbmQodGhpcykpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgb3JpZ2luIGVtaXR0ZXIsIGlmIGl0IGV4aXN0cy4gT3RoZXJ3aXNlLCBzdG9yZXNcblx0ICogdGhlIHBlbmRpbmcgbGlzdGVuZXIgc28gaXQgY2FuIGJlIHVzZWQgb24gYSBmdXR1cmUgb3JpZ2luIGVtaXR0ZXIuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHR0cnlUb0FkZExpc3RlbmVyXyhldmVudCkge1xuXHRcdGlmICh0aGlzLm9yaWdpbkVtaXR0ZXJfKSB7XG5cdFx0XHR0aGlzLnByb3hpZWRFdmVudHNfID0gdGhpcy5wcm94aWVkRXZlbnRzXyB8fCB7fTtcblx0XHRcdHRoaXMucHJveGllZEV2ZW50c19bZXZlbnRdID0gdGhpcy5hZGRMaXN0ZW5lcl8oXG5cdFx0XHRcdGV2ZW50LFxuXHRcdFx0XHR0aGlzLmVtaXRPblRhcmdldF8uYmluZCh0aGlzLCBldmVudClcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucGVuZGluZ0V2ZW50c18gPSB0aGlzLnBlbmRpbmdFdmVudHNfIHx8IFtdO1xuXHRcdFx0dGhpcy5wZW5kaW5nRXZlbnRzXy5wdXNoKGV2ZW50KTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXZlbnRFbWl0dGVyUHJveHk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7RGlzcG9zYWJsZX0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEV2ZW50SGFuZGxlciB1dGlsaXR5LiBJdCdzIHVzZWZ1bCBmb3IgZWFzaWx5IHJlbW92aW5nIGEgZ3JvdXAgb2ZcbiAqIGxpc3RlbmVycyBmcm9tIGRpZmZlcmVudCBFdmVudEVtaXR0ZXIgaW5zdGFuY2VzLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIEV2ZW50SGFuZGxlciBleHRlbmRzIERpc3Bvc2FibGUge1xuXHQvKipcblx0ICogRXZlbnRIYW5kbGVyIGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXG5cdFx0LyoqXG5cdFx0ICogQW4gYXJyYXkgdGhhdCBob2xkcyB0aGUgYWRkZWQgZXZlbnQgaGFuZGxlcywgc28gdGhlIGxpc3RlbmVycyBjYW4gYmVcblx0XHQgKiByZW1vdmVkIGxhdGVyLlxuXHRcdCAqIEB0eXBlIHtBcnJheS48RXZlbnRIYW5kbGU+fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBbXTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIGV2ZW50IGhhbmRsZXMgdG8gYmUgcmVtb3ZlZCBsYXRlciB0aHJvdWdoIHRoZSBgcmVtb3ZlQWxsTGlzdGVuZXJzYFxuXHQgKiBtZXRob2QuXG5cdCAqIEBwYXJhbSB7Li4uKCFFdmVudEhhbmRsZSl9IHZhcl9hcmdzXG5cdCAqL1xuXHRhZGQoLi4uYXJncykge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmV2ZW50SGFuZGxlc18ucHVzaChhcmdzW2ldKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZXMgb2YgdGhpcyBpbnN0YW5jZSdzIG9iamVjdCByZWZlcmVuY2VzLlxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHR0aGlzLmV2ZW50SGFuZGxlc18gPSBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyB0aGF0IGhhdmUgYmVlbiBhZGRlZCB0aHJvdWdoIHRoZSBgYWRkYCBtZXRob2QuXG5cdCAqL1xuXHRyZW1vdmVBbGxMaXN0ZW5lcnMoKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmV2ZW50SGFuZGxlc18ubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuZXZlbnRIYW5kbGVzX1tpXS5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdH1cblxuXHRcdHRoaXMuZXZlbnRIYW5kbGVzXyA9IFtdO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50SGFuZGxlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHthcnJheSwgaXNTdHJpbmd9IGZyb20gJ21ldGFsJztcbmltcG9ydCBkb21EYXRhIGZyb20gJy4vZG9tRGF0YSc7XG5pbXBvcnQge0V2ZW50SGFuZGxlfSBmcm9tICdtZXRhbC1ldmVudHMnO1xuXG4vKipcbiAqIFRoaXMgaXMgYSBzcGVjaWFsIEV2ZW50SGFuZGxlLCB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciBkb20gZGVsZWdhdGVkIGV2ZW50c1xuICogKG9ubHkgdGhlIG9uZXMgdGhhdCByZWNlaXZlIGEgdGFyZ2V0IGVsZW1lbnQsIG5vdCBhIHNlbGVjdG9yIHN0cmluZykuXG4gKiBAZXh0ZW5kcyB7RXZlbnRIYW5kbGV9XG4gKi9cbmNsYXNzIERvbURlbGVnYXRlZEV2ZW50SGFuZGxlIGV4dGVuZHMgRXZlbnRIYW5kbGUge1xuXHQvKipcblx0ICogVGhlIGNvbnN0cnVjdG9yIGZvciBgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGVgLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZW1pdHRlciBFbGVtZW50IHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZz19IHNlbGVjdG9yIEFuIG9wdGlvbmFsIHNlbGVjdG9yIHVzZWQgd2hlbiBkZWxlZ2F0aW5nXG5cdCAqICAgICB0aGUgZXZlbnQuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoZW1pdHRlciwgZXZlbnQsIGxpc3RlbmVyLCBzZWxlY3Rvcikge1xuXHRcdHN1cGVyKGVtaXR0ZXIsIGV2ZW50LCBsaXN0ZW5lcik7XG5cdFx0dGhpcy5zZWxlY3Rvcl8gPSBzZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0cmVtb3ZlTGlzdGVuZXIoKSB7XG5cdFx0Y29uc3QgZGVsZWdhdGluZyA9IGRvbURhdGEuZ2V0KHRoaXMuZW1pdHRlcl8sICdkZWxlZ2F0aW5nJywge30pO1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IGRvbURhdGEuZ2V0KHRoaXMuZW1pdHRlcl8sICdsaXN0ZW5lcnMnLCB7fSk7XG5cdFx0Y29uc3Qgc2VsZWN0b3IgPSB0aGlzLnNlbGVjdG9yXztcblx0XHRjb25zdCBhcnIgPSBpc1N0cmluZyhzZWxlY3Rvcilcblx0XHRcdD8gZGVsZWdhdGluZ1t0aGlzLmV2ZW50X10uc2VsZWN0b3JzXG5cdFx0XHQ6IGxpc3RlbmVycztcblx0XHRjb25zdCBrZXkgPSBpc1N0cmluZyhzZWxlY3RvcikgPyBzZWxlY3RvciA6IHRoaXMuZXZlbnRfO1xuXG5cdFx0YXJyYXkucmVtb3ZlKGFycltrZXldIHx8IFtdLCB0aGlzLmxpc3RlbmVyXyk7XG5cdFx0aWYgKGFycltrZXldICYmIGFycltrZXldLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0ZGVsZXRlIGFycltrZXldO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtFdmVudEhhbmRsZX0gZnJvbSAnbWV0YWwtZXZlbnRzJztcblxuLyoqXG4gKiBUaGlzIGlzIGEgc3BlY2lhbCBFdmVudEhhbmRsZSwgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgZG9tIGV2ZW50cywgaW5zdGVhZFxuICogb2YgRXZlbnRFbWl0dGVyIGV2ZW50cy5cbiAqIEBleHRlbmRzIHtFdmVudEhhbmRsZX1cbiAqL1xuY2xhc3MgRG9tRXZlbnRIYW5kbGUgZXh0ZW5kcyBFdmVudEhhbmRsZSB7XG5cdC8qKlxuXHQgKiBUaGUgY29uc3RydWN0b3IgZm9yIGBEb21FdmVudEhhbmRsZWAuXG5cdCAqIEBwYXJhbSB7IUV2ZW50RW1pdHRlcn0gZW1pdHRlciBFbWl0dGVyIHRoZSBldmVudCB3YXMgc3Vic2NyaWJlZCB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IFRoZSBuYW1lIG9mIHRoZSBldmVudCB0aGF0IHdhcyBzdWJzY3JpYmVkIHRvLlxuXHQgKiBAcGFyYW0geyFGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHN1YnNjcmliZWQgdG8gdGhlIGV2ZW50LlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGNhcHR1cmUgRmxhZyBpbmRpY2F0aW5nIGlmIGxpc3RlbmVyIHNob3VsZCBiZSB0cmlnZ2VyZWRcblx0ICogICBkdXJpbmcgY2FwdHVyZSBwaGFzZSwgaW5zdGVhZCBvZiBkdXJpbmcgdGhlIGJ1YmJsaW5nIHBoYXNlLiBEZWZhdWx0cyB0byBmYWxzZS5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIsIGNhcHR1cmUpIHtcblx0XHRzdXBlcihlbWl0dGVyLCBldmVudCwgbGlzdGVuZXIpO1xuXHRcdHRoaXMuY2FwdHVyZV8gPSBjYXB0dXJlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRyZW1vdmVMaXN0ZW5lcigpIHtcblx0XHR0aGlzLmVtaXR0ZXJfLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG5cdFx0XHR0aGlzLmV2ZW50Xyxcblx0XHRcdHRoaXMubGlzdGVuZXJfLFxuXHRcdFx0dGhpcy5jYXB0dXJlX1xuXHRcdCk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRG9tRXZlbnRIYW5kbGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7XG5cdGlzRGVmLFxuXHRpc0RlZkFuZE5vdE51bGwsXG5cdGlzRG9jdW1lbnQsXG5cdGlzRG9jdW1lbnRGcmFnbWVudCxcblx0aXNFbGVtZW50LFxuXHRpc09iamVjdCxcblx0aXNTdHJpbmcsXG5cdG9iamVjdCxcbn0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IGRvbURhdGEgZnJvbSAnLi9kb21EYXRhJztcbmltcG9ydCBEb21EZWxlZ2F0ZWRFdmVudEhhbmRsZSBmcm9tICcuL0RvbURlbGVnYXRlZEV2ZW50SGFuZGxlJztcbmltcG9ydCBEb21FdmVudEhhbmRsZSBmcm9tICcuL0RvbUV2ZW50SGFuZGxlJztcblxuY29uc3QgZWxlbWVudHNCeVRhZ18gPSB7fTtcbmNvbnN0IHN1cHBvcnRDYWNoZV8gPSB7fTtcbmV4cG9ydCBjb25zdCBjdXN0b21FdmVudHMgPSB7fTtcblxuY29uc3QgTEFTVF9DT05UQUlORVIgPSAnX19tZXRhbF9sYXN0X2NvbnRhaW5lcl9fJztcbmNvbnN0IFVTRV9DQVBUVVJFID0ge1xuXHRibHVyOiB0cnVlLFxuXHRlcnJvcjogdHJ1ZSxcblx0Zm9jdXM6IHRydWUsXG5cdGludmFsaWQ6IHRydWUsXG5cdGxvYWQ6IHRydWUsXG5cdHNjcm9sbDogdHJ1ZSxcbn07XG5cbi8qKlxuICogQWRkcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIHRvIGFuIGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fCFOb2RlbGlzdH0gZWxlbWVudHMgVGhlIGVsZW1lbnQgb3IgZWxlbWVudHMgdG8gYWRkIENTUyBjbGFzc2VzIHRvLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gYWRkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkQ2xhc3NlcyhlbGVtZW50cywgY2xhc3Nlcykge1xuXHRpZiAoIWlzT2JqZWN0KGVsZW1lbnRzKSB8fCAhaXNTdHJpbmcoY2xhc3NlcykpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuXHRcdGVsZW1lbnRzID0gW2VsZW1lbnRzXTtcblx0fVxuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRpZiAoJ2NsYXNzTGlzdCcgaW4gZWxlbWVudHNbaV0pIHtcblx0XHRcdGFkZENsYXNzZXNXaXRoTmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFkZENsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50c1tpXSwgY2xhc3Nlcyk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgcmVxdWVzdGVkIENTUyBjbGFzc2VzIHRvIGFuIGVsZW1lbnQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBhZGQgQ1NTIGNsYXNzZXMgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byBhZGQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRpZiAoY2xhc3NOYW1lKSB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcblx0XHR9XG5cdH0pO1xufVxuXG4vKipcbiAqIEFkZHMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyB0byBhbiBlbGVtZW50IHdpdGhvdXQgdXNpbmcgY2xhc3NMaXN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB0byBhZGQgQ1NTIGNsYXNzZXMgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byBhZGQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRDbGFzc2VzV2l0aG91dE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjb25zdCBlbGVtZW50Q2xhc3NOYW1lID0gYCAke2VsZW1lbnQuY2xhc3NOYW1lfSBgO1xuXHRsZXQgY2xhc3Nlc1RvQXBwZW5kID0gJyc7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRjb25zdCBjbGFzc05hbWUgPSBjbGFzc2VzW2ldO1xuXG5cdFx0aWYgKGVsZW1lbnRDbGFzc05hbWUuaW5kZXhPZihgICR7Y2xhc3NOYW1lfSBgKSA9PT0gLTEpIHtcblx0XHRcdGNsYXNzZXNUb0FwcGVuZCArPSBgICR7Y2xhc3NOYW1lfWA7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGNsYXNzZXNUb0FwcGVuZCkge1xuXHRcdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWUgKyBjbGFzc2VzVG9BcHBlbmQ7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIGFuIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBnaXZlbiBlbGVtZW50LCB0byBiZSB0cmlnZ2VyZWQgdmlhIGRlbGVnYXRlLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHshZnVuY3Rpb24oKX0gbGlzdGVuZXJcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGFkZEVsZW1lbnRMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBsaXN0ZW5lcikge1xuXHRhZGRUb0Fycl8oZG9tRGF0YS5nZXQoZWxlbWVudCwgJ2xpc3RlbmVycycsIHt9KSwgZXZlbnROYW1lLCBsaXN0ZW5lcik7XG59XG5cbi8qKlxuICogQWRkcyBhbiBldmVudCBsaXN0ZW5lciB0byB0aGUgZ2l2ZW4gZWxlbWVudCwgdG8gYmUgdHJpZ2dlcmVkIHZpYSBkZWxlZ2F0ZVxuICogc2VsZWN0b3JzLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYWRkU2VsZWN0b3JMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3RvciwgbGlzdGVuZXIpIHtcblx0Y29uc3QgZGVsZWdhdGluZ0RhdGEgPSBkb21EYXRhLmdldChlbGVtZW50LCAnZGVsZWdhdGluZycsIHt9KTtcblx0YWRkVG9BcnJfKGRlbGVnYXRpbmdEYXRhW2V2ZW50TmFtZV0uc2VsZWN0b3JzLCBzZWxlY3RvciwgbGlzdGVuZXIpO1xufVxuXG4vKipcbiAqIEFkZHMgYSB2YWx1ZSB0byBhbiBhcnJheSBpbnNpZGUgYW4gb2JqZWN0LCBjcmVhdGluZyBpdCBmaXJzdCBpZiBpdCBkb2Vzbid0XG4gKiB5ZXQgZXhpc3QuXG4gKiBAcGFyYW0geyFBcnJheX0gYXJyXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBhZGRUb0Fycl8oYXJyLCBrZXksIHZhbHVlKSB7XG5cdGlmICghYXJyW2tleV0pIHtcblx0XHRhcnJba2V5XSA9IFtdO1xuXHR9XG5cdGFycltrZXldLnB1c2godmFsdWUpO1xufVxuXG4vKipcbiAqIEF0dGFjaGVzIGEgZGVsZWdhdGUgbGlzdGVuZXIsIHVubGVzcyB0aGVyZSdzIGFscmVhZHkgb25lIGF0dGFjaGVkLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gYXR0YWNoRGVsZWdhdGVFdmVudF8oZWxlbWVudCwgZXZlbnROYW1lKSB7XG5cdGxldCBkZWxlZ2F0aW5nRGF0YSA9IGRvbURhdGEuZ2V0KGVsZW1lbnQsICdkZWxlZ2F0aW5nJywge30pO1xuXHRpZiAoIWRlbGVnYXRpbmdEYXRhW2V2ZW50TmFtZV0pIHtcblx0XHRkZWxlZ2F0aW5nRGF0YVtldmVudE5hbWVdID0ge1xuXHRcdFx0aGFuZGxlOiBvbihcblx0XHRcdFx0ZWxlbWVudCxcblx0XHRcdFx0ZXZlbnROYW1lLFxuXHRcdFx0XHRoYW5kbGVEZWxlZ2F0ZUV2ZW50Xyxcblx0XHRcdFx0ISFVU0VfQ0FQVFVSRVtldmVudE5hbWVdXG5cdFx0XHQpLFxuXHRcdFx0c2VsZWN0b3JzOiB7fSxcblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogR2V0cyB0aGUgY2xvc2VzdCBlbGVtZW50IHVwIHRoZSB0cmVlIGZyb20gdGhlIGdpdmVuIGVsZW1lbnQgKGluY2x1ZGluZ1xuICogaXRzZWxmKSB0aGF0IG1hdGNoZXMgdGhlIHNwZWNpZmllZCBzZWxlY3Rvciwgb3IgbnVsbCBpZiBub25lIG1hdGNoLlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZXN0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XG5cdHdoaWxlIChlbGVtZW50ICYmICFtYXRjaChlbGVtZW50LCBzZWxlY3RvcikpIHtcblx0XHRlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXHR9XG5cdHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIEFwcGVuZHMgYSBjaGlsZCBub2RlIHdpdGggdGV4dCBvciBvdGhlciBub2RlcyB0byBhIHBhcmVudCBub2RlLiBJZlxuICogY2hpbGQgaXMgYSBIVE1MIHN0cmluZyBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIGEgZG9jdW1lbnRcbiAqIGZyYWdtZW50IGJlZm9yZSBhcHBlbmRpbmcgaXQgdG8gdGhlIHBhcmVudC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IHBhcmVudCBUaGUgbm9kZSB0byBhcHBlbmQgbm9kZXMgdG8uXG4gKiBAcGFyYW0geyEoRWxlbWVudHxOb2RlTGlzdHxzdHJpbmcpfSBjaGlsZCBUaGUgdGhpbmcgdG8gYXBwZW5kIHRvIHRoZSBwYXJlbnQuXG4gKiBAcmV0dXJuIHshRWxlbWVudH0gVGhlIGFwcGVuZGVkIGNoaWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kKHBhcmVudCwgY2hpbGQpIHtcblx0aWYgKGlzU3RyaW5nKGNoaWxkKSkge1xuXHRcdGNoaWxkID0gYnVpbGRGcmFnbWVudChjaGlsZCk7XG5cdH1cblx0aWYgKGlzTm9kZUxpc3RMaWtlKGNoaWxkKSkge1xuXHRcdGNvbnN0IGNoaWxkQXJyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoY2hpbGQpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRBcnIubGVuZ3RoOyBpKyspIHtcblx0XHRcdHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZEFycltpXSk7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG5cdH1cblx0cmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAqIEhlbHBlciBmb3IgY29udmVydGluZyBhIEhUTUwgc3RyaW5nIGludG8gYSBkb2N1bWVudCBmcmFnbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sU3RyaW5nIFRoZSBIVE1MIHN0cmluZyB0byBjb252ZXJ0LlxuICogQHJldHVybiB7IUVsZW1lbnR9IFRoZSByZXN1bHRpbmcgZG9jdW1lbnQgZnJhZ21lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEZyYWdtZW50KGh0bWxTdHJpbmcpIHtcblx0Y29uc3QgdGVtcERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHR0ZW1wRGl2LmlubmVySFRNTCA9IGA8YnI+JHtodG1sU3RyaW5nfWA7XG5cdHRlbXBEaXYucmVtb3ZlQ2hpbGQodGVtcERpdi5maXJzdENoaWxkKTtcblxuXHRjb25zdCBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblx0d2hpbGUgKHRlbXBEaXYuZmlyc3RDaGlsZCkge1xuXHRcdGZyYWdtZW50LmFwcGVuZENoaWxkKHRlbXBEaXYuZmlyc3RDaGlsZCk7XG5cdH1cblx0cmV0dXJuIGZyYWdtZW50O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZmlyc3QgZWxlbWVudCBjb250YWlucyB0aGUgc2Vjb25kIG9uZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQxXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50MlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zKGVsZW1lbnQxLCBlbGVtZW50Mikge1xuXHRpZiAoaXNEb2N1bWVudChlbGVtZW50MSkpIHtcblx0XHQvLyBkb2N1bWVudC5jb250YWlucyBpcyBub3QgZGVmaW5lZCBvbiBJRTksIHNvIGNhbGwgaXQgb24gZG9jdW1lbnRFbGVtZW50IGluc3RlYWQuXG5cdFx0cmV0dXJuIGVsZW1lbnQxLmRvY3VtZW50RWxlbWVudC5jb250YWlucyhlbGVtZW50Mik7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGVsZW1lbnQxLmNvbnRhaW5zKGVsZW1lbnQyKTtcblx0fVxufVxuXG4vKipcbiAqIExpc3RlbnMgdG8gdGhlIHNwZWNpZmllZCBldmVudCBvbiB0aGUgZ2l2ZW4gRE9NIGVsZW1lbnQsIGJ1dCBvbmx5IGNhbGxzIHRoZVxuICogZ2l2ZW4gY2FsbGJhY2sgbGlzdGVuZXIgd2hlbiBpdCdzIHRyaWdnZXJlZCBieSBlbGVtZW50cyB0aGF0IG1hdGNoIHRoZVxuICogZ2l2ZW4gc2VsZWN0b3Igb3IgdGFyZ2V0IGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBET00gZWxlbWVudCB0aGUgZXZlbnQgc2hvdWxkIGJlIGxpc3RlbmVkIG9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIHRvLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IHNlbGVjdG9yT3JUYXJnZXQgRWl0aGVyIGFuIGVsZW1lbnQgb3IgY3NzIHNlbGVjdG9yXG4gKiAgICAgdGhhdCBzaG91bGQgbWF0Y2ggdGhlIGV2ZW50IGZvciB0aGUgbGlzdGVuZXIgdG8gYmUgdHJpZ2dlcmVkLlxuICogQHBhcmFtIHshZnVuY3Rpb24oIU9iamVjdCl9IGNhbGxiYWNrIEZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudFxuICogICAgIGlzIHRyaWdnZXJlZC4gSXQgd2lsbCByZWNlaXZlIHRoZSBub3JtYWxpemVkIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IGRlZmF1bHRMaXN0ZW5lciBPcHRpb25hbCBmbGFnIGluZGljYXRpbmcgaWYgdGhpcyBpcyBhIGRlZmF1bHRcbiAqICAgICBsaXN0ZW5lci4gVGhhdCBtZWFucyB0aGF0IGl0IHdvdWxkIG9ubHkgYmUgZXhlY3V0ZWQgYWZ0ZXIgYWxsIG5vblxuICogICAgIGRlZmF1bHQgbGlzdGVuZXJzLCBhbmQgb25seSBpZiB0aGUgZXZlbnQgaXNuJ3QgcHJldmVudGVkIHZpYVxuICogICAgIGBwcmV2ZW50RGVmYXVsdGAuXG4gKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IENhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxlZ2F0ZShcblx0ZWxlbWVudCxcblx0ZXZlbnROYW1lLFxuXHRzZWxlY3Rvck9yVGFyZ2V0LFxuXHRjYWxsYmFjayxcblx0ZGVmYXVsdExpc3RlbmVyXG4pIHtcblx0Y29uc3QgY3VzdG9tQ29uZmlnID0gY3VzdG9tRXZlbnRzW2V2ZW50TmFtZV07XG5cdGlmIChjdXN0b21Db25maWcgJiYgY3VzdG9tQ29uZmlnLmRlbGVnYXRlKSB7XG5cdFx0ZXZlbnROYW1lID0gY3VzdG9tQ29uZmlnLm9yaWdpbmFsRXZlbnQ7XG5cdFx0Y2FsbGJhY2sgPSBjdXN0b21Db25maWcuaGFuZGxlci5iaW5kKGN1c3RvbUNvbmZpZywgY2FsbGJhY2spO1xuXHR9XG5cblx0aWYgKGRlZmF1bHRMaXN0ZW5lcikge1xuXHRcdC8vIFdyYXAgY2FsbGJhY2sgc28gd2UgZG9uJ3Qgc2V0IHByb3BlcnR5IGRpcmVjdGx5IG9uIGl0LlxuXHRcdGNhbGxiYWNrID0gY2FsbGJhY2suYmluZCgpO1xuXHRcdGNhbGxiYWNrLmRlZmF1bHRMaXN0ZW5lcl8gPSB0cnVlO1xuXHR9XG5cblx0YXR0YWNoRGVsZWdhdGVFdmVudF8oZWxlbWVudCwgZXZlbnROYW1lKTtcblx0aWYgKGlzU3RyaW5nKHNlbGVjdG9yT3JUYXJnZXQpKSB7XG5cdFx0YWRkU2VsZWN0b3JMaXN0ZW5lcl8oZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3Rvck9yVGFyZ2V0LCBjYWxsYmFjayk7XG5cdH0gZWxzZSB7XG5cdFx0YWRkRWxlbWVudExpc3RlbmVyXyhzZWxlY3Rvck9yVGFyZ2V0LCBldmVudE5hbWUsIGNhbGxiYWNrKTtcblx0fVxuXG5cdHJldHVybiBuZXcgRG9tRGVsZWdhdGVkRXZlbnRIYW5kbGUoXG5cdFx0aXNTdHJpbmcoc2VsZWN0b3JPclRhcmdldCkgPyBlbGVtZW50IDogc2VsZWN0b3JPclRhcmdldCxcblx0XHRldmVudE5hbWUsXG5cdFx0Y2FsbGJhY2ssXG5cdFx0aXNTdHJpbmcoc2VsZWN0b3JPclRhcmdldCkgPyBzZWxlY3Rvck9yVGFyZ2V0IDogbnVsbFxuXHQpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIGlmIHRoZSBlbGVtZW50IGlzIGFibGUgdG8gdHJpZ2dlciB0aGUgQ2xpY2sgZXZlbnQsXG4gKiBzaW11bGF0aW5nIGJyb3dzZXJzIGJlaGF2aW91ciwgYXZvaWRpbmcgZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGNhbGxlZCBieSB0cmlnZ2VyRXZlbnQgbWV0aG9kLlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gYmUgY2hlY2tlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUuXG4gKiBAcGFyYW0ge09iamVjdD19IGV2ZW50T2JqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNBYmxlVG9JbnRlcmFjdFdpdGhfKG5vZGUsIGV2ZW50TmFtZSwgZXZlbnRPYmopIHtcblx0aWYgKGV2ZW50T2JqICYmIGV2ZW50TmFtZSA9PT0gJ2NsaWNrJyAmJiBldmVudE9iai5idXR0b24gPT09IDIpIHtcblx0XHQvLyBGaXJlZm94IHRyaWdnZXJzIFwiY2xpY2tcIiBldmVudHMgb24gdGhlIGRvY3VtZW50IGZvciByaWdodCBjbGlja3MuIFRoaXNcblx0XHQvLyBjYXVzZXMgb3VyIGRlbGVnYXRlIGxvZ2ljIHRvIHRyaWdnZXIgaXQgZm9yIHJlZ3VsYXIgZWxlbWVudHMgdG9vLCB3aGljaFxuXHRcdC8vIHNob3VsZG4ndCBoYXBwZW4uIElnbm9yaW5nIHRoZW0gaGVyZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRjb25zdCBtYXRjaGVzU2VsZWN0b3IgPSBbXG5cdFx0J0JVVFRPTicsXG5cdFx0J0lOUFVUJyxcblx0XHQnU0VMRUNUJyxcblx0XHQnVEVYVEFSRUEnLFxuXHRcdCdGSUVMRFNFVCcsXG5cdF07XG5cdGlmIChldmVudE5hbWUgPT09ICdjbGljaycgJiYgbWF0Y2hlc1NlbGVjdG9yLmluZGV4T2Yobm9kZS50YWdOYW1lKSA+IC0xKSB7XG5cdFx0cmV0dXJuICEobm9kZS5kaXNhYmxlZCB8fCBwYXJlbnQobm9kZSwgJ2ZpZWxkc2V0W2Rpc2FibGVkXScpKTtcblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhIE5vZGVMaXN0IG9yIGxpa2Ugb25lLlxuICogQHBhcmFtIHs/fSB2YWwgVmFyaWFibGUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdmFyaWFibGUgaXMgbGlrZSBhIE5vZGVMaXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb2RlTGlzdExpa2UodmFsKSB7XG5cdHJldHVybiAoXG5cdFx0aXNEZWZBbmROb3ROdWxsKHZhbCkgJiZcblx0XHR0eXBlb2YgdmFsLmxlbmd0aCA9PT0gJ251bWJlcicgJiZcblx0XHR0eXBlb2YgdmFsLml0ZW0gPT09ICdmdW5jdGlvbidcblx0KTtcbn1cblxuLyoqXG4gKiBJbnNlcnRzIG5vZGUgaW4gZG9jdW1lbnQgYXMgbGFzdCBlbGVtZW50LlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gcmVtb3ZlIGNoaWxkcmVuIGZyb20uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnRlckRvY3VtZW50KG5vZGUpIHtcblx0bm9kZSAmJiBhcHBlbmQoZG9jdW1lbnQuYm9keSwgbm9kZSk7XG59XG5cbi8qKlxuICogUmVtb3ZlcyBub2RlIGZyb20gZG9jdW1lbnQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgRWxlbWVudCB0byByZW1vdmUgY2hpbGRyZW4gZnJvbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4aXREb2N1bWVudChub2RlKSB7XG5cdGlmIChub2RlICYmIG5vZGUucGFyZW50Tm9kZSkge1xuXHRcdG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcblx0fVxufVxuXG4vKipcbiAqIFRoaXMgaXMgY2FsbGVkIHdoZW4gYW4gZXZlbnQgaXMgdHJpZ2dlcmVkIGJ5IGEgZGVsZWdhdGUgbGlzdGVuZXIuIEFsbFxuICogbWF0Y2hpbmcgbGlzdGVuZXJzIG9mIHRoaXMgZXZlbnQgdHlwZSBmcm9tIGB0YXJnZXRgIHRvIGBjdXJyZW50VGFyZ2V0YCB3aWxsXG4gKiBiZSB0cmlnZ2VyZWQuXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHBheWxvYWQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGhhbmRsZURlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdG5vcm1hbGl6ZURlbGVnYXRlRXZlbnRfKGV2ZW50KTtcblx0bGV0IHJldCA9IHRydWU7XG5cdGNvbnN0IGNvbnRhaW5lciA9IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XG5cdGNvbnN0IGRlZkZucyA9IFtdO1xuXG5cdHJldCAmPSB0cmlnZ2VyRGVsZWdhdGVkTGlzdGVuZXJzXyhjb250YWluZXIsIGV2ZW50LCBkZWZGbnMpO1xuXHRyZXQgJj0gdHJpZ2dlckRlZmF1bHREZWxlZ2F0ZWRMaXN0ZW5lcnNfKGRlZkZucywgZXZlbnQpO1xuXG5cdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gbnVsbDtcblx0ZXZlbnRbTEFTVF9DT05UQUlORVJdID0gY29udGFpbmVyO1xuXHRyZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBoYXMgdGhlIHJlcXVlc3RlZCBjc3MgY2xhc3MuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lKSB7XG5cdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XG5cdFx0cmV0dXJuIGhhc0NsYXNzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3NOYW1lKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gaGFzQ2xhc3NXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc05hbWUpO1xuXHR9XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgcmVxdWVzdGVkIGNzcyBjbGFzcyB1c2luZyBjbGFzc0xpc3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gaGFzQ2xhc3NXaXRoTmF0aXZlXyhlbGVtZW50LCBjbGFzc05hbWUpIHtcblx0cmV0dXJuIChcblx0XHRjbGFzc05hbWUuaW5kZXhPZignICcpID09PSAtMSAmJiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpXG5cdCk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyB0aGUgcmVxdWVzdGVkIGNzcyBjbGFzcyB3aXRob3V0IHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBoYXNDbGFzc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuXHRyZXR1cm4gKFxuXHRcdGAgJHtlbGVtZW50LmNsYXNzTmFtZX0gYC5pbmRleE9mKGAgJHtjbGFzc05hbWV9IGApID49IDAgJiZcblx0XHRjbGFzc05hbWUuc3BsaXQoJyAnKS5sZW5ndGggPT09IDFcblx0KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgZW1wdHkgb3Igbm90LlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkoZWxlbWVudCkge1xuXHRyZXR1cm4gZWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMDtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IG1hdGNoZXMgYSBnaXZlbiBzZWxlY3Rvci5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0aWYgKCFlbGVtZW50IHx8IGVsZW1lbnQubm9kZVR5cGUgIT09IDEpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRjb25zdCBwID0gRWxlbWVudC5wcm90b3R5cGU7XG5cdGNvbnN0IG0gPVxuXHRcdHAubWF0Y2hlcyB8fFxuXHRcdHAud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0cC5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRwLm1zTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0cC5vTWF0Y2hlc1NlbGVjdG9yO1xuXHRpZiAobSkge1xuXHRcdHJldHVybiBtLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpO1xuXHR9XG5cblx0cmV0dXJuIG1hdGNoRmFsbGJhY2tfKGVsZW1lbnQsIHNlbGVjdG9yKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IG1hdGNoZXMgYSBnaXZlbiBzZWxlY3RvciwgdXNpbmcgYW4gaW50ZXJuYWwgaW1wbGVtZW50YXRpb25cbiAqIGluc3RlYWQgb2YgY2FsbGluZyBleGlzdGluZyBqYXZhc2NyaXB0IGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gbWF0Y2hGYWxsYmFja18oZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0Y29uc3QgcGFyZW50Tm9kZSA9IGVsZW1lbnQucGFyZW50Tm9kZTtcblxuXHRpZiAocGFyZW50Tm9kZSkge1xuXHRcdGNvbnN0IG5vZGVzID0gcGFyZW50Tm9kZS5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyArK2kpIHtcblx0XHRcdGlmIChub2Rlc1tpXSA9PT0gZWxlbWVudCkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbmV4dCBzaWJsaW5nIG9mIHRoZSBnaXZlbiBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkXG4gKiBzZWxlY3Rvciwgb3IgbnVsbCBpZiB0aGVyZSBpcyBub25lLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHs/c3RyaW5nfSBzZWxlY3RvclxuICogQHJldHVybiB7RWxlbWVudHxudWxsfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbmV4dChlbGVtZW50LCBzZWxlY3Rvcikge1xuXHRkbyB7XG5cdFx0ZWxlbWVudCA9IGVsZW1lbnQubmV4dFNpYmxpbmc7XG5cdFx0aWYgKGVsZW1lbnQgJiYgbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpKSB7XG5cdFx0XHRyZXR1cm4gZWxlbWVudDtcblx0XHR9XG5cdH0gd2hpbGUgKGVsZW1lbnQpO1xuXHRyZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIHRoZSBldmVudCBwYXlsb2FkIGZvciBkZWxlZ2F0ZSBsaXN0ZW5lcnMuXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZURlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdGV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IHN0b3BQcm9wYWdhdGlvbl87XG5cdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9IHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbl87XG59XG5cbi8qKlxuICogTGlzdGVucyB0byB0aGUgc3BlY2lmaWVkIGV2ZW50IG9uIHRoZSBnaXZlbiBET00gZWxlbWVudC4gVGhpcyBmdW5jdGlvbiBub3JtYWxpemVzXG4gKiBET00gZXZlbnQgcGF5bG9hZHMgYW5kIGZ1bmN0aW9ucyBzbyB0aGV5J2xsIHdvcmsgdGhlIHNhbWUgd2F5IG9uIGFsbCBzdXBwb3J0ZWRcbiAqIGJyb3dzZXJzLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IGVsZW1lbnQgVGhlIERPTSBlbGVtZW50IHRvIGxpc3RlbiB0byB0aGUgZXZlbnQgb24sIG9yXG4gKiAgIGEgc2VsZWN0b3IgdGhhdCBzaG91bGQgYmUgZGVsZWdhdGVkIG9uIHRoZSBlbnRpcmUgZG9jdW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gdG8uXG4gKiBAcGFyYW0geyFmdW5jdGlvbighT2JqZWN0KX0gY2FsbGJhY2sgRnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzXG4gKiAgIHRyaWdnZXJlZC4gSXQgd2lsbCByZWNlaXZlIHRoZSBub3JtYWxpemVkIGV2ZW50IG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2FwdHVyZSBGbGFnIGluZGljYXRpbmcgaWYgbGlzdGVuZXIgc2hvdWxkIGJlIHRyaWdnZXJlZFxuICogICBkdXJpbmcgY2FwdHVyZSBwaGFzZSwgaW5zdGVhZCBvZiBkdXJpbmcgdGhlIGJ1YmJsaW5nIHBoYXNlLiBEZWZhdWx0cyB0byBmYWxzZS5cbiAqIEByZXR1cm4geyFEb21FdmVudEhhbmRsZX0gQ2FuIGJlIHVzZWQgdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpIHtcblx0aWYgKGlzU3RyaW5nKGVsZW1lbnQpKSB7XG5cdFx0cmV0dXJuIGRlbGVnYXRlKGRvY3VtZW50LCBldmVudE5hbWUsIGVsZW1lbnQsIGNhbGxiYWNrKTtcblx0fVxuXHRjb25zdCBjdXN0b21Db25maWcgPSBjdXN0b21FdmVudHNbZXZlbnROYW1lXTtcblx0aWYgKGN1c3RvbUNvbmZpZyAmJiBjdXN0b21Db25maWcuZXZlbnQpIHtcblx0XHRldmVudE5hbWUgPSBjdXN0b21Db25maWcub3JpZ2luYWxFdmVudDtcblx0XHRjYWxsYmFjayA9IGN1c3RvbUNvbmZpZy5oYW5kbGVyLmJpbmQoY3VzdG9tQ29uZmlnLCBjYWxsYmFjayk7XG5cdH1cblx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xuXHRyZXR1cm4gbmV3IERvbUV2ZW50SGFuZGxlKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xufVxuXG4vKipcbiAqIExpc3RlbnMgdG8gdGhlIHNwZWNpZmllZCBldmVudCBvbiB0aGUgZ2l2ZW4gRE9NIGVsZW1lbnQgb25jZS4gVGhpc1xuICogZnVuY3Rpb24gbm9ybWFsaXplcyBET00gZXZlbnQgcGF5bG9hZHMgYW5kIGZ1bmN0aW9ucyBzbyB0aGV5J2xsIHdvcmsgdGhlXG4gKiBzYW1lIHdheSBvbiBhbGwgc3VwcG9ydGVkIGJyb3dzZXJzLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgRE9NIGVsZW1lbnQgdG8gbGlzdGVuIHRvIHRoZSBldmVudCBvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiB0by5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCFPYmplY3QpfSBjYWxsYmFjayBGdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnRcbiAqICAgaXMgdHJpZ2dlcmVkLiBJdCB3aWxsIHJlY2VpdmUgdGhlIG5vcm1hbGl6ZWQgZXZlbnQgb2JqZWN0LlxuICogQHJldHVybiB7IURvbUV2ZW50SGFuZGxlfSBDYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGxpc3RlbmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb25jZShlbGVtZW50LCBldmVudE5hbWUsIGNhbGxiYWNrKSB7XG5cdGNvbnN0IGRvbUV2ZW50SGFuZGxlID0gb24oZWxlbWVudCwgZXZlbnROYW1lLCBmdW5jdGlvbigpIHtcblx0XHRkb21FdmVudEhhbmRsZS5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdHJldHVybiBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdH0pO1xuXHRyZXR1cm4gZG9tRXZlbnRIYW5kbGU7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgZmlyc3QgcGFyZW50IGZyb20gdGhlIGdpdmVuIGVsZW1lbnQgdGhhdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWRcbiAqIHNlbGVjdG9yLCBvciBudWxsIGlmIG5vbmUgbWF0Y2guXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJlbnQoZWxlbWVudCwgc2VsZWN0b3IpIHtcblx0cmV0dXJuIGNsb3Nlc3QoZWxlbWVudC5wYXJlbnROb2RlLCBzZWxlY3Rvcik7XG59XG5cbi8qKlxuICogSW5zZXJ0cyBhIG5vZGUgYmVmb3JlIGZpcnN0IGNoaWxkIG9mIHRoZSBwYXJlbnQuIElmIGNoaWxkIGlzIGEgSFRNTCBzdHJpbmdcbiAqIGl0IHdpbGwgYmUgY29udmVydGVkIHRvIGRvY3VtZW50IGZyYWdtZW50IGJlZm9yZSBwcmVwZW5kaW5nIGl0IHRvIHRoZSBwYXJlbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBwYXJlbnQgVGhlIG5vZGUgdG8gcHJlcGVuZCB0by5cbiAqIEBwYXJhbSB7IShFbGVtZW50fE5vZGVMaXN0fHN0cmluZyl9IGNoaWxkIFRoZSB0aGluZyB0byBwcmVwZW5kIHRvIHRoZSBwYXJlbnQuXG4gKiBAcmV0dXJuIHshRWxlbWVudH0gVGhlIHByZXBlbmRlZCBjaGlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZXBlbmQocGFyZW50LCBjaGlsZCkge1xuXHRpZiAoaXNTdHJpbmcoY2hpbGQpKSB7XG5cdFx0Y2hpbGQgPSBidWlsZEZyYWdtZW50KGNoaWxkKTtcblx0fVxuXG5cdGlmICghaXNOb2RlTGlzdExpa2UoY2hpbGQpICYmICFpc0RlZkFuZE5vdE51bGwocGFyZW50LmZpcnN0Q2hpbGQpKSB7XG5cdFx0cmV0dXJuIGFwcGVuZChwYXJlbnQsIGNoaWxkKTtcblx0fVxuXG5cdGlmIChpc05vZGVMaXN0TGlrZShjaGlsZCkpIHtcblx0XHRjb25zdCBjaGlsZEFyciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGNoaWxkKTtcblx0XHRmb3IgKGxldCBpID0gY2hpbGRBcnIubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcblx0XHRcdHBhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGRBcnJbaV0sIHBhcmVudC5maXJzdENoaWxkKTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgcGFyZW50LmZpcnN0Q2hpbGQpO1xuXHR9XG5cblx0cmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGN1c3RvbSBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGN1c3RvbSBldmVudC5cbiAqIEBwYXJhbSB7IU9iamVjdH0gY3VzdG9tQ29uZmlnIEFuIG9iamVjdCB3aXRoIGluZm9ybWF0aW9uIGFib3V0IGhvdyB0aGUgZXZlbnRcbiAqICAgc2hvdWxkIGJlIGhhbmRsZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckN1c3RvbUV2ZW50KGV2ZW50TmFtZSwgY3VzdG9tQ29uZmlnKSB7XG5cdGN1c3RvbUV2ZW50c1tldmVudE5hbWVdID0gY3VzdG9tQ29uZmlnO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgYWxsIHRoZSBjaGlsZCBub2RlcyBvbiBhIERPTSBub2RlLlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlIEVsZW1lbnQgdG8gcmVtb3ZlIGNoaWxkcmVuIGZyb20uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDaGlsZHJlbihub2RlKSB7XG5cdGxldCBjaGlsZDtcblx0d2hpbGUgKChjaGlsZCA9IG5vZGUuZmlyc3RDaGlsZCkpIHtcblx0XHRub2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcblx0fVxufVxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fCFOb2RlTGlzdH0gZWxlbWVudHMgVGhlIGVsZW1lbnQgb3IgZWxlbWVudHMgdG8gcmVtb3ZlIENTUyBjbGFzc2VzIGZyb20uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byByZW1vdmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDbGFzc2VzKGVsZW1lbnRzLCBjbGFzc2VzKSB7XG5cdGlmICghaXNPYmplY3QoZWxlbWVudHMpIHx8ICFpc1N0cmluZyhjbGFzc2VzKSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGlmICghZWxlbWVudHMubGVuZ3RoKSB7XG5cdFx0ZWxlbWVudHMgPSBbZWxlbWVudHNdO1xuXHR9XG5cblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50c1tpXSkge1xuXHRcdFx0cmVtb3ZlQ2xhc3Nlc1dpdGhOYXRpdmVfKGVsZW1lbnRzW2ldLCBjbGFzc2VzKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmVtb3ZlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnRzW2ldLCBjbGFzc2VzKTtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSByZXF1ZXN0ZWQgQ1NTIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50IHVzaW5nIGNsYXNzTGlzdC5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gcmVtb3ZlIENTUyBjbGFzc2VzIGZyb20uXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBDU1MgY2xhc3NlcyB0byByZW1vdmUuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiByZW1vdmVDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRpZiAoY2xhc3NOYW1lKSB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKTtcblx0XHR9XG5cdH0pO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHJlcXVlc3RlZCBDU1MgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQgd2l0aG91dCB1c2luZyBjbGFzc0xpc3QuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIHJlbW92ZSBDU1MgY2xhc3NlcyBmcm9tLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgQ1NTIGNsYXNzZXMgdG8gcmVtb3ZlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0bGV0IGVsZW1lbnRDbGFzc05hbWUgPSBgICR7ZWxlbWVudC5jbGFzc05hbWV9IGA7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRlbGVtZW50Q2xhc3NOYW1lID0gZWxlbWVudENsYXNzTmFtZS5yZXBsYWNlKGAgJHtjbGFzc2VzW2ldfSBgLCAnICcpO1xuXHR9XG5cblx0ZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50Q2xhc3NOYW1lLnRyaW0oKTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlcyB0aGUgZmlyc3QgZWxlbWVudCB3aXRoIHRoZSBzZWNvbmQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQxXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlKGVsZW1lbnQxLCBlbGVtZW50Mikge1xuXHRpZiAoZWxlbWVudDEgJiYgZWxlbWVudDIgJiYgZWxlbWVudDEgIT09IGVsZW1lbnQyICYmIGVsZW1lbnQxLnBhcmVudE5vZGUpIHtcblx0XHRlbGVtZW50MS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50MiwgZWxlbWVudDEpO1xuXHRcdGVsZW1lbnQxLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudDEpO1xuXHR9XG59XG5cbi8qKlxuICogVGhlIGZ1bmN0aW9uIHRoYXQgcmVwbGFjZXMgYHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbl9gIGZvciBldmVudHMuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25fKCkge1xuXHRjb25zdCBldmVudCA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0ZXZlbnQuc3RvcHBlZCA9IHRydWU7XG5cdGV2ZW50LnN0b3BwZWRJbW1lZGlhdGUgPSB0cnVlO1xuXHRFdmVudC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uLmNhbGwoZXZlbnQpO1xufVxuXG4vKipcbiAqIFRoZSBmdW5jdGlvbiB0aGF0IHJlcGxhY2VzIGBzdG9wUHJvcGFnYXRpb25gIGZvciBldmVudHMuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzdG9wUHJvcGFnYXRpb25fKCkge1xuXHRjb25zdCBldmVudCA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0ZXZlbnQuc3RvcHBlZCA9IHRydWU7XG5cdEV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24uY2FsbChldmVudCk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBlbGVtZW50IHN1cHBvcnRzIHRoZSBnaXZlbiBldmVudCB0eXBlLlxuICogQHBhcmFtIHshRWxlbWVudHxzdHJpbmd9IGVsZW1lbnQgVGhlIERPTSBlbGVtZW50IG9yIGVsZW1lbnQgdGFnIG5hbWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBjaGVjay5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdXBwb3J0c0V2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSkge1xuXHRpZiAoY3VzdG9tRXZlbnRzW2V2ZW50TmFtZV0pIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdGlmIChpc1N0cmluZyhlbGVtZW50KSkge1xuXHRcdGlmICghZWxlbWVudHNCeVRhZ19bZWxlbWVudF0pIHtcblx0XHRcdGVsZW1lbnRzQnlUYWdfW2VsZW1lbnRdID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChlbGVtZW50KTtcblx0XHR9XG5cdFx0ZWxlbWVudCA9IGVsZW1lbnRzQnlUYWdfW2VsZW1lbnRdO1xuXHR9XG5cblx0Y29uc3QgdGFnID0gZWxlbWVudC50YWdOYW1lO1xuXHRpZiAoIXN1cHBvcnRDYWNoZV9bdGFnXSB8fCAhc3VwcG9ydENhY2hlX1t0YWddLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcblx0XHRzdXBwb3J0Q2FjaGVfW3RhZ10gPSBzdXBwb3J0Q2FjaGVfW3RhZ10gfHwge307XG5cdFx0c3VwcG9ydENhY2hlX1t0YWddW2V2ZW50TmFtZV0gPSAnb24nICsgZXZlbnROYW1lIGluIGVsZW1lbnQ7XG5cdH1cblx0cmV0dXJuIHN1cHBvcnRDYWNoZV9bdGFnXVtldmVudE5hbWVdO1xufVxuXG4vKipcbiAqIFRoaXMgdHJpZ2dlcnMgYWxsIGRlZmF1bHQgbWF0Y2hlZCBkZWxlZ2F0ZWQgbGlzdGVuZXJzIG9mIGEgZ2l2ZW4gZXZlbnQgdHlwZS5cbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogQHBhcmFtIHshRXZlbnR9IGV2ZW50XG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJEZWZhdWx0RGVsZWdhdGVkTGlzdGVuZXJzXyhkZWZGbnMsIGV2ZW50KSB7XG5cdGxldCByZXQgPSB0cnVlO1xuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgZGVmRm5zLmxlbmd0aCAmJiAhZXZlbnQuZGVmYXVsdFByZXZlbnRlZDsgaSsrKSB7XG5cdFx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSBkZWZGbnNbaV0uZWxlbWVudDtcblx0XHRyZXQgJj0gZGVmRm5zW2ldLmZuKGV2ZW50KTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogVGhpcyB0cmlnZ2VycyBhbGwgbWF0Y2hlZCBkZWxlZ2F0ZWQgbGlzdGVuZXJzIG9mIGEgZ2l2ZW4gZXZlbnQgdHlwZSB3aGVuIGl0c1xuICogZGVsZWdhdGVkIHRhcmdldCBpcyBhYmxlIHRvIGludGVyYWN0LlxuICogQHBhcmFtIHshRWxlbWVudH0gY29udGFpbmVyXG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZhdWx0Rm5zIEFycmF5IHRvIGNvbGxlY3QgZGVmYXVsdCBsaXN0ZW5lcnMgaW4sIGluc3RlYWRcbiAqICAgICBvZiBydW5uaW5nIHRoZW0uXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJEZWxlZ2F0ZWRMaXN0ZW5lcnNfKGNvbnRhaW5lciwgZXZlbnQsIGRlZmF1bHRGbnMpIHtcblx0bGV0IHJldCA9IHRydWU7XG5cdGxldCBjdXJyRWxlbWVudCA9IGV2ZW50LnRhcmdldDtcblx0Y29uc3QgbGltaXQgPSBjb250YWluZXIucGFyZW50Tm9kZTtcblxuXHR3aGlsZSAoY3VyckVsZW1lbnQgJiYgY3VyckVsZW1lbnQgIT09IGxpbWl0ICYmICFldmVudC5zdG9wcGVkKSB7XG5cdFx0aWYgKGlzQWJsZVRvSW50ZXJhY3RXaXRoXyhjdXJyRWxlbWVudCwgZXZlbnQudHlwZSwgZXZlbnQpKSB7XG5cdFx0XHRldmVudC5kZWxlZ2F0ZVRhcmdldCA9IGN1cnJFbGVtZW50O1xuXHRcdFx0cmV0ICY9IHRyaWdnZXJFbGVtZW50TGlzdGVuZXJzXyhjdXJyRWxlbWVudCwgZXZlbnQsIGRlZmF1bHRGbnMpO1xuXHRcdFx0cmV0ICY9IHRyaWdnZXJTZWxlY3Rvckxpc3RlbmVyc18oXG5cdFx0XHRcdGNvbnRhaW5lcixcblx0XHRcdFx0Y3VyckVsZW1lbnQsXG5cdFx0XHRcdGV2ZW50LFxuXHRcdFx0XHRkZWZhdWx0Rm5zXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRjdXJyRWxlbWVudCA9IGN1cnJFbGVtZW50LnBhcmVudE5vZGU7XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBhcmd1bWVudCB0byBhIERPTSBlbGVtZW50LiBTdHJpbmdzIGFyZSBhc3N1bWVkIHRvXG4gKiBiZSBzZWxlY3RvcnMsIGFuZCBzbyBhIG1hdGNoZWQgZWxlbWVudCB3aWxsIGJlIHJldHVybmVkLiBJZiB0aGUgYXJnXG4gKiBpcyBhbHJlYWR5IGEgRE9NIGVsZW1lbnQgaXQgd2lsbCBiZSB0aGUgcmV0dXJuIHZhbHVlLlxuICogQHBhcmFtIHtzdHJpbmd8RWxlbWVudHxEb2N1bWVudH0gc2VsZWN0b3JPckVsZW1lbnRcbiAqIEByZXR1cm4ge0VsZW1lbnR9IFRoZSBjb252ZXJ0ZWQgZWxlbWVudCwgb3IgbnVsbCBpZiBub25lIHdhcyBmb3VuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRWxlbWVudChzZWxlY3Rvck9yRWxlbWVudCkge1xuXHRpZiAoXG5cdFx0aXNFbGVtZW50KHNlbGVjdG9yT3JFbGVtZW50KSB8fFxuXHRcdGlzRG9jdW1lbnQoc2VsZWN0b3JPckVsZW1lbnQpIHx8XG5cdFx0aXNEb2N1bWVudEZyYWdtZW50KHNlbGVjdG9yT3JFbGVtZW50KVxuXHQpIHtcblx0XHRyZXR1cm4gc2VsZWN0b3JPckVsZW1lbnQ7XG5cdH0gZWxzZSBpZiAoaXNTdHJpbmcoc2VsZWN0b3JPckVsZW1lbnQpKSB7XG5cdFx0aWYgKFxuXHRcdFx0c2VsZWN0b3JPckVsZW1lbnRbMF0gPT09ICcjJyAmJlxuXHRcdFx0c2VsZWN0b3JPckVsZW1lbnQuaW5kZXhPZignICcpID09PSAtMVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHNlbGVjdG9yT3JFbGVtZW50LnN1YnN0cigxKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yT3JFbGVtZW50KTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIG9yIHJlbW92ZXMgb25lIG9yIG1vcmUgY2xhc3NlcyBmcm9tIGFuIGVsZW1lbnQuIElmIGFueSBvZiB0aGUgY2xhc3Nlc1xuICogaXMgcHJlc2VudCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQsIG9yIGFkZGVkIG90aGVyd2lzZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQgd2hpY2ggY2xhc3NlcyB3aWxsIGJlIHRvZ2dsZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NlcyBUaGUgY2xhc3NlcyB3aGljaCBoYXZlIHRvIGFkZGVkIG9yIHJlbW92ZWQgZnJvbSB0aGUgZWxlbWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvZ2dsZUNsYXNzZXMoZWxlbWVudCwgY2xhc3Nlcykge1xuXHRpZiAoIWlzT2JqZWN0KGVsZW1lbnQpIHx8ICFpc1N0cmluZyhjbGFzc2VzKSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGlmICgnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XG5cdFx0dG9nZ2xlQ2xhc3Nlc1dpdGhOYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpO1xuXHR9IGVsc2Uge1xuXHRcdHRvZ2dsZUNsYXNzZXNXaXRob3V0TmF0aXZlXyhlbGVtZW50LCBjbGFzc2VzKTtcblx0fVxufVxuXG4vKipcbiAqIEFkZHMgb3IgcmVtb3ZlcyBvbmUgb3IgbW9yZSBjbGFzc2VzIGZyb20gYW4gZWxlbWVudCB1c2luZyBjbGFzc0xpc3QuXG4gKiBJZiBhbnkgb2YgdGhlIGNsYXNzZXMgaXMgcHJlc2VudCwgaXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQsXG4gKiBvciBhZGRlZCBvdGhlcndpc2UuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHdoaWNoIGNsYXNzZXMgd2lsbCBiZSB0b2dnbGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzZXMgVGhlIGNsYXNzZXMgd2hpY2ggaGF2ZSB0byBhZGRlZCBvciByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiB0b2dnbGVDbGFzc2VzV2l0aE5hdGl2ZV8oZWxlbWVudCwgY2xhc3Nlcykge1xuXHRjbGFzc2VzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcblx0XHRlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoY2xhc3NOYW1lKTtcblx0fSk7XG59XG5cbi8qKlxuICogQWRkcyBvciByZW1vdmVzIG9uZSBvciBtb3JlIGNsYXNzZXMgZnJvbSBhbiBlbGVtZW50IHdpdGhvdXQgdXNpbmcgY2xhc3NMaXN0LlxuICogSWYgYW55IG9mIHRoZSBjbGFzc2VzIGlzIHByZXNlbnQsIGl0IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBlbGVtZW50LFxuICogb3IgYWRkZWQgb3RoZXJ3aXNlLlxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCB3aGljaCBjbGFzc2VzIHdpbGwgYmUgdG9nZ2xlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc2VzIFRoZSBjbGFzc2VzIHdoaWNoIGhhdmUgdG8gYWRkZWQgb3IgcmVtb3ZlZCBmcm9tIHRoZSBlbGVtZW50LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlQ2xhc3Nlc1dpdGhvdXROYXRpdmVfKGVsZW1lbnQsIGNsYXNzZXMpIHtcblx0bGV0IGVsZW1lbnRDbGFzc05hbWUgPSBgICR7ZWxlbWVudC5jbGFzc05hbWV9IGA7XG5cblx0Y2xhc3NlcyA9IGNsYXNzZXMuc3BsaXQoJyAnKTtcblxuXHRmb3IgKGxldCBpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHtcblx0XHRjb25zdCBjbGFzc05hbWUgPSBgICR7Y2xhc3Nlc1tpXX0gYDtcblx0XHRjb25zdCBjbGFzc0luZGV4ID0gZWxlbWVudENsYXNzTmFtZS5pbmRleE9mKGNsYXNzTmFtZSk7XG5cblx0XHRpZiAoY2xhc3NJbmRleCA9PT0gLTEpIHtcblx0XHRcdGVsZW1lbnRDbGFzc05hbWUgPSBgJHtlbGVtZW50Q2xhc3NOYW1lfSR7Y2xhc3Nlc1tpXX0gYDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3QgYmVmb3JlID0gZWxlbWVudENsYXNzTmFtZS5zdWJzdHJpbmcoMCwgY2xhc3NJbmRleCk7XG5cdFx0XHRjb25zdCBhZnRlciA9IGVsZW1lbnRDbGFzc05hbWUuc3Vic3RyaW5nKFxuXHRcdFx0XHRjbGFzc0luZGV4ICsgY2xhc3NOYW1lLmxlbmd0aFxuXHRcdFx0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdFx0ZWxlbWVudENsYXNzTmFtZSA9IGAke2JlZm9yZX0gJHthZnRlcn1gO1xuXHRcdH1cblx0fVxuXG5cdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudENsYXNzTmFtZS50cmltKCk7XG59XG5cbi8qKlxuICogVHJpZ2dlcnMgYWxsIGxpc3RlbmVycyBmb3IgdGhlIGdpdmVuIGV2ZW50IHR5cGUgdGhhdCBhcmUgc3RvcmVkIGluIHRoZVxuICogc3BlY2lmaWVkIGVsZW1lbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0geyFFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7IUFycmF5fSBkZWZhdWx0Rm5zIEFycmF5IHRvIGNvbGxlY3QgZGVmYXVsdCBsaXN0ZW5lcnMgaW4sIGluc3RlYWRcbiAqICAgICBvZiBydW5uaW5nIHRoZW0uXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZSBpZiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRyaWdnZXJlZCBjYWxsYmFja3MgcmV0dXJuc1xuICogICAgIGZhbHNlLCBvciB0cnVlIG90aGVyd2lzZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHRyaWdnZXJFbGVtZW50TGlzdGVuZXJzXyhlbGVtZW50LCBldmVudCwgZGVmYXVsdEZucykge1xuXHRjb25zdCBsYXN0Q29udGFpbmVyID0gZXZlbnRbTEFTVF9DT05UQUlORVJdO1xuXHRpZiAoIWlzRGVmKGxhc3RDb250YWluZXIpIHx8ICFjb250YWlucyhsYXN0Q29udGFpbmVyLCBlbGVtZW50KSkge1xuXHRcdGNvbnN0IGxpc3RlbmVycyA9IGRvbURhdGEuZ2V0KGVsZW1lbnQsICdsaXN0ZW5lcnMnLCB7fSlbZXZlbnQudHlwZV07XG5cdFx0cmV0dXJuIHRyaWdnZXJMaXN0ZW5lcnNfKGxpc3RlbmVycywgZXZlbnQsIGVsZW1lbnQsIGRlZmF1bHRGbnMpO1xuXHR9XG5cdHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIFRyaWdnZXJzIHRoZSBzcGVjaWZpZWQgZXZlbnQgb24gdGhlIGdpdmVuIGVsZW1lbnQuXG4gKiBOT1RFOiBUaGlzIHNob3VsZCBtb3N0bHkgYmUgdXNlZCBmb3IgdGVzdGluZywgbm90IG9uIHJlYWwgY29kZS5cbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnQgVGhlIG5vZGUgdGhhdCBzaG91bGQgdHJpZ2dlciB0aGUgZXZlbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBiZSB0cmlnZ3JlZC5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gZXZlbnRPYmogQW4gb2JqZWN0IHdpdGggZGF0YSB0aGF0IHNob3VsZCBiZSBvbiB0aGVcbiAqICAgdHJpZ2dlcmVkIGV2ZW50J3MgcGF5bG9hZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXJFdmVudChlbGVtZW50LCBldmVudE5hbWUsIGV2ZW50T2JqKSB7XG5cdGlmIChpc0FibGVUb0ludGVyYWN0V2l0aF8oZWxlbWVudCwgZXZlbnROYW1lLCBldmVudE9iaikpIHtcblx0XHRjb25zdCBwYXlsb2FkID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKTtcblx0XHRwYXlsb2FkLmluaXRFdmVudChldmVudE5hbWUsIHRydWUsIHRydWUpO1xuXHRcdG9iamVjdC5taXhpbihwYXlsb2FkLCBldmVudE9iaik7XG5cdFx0ZWxlbWVudC5kaXNwYXRjaEV2ZW50KHBheWxvYWQpO1xuXHR9XG59XG5cbi8qKlxuICogVHJpZ2dlcnMgdGhlIGdpdmVuIGxpc3RlbmVycyBhcnJheS5cbiAqIEBwYXJhbSB7QXJyYXk8IWZ1bmN0aW9uKCk+fSBsaXN0ZW5lcnNcbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHBhcmFtIHshRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHshQXJyYXl9IGRlZmF1bHRGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogICAgIG9mIHJ1bm5pbmcgdGhlbS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlckxpc3RlbmVyc18obGlzdGVuZXJzLCBldmVudCwgZWxlbWVudCwgZGVmYXVsdEZucykge1xuXHRsZXQgcmV0ID0gdHJ1ZTtcblx0bGlzdGVuZXJzID0gbGlzdGVuZXJzIHx8IFtdO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGggJiYgIWV2ZW50LnN0b3BwZWRJbW1lZGlhdGU7IGkrKykge1xuXHRcdGlmIChsaXN0ZW5lcnNbaV0uZGVmYXVsdExpc3RlbmVyXykge1xuXHRcdFx0ZGVmYXVsdEZucy5wdXNoKHtcblx0XHRcdFx0ZWxlbWVudCxcblx0XHRcdFx0Zm46IGxpc3RlbmVyc1tpXSxcblx0XHRcdH0pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXQgJj0gbGlzdGVuZXJzW2ldKGV2ZW50KTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBUcmlnZ2VycyBhbGwgc2VsZWN0b3IgbGlzdGVuZXJzIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG4gKiBAcGFyYW0geyFFbGVtZW50fSBjb250YWluZXJcbiAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7IUV2ZW50fSBldmVudFxuICogQHBhcmFtIHshQXJyYXl9IGRlZmF1bHRGbnMgQXJyYXkgdG8gY29sbGVjdCBkZWZhdWx0IGxpc3RlbmVycyBpbiwgaW5zdGVhZFxuICogICAgIG9mIHJ1bm5pbmcgdGhlbS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgdHJpZ2dlcmVkIGNhbGxiYWNrcyByZXR1cm5zXG4gKiAgICAgZmFsc2UsIG9yIHRydWUgb3RoZXJ3aXNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlclNlbGVjdG9yTGlzdGVuZXJzXyhjb250YWluZXIsIGVsZW1lbnQsIGV2ZW50LCBkZWZhdWx0Rm5zKSB7XG5cdGxldCByZXQgPSB0cnVlO1xuXHRjb25zdCBkYXRhID0gZG9tRGF0YS5nZXQoY29udGFpbmVyLCAnZGVsZWdhdGluZycsIHt9KTtcblx0Y29uc3QgbWFwID0gZGF0YVtldmVudC50eXBlXS5zZWxlY3RvcnM7XG5cdGNvbnN0IHNlbGVjdG9ycyA9IE9iamVjdC5rZXlzKG1hcCk7XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0b3JzLmxlbmd0aCAmJiAhZXZlbnQuc3RvcHBlZEltbWVkaWF0ZTsgaSsrKSB7XG5cdFx0aWYgKG1hdGNoKGVsZW1lbnQsIHNlbGVjdG9yc1tpXSkpIHtcblx0XHRcdGNvbnN0IGxpc3RlbmVycyA9IG1hcFtzZWxlY3RvcnNbaV1dO1xuXHRcdFx0cmV0ICY9IHRyaWdnZXJMaXN0ZW5lcnNfKGxpc3RlbmVycywgZXZlbnQsIGVsZW1lbnQsIGRlZmF1bHRGbnMpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gcmV0O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBUaGlzIGZpbGUgZXhpc3RzIGp1c3QgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBtYWtpbmcgc3VyZSB0aGF0IG9sZFxuLy8gZGVmYXVsdCBpbXBvcnRzIGZvciB0aGlzIGZpbGUgc3RpbGwgd29yay4gSXQncyBiZXN0IHRvIHVzZSB0aGUgbmFtZWQgZXhwb3J0c1xuLy8gZm9yIGVhY2ggZnVuY3Rpb24gaW5zdGVhZCB0aG91Z2gsIHNpbmNlIHRoYXQgYWxsb3dzIGJ1bmRsZXJzIGxpa2UgUm9sbHVwIHRvXG4vLyByZWR1Y2UgdGhlIGJ1bmRsZSBzaXplIGJ5IHJlbW92aW5nIHVudXNlZCBjb2RlLlxuaW1wb3J0ICogYXMgZG9tIGZyb20gJy4vZG9tTmFtZWQnO1xuXG5leHBvcnQgZGVmYXVsdCBkb207XG5leHBvcnQge2RvbX07XG5leHBvcnQgKiBmcm9tICcuL2RvbU5hbWVkJztcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtkZWxlZ2F0ZSwgb24sIHN1cHBvcnRzRXZlbnR9IGZyb20gJy4vZG9tJztcbmltcG9ydCB7RXZlbnRFbWl0dGVyUHJveHl9IGZyb20gJ21ldGFsLWV2ZW50cyc7XG5cbi8qKlxuICogRG9tRXZlbnRFbWl0dGVyUHJveHkgdXRpbGl0eS4gSXQgZXh0ZW5kcyBgRXZlbnRFbWl0dGVyUHJveHlgIHRvIGFsc28gYWNjZXB0XG4gKiBkb20gZWxlbWVudHMgYXMgb3JpZ2luIGVtaXR0ZXJzLlxuICogQGV4dGVuZHMge0V2ZW50RW1pdHRlclByb3h5fVxuICovXG5jbGFzcyBEb21FdmVudEVtaXR0ZXJQcm94eSBleHRlbmRzIEV2ZW50RW1pdHRlclByb3h5IHtcblx0LyoqXG5cdCAqIEFkZHMgdGhlIGdpdmVuIGxpc3RlbmVyIGZvciB0aGUgZ2l2ZW4gZXZlbnQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBsaXN0ZW5lclxuXHQgKiBAcmV0dXJuIHshRXZlbnRIYW5kbGV9IFRoZSBsaXN0ZW5lZCBldmVudCdzIGhhbmRsZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKiBAb3ZlcnJpZGVcblx0ICovXG5cdGFkZExpc3RlbmVyXyhldmVudCwgbGlzdGVuZXIpIHtcblx0XHRpZiAodGhpcy5vcmlnaW5FbWl0dGVyXy5hZGRFdmVudExpc3RlbmVyKSB7XG5cdFx0XHRpZiAodGhpcy5pc0RlbGVnYXRlRXZlbnRfKGV2ZW50KSkge1xuXHRcdFx0XHRjb25zdCBpbmRleCA9IGV2ZW50LmluZGV4T2YoJzonLCA5KTtcblx0XHRcdFx0Y29uc3QgZXZlbnROYW1lID0gZXZlbnQuc3Vic3RyaW5nKDksIGluZGV4KTtcblx0XHRcdFx0Y29uc3Qgc2VsZWN0b3IgPSBldmVudC5zdWJzdHJpbmcoaW5kZXggKyAxKTtcblx0XHRcdFx0cmV0dXJuIGRlbGVnYXRlKFxuXHRcdFx0XHRcdHRoaXMub3JpZ2luRW1pdHRlcl8sXG5cdFx0XHRcdFx0ZXZlbnROYW1lLFxuXHRcdFx0XHRcdHNlbGVjdG9yLFxuXHRcdFx0XHRcdGxpc3RlbmVyXG5cdFx0XHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBvbih0aGlzLm9yaWdpbkVtaXR0ZXJfLCBldmVudCwgbGlzdGVuZXIpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gc3VwZXIuYWRkTGlzdGVuZXJfKGV2ZW50LCBsaXN0ZW5lcik7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXZlbnQgaXMgb2YgdGhlIGRlbGVnYXRlIHR5cGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRpc0RlbGVnYXRlRXZlbnRfKGV2ZW50KSB7XG5cdFx0cmV0dXJuIGV2ZW50LnN1YnN0cigwLCA5KSA9PT0gJ2RlbGVnYXRlOic7XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBldmVudCBpcyBzdXBwb3J0ZWQgYnkgdGhlIG9yaWdpbiBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcblx0ICogQHByb3RlY3RlZFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0aXNTdXBwb3J0ZWREb21FdmVudF8oZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMub3JpZ2luRW1pdHRlcl8gfHwgIXRoaXMub3JpZ2luRW1pdHRlcl8uYWRkRXZlbnRMaXN0ZW5lcikge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAoXG5cdFx0XHQodGhpcy5pc0RlbGVnYXRlRXZlbnRfKGV2ZW50KSAmJiBldmVudC5pbmRleE9mKCc6JywgOSkgIT09IC0xKSB8fFxuXHRcdFx0c3VwcG9ydHNFdmVudCh0aGlzLm9yaWdpbkVtaXR0ZXJfLCBldmVudClcblx0XHQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZXZlbnQgc2hvdWxkIGJlIHByb3hpZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0c2hvdWxkUHJveHlFdmVudF8oZXZlbnQpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0c3VwZXIuc2hvdWxkUHJveHlFdmVudF8oZXZlbnQpICYmIHRoaXMuaXNTdXBwb3J0ZWREb21FdmVudF8oZXZlbnQpXG5cdFx0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERvbUV2ZW50RW1pdHRlclByb3h5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQge2FwcGVuZH0gZnJvbSAnLi9kb20nO1xuaW1wb3J0IHtzdHJpbmd9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBDbGFzcyB3aXRoIHN0YXRpYyBtZXRob2RzIHJlc3BvbnNpYmxlIGZvciBkb2luZyBicm93c2VyIGZlYXR1cmUgY2hlY2tzLlxuICovXG5jbGFzcyBmZWF0dXJlcyB7XG5cdC8qKlxuXHQgKiBTb21lIGJyb3dzZXJzIHN0aWxsIHN1cHBvcnRzIHByZWZpeGVkIGFuaW1hdGlvbiBldmVudHMuIFRoaXMgbWV0aG9kIGNhblxuXHQgKiBiZSB1c2VkIHRvIHJldHJpZXZlIHRoZSBjdXJyZW50IGJyb3dzZXIgZXZlbnQgbmFtZSBmb3IgYm90aCwgYW5pbWF0aW9uXG5cdCAqIGFuZCB0cmFuc2l0aW9uLlxuXHQgKiBAcmV0dXJuIHtvYmplY3R9XG5cdCAqL1xuXHRzdGF0aWMgY2hlY2tBbmltYXRpb25FdmVudE5hbWUoKSB7XG5cdFx0aWYgKGZlYXR1cmVzLmFuaW1hdGlvbkV2ZW50TmFtZV8gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0ZmVhdHVyZXMuYW5pbWF0aW9uRXZlbnROYW1lXyA9IHtcblx0XHRcdFx0YW5pbWF0aW9uOiBmZWF0dXJlcy5jaGVja0FuaW1hdGlvbkV2ZW50TmFtZV8oJ2FuaW1hdGlvbicpLFxuXHRcdFx0XHR0cmFuc2l0aW9uOiBmZWF0dXJlcy5jaGVja0FuaW1hdGlvbkV2ZW50TmFtZV8oJ3RyYW5zaXRpb24nKSxcblx0XHRcdH07XG5cdFx0fVxuXHRcdHJldHVybiBmZWF0dXJlcy5hbmltYXRpb25FdmVudE5hbWVfO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZSB0byB0ZXN0OiBhbmltYXRpb24sIHRyYW5zaXRpb24uXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gQnJvd3NlciBldmVudCBuYW1lLlxuXHQgKi9cblx0c3RhdGljIGNoZWNrQW5pbWF0aW9uRXZlbnROYW1lXyh0eXBlKSB7XG5cdFx0Y29uc3QgcHJlZml4ZXMgPSBbJ1dlYmtpdCcsICdNUycsICdPJywgJyddO1xuXHRcdGNvbnN0IHR5cGVUaXRsZUNhc2UgPSBzdHJpbmcucmVwbGFjZUludGVydmFsKFxuXHRcdFx0dHlwZSxcblx0XHRcdDAsXG5cdFx0XHQxLFxuXHRcdFx0dHlwZS5zdWJzdHJpbmcoMCwgMSkudG9VcHBlckNhc2UoKVxuXHRcdCk7XG5cdFx0Y29uc3Qgc3VmZml4ZXMgPSBbXG5cdFx0XHRgJHt0eXBlVGl0bGVDYXNlfUVuZGAsXG5cdFx0XHRgJHt0eXBlVGl0bGVDYXNlfUVuZGAsXG5cdFx0XHRgJHt0eXBlVGl0bGVDYXNlfUVuZGAsXG5cdFx0XHRgJHt0eXBlfWVuZGAsXG5cdFx0XTtcblx0XHRpZiAoIWZlYXR1cmVzLmFuaW1hdGlvbkVsZW1lbnRfKSB7XG5cdFx0XHRmZWF0dXJlcy5hbmltYXRpb25FbGVtZW50XyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdH1cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdGZlYXR1cmVzLmFuaW1hdGlvbkVsZW1lbnRfLnN0eWxlW1xuXHRcdFx0XHRcdHByZWZpeGVzW2ldICsgdHlwZVRpdGxlQ2FzZVxuXHRcdFx0XHRdICE9PSB1bmRlZmluZWQgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiBwcmVmaXhlc1tpXS50b0xvd2VyQ2FzZSgpICsgc3VmZml4ZXNbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBgJHt0eXBlfWVuZGA7XG5cdH1cblxuXHQvKipcblx0ICogU29tZSBicm93c2VycyAobGlrZSBJRTkpIGNoYW5nZSB0aGUgb3JkZXIgb2YgZWxlbWVudCBhdHRyaWJ1dGVzLCB3aGVuIGh0bWxcblx0ICogaXMgcmVuZGVyZWQuIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNoZWNrIGlmIHRoaXMgYmVoYXZpb3IgaGFwcGVucyBvblxuXHQgKiB0aGUgY3VycmVudCBicm93c2VyLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0c3RhdGljIGNoZWNrQXR0ck9yZGVyQ2hhbmdlKCkge1xuXHRcdGlmIChmZWF0dXJlcy5hdHRyT3JkZXJDaGFuZ2VfID09PSB1bmRlZmluZWQpIHtcblx0XHRcdGNvbnN0IG9yaWdpbmFsQ29udGVudCA9ICc8ZGl2IGRhdGEtY29tcG9uZW50PVwiXCIgZGF0YS1yZWY9XCJcIj48L2Rpdj4nO1xuXHRcdFx0Y29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0YXBwZW5kKGVsZW1lbnQsIG9yaWdpbmFsQ29udGVudCk7XG5cdFx0XHRmZWF0dXJlcy5hdHRyT3JkZXJDaGFuZ2VfID0gb3JpZ2luYWxDb250ZW50ICE9PSBlbGVtZW50LmlubmVySFRNTDtcblx0XHR9XG5cdFx0cmV0dXJuIGZlYXR1cmVzLmF0dHJPcmRlckNoYW5nZV87XG5cdH1cbn1cblxuZmVhdHVyZXMuYW5pbWF0aW9uRWxlbWVudF8gPSB1bmRlZmluZWQ7XG5mZWF0dXJlcy5hbmltYXRpb25FdmVudE5hbWVfID0gdW5kZWZpbmVkO1xuZmVhdHVyZXMuYXR0ck9yZGVyQ2hhbmdlXyA9IHVuZGVmaW5lZDtcblxuZXhwb3J0IGRlZmF1bHQgZmVhdHVyZXM7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXN5bmN9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7ZXhpdERvY3VtZW50LCBvbmNlfSBmcm9tICcuL2RvbSc7XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIHJ1bm5pbmcgamF2YXNjcmlwdCBjb2RlIGluIHRoZSBnbG9iYWwgc2NvcGUuXG4gKi9cbmNsYXNzIGdsb2JhbEV2YWwge1xuXHQvKipcblx0ICogRXZhbHVhdGVzIHRoZSBnaXZlbiBzdHJpbmcgaW4gdGhlIGdsb2JhbCBzY29wZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHRleHRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc2NyaXB0XG5cdCAqL1xuXHRzdGF0aWMgcnVuKHRleHQsIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cdFx0c2NyaXB0LnRleHQgPSB0ZXh0O1xuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc2NyaXB0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH1cblx0XHRleGl0RG9jdW1lbnQoc2NyaXB0KTtcblx0XHRyZXR1cm4gc2NyaXB0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gamF2YXNjcmlwdCBmaWxlIGluIHRoZSBnbG9iYWwgc2NvcGUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgVGhlIGZpbGUncyBwYXRoLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc2NyaXB0XG5cdCAqL1xuXHRzdGF0aWMgcnVuRmlsZShzcmMsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRzY3JpcHQuc3JjID0gc3JjO1xuXG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGV4aXREb2N1bWVudChzY3JpcHQpO1xuXHRcdFx0ZGVmYXVsdEZuICYmIGRlZmF1bHRGbigpO1xuXHRcdH07XG5cdFx0b25jZShzY3JpcHQsICdsb2FkJywgY2FsbGJhY2spO1xuXHRcdG9uY2Uoc2NyaXB0LCAnZXJyb3InLCBjYWxsYmFjayk7XG5cblx0XHRpZiAoYXBwZW5kRm4pIHtcblx0XHRcdGFwcGVuZEZuKHNjcmlwdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc2NyaXB0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgY29kZSByZWZlcmVuY2VkIGJ5IHRoZSBnaXZlbiBzY3JpcHQgZWxlbWVudC5cblx0ICogQHBhcmFtIHshRWxlbWVudH0gc2NyaXB0XG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWRcblx0ICogICB3aGVuIHRoZSBzY3JpcHQgaGFzIGJlZW4gcnVuLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzY3JpcHRcblx0ICovXG5cdHN0YXRpYyBydW5TY3JpcHQoc2NyaXB0LCBkZWZhdWx0Rm4sIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGRlZmF1bHRGbiAmJiBkZWZhdWx0Rm4oKTtcblx0XHR9O1xuXHRcdGlmIChzY3JpcHQudHlwZSAmJiBzY3JpcHQudHlwZSAhPT0gJ3RleHQvamF2YXNjcmlwdCcpIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGNhbGxiYWNrKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZXhpdERvY3VtZW50KHNjcmlwdCk7XG5cdFx0aWYgKHNjcmlwdC5zcmMpIHtcblx0XHRcdHJldHVybiBnbG9iYWxFdmFsLnJ1bkZpbGUoc2NyaXB0LnNyYywgZGVmYXVsdEZuLCBhcHBlbmRGbik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGNhbGxiYWNrKTtcblx0XHRcdHJldHVybiBnbG9iYWxFdmFsLnJ1bihzY3JpcHQudGV4dCwgYXBwZW5kRm4pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgYW55IHNjcmlwdCB0YWdzIHByZXNlbnQgaW4gdGhlIGdpdmVuIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiAgIHdoZW4gdGhlIHNjcmlwdCBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU2NyaXB0c0luRWxlbWVudChlbGVtZW50LCBkZWZhdWx0Rm4sIGFwcGVuZEZuKSB7XG5cdFx0Y29uc3Qgc2NyaXB0cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnc2NyaXB0Jyk7XG5cdFx0aWYgKHNjcmlwdHMubGVuZ3RoKSB7XG5cdFx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdHNJbk9yZGVyKHNjcmlwdHMsIDAsIGRlZmF1bHRGbiwgYXBwZW5kRm4pO1xuXHRcdH0gZWxzZSBpZiAoZGVmYXVsdEZuKSB7XG5cdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSdW5zIHRoZSBnaXZlbiBzY3JpcHRzIGVsZW1lbnRzIGluIHRoZSBvcmRlciB0aGF0IHRoZXkgYXBwZWFyLlxuXHQgKiBAcGFyYW0geyFOb2RlTGlzdH0gc2NyaXB0c1xuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gZGVmYXVsdEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZFxuXHQgKiAgIHdoZW4gdGhlIHNjcmlwdCBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU2NyaXB0c0luT3JkZXIoc2NyaXB0cywgaW5kZXgsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRnbG9iYWxFdmFsLnJ1blNjcmlwdChcblx0XHRcdHNjcmlwdHMuaXRlbShpbmRleCksXG5cdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKGluZGV4IDwgc2NyaXB0cy5sZW5ndGggLSAxKSB7XG5cdFx0XHRcdFx0Z2xvYmFsRXZhbC5ydW5TY3JpcHRzSW5PcmRlcihcblx0XHRcdFx0XHRcdHNjcmlwdHMsXG5cdFx0XHRcdFx0XHRpbmRleCArIDEsXG5cdFx0XHRcdFx0XHRkZWZhdWx0Rm4sXG5cdFx0XHRcdFx0XHRhcHBlbmRGblxuXHRcdFx0XHRcdCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHRcdFx0fSBlbHNlIGlmIChkZWZhdWx0Rm4pIHtcblx0XHRcdFx0XHRhc3luYy5uZXh0VGljayhkZWZhdWx0Rm4pO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0YXBwZW5kRm5cblx0XHQpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGdsb2JhbEV2YWw7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7YXN5bmN9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7b25jZX0gZnJvbSAnLi9kb20nO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zIGZvciBydW5uaW5nIHN0eWxlcy5cbiAqL1xuY2xhc3MgZ2xvYmFsRXZhbFN0eWxlcyB7XG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdGhlIGdpdmVuIHN0eWxlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBhcHBlbmRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBhcHBlbmQgdGhlIG5vZGVcblx0ICogICBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBzdHlsZVxuXHQgKi9cblx0c3RhdGljIHJ1bih0ZXh0LCBhcHBlbmRGbikge1xuXHRcdGNvbnN0IHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblx0XHRzdHlsZS5pbm5lckhUTUwgPSB0ZXh0O1xuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc3R5bGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblx0XHR9XG5cdFx0cmV0dXJuIHN0eWxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gc3R5bGUgZmlsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGhyZWYgVGhlIGZpbGUncyBwYXRoLlxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc3R5bGVzIGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogQHJldHVybiB7RWxlbWVudH0gc3R5bGVcblx0ICovXG5cdHN0YXRpYyBydW5GaWxlKGhyZWYsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGluaycpO1xuXHRcdGxpbmsucmVsID0gJ3N0eWxlc2hlZXQnO1xuXHRcdGxpbmsuaHJlZiA9IGhyZWY7XG5cdFx0Z2xvYmFsRXZhbFN0eWxlcy5ydW5TdHlsZShsaW5rLCBkZWZhdWx0Rm4sIGFwcGVuZEZuKTtcblx0XHRyZXR1cm4gbGluaztcblx0fVxuXG5cdC8qKlxuXHQgKiBFdmFsdWF0ZXMgdGhlIGNvZGUgcmVmZXJlbmNlZCBieSB0aGUgZ2l2ZW4gc3R5bGUvbGluayBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBzdHlsZVxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBkZWZhdWx0Rm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXG5cdCAqICAgd2hlbiB0aGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi5cblx0ICogQHBhcmFtIHtmdW5jdGlvbigpPX0gYXBwZW5kRm4gT3B0aW9uYWwgZnVuY3Rpb24gdG8gYXBwZW5kIHRoZSBub2RlXG5cdCAqICAgaW50byBkb2N1bWVudC5cblx0ICogIEByZXR1cm4ge0VsZW1lbnR9IHN0eWxlXG5cdCAqL1xuXHRzdGF0aWMgcnVuU3R5bGUoc3R5bGUsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBjYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGVmYXVsdEZuICYmIGRlZmF1bHRGbigpO1xuXHRcdH07XG5cdFx0aWYgKHN0eWxlLnJlbCAmJiBzdHlsZS5yZWwgIT09ICdzdHlsZXNoZWV0Jykge1xuXHRcdFx0YXN5bmMubmV4dFRpY2soY2FsbGJhY2spO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChzdHlsZS50YWdOYW1lID09PSAnU1RZTEUnKSB7XG5cdFx0XHRhc3luYy5uZXh0VGljayhjYWxsYmFjayk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG9uY2Uoc3R5bGUsICdsb2FkJywgY2FsbGJhY2spO1xuXHRcdFx0b25jZShzdHlsZSwgJ2Vycm9yJywgY2FsbGJhY2spO1xuXHRcdH1cblxuXHRcdGlmIChhcHBlbmRGbikge1xuXHRcdFx0YXBwZW5kRm4oc3R5bGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc3R5bGU7XG5cdH1cblxuXHQvKipcblx0ICogRXZhbHVhdGVzIGFueSBzdHlsZSBwcmVzZW50IGluIHRoZSBnaXZlbiBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGRlZmF1bHRGbiBPcHRpb25hbCBmdW5jdGlvbiB0byBiZSBjYWxsZWQgd2hlbiB0aGVcblx0ICogICBzdHlsZSBoYXMgYmVlbiBydW4uXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oKT19IGFwcGVuZEZuIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZVxuXHQgKiAgIGludG8gZG9jdW1lbnQuXG5cdCAqL1xuXHRzdGF0aWMgcnVuU3R5bGVzSW5FbGVtZW50KGVsZW1lbnQsIGRlZmF1bHRGbiwgYXBwZW5kRm4pIHtcblx0XHRjb25zdCBzdHlsZXMgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3N0eWxlLGxpbmsnKTtcblx0XHRpZiAoc3R5bGVzLmxlbmd0aCA9PT0gMCAmJiBkZWZhdWx0Rm4pIHtcblx0XHRcdGFzeW5jLm5leHRUaWNrKGRlZmF1bHRGbik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0bGV0IGxvYWRDb3VudCA9IDA7XG5cdFx0Y29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmIChkZWZhdWx0Rm4gJiYgKytsb2FkQ291bnQgPT09IHN0eWxlcy5sZW5ndGgpIHtcblx0XHRcdFx0YXN5bmMubmV4dFRpY2soZGVmYXVsdEZuKTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc3R5bGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRnbG9iYWxFdmFsU3R5bGVzLnJ1blN0eWxlKHN0eWxlc1tpXSwgY2FsbGJhY2ssIGFwcGVuZEZuKTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZ2xvYmFsRXZhbFN0eWxlcztcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtpc1NlcnZlclNpZGV9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7cmVnaXN0ZXJDdXN0b21FdmVudCwgY29udGFpbnN9IGZyb20gJy4vZG9tJztcbmltcG9ydCBmZWF0dXJlcyBmcm9tICcuL2ZlYXR1cmVzJztcblxuLyoqXG4gKiBSZWdpc3RlciBjdXN0b20gZXZlbnRzIGZvciBldmVudCBkZWxlZ2F0aW9uLlxuICovXG5mdW5jdGlvbiByZWdpc3RlckV2ZW50cygpIHtcblx0Y29uc3QgbW91c2VFdmVudE1hcCA9IHtcblx0XHRtb3VzZWVudGVyOiAnbW91c2VvdmVyJyxcblx0XHRtb3VzZWxlYXZlOiAnbW91c2VvdXQnLFxuXHRcdHBvaW50ZXJlbnRlcjogJ3BvaW50ZXJvdmVyJyxcblx0XHRwb2ludGVybGVhdmU6ICdwb2ludGVyb3V0Jyxcblx0fTtcblx0T2JqZWN0LmtleXMobW91c2VFdmVudE1hcCkuZm9yRWFjaChmdW5jdGlvbihldmVudE5hbWUpIHtcblx0XHRyZWdpc3RlckN1c3RvbUV2ZW50KGV2ZW50TmFtZSwge1xuXHRcdFx0ZGVsZWdhdGU6IHRydWUsXG5cdFx0XHRoYW5kbGVyOiBmdW5jdGlvbihjYWxsYmFjaywgZXZlbnQpIHtcblx0XHRcdFx0Y29uc3QgcmVsYXRlZCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7XG5cdFx0XHRcdGNvbnN0IHRhcmdldCA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0O1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdCFyZWxhdGVkIHx8XG5cdFx0XHRcdFx0KHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhY29udGFpbnModGFyZ2V0LCByZWxhdGVkKSlcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0ZXZlbnQuY3VzdG9tVHlwZSA9IGV2ZW50TmFtZTtcblx0XHRcdFx0XHRyZXR1cm4gY2FsbGJhY2soZXZlbnQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0b3JpZ2luYWxFdmVudDogbW91c2VFdmVudE1hcFtldmVudE5hbWVdLFxuXHRcdH0pO1xuXHR9KTtcblxuXHRjb25zdCBhbmltYXRpb25FdmVudE1hcCA9IHtcblx0XHRhbmltYXRpb246ICdhbmltYXRpb25lbmQnLFxuXHRcdHRyYW5zaXRpb246ICd0cmFuc2l0aW9uZW5kJyxcblx0fTtcblx0T2JqZWN0LmtleXMoYW5pbWF0aW9uRXZlbnRNYXApLmZvckVhY2goZnVuY3Rpb24oZXZlbnRUeXBlKSB7XG5cdFx0Y29uc3QgZXZlbnROYW1lID0gYW5pbWF0aW9uRXZlbnRNYXBbZXZlbnRUeXBlXTtcblx0XHRyZWdpc3RlckN1c3RvbUV2ZW50KGV2ZW50TmFtZSwge1xuXHRcdFx0ZXZlbnQ6IHRydWUsXG5cdFx0XHRkZWxlZ2F0ZTogdHJ1ZSxcblx0XHRcdGhhbmRsZXI6IGZ1bmN0aW9uKGNhbGxiYWNrLCBldmVudCkge1xuXHRcdFx0XHRldmVudC5jdXN0b21UeXBlID0gZXZlbnROYW1lO1xuXHRcdFx0XHRyZXR1cm4gY2FsbGJhY2soZXZlbnQpO1xuXHRcdFx0fSxcblx0XHRcdG9yaWdpbmFsRXZlbnQ6IGZlYXR1cmVzLmNoZWNrQW5pbWF0aW9uRXZlbnROYW1lKClbZXZlbnRUeXBlXSxcblx0XHR9KTtcblx0fSk7XG59XG5cbmlmICghaXNTZXJ2ZXJTaWRlKCkpIHtcblx0cmVnaXN0ZXJFdmVudHMoKTtcbn1cbiIsInZhciBnbG9iYWxzID0gZ2xvYmFscyB8fCB7fTtcblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG5cdGdsb2JhbHMud2luZG93ID0gd2luZG93O1xufVxuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuXHRnbG9iYWxzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGdsb2JhbHM7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuICogQHBhcmFtIHsqPX0gb3B0X3VyaSBPcHRpb25hbCBzdHJpbmcgVVJJIHRvIHBhcnNlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlRnJvbUFuY2hvcihvcHRfdXJpKSB7XG5cdHZhciBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXHRsaW5rLmhyZWYgPSBvcHRfdXJpO1xuXG5cdGlmKGxpbmsucHJvdG9jb2wgPT09ICc6JyB8fCAhLzovLnRlc3QobGluay5ocmVmKSkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7b3B0X3VyaX0gaXMgbm90IGEgdmFsaWQgVVJMYCk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdGhhc2g6IGxpbmsuaGFzaCxcblx0XHRob3N0bmFtZTogbGluay5ob3N0bmFtZSxcblx0XHRwYXNzd29yZDogbGluay5wYXNzd29yZCxcblx0XHRwYXRobmFtZTogbGluay5wYXRobmFtZVswXSA9PT0gJy8nID8gbGluay5wYXRobmFtZSA6ICcvJyArIGxpbmsucGF0aG5hbWUsXG5cdFx0cG9ydDogbGluay5wb3J0LFxuXHRcdHByb3RvY29sOiBsaW5rLnByb3RvY29sLFxuXHRcdHNlYXJjaDogbGluay5zZWFyY2gsXG5cdFx0dXNlcm5hbWU6IGxpbmsudXNlcm5hbWVcblx0fTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgcGFyc2VGcm9tQW5jaG9yO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHBhcnNlRnJvbUFuY2hvciBmcm9tICcuL3BhcnNlRnJvbUFuY2hvcic7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LiBUaGUgVVJMIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZFxuICogd2hlbiBwcmVzZW50LCBvdGhlcndpc2Ugd2UnbGwgZmFsbCBiYWNrIHRvIHRoZSBhbmNob3Igbm9kZSBlbGVtZW50LlxuICogQHBhcmFtIHsqPX0gb3B0X3VyaSBPcHRpb25hbCBzdHJpbmcgVVJJIHRvIHBhcnNlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlKG9wdF91cmkpIHtcblx0aWYgKGlzRnVuY3Rpb24oVVJMKSAmJiBVUkwubGVuZ3RoKSB7XG5cdFx0Y29uc3QgdXJsID0gbmV3IFVSTChvcHRfdXJpKTtcblxuXHRcdC8vIFNhZmFyaSBCcm93c2VycyB3aWxsIGNhcCBwb3J0IHRvIHRoZSBtYXggMTYtYml0IHVuc2lnbmVkIGludGVnZXIgKDY1NTM1KSBpbnN0ZWFkXG5cdFx0Ly8gb2YgdGhyb3dpbmcgYSBUeXBlRXJyb3IgYXMgcGVyIHNwZWMuIEl0IHdpbGwgc3RpbGwga2VlcCB0aGUgcG9ydCBudW1iZXIgaW4gdGhlXG5cdFx0Ly8gaHJlZiBhdHRyaWJ1dGUsIHNvIHdlIGNhbiB1c2UgdGhpcyBtaXNtYXRjaCB0byByYWlzZSB0aGUgZXhwZWN0ZWQgZXhjZXB0aW9uLlxuXHRcdGlmICh1cmwucG9ydCAmJiB1cmwuaHJlZi5pbmRleE9mKHVybC5wb3J0KSA9PT0gLTEpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYCR7b3B0X3VyaX0gaXMgbm90IGEgdmFsaWQgVVJMYCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVybDtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gcGFyc2VGcm9tQW5jaG9yKG9wdF91cmkpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHBhcnNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBEaXNwb3NhYmxlIH0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIEEgY2FjaGVkIHJlZmVyZW5jZSB0byB0aGUgY3JlYXRlIGZ1bmN0aW9uLlxuICovXG52YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTtcblxuLyoqXG4gKiBDYXNlIGluc2Vuc2l0aXZlIHN0cmluZyBNdWx0aW1hcCBpbXBsZW1lbnRhdGlvbi4gQWxsb3dzIG11bHRpcGxlIHZhbHVlcyBmb3JcbiAqIHRoZSBzYW1lIGtleSBuYW1lLlxuICogQGV4dGVuZHMge0Rpc3Bvc2FibGV9XG4gKi9cbmNsYXNzIE11bHRpTWFwIGV4dGVuZHMgRGlzcG9zYWJsZSB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cdFx0dGhpcy5rZXlzID0gY3JlYXRlKG51bGwpO1xuXHRcdHRoaXMudmFsdWVzID0gY3JlYXRlKG51bGwpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdmFsdWUgdG8gYSBrZXkgbmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHBhcmFtIHsqfSB2YWx1ZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRhZGQobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IG5hbWU7XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IHRoaXMudmFsdWVzW25hbWUudG9Mb3dlckNhc2UoKV0gfHwgW107XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXS5wdXNoKHZhbHVlKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhcnMgbWFwIG5hbWVzIGFuZCB2YWx1ZXMuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGNsZWFyKCkge1xuXHRcdHRoaXMua2V5cyA9IGNyZWF0ZShudWxsKTtcblx0XHR0aGlzLnZhbHVlcyA9IGNyZWF0ZShudWxsKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgbWFwIGNvbnRhaW5zIGEgdmFsdWUgdG8gdGhlIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRjb250YWlucyhuYW1lKSB7XG5cdFx0cmV0dXJuIG5hbWUudG9Mb3dlckNhc2UoKSBpbiB0aGlzLnZhbHVlcztcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMudmFsdWVzID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgYE11bHRpTWFwYCBpbnN0YW5jZSBmcm9tIHRoZSBnaXZlbiBvYmplY3QuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gb2JqXG5cdCAqIEByZXR1cm4geyFNdWx0aU1hcH1cblx0ICovXG5cdHN0YXRpYyBmcm9tT2JqZWN0KG9iaikge1xuXHRcdHZhciBtYXAgPSBuZXcgTXVsdGlNYXAoKTtcblx0XHR2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRtYXAuc2V0KGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG5cdFx0fVxuXHRcdHJldHVybiBtYXA7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZmlyc3QgYWRkZWQgdmFsdWUgZnJvbSBhIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAcmV0dXJuIHsqfVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRnZXQobmFtZSkge1xuXHRcdHZhciB2YWx1ZXMgPSB0aGlzLnZhbHVlc1tuYW1lLnRvTG93ZXJDYXNlKCldO1xuXHRcdGlmICh2YWx1ZXMpIHtcblx0XHRcdHJldHVybiB2YWx1ZXNbMF07XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYWxsIHZhbHVlcyBmcm9tIGEga2V5IG5hbWUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG5cdCAqIEByZXR1cm4ge0FycmF5LjwqPn1cblx0ICovXG5cdGdldEFsbChuYW1lKSB7XG5cdFx0cmV0dXJuIHRoaXMudmFsdWVzW25hbWUudG9Mb3dlckNhc2UoKV07XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIGlmIHRoZSBtYXAgaXMgZW1wdHksIGZhbHNlIG90aGVyd2lzZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGlzRW1wdHkoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2l6ZSgpID09PSAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYXJyYXkgb2Yga2V5IG5hbWVzLlxuXHQgKiBAcmV0dXJuIHtBcnJheS48c3RyaW5nPn1cblx0ICovXG5cdG5hbWVzKCkge1xuXHRcdHJldHVybiBPYmplY3Qua2V5cyh0aGlzLnZhbHVlcykubWFwKChrZXkpID0+IHRoaXMua2V5c1trZXldKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGFsbCB2YWx1ZXMgZnJvbSBhIGtleSBuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRyZW1vdmUobmFtZSkge1xuXHRcdGRlbGV0ZSB0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcblx0XHRkZWxldGUgdGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSB2YWx1ZSBvZiBhIGtleSBuYW1lLiBSZWxldmFudCB0byByZXBsYWNlIHRoZSBjdXJyZW50IHZhbHVlcyB3aXRoXG5cdCAqIGEgbmV3IG9uZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHBhcmFtIHsqfSB2YWx1ZVxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXQobmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLmtleXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IG5hbWU7XG5cdFx0dGhpcy52YWx1ZXNbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IFt2YWx1ZV07XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgbWFwIGtleSBuYW1lcy5cblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cblx0c2l6ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5uYW1lcygpLmxlbmd0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBwYXJzZWQgdmFsdWVzIGFzIGEgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy52YWx1ZXMpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE11bHRpTWFwO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBhcnJheSB9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBHZW5lcmljIHRyZWUgbm9kZSBkYXRhIHN0cnVjdHVyZSB3aXRoIGFyYml0cmFyeSBudW1iZXIgb2YgY2hpbGQgbm9kZXMuXG4gKiBAcGFyYW0ge1Z9IHZhbHVlIFZhbHVlLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmNsYXNzIFRyZWVOb2RlIHtcblxuXHRjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuXHRcdC8qKlxuXHRcdCAqIFRoZSB2YWx1ZS5cblx0XHQgKiBAcHJpdmF0ZSB7Vn1cblx0XHQgKi9cblx0XHR0aGlzLnZhbHVlXyA9IHZhbHVlO1xuXG5cdFx0LyoqXG5cdFx0ICogUmVmZXJlbmNlIHRvIHRoZSBwYXJlbnQgbm9kZSBvciBudWxsIGlmIGl0IGhhcyBubyBwYXJlbnQuXG5cdFx0ICogQHByaXZhdGUge1RyZWVOb2RlfVxuXHRcdCAqL1xuXHRcdHRoaXMucGFyZW50XyA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBDaGlsZCBub2RlcyBvciBudWxsIGluIGNhc2Ugb2YgbGVhZiBub2RlLlxuXHRcdCAqIEBwcml2YXRlIHtBcnJheTwhVHJlZU5vZGU+fVxuXHRcdCAqL1xuXHRcdHRoaXMuY2hpbGRyZW5fID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBBcHBlbmRzIGEgY2hpbGQgbm9kZSB0byB0aGlzIG5vZGUuXG5cdCAqIEBwYXJhbSB7IVRyZWVOb2RlfSBjaGlsZCBPcnBoYW4gY2hpbGQgbm9kZS5cblx0ICovXG5cdGFkZENoaWxkKGNoaWxkKSB7XG5cdFx0YXNzZXJ0Q2hpbGRIYXNOb1BhcmVudChjaGlsZCk7XG5cdFx0Y2hpbGQuc2V0UGFyZW50KHRoaXMpO1xuXHRcdHRoaXMuY2hpbGRyZW5fID0gdGhpcy5jaGlsZHJlbl8gfHwgW107XG5cdFx0dGhpcy5jaGlsZHJlbl8ucHVzaChjaGlsZCk7XG5cdH1cblxuXHQvKipcblx0ICogVGVsbHMgd2hldGhlciB0aGlzIG5vZGUgaXMgdGhlIGFuY2VzdG9yIG9mIHRoZSBnaXZlbiBub2RlLlxuXHQgKiBAcGFyYW0geyFUcmVlTm9kZX0gbm9kZSBBIG5vZGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhpcyBub2RlIGlzIHRoZSBhbmNlc3RvciBvZiB7QGNvZGUgbm9kZX0uXG5cdCAqL1xuXHRjb250YWlucyhub2RlKSB7XG5cdFx0bGV0IGN1cnJlbnQgPSBub2RlLmdldFBhcmVudCgpO1xuXHRcdHdoaWxlIChjdXJyZW50KSB7XG5cdFx0XHRpZiAoY3VycmVudCA9PT0gdGhpcykge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdGN1cnJlbnQgPSBjdXJyZW50LmdldFBhcmVudCgpO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7IUFycmF5PFRyZWVOb2RlPn0gQWxsIGFuY2VzdG9yIG5vZGVzIGluIGJvdHRvbS11cCBvcmRlci5cblx0ICovXG5cdGdldEFuY2VzdG9ycygpIHtcblx0XHRsZXQgYW5jZXN0b3JzID0gW107XG5cdFx0bGV0IG5vZGUgPSB0aGlzLmdldFBhcmVudCgpO1xuXHRcdHdoaWxlIChub2RlKSB7XG5cdFx0XHRhbmNlc3RvcnMucHVzaChub2RlKTtcblx0XHRcdG5vZGUgPSBub2RlLmdldFBhcmVudCgpO1xuXHRcdH1cblx0XHRyZXR1cm4gYW5jZXN0b3JzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGNoaWxkIG5vZGUgb2YgdGhpcyBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC5cblx0ICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IENoaWxkIGluZGV4LlxuXHQgKiBAcmV0dXJuIHs/VHJlZU5vZGV9IFRoZSBub2RlIGF0IHRoZSBnaXZlbiBpbmRleFxuXHQgKiBvciBudWxsIGlmIG5vdCBmb3VuZC5cblx0ICovXG5cdGdldENoaWxkQXQoaW5kZXgpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRDaGlsZHJlbigpW2luZGV4XSB8fCBudWxsO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4gez9BcnJheTwhVHJlZU5vZGU+fSBDaGlsZCBub2RlcyBvciBudWxsIGluIGNhc2Ugb2YgbGVhZiBub2RlLlxuXHQgKi9cblx0Z2V0Q2hpbGRyZW4oKSB7XG5cdFx0cmV0dXJuIHRoaXMuY2hpbGRyZW5fIHx8IFRyZWVOb2RlLkVNUFRZX0FSUkFZO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBjaGlsZHJlbi5cblx0ICovXG5cdGdldENoaWxkQ291bnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0Q2hpbGRyZW4oKS5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGFuY2VzdG9ycyBvZiB0aGUgbm9kZS5cblx0ICovXG5cdGdldERlcHRoKCkge1xuXHRcdGxldCBkZXB0aCA9IDA7XG5cdFx0bGV0IG5vZGUgPSB0aGlzO1xuXHRcdHdoaWxlIChub2RlLmdldFBhcmVudCgpKSB7XG5cdFx0XHRkZXB0aCsrO1xuXHRcdFx0bm9kZSA9IG5vZGUuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiBkZXB0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHs/VHJlZU5vZGV9IFBhcmVudCBub2RlIG9yIG51bGwgaWYgaXQgaGFzIG5vIHBhcmVudC5cblx0ICovXG5cdGdldFBhcmVudCgpIHtcblx0XHRyZXR1cm4gdGhpcy5wYXJlbnRfO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4geyFUcmVlTm9kZX0gVGhlIHJvb3Qgb2YgdGhlIHRyZWUgc3RydWN0dXJlLCBpLmUuIHRoZSBmYXJ0aGVzdFxuXHQgKiBhbmNlc3RvciBvZiB0aGUgbm9kZSBvciB0aGUgbm9kZSBpdHNlbGYgaWYgaXQgaGFzIG5vIHBhcmVudHMuXG5cdCAqL1xuXHRnZXRSb290KCkge1xuXHRcdGxldCByb290ID0gdGhpcztcblx0XHR3aGlsZSAocm9vdC5nZXRQYXJlbnQoKSkge1xuXHRcdFx0cm9vdCA9IHJvb3QuZ2V0UGFyZW50KCk7XG5cdFx0fVxuXHRcdHJldHVybiByb290O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHZhbHVlLlxuXHQgKiBAcmV0dXJuIHtWfSBUaGUgdmFsdWUuXG5cdCAqL1xuXHRnZXRWYWx1ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy52YWx1ZV87XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBpcyBhIGxlYWYgbm9kZS5cblx0ICovXG5cdGlzTGVhZigpIHtcblx0XHRyZXR1cm4gIXRoaXMuZ2V0Q2hpbGRDb3VudCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGdpdmVuIGNoaWxkIG5vZGUgb2YgdGhpcyBub2RlLlxuXHQgKiBAcGFyYW0ge1RyZWVOb2RlfSBjaGlsZCBUaGUgbm9kZSB0byByZW1vdmUuXG5cdCAqIEByZXR1cm4ge1RyZWVOb2RlfSBUaGUgcmVtb3ZlZCBub2RlIGlmIGFueSwgbnVsbCBvdGhlcndpc2UuXG5cdCAqL1xuXHRyZW1vdmVDaGlsZChjaGlsZCkge1xuXHRcdGlmIChhcnJheS5yZW1vdmUodGhpcy5nZXRDaGlsZHJlbigpLCBjaGlsZCkpIHtcblx0XHRcdHJldHVybiBjaGlsZDtcblx0XHR9XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgcGFyZW50IG5vZGUgb2YgdGhpcyBub2RlLiBUaGUgY2FsbGVycyBtdXN0IGVuc3VyZSB0aGF0IHRoZVxuXHQgKiBwYXJlbnQgbm9kZSBhbmQgb25seSB0aGF0IGhhcyB0aGlzIG5vZGUgYW1vbmcgaXRzIGNoaWxkcmVuLlxuXHQgKiBAcGFyYW0ge1RyZWVOb2RlfSBwYXJlbnQgVGhlIHBhcmVudCB0byBzZXQuIElmIG51bGwsIHRoZSBub2RlIHdpbGwgYmVcblx0ICogZGV0YWNoZWQgZnJvbSB0aGUgdHJlZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0c2V0UGFyZW50KHBhcmVudCkge1xuXHRcdHRoaXMucGFyZW50XyA9IHBhcmVudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUcmF2ZXJzZXMgdGhlIHN1YnRyZWUuIFRoZSBmaXJzdCBjYWxsYmFjayBzdGFydHMgd2l0aCB0aGlzIG5vZGUsXG5cdCAqIGFuZCB2aXNpdHMgdGhlIGRlc2NlbmRhbnQgbm9kZXMgZGVwdGgtZmlyc3QsIGluIHByZW9yZGVyLlxuXHQgKiBUaGUgc2Vjb25kIGNhbGxiYWNrLCBzdGFydHMgd2l0aCBkZWVwZXN0IGNoaWxkIHRoZW4gdmlzaXRzXG5cdCAqIHRoZSBhbmNlc3RvciBub2RlcyBkZXB0aC1maXJzdCwgaW4gcG9zdG9yZGVyLiBFLmcuXG5cdCAqXG5cdCAqICBcdCBBXG5cdCAqICAgIC8gXFxcblx0ICogICBCICAgQ1xuXHQgKiAgLyAgIC8gXFxcblx0ICogRCAgIEUgICBGXG5cdCAqXG5cdCAqIHByZW9yZGVyIC0+IFsnQScsICdCJywgJ0QnLCAnQycsICdFJywgJ0YnXVxuXHQgKiBwb3N0b3JkZXIgLT4gWydEJywgJ0InLCAnRScsICdGJywgJ0MnLCAnQSddXG5cdCAqXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb249fSBvcHRfcHJlb3JkZXJGbiBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSB3aGVuIHZpc2l0aW5nIGEgbm9kZS5cblx0ICogQHBhcmFtIHtmdW5jdGlvbj19IG9wdF9wb3N0b3JkZXJGbiBUaGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSBiZWZvcmUgbGVhdmluZyBhIG5vZGUuXG5cdCAqL1xuXHR0cmF2ZXJzZShvcHRfcHJlb3JkZXJGbiwgb3B0X3Bvc3RvcmRlckZuKSB7XG5cdFx0aWYgKG9wdF9wcmVvcmRlckZuKSB7XG5cdFx0XHRvcHRfcHJlb3JkZXJGbih0aGlzKTtcblx0XHR9XG5cdFx0dGhpcy5nZXRDaGlsZHJlbigpLmZvckVhY2goKGNoaWxkKSA9PiBjaGlsZC50cmF2ZXJzZShvcHRfcHJlb3JkZXJGbiwgb3B0X3Bvc3RvcmRlckZuKSk7XG5cdFx0aWYgKG9wdF9wb3N0b3JkZXJGbikge1xuXHRcdFx0b3B0X3Bvc3RvcmRlckZuKHRoaXMpO1xuXHRcdH1cblx0fVxuXG59XG5cbi8qKlxuICogQ29uc3RhbnQgZm9yIGVtcHR5IGFycmF5IHRvIGF2b2lkIHVubmVjZXNzYXJ5IGFsbG9jYXRpb25zLlxuICogQHByaXZhdGVcbiAqL1xuVHJlZU5vZGUuRU1QVFlfQVJSQVkgPSBbXTtcblxuLyoqXG4gKiBBc3NlcnRzIHRoYXQgY2hpbGQgaGFzIG5vIHBhcmVudC5cbiAqIEBwYXJhbSB7VHJlZU5vZGV9IGNoaWxkIEEgY2hpbGQuXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBhc3NlcnRDaGlsZEhhc05vUGFyZW50ID0gZnVuY3Rpb24oY2hpbGQpIHtcblx0aWYgKGNoaWxkLmdldFBhcmVudCgpKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgYWRkIGNoaWxkIHdpdGggcGFyZW50LicpO1xuXHR9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBUcmVlTm9kZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgaXNEZWYsIHN0cmluZyB9IGZyb20gJ21ldGFsJztcbmltcG9ydCBwYXJzZSBmcm9tICcuL3BhcnNlJztcbmltcG9ydCB7IE11bHRpTWFwIH0gZnJvbSAnbWV0YWwtc3RydWN0cyc7XG5cbnZhciBwYXJzZUZuXyA9IHBhcnNlO1xuXG5jbGFzcyBVcmkge1xuXG5cdC8qKlxuXHQgKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHNldHRlcnMgYW5kIGdldHRlcnMgZm9yIHRoZSBwYXJ0cyBvZiB0aGUgVVJJLlxuXHQgKiBUaGUgZm9sbG93aW5nIGZpZ3VyZSBkaXNwbGF5cyBhbiBleGFtcGxlIFVSSXMgYW5kIHRoZWlyIGNvbXBvbmVudCBwYXJ0cy5cblx0ICpcblx0ICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aFxuXHQgKlx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIzilIDilIDilIDilLTilIDilIDilIDilIDilJBcblx0ICpcdCAgYWJjOi8vZXhhbXBsZS5jb206MTIzL3BhdGgvZGF0YT9rZXk9dmFsdWUjZnJhZ2lkMVxuXHQgKlx0ICDilJTilKzilJggICDilJTilIDilIDilIDilIDilKzilIDilIDilIDilIDilJgg4pSU4pSs4pSYICAgICAgICAgICDilJTilIDilIDilIDilKzilIDilIDilIDilJgg4pSU4pSA4pSA4pSs4pSA4pSA4pSYXG5cdCAqIHByb3RvY29sICBob3N0bmFtZSAgcG9ydCAgICAgICAgICAgIHNlYXJjaCAgICBoYXNoXG5cdCAqICAgICAgICAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuXHQgKiAgICAgICAgICAgICAgICBob3N0XG5cdCAqXG5cdCAqIEBwYXJhbSB7Kj19IG9wdF91cmkgT3B0aW9uYWwgc3RyaW5nIFVSSSB0byBwYXJzZVxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKG9wdF91cmkgPSAnJykge1xuXHRcdHRoaXMudXJsID0gVXJpLnBhcnNlKHRoaXMubWF5YmVBZGRQcm90b2NvbEFuZEhvc3RuYW1lXyhvcHRfdXJpKSk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBwYXJhbWV0ZXJzIHRvIHVyaSBmcm9tIGEgPGNvZGU+TXVsdGlNYXA8L2NvZGU+IGFzIHNvdXJjZS5cblx0ICogQHBhcmFtIHtNdWx0aU1hcH0gbXVsdGltYXAgVGhlIDxjb2RlPk11bHRpTWFwPC9jb2RlPiBjb250YWluaW5nIHRoZVxuXHQgKiAgIHBhcmFtZXRlcnMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0YWRkUGFyYW1ldGVyc0Zyb21NdWx0aU1hcChtdWx0aW1hcCkge1xuXHRcdG11bHRpbWFwLm5hbWVzKCkuZm9yRWFjaCgobmFtZSkgPT4ge1xuXHRcdFx0bXVsdGltYXAuZ2V0QWxsKG5hbWUpLmZvckVhY2goKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyB0aGUgdmFsdWUgb2YgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlcnMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHBhcmFtZXRlciB0byBzZXQuXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZS4gV2lsbCBiZSBleHBsaWNpdGx5IGNhc3RlZCB0byBTdHJpbmcuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFBhcmFtZXRlclZhbHVlKG5hbWUsIHZhbHVlKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdGlmIChpc0RlZih2YWx1ZSkpIHtcblx0XHRcdHZhbHVlID0gU3RyaW5nKHZhbHVlKTtcblx0XHR9XG5cdFx0dGhpcy5xdWVyeS5hZGQobmFtZSwgdmFsdWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIHZhbHVlcyBvZiB0aGUgbmFtZWQgcXVlcnkgcGFyYW1ldGVyLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFBhcmFtZXRlclZhbHVlcyhuYW1lLCB2YWx1ZXMpIHtcblx0XHR2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBFbnN1cmVzIHF1ZXJ5IGludGVybmFsIG1hcCBpcyBpbml0aWFsaXplZCBhbmQgc3luY2VkIHdpdGggaW5pdGlhbCB2YWx1ZVxuXHQgKiBleHRyYWN0ZWQgZnJvbSBVUkkgc2VhcmNoIHBhcnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCkge1xuXHRcdGlmICh0aGlzLnF1ZXJ5KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMucXVlcnkgPSBuZXcgTXVsdGlNYXAoKTtcblx0XHR2YXIgc2VhcmNoID0gdGhpcy51cmwuc2VhcmNoO1xuXHRcdGlmIChzZWFyY2gpIHtcblx0XHRcdHNlYXJjaC5zdWJzdHJpbmcoMSkuc3BsaXQoJyYnKS5mb3JFYWNoKChwYXJhbSkgPT4ge1xuXHRcdFx0XHR2YXIgW2tleSwgdmFsdWVdID0gcGFyYW0uc3BsaXQoJz0nKTtcblx0XHRcdFx0aWYgKGlzRGVmKHZhbHVlKSkge1xuXHRcdFx0XHRcdHZhbHVlID0gVXJpLnVybERlY29kZSh2YWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShrZXksIHZhbHVlKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBoYXNoIHBhcnQgb2YgdXJpLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRIYXNoKCkge1xuXHRcdHJldHVybiB0aGlzLnVybC5oYXNoIHx8ICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGhvc3QgcGFydCBvZiB1cmkuIEUuZy4gPGNvZGU+W2hvc3RuYW1lXTpbcG9ydF08L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRIb3N0KCkge1xuXHRcdHZhciBob3N0ID0gdGhpcy5nZXRIb3N0bmFtZSgpO1xuXHRcdGlmIChob3N0KSB7XG5cdFx0XHR2YXIgcG9ydCA9IHRoaXMuZ2V0UG9ydCgpO1xuXHRcdFx0aWYgKHBvcnQgJiYgcG9ydCAhPT0gJzgwJykge1xuXHRcdFx0XHRob3N0ICs9ICc6JyArIHBvcnQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBob3N0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGhvc3RuYW1lIHBhcnQgb2YgdXJpIHdpdGhvdXQgcHJvdG9jb2wgYW5kIHBvcnQuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldEhvc3RuYW1lKCkge1xuXHRcdHZhciBob3N0bmFtZSA9IHRoaXMudXJsLmhvc3RuYW1lO1xuXHRcdGlmIChob3N0bmFtZSA9PT0gVXJpLkhPU1ROQU1FX1BMQUNFSE9MREVSKSB7XG5cdFx0XHRyZXR1cm4gJyc7XG5cdFx0fVxuXHRcdHJldHVybiBob3N0bmFtZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBvcmlnaW4gcGFydCBvZiB1cmkuIEUuZy4gPGNvZGU+aHR0cDovL1tob3N0bmFtZV06W3BvcnRdPC9jb2RlPi5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0T3JpZ2luKCkge1xuXHRcdHZhciBob3N0ID0gdGhpcy5nZXRIb3N0KCk7XG5cdFx0aWYgKGhvc3QpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldFByb3RvY29sKCkgKyAnLy8nICsgaG9zdDtcblx0XHR9XG5cdFx0cmV0dXJuICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGZpcnN0IHZhbHVlIGZvciBhIGdpdmVuIHBhcmFtZXRlciBvciB1bmRlZmluZWQgaWYgdGhlIGdpdmVuXG5cdCAqIHBhcmFtZXRlciBuYW1lIGRvZXMgbm90IGFwcGVhciBpbiB0aGUgcXVlcnkgc3RyaW5nLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1OYW1lIFVuZXNjYXBlZCBwYXJhbWV0ZXIgbmFtZS5cblx0ICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gVGhlIGZpcnN0IHZhbHVlIGZvciBhIGdpdmVuIHBhcmFtZXRlciBvclxuXHQgKiAgIHVuZGVmaW5lZCBpZiB0aGUgZ2l2ZW4gcGFyYW1ldGVyIG5hbWUgZG9lcyBub3QgYXBwZWFyIGluIHRoZSBxdWVyeVxuXHQgKiAgIHN0cmluZy5cblx0ICovXG5cdGdldFBhcmFtZXRlclZhbHVlKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0cmV0dXJuIHRoaXMucXVlcnkuZ2V0KG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIHZhbHVlPGI+czwvYj4gZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyIGFzIGEgbGlzdCBvZiBkZWNvZGVkXG5cdCAqIHF1ZXJ5IHBhcmFtZXRlciB2YWx1ZXMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFRoZSBwYXJhbWV0ZXIgdG8gZ2V0IHZhbHVlcyBmb3IuXG5cdCAqIEByZXR1cm4geyFBcnJheTw/Pn0gVGhlIHZhbHVlcyBmb3IgYSBnaXZlbiBwYXJhbWV0ZXIgYXMgYSBsaXN0IG9mIGRlY29kZWRcblx0ICogICBxdWVyeSBwYXJhbWV0ZXIgdmFsdWVzLlxuXHQgKi9cblx0Z2V0UGFyYW1ldGVyVmFsdWVzKG5hbWUpIHtcblx0XHR0aGlzLmVuc3VyZVF1ZXJ5SW5pdGlhbGl6ZWRfKCk7XG5cdFx0cmV0dXJuIHRoaXMucXVlcnkuZ2V0QWxsKG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIG5hbWU8Yj5zPC9iPiBvZiB0aGUgcGFyYW1ldGVycy5cblx0ICogQHJldHVybiB7IUFycmF5PHN0cmluZz59IFRoZSBuYW1lcyBmb3IgdGhlIHBhcmFtZXRlcnMgYXMgYSBsaXN0IG9mXG5cdCAqICAgc3RyaW5ncy5cblx0ICovXG5cdGdldFBhcmFtZXRlck5hbWVzKCkge1xuXHRcdHRoaXMuZW5zdXJlUXVlcnlJbml0aWFsaXplZF8oKTtcblx0XHRyZXR1cm4gdGhpcy5xdWVyeS5uYW1lcygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGZ1bmN0aW9uIGN1cnJlbnRseSBiZWluZyB1c2VkIHRvIHBhcnNlIFVSSXMuXG5cdCAqIEByZXR1cm4geyFmdW5jdGlvbigpfVxuXHQgKi9cblx0c3RhdGljIGdldFBhcnNlRm4oKSB7XG5cdFx0cmV0dXJuIHBhcnNlRm5fO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHBhdGhuYW1lIHBhcnQgb2YgdXJpLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRQYXRobmFtZSgpIHtcblx0XHRyZXR1cm4gdGhpcy51cmwucGF0aG5hbWU7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcG9ydCBudW1iZXIgcGFydCBvZiB1cmkgYXMgc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRQb3J0KCkge1xuXHRcdHJldHVybiB0aGlzLnVybC5wb3J0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHByb3RvY29sIHBhcnQgb2YgdXJpLiBFLmcuIDxjb2RlPmh0dHA6PC9jb2RlPi5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0UHJvdG9jb2woKSB7XG5cdFx0cmV0dXJuIHRoaXMudXJsLnByb3RvY29sO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHNlYXJjaCBwYXJ0IG9mIHVyaS4gU2VhcmNoIHZhbHVlIGlzIHJldHJpZXZlZCBmcm9tIHF1ZXJ5XG5cdCAqIHBhcmFtZXRlcnMuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG5cdGdldFNlYXJjaCgpIHtcblx0XHR2YXIgc2VhcmNoID0gJyc7XG5cdFx0dmFyIHF1ZXJ5c3RyaW5nID0gJyc7XG5cdFx0dGhpcy5nZXRQYXJhbWV0ZXJOYW1lcygpLmZvckVhY2goKG5hbWUpID0+IHtcblx0XHRcdHRoaXMuZ2V0UGFyYW1ldGVyVmFsdWVzKG5hbWUpLmZvckVhY2goKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHF1ZXJ5c3RyaW5nICs9IG5hbWU7XG5cdFx0XHRcdGlmIChpc0RlZih2YWx1ZSkpIHtcblx0XHRcdFx0XHRxdWVyeXN0cmluZyArPSAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHF1ZXJ5c3RyaW5nICs9ICcmJztcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHRcdHF1ZXJ5c3RyaW5nID0gcXVlcnlzdHJpbmcuc2xpY2UoMCwgLTEpO1xuXHRcdGlmIChxdWVyeXN0cmluZykge1xuXHRcdFx0c2VhcmNoICs9ICc/JyArIHF1ZXJ5c3RyaW5nO1xuXHRcdH1cblx0XHRyZXR1cm4gc2VhcmNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiB1cmkgY29udGFpbnMgdGhlIHBhcmFtZXRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGhhc1BhcmFtZXRlcihuYW1lKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdHJldHVybiB0aGlzLnF1ZXJ5LmNvbnRhaW5zKG5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1ha2VzIHRoaXMgVVJMIHVuaXF1ZSBieSBhZGRpbmcgYSByYW5kb20gcGFyYW0gdG8gaXQuIFVzZWZ1bCBmb3IgYXZvaWRpbmdcblx0ICogY2FjaGUuXG5cdCAqL1xuXHRtYWtlVW5pcXVlKCkge1xuXHRcdHRoaXMuc2V0UGFyYW1ldGVyVmFsdWUoVXJpLlJBTkRPTV9QQVJBTSwgc3RyaW5nLmdldFJhbmRvbVN0cmluZygpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBhZGRzIHByb3RvY29sIGFuZCBhIGhvc3RuYW1lIHBsYWNlaG9sZGVyIG9uIGEgcGFyaWFsIFVSSSBpZiBuZWVkZWQuXG5cdCAqIFJlbGV2ZW50IGZvciBjb21wYXRpYmlsaXR5IHdpdGggPGNvZGU+VVJMPC9jb2RlPiBuYXRpdmUgb2JqZWN0LlxuXHQgKiBAcGFyYW0ge3N0cmluZz19IG9wdF91cmlcblx0ICogQHJldHVybiB7c3RyaW5nfSBVUkkgd2l0aCBwcm90b2NvbCBhbmQgaG9zdG5hbWUgcGxhY2Vob2xkZXIuXG5cdCAqL1xuXHRtYXliZUFkZFByb3RvY29sQW5kSG9zdG5hbWVfKG9wdF91cmkpIHtcblx0XHR2YXIgdXJsID0gb3B0X3VyaTtcblx0XHRpZiAob3B0X3VyaS5pbmRleE9mKCc6Ly8nKSA9PT0gLTEgJiZcblx0XHRcdG9wdF91cmkuaW5kZXhPZignamF2YXNjcmlwdDonKSAhPT0gMCkgeyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuXHRcdFx0dXJsID0gVXJpLkRFRkFVTFRfUFJPVE9DT0w7XG5cdFx0XHRpZiAob3B0X3VyaVswXSAhPT0gJy8nIHx8IG9wdF91cmlbMV0gIT09ICcvJykge1xuXHRcdFx0XHR1cmwgKz0gJy8vJztcblx0XHRcdH1cblxuXHRcdFx0c3dpdGNoIChvcHRfdXJpLmNoYXJBdCgwKSkge1xuXHRcdFx0XHRjYXNlICcuJzpcblx0XHRcdFx0Y2FzZSAnPyc6XG5cdFx0XHRcdGNhc2UgJyMnOlxuXHRcdFx0XHRcdHVybCArPSBVcmkuSE9TVE5BTUVfUExBQ0VIT0xERVI7XG5cdFx0XHRcdFx0dXJsICs9ICcvJztcblx0XHRcdFx0XHR1cmwgKz0gb3B0X3VyaTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnJzpcblx0XHRcdFx0Y2FzZSAnLyc6XG5cdFx0XHRcdFx0aWYgKG9wdF91cmlbMV0gIT09ICcvJykge1xuXHRcdFx0XHRcdFx0dXJsICs9IFVyaS5IT1NUTkFNRV9QTEFDRUhPTERFUjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dXJsICs9IG9wdF91cmk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0dXJsICs9IG9wdF91cmk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB1cmw7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2VzIHRoZSBnaXZlbiB1cmkgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuXHQgKiBAcGFyYW0geyo9fSBvcHRfdXJpIE9wdGlvbmFsIHN0cmluZyBVUkkgdG8gcGFyc2Vcblx0ICovXG5cdHN0YXRpYyBwYXJzZShvcHRfdXJpKSB7XG5cdFx0cmV0dXJuIHBhcnNlRm5fKG9wdF91cmkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIG5hbWVkIHF1ZXJ5IHBhcmFtZXRlci5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIHBhcmFtZXRlciB0byByZW1vdmUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHJlbW92ZVBhcmFtZXRlcihuYW1lKSB7XG5cdFx0dGhpcy5lbnN1cmVRdWVyeUluaXRpYWxpemVkXygpO1xuXHRcdHRoaXMucXVlcnkucmVtb3ZlKG5hbWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdW5pcXVlbmVzcyBwYXJhbWV0ZXIgb2YgdGhlIHVyaS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0cmVtb3ZlVW5pcXVlKCkge1xuXHRcdHRoaXMucmVtb3ZlUGFyYW1ldGVyKFVyaS5SQU5ET01fUEFSQU0pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGhhc2guXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldEhhc2goaGFzaCkge1xuXHRcdHRoaXMudXJsLmhhc2ggPSBoYXNoO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGhvc3RuYW1lLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaG9zdG5hbWVcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0SG9zdG5hbWUoaG9zdG5hbWUpIHtcblx0XHR0aGlzLnVybC5ob3N0bmFtZSA9IGhvc3RuYW1lO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBuYW1lZCBxdWVyeSBwYXJhbWV0ZXJzLCBjbGVhcmluZyBwcmV2aW91cyB2YWx1ZXNcblx0ICogZm9yIHRoYXQga2V5LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhcmFtZXRlclZhbHVlKG5hbWUsIHZhbHVlKSB7XG5cdFx0dGhpcy5yZW1vdmVQYXJhbWV0ZXIobmFtZSk7XG5cdFx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZShuYW1lLCB2YWx1ZSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdmFsdWVzIG9mIHRoZSBuYW1lZCBxdWVyeSBwYXJhbWV0ZXJzLCBjbGVhcmluZyBwcmV2aW91cyB2YWx1ZXNcblx0ICogZm9yIHRoYXQga2V5LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBwYXJhbWV0ZXIgdG8gc2V0LlxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhcmFtZXRlclZhbHVlcyhuYW1lLCB2YWx1ZXMpIHtcblx0XHR0aGlzLnJlbW92ZVBhcmFtZXRlcihuYW1lKTtcblx0XHR2YWx1ZXMuZm9yRWFjaCgodmFsdWUpID0+IHRoaXMuYWRkUGFyYW1ldGVyVmFsdWUobmFtZSwgdmFsdWUpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwYXRobmFtZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGhuYW1lXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdHNldFBhdGhuYW1lKHBhdGhuYW1lKSB7XG5cdFx0dGhpcy51cmwucGF0aG5hbWUgPSBwYXRobmFtZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwb3J0IG51bWJlci5cblx0ICogQHBhcmFtIHsqfSBwb3J0IFBvcnQgbnVtYmVyLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRzZXRQb3J0KHBvcnQpIHtcblx0XHR0aGlzLnVybC5wb3J0ID0gcG9ydDtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgdXNlZCBmb3IgcGFyc2luZyB0aGUgb3JpZ2luYWwgc3RyaW5nIHVyaVxuXHQgKiBpbnRvIGFuIG9iamVjdC5cblx0ICogQHBhcmFtIHshZnVuY3Rpb24oKX0gcGFyc2VGblxuXHQgKi9cblx0c3RhdGljIHNldFBhcnNlRm4ocGFyc2VGbikge1xuXHRcdHBhcnNlRm5fID0gcGFyc2VGbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBwcm90b2NvbC4gSWYgbWlzc2luZyA8Y29kZT5odHRwOjwvY29kZT4gaXMgdXNlZCBhcyBkZWZhdWx0LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcHJvdG9jb2xcblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0c2V0UHJvdG9jb2wocHJvdG9jb2wpIHtcblx0XHR0aGlzLnVybC5wcm90b2NvbCA9IHByb3RvY29sO1xuXHRcdGlmICh0aGlzLnVybC5wcm90b2NvbFt0aGlzLnVybC5wcm90b2NvbC5sZW5ndGggLSAxXSAhPT0gJzonKSB7XG5cdFx0XHR0aGlzLnVybC5wcm90b2NvbCArPSAnOic7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZyBmb3JtIG9mIHRoZSB1cmwuXG5cdCAqIEBvdmVycmlkZVxuXHQgKi9cblx0dG9TdHJpbmcoKSB7XG5cdFx0dmFyIGhyZWYgPSAnJztcblx0XHR2YXIgaG9zdCA9IHRoaXMuZ2V0SG9zdCgpO1xuXHRcdGlmIChob3N0KSB7XG5cdFx0XHRocmVmICs9IHRoaXMuZ2V0UHJvdG9jb2woKSArICcvLyc7XG5cdFx0fVxuXHRcdGhyZWYgKz0gaG9zdCArIHRoaXMuZ2V0UGF0aG5hbWUoKSArIHRoaXMuZ2V0U2VhcmNoKCkgKyB0aGlzLmdldEhhc2goKTtcblx0XHRyZXR1cm4gaHJlZjtcblx0fVxuXG5cdC8qKlxuXHQgKiBKb2lucyB0aGUgZ2l2ZW4gcGF0aHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aFxuXHQgKiBAcGFyYW0gey4uLnN0cmluZ30gLi4ucGF0aHMgQW55IG51bWJlciBvZiBwYXRocyB0byBiZSBqb2luZWQgd2l0aCB0aGUgYmFzZSB1cmwuXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBqb2luUGF0aHMoYmFzZVBhdGgsIC4uLnBhdGhzKSB7XG5cdFx0aWYgKGJhc2VQYXRoLmNoYXJBdChiYXNlUGF0aC5sZW5ndGggLSAxKSA9PT0gJy8nKSB7XG5cdFx0XHRiYXNlUGF0aCA9IGJhc2VQYXRoLnN1YnN0cmluZygwLCBiYXNlUGF0aC5sZW5ndGggLSAxKTtcblx0XHR9XG5cdFx0cGF0aHMgPSBwYXRocy5tYXAocGF0aCA9PiBwYXRoLmNoYXJBdCgwKSA9PT0gJy8nID8gcGF0aC5zdWJzdHJpbmcoMSkgOiBwYXRoKTtcblx0XHRyZXR1cm4gW2Jhc2VQYXRoXS5jb25jYXQocGF0aHMpLmpvaW4oJy8nKS5yZXBsYWNlKC9cXC8kLywgJycpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVSTC1kZWNvZGVzIHRoZSBzdHJpbmcuIFdlIG5lZWQgdG8gc3BlY2lhbGx5IGhhbmRsZSAnKydzIGJlY2F1c2Vcblx0ICogdGhlIGphdmFzY3JpcHQgbGlicmFyeSBkb2Vzbid0IGNvbnZlcnQgdGhlbSB0byBzcGFjZXMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0byB1cmwgZGVjb2RlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBkZWNvZGVkIHtAY29kZSBzdHJ9LlxuXHQgKi9cblx0c3RhdGljIHVybERlY29kZShzdHIpIHtcblx0XHRyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0ci5yZXBsYWNlKC9cXCsvZywgJyAnKSk7XG5cdH1cblxufVxuXG4vKipcbiAqIERlZmF1bHQgcHJvdG9jb2wgdmFsdWUuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGRlZmF1bHQgaHR0cDpcbiAqIEBzdGF0aWNcbiAqL1xuY29uc3QgaXNTZWN1cmUgPSAoKSA9PlxuXHQodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcblx0XHR3aW5kb3cubG9jYXRpb24gJiZcblx0XHR3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgJiZcblx0XHR3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wuaW5kZXhPZignaHR0cHMnKSA9PT0gMCk7XG5cblVyaS5ERUZBVUxUX1BST1RPQ09MID0gaXNTZWN1cmUoKSA/ICdodHRwczonIDogJ2h0dHA6JztcblxuLyoqXG4gKiBIb3N0bmFtZSBwbGFjZWhvbGRlci4gUmVsZXZhbnQgdG8gaW50ZXJuYWwgdXNhZ2Ugb25seS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cblVyaS5IT1NUTkFNRV9QTEFDRUhPTERFUiA9ICdob3N0bmFtZScgKyBEYXRlLm5vdygpO1xuXG4vKipcbiAqIE5hbWUgdXNlZCBieSB0aGUgcGFyYW0gZ2VuZXJhdGVkIGJ5IGBtYWtlVW5pcXVlYC5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cblVyaS5SQU5ET01fUEFSQU0gPSAnengnO1xuXG5leHBvcnQgZGVmYXVsdCBVcmk7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGV4aXREb2N1bWVudCB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBzdGF0aWMgdXRpbGl0eSBmdW5jdGlvbnMuXG4gKiBAY29uc3RcbiAqL1xuY2xhc3MgdXRpbHMge1xuXG5cdC8qKlxuXHQgKiBDb3BpZXMgYXR0cmlidXRlcyBmb3JtIHNvdXJjZSBub2RlIHRvIHRhcmdldCBub2RlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgY29weU5vZGVBdHRyaWJ1dGVzKHNvdXJjZSwgdGFyZ2V0KSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoc291cmNlLmF0dHJpYnV0ZXMpLmZvckVhY2goKGF0dHJpYnV0ZSkgPT4gdGFyZ2V0LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUubmFtZSwgYXR0cmlidXRlLnZhbHVlKSk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY3VycmVudCBicm93c2VyIHBhdGggaW5jbHVkaW5nIGhhc2hiYW5nLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0Q3VycmVudEJyb3dzZXJQYXRoKCkge1xuXHRcdHJldHVybiB0aGlzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCkgKyBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGN1cnJlbnQgYnJvd3NlciBwYXRoIGV4Y2x1ZGluZyBoYXNoYmFuZy5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCkge1xuXHRcdHJldHVybiBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnNlYXJjaDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBnaXZlbiBub2RlIG9mZnNldCBjb29yZGluYXRlcy5cblx0ICogQHJldHVybiB7IW9iamVjdH1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldE5vZGVPZmZzZXQobm9kZSkge1xuXHRcdGxldCBbb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wXSA9IFswLCAwXTtcblx0XHRkbyB7XG5cdFx0XHRvZmZzZXRMZWZ0ICs9IG5vZGUub2Zmc2V0TGVmdDtcblx0XHRcdG9mZnNldFRvcCArPSBub2RlLm9mZnNldFRvcDtcblx0XHRcdG5vZGUgPSBub2RlLm9mZnNldFBhcmVudDtcblx0XHR9IHdoaWxlIChub2RlKTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0b2Zmc2V0TGVmdCxcblx0XHRcdG9mZnNldFRvcFxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgdGhlIHBhdGggcGFydCBvZiBhbiB1cmwuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXRVcmxQYXRoKHVybCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHVybCk7XG5cdFx0cmV0dXJuIHVyaS5nZXRQYXRobmFtZSgpICsgdXJpLmdldFNlYXJjaCgpICsgdXJpLmdldEhhc2goKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyB0aGUgcGF0aCBwYXJ0IG9mIGFuIHVybCB3aXRob3V0IGhhc2hiYW5nLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgZ2V0VXJsUGF0aFdpdGhvdXRIYXNoKHVybCkge1xuXHRcdHZhciB1cmkgPSBuZXcgVXJpKHVybCk7XG5cdFx0cmV0dXJuIHVyaS5nZXRQYXRobmFtZSgpICsgdXJpLmdldFNlYXJjaCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIHRoZSBwYXRoIHBhcnQgb2YgYW4gdXJsIHdpdGhvdXQgaGFzaGJhbmcgYW5kIHF1ZXJ5IHNlYXJjaC5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaCh1cmwpIHtcblx0XHR2YXIgdXJpID0gbmV3IFVyaSh1cmwpO1xuXHRcdHJldHVybiB1cmkuZ2V0UGF0aG5hbWUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgdXJsIGlzIGluIHRoZSBzYW1lIGJyb3dzZXIgY3VycmVudCB1cmwgZXhjbHVkaW5nIHRoZSBoYXNoYmFuZy5cblx0ICogQHBhcmFtICB7IXN0cmluZ30gdXJsXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBpc0N1cnJlbnRCcm93c2VyUGF0aCh1cmwpIHtcblx0XHRpZiAodXJsKSB7XG5cdFx0XHRjb25zdCBjdXJyZW50QnJvd3NlclBhdGggPSB0aGlzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCk7XG5cdFx0XHQvLyB0aGUgZ2V0VXJsUGF0aCB3aWxsIGNyZWF0ZSBhIFVyaSBhbmQgd2lsbCBub3JtYWxpemUgdGhlIHBhdGggYW5kXG5cdFx0XHQvLyByZW1vdmUgdGhlIHRyYWlsbGluZyAnLycgZm9yIHByb3Blcmx5IGNvbXBhcmluZyBwYXRocy5cblx0XHRcdHJldHVybiB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2godXJsKSA9PT0gdGhpcy5nZXRVcmxQYXRoKGN1cnJlbnRCcm93c2VyUGF0aCk7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHRydWUgaWYgSFRNTDUgSGlzdG9yeSBhcGkgaXMgc3VwcG9ydGVkLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgaXNIdG1sNUhpc3RvcnlTdXBwb3J0ZWQoKSB7XG5cdFx0cmV0dXJuICEhKGdsb2JhbHMud2luZG93Lmhpc3RvcnkgJiYgZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBhIGdpdmVuIHVybCBpcyBhIHZhbGlkIGh0dHAocykgdXJpIGFuZCByZXR1cm5zIHRoZSBmb3JtZWQgVXJpXG5cdCAqIG9yIGZhbHNlIGlmIHRoZSBwYXJzaW5nIGZhaWxlZFxuXHQgKiBAcmV0dXJuIHtVcml8Ym9vbGVhbn1cblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGlzV2ViVXJpKHVybCkge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gbmV3IFVyaSh1cmwpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJHtlcnIubWVzc2FnZX0gJHt1cmx9YCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIGF0dHJpYnV0ZXMgZm9ybSBub2RlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgY2xlYXJOb2RlQXR0cmlidXRlcyhub2RlKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobm9kZS5hdHRyaWJ1dGVzKS5mb3JFYWNoKChhdHRyaWJ1dGUpID0+IG5vZGUucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZS5uYW1lKSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlIGVsZW1lbnRzIGZyb20gdGhlIGRvY3VtZW50LlxuXHQgKiBAcGFyYW0geyFBcnJheTxFbGVtZW50Pn0gZWxlbWVudHNcblx0ICovXG5cdHN0YXRpYyByZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudChlbGVtZW50cykge1xuXHRcdGVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IGV4aXREb2N1bWVudChlbGVtZW50KSk7XG5cdH1cblxuXHQvKipcblx0KiBSZW1vdmVzIHRyYWlsaW5nIHNsYXNoIGluIHBhdGguXG5cdCogQHBhcmFtIHshc3RyaW5nfVxuXHQqIEByZXR1cm4ge3N0cmluZ31cblx0Ki9cblx0c3RhdGljIHJlbW92ZVBhdGhUcmFpbGluZ1NsYXNoKHBhdGgpIHtcblx0XHR2YXIgbGVuZ3RoID0gcGF0aCA/IHBhdGgubGVuZ3RoIDogMDtcblx0XHRpZiAobGVuZ3RoID4gMSAmJiBwYXRoW2xlbmd0aCAtIDFdID09PSAnLycpIHtcblx0XHRcdHBhdGggPSBwYXRoLnN1YnN0cigwLCBsZW5ndGggLSAxKTtcblx0XHR9XG5cdFx0cmV0dXJuIHBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhIHJhbmRvbSBzdWZmaXggdG8gdGhlIGhyZWYgYXR0cmlidXRlIG9mIHRoZSBlbGVtZW50LlxuXHQgKiBAcGFyYW0geyFlbGVtZW50fSBlbGVtZW50XG5cdCAqIEByZXR1cm4ge2VsZW1lbnR9XG5cdCAqL1xuXHRzdGF0aWMgc2V0RWxlbWVudFdpdGhSYW5kb21IcmVmKGVsZW1lbnQpIHtcblx0XHRlbGVtZW50LmhyZWYgPSBlbGVtZW50LmhyZWYgKyAnP3E9JyArIE1hdGgucmFuZG9tKCk7XG5cdFx0cmV0dXJuIGVsZW1lbnQ7XG5cdH1cblxuXHQvKipcblx0ICogT3ZlcnJpZGVzIGRvY3VtZW50IHJlZmVycmVyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSByZWZlcnJlclxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgc2V0UmVmZXJyZXIocmVmZXJyZXIpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFscy5kb2N1bWVudCwgJ3JlZmVycmVyJywge1xuXHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIHJlZmVycmVyO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHV0aWxzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG5cdGJhc2VQYXRoOiAnZGF0YS1zZW5uYS1iYXNlLXBhdGgnLFxuXHRsaW5rU2VsZWN0b3I6ICdkYXRhLXNlbm5hLWxpbmstc2VsZWN0b3InLFxuXHRsb2FkaW5nQ3NzQ2xhc3M6ICdkYXRhLXNlbm5hLWxvYWRpbmctY3NzLWNsYXNzJyxcblx0c2VubmE6ICdkYXRhLXNlbm5hJyxcblx0ZGlzcGF0Y2g6ICdkYXRhLXNlbm5hLWRpc3BhdGNoJyxcblx0c3VyZmFjZTogJ2RhdGEtc2VubmEtc3VyZmFjZScsXG5cdHVwZGF0ZVNjcm9sbFBvc2l0aW9uOiAnZGF0YS1zZW5uYS11cGRhdGUtc2Nyb2xsLXBvc2l0aW9uJ1xufTsiLCIvKiFcbiAqIFByb21pc2VzIHBvbHlmaWxsIGZyb20gR29vZ2xlJ3MgQ2xvc3VyZSBMaWJyYXJ5LlxuICpcbiAqICAgICAgQ29weXJpZ2h0IDIwMTMgVGhlIENsb3N1cmUgTGlicmFyeSBBdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE5PVEUoZWR1YXJkbyk6IFByb21pc2Ugc3VwcG9ydCBpcyBub3QgcmVhZHkgb24gYWxsIHN1cHBvcnRlZCBicm93c2VycyxcbiAqIHRoZXJlZm9yZSBtZXRhbC1wcm9taXNlIGlzIHRlbXBvcmFyaWx5IHVzaW5nIEdvb2dsZSdzIHByb21pc2VzIGFzIHBvbHlmaWxsLlxuICogSXQgc3VwcG9ydHMgY2FuY2VsbGFibGUgcHJvbWlzZXMgYW5kIGhhcyBjbGVhbiBhbmQgZmFzdCBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGlzRGVmLCBpc0Z1bmN0aW9uLCBpc09iamVjdCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IGFzeW5jIH0gZnJvbSAnbWV0YWwnO1xuXG4vKipcbiAqIFByb3ZpZGVzIGEgbW9yZSBzdHJpY3QgaW50ZXJmYWNlIGZvciBUaGVuYWJsZXMgaW4gdGVybXMgb2ZcbiAqIGh0dHA6Ly9wcm9taXNlc2FwbHVzLmNvbSBmb3IgaW50ZXJvcCB3aXRoIHtAc2VlIENhbmNlbGxhYmxlUHJvbWlzZX0uXG4gKlxuICogQGludGVyZmFjZVxuICogQGV4dGVuZHMge0lUaGVuYWJsZS48VFlQRT59XG4gKiBAdGVtcGxhdGUgVFlQRVxuICovXG52YXIgVGhlbmFibGUgPSBmdW5jdGlvbigpIHt9O1xuXG4vKipcbiAqIEFkZHMgY2FsbGJhY2tzIHRoYXQgd2lsbCBvcGVyYXRlIG9uIHRoZSByZXN1bHQgb2YgdGhlIFRoZW5hYmxlLCByZXR1cm5pbmcgYVxuICogbmV3IGNoaWxkIFByb21pc2UuXG4gKlxuICogSWYgdGhlIFRoZW5hYmxlIGlzIGZ1bGZpbGxlZCwgdGhlIHtAY29kZSBvbkZ1bGZpbGxlZH0gY2FsbGJhY2sgd2lsbCBiZVxuICogaW52b2tlZCB3aXRoIHRoZSBmdWxmaWxsbWVudCB2YWx1ZSBhcyBhcmd1bWVudCwgYW5kIHRoZSBjaGlsZCBQcm9taXNlIHdpbGxcbiAqIGJlIGZ1bGZpbGxlZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrLiBJZiB0aGUgY2FsbGJhY2sgdGhyb3dzXG4gKiBhbiBleGNlcHRpb24sIHRoZSBjaGlsZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgdGhyb3duIHZhbHVlXG4gKiBpbnN0ZWFkLlxuICpcbiAqIElmIHRoZSBUaGVuYWJsZSBpcyByZWplY3RlZCwgdGhlIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWRcbiAqIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb24gYXMgYXJndW1lbnQsIGFuZCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkXG4gKiB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNhbGxiYWNrIG9yIHRocm93biB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0gez8oZnVuY3Rpb24odGhpczpUSElTLCBUWVBFKTpcbiAqICAgICAgICAgICAgIChSRVNVTFR8SVRoZW5hYmxlLjxSRVNVTFQ+fFRoZW5hYmxlKSk9fSBvcHRfb25GdWxmaWxsZWQgQVxuICogICAgIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBpbnZva2VkIHdpdGggdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlmIHRoZSBQcm9taXNlXG4gKiAgICAgaXMgZnVsbGZpbGxlZC5cbiAqIEBwYXJhbSB7PyhmdW5jdGlvbigqKTogKik9fSBvcHRfb25SZWplY3RlZCBBIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBpbnZva2VkXG4gKiAgICAgd2l0aCB0aGUgcmVqZWN0aW9uIHJlYXNvbiBpZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZC5cbiAqIEBwYXJhbSB7VEhJUz19IG9wdF9jb250ZXh0IEFuIG9wdGlvbmFsIGNvbnRleHQgb2JqZWN0IHRoYXQgd2lsbCBiZSB0aGVcbiAqICAgICBleGVjdXRpb24gY29udGV4dCBmb3IgdGhlIGNhbGxiYWNrcy4gQnkgZGVmYXVsdCwgZnVuY3Rpb25zIGFyZSBleGVjdXRlZFxuICogICAgIHdpdGggdGhlIGRlZmF1bHQgdGhpcy5cbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPFJFU1VMVD59IEEgbmV3IFByb21pc2UgdGhhdCB3aWxsIHJlY2VpdmUgdGhlXG4gKiAgICAgcmVzdWx0IG9mIHRoZSBmdWxmaWxsbWVudCBvciByZWplY3Rpb24gY2FsbGJhY2suXG4gKiBAdGVtcGxhdGUgUkVTVUxULFRISVNcbiAqL1xuVGhlbmFibGUucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbigpIHt9O1xuXG5cbi8qKlxuICogQW4gZXhwYW5kbyBwcm9wZXJ0eSB0byBpbmRpY2F0ZSB0aGF0IGFuIG9iamVjdCBpbXBsZW1lbnRzXG4gKiB7QGNvZGUgVGhlbmFibGV9LlxuICpcbiAqIHtAc2VlIGFkZEltcGxlbWVudGF0aW9ufS5cbiAqXG4gKiBAY29uc3RcbiAqL1xuVGhlbmFibGUuSU1QTEVNRU5URURfQllfUFJPUCA9ICckZ29vZ19UaGVuYWJsZSc7XG5cblxuLyoqXG4gKiBNYXJrcyBhIGdpdmVuIGNsYXNzIChjb25zdHJ1Y3RvcikgYXMgYW4gaW1wbGVtZW50YXRpb24gb2YgVGhlbmFibGUsIHNvXG4gKiB0aGF0IHdlIGNhbiBxdWVyeSB0aGF0IGZhY3QgYXQgcnVudGltZS4gVGhlIGNsYXNzIG11c3QgaGF2ZSBhbHJlYWR5XG4gKiBpbXBsZW1lbnRlZCB0aGUgaW50ZXJmYWNlLlxuICogRXhwb3J0cyBhICd0aGVuJyBtZXRob2Qgb24gdGhlIGNvbnN0cnVjdG9yIHByb3RvdHlwZSwgc28gdGhhdCB0aGUgb2JqZWN0c1xuICogYWxzbyBpbXBsZW1lbnQgdGhlIGV4dGVybiB7QHNlZSBUaGVuYWJsZX0gaW50ZXJmYWNlIGZvciBpbnRlcm9wIHdpdGhcbiAqIG90aGVyIFByb21pc2UgaW1wbGVtZW50YXRpb25zLlxuICogQHBhcmFtIHtmdW5jdGlvbihuZXc6VGhlbmFibGUsLi4uWz9dKX0gY3RvciBUaGUgY2xhc3MgY29uc3RydWN0b3IuIFRoZVxuICogICAgIGNvcnJlc3BvbmRpbmcgY2xhc3MgbXVzdCBoYXZlIGFscmVhZHkgaW1wbGVtZW50ZWQgdGhlIGludGVyZmFjZS5cbiAqL1xuVGhlbmFibGUuYWRkSW1wbGVtZW50YXRpb24gPSBmdW5jdGlvbihjdG9yKSB7XG4gIGN0b3IucHJvdG90eXBlLnRoZW4gPSBjdG9yLnByb3RvdHlwZS50aGVuO1xuICBjdG9yLnByb3RvdHlwZS4kZ29vZ19UaGVuYWJsZSA9IHRydWU7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHsqfSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgYSBnaXZlbiBpbnN0YW5jZSBpbXBsZW1lbnRzIHtAY29kZSBUaGVuYWJsZX0uXG4gKiAgICAgVGhlIGNsYXNzL3N1cGVyY2xhc3Mgb2YgdGhlIGluc3RhbmNlIG11c3QgY2FsbCB7QGNvZGUgYWRkSW1wbGVtZW50YXRpb259LlxuICovXG5UaGVuYWJsZS5pc0ltcGxlbWVudGVkQnkgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgaWYgKCFvYmplY3QpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gISFvYmplY3QuJGdvb2dfVGhlbmFibGU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBQcm9wZXJ0eSBhY2Nlc3Mgc2VlbXMgdG8gYmUgZm9yYmlkZGVuLlxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuXG4vKipcbiAqIExpa2UgYmluZCgpLCBleGNlcHQgdGhhdCBhICd0aGlzIG9iamVjdCcgaXMgbm90IHJlcXVpcmVkLiBVc2VmdWwgd2hlbiB0aGVcbiAqIHRhcmdldCBmdW5jdGlvbiBpcyBhbHJlYWR5IGJvdW5kLlxuICpcbiAqIFVzYWdlOlxuICogdmFyIGcgPSBwYXJ0aWFsKGYsIGFyZzEsIGFyZzIpO1xuICogZyhhcmczLCBhcmc0KTtcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBBIGZ1bmN0aW9uIHRvIHBhcnRpYWxseSBhcHBseS5cbiAqIEBwYXJhbSB7Li4uKn0gdmFyX2FyZ3MgQWRkaXRpb25hbCBhcmd1bWVudHMgdGhhdCBhcmUgcGFydGlhbGx5IGFwcGxpZWQgdG8gZm4uXG4gKiBAcmV0dXJuIHshRnVuY3Rpb259IEEgcGFydGlhbGx5LWFwcGxpZWQgZm9ybSBvZiB0aGUgZnVuY3Rpb24gYmluZCgpIHdhc1xuICogICAgIGludm9rZWQgYXMgYSBtZXRob2Qgb2YuXG4gKi9cbnZhciBwYXJ0aWFsID0gZnVuY3Rpb24oZm4pIHtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgLy8gQ2xvbmUgdGhlIGFycmF5ICh3aXRoIHNsaWNlKCkpIGFuZCBhcHBlbmQgYWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICAvLyB0byB0aGUgZXhpc3RpbmcgYXJndW1lbnRzLlxuICAgIHZhciBuZXdBcmdzID0gYXJncy5zbGljZSgpO1xuICAgIG5ld0FyZ3MucHVzaC5hcHBseShuZXdBcmdzLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBuZXdBcmdzKTtcbiAgfTtcbn07XG5cbi8qKlxuICogUHJvbWlzZXMgcHJvdmlkZSBhIHJlc3VsdCB0aGF0IG1heSBiZSByZXNvbHZlZCBhc3luY2hyb25vdXNseS4gQSBQcm9taXNlIG1heVxuICogYmUgcmVzb2x2ZWQgYnkgYmVpbmcgZnVsZmlsbGVkIG9yIHJlamVjdGVkIHdpdGggYSB2YWx1ZSwgd2hpY2ggd2lsbCBiZSBrbm93blxuICogYXMgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIG9yIHRoZSByZWplY3Rpb24gcmVhc29uLiBXaGV0aGVyIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQsIHRoZSBQcm9taXNlIHJlc3VsdCBpcyBpbW11dGFibGUgb25jZSBpdCBpcyBzZXQuXG4gKlxuICogUHJvbWlzZXMgbWF5IHJlcHJlc2VudCByZXN1bHRzIG9mIGFueSB0eXBlLCBpbmNsdWRpbmcgdW5kZWZpbmVkLiBSZWplY3Rpb25cbiAqIHJlYXNvbnMgYXJlIHR5cGljYWxseSBFcnJvcnMsIGJ1dCBtYXkgYWxzbyBiZSBvZiBhbnkgdHlwZS4gQ2xvc3VyZSBQcm9taXNlc1xuICogYWxsb3cgZm9yIG9wdGlvbmFsIHR5cGUgYW5ub3RhdGlvbnMgdGhhdCBlbmZvcmNlIHRoYXQgZnVsZmlsbG1lbnQgdmFsdWVzIGFyZVxuICogb2YgdGhlIGFwcHJvcHJpYXRlIHR5cGVzIGF0IGNvbXBpbGUgdGltZS5cbiAqXG4gKiBUaGUgcmVzdWx0IG9mIGEgUHJvbWlzZSBpcyBhY2Nlc3NpYmxlIGJ5IGNhbGxpbmcge0Bjb2RlIHRoZW59IGFuZCByZWdpc3RlcmluZ1xuICoge0Bjb2RlIG9uRnVsZmlsbGVkfSBhbmQge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrcy4gT25jZSB0aGUgUHJvbWlzZVxuICogcmVzb2x2ZXMsIHRoZSByZWxldmFudCBjYWxsYmFja3MgYXJlIGludm9rZWQgd2l0aCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgb3JcbiAqIHJlamVjdGlvbiByZWFzb24gYXMgYXJndW1lbnQuIENhbGxiYWNrcyBhcmUgYWx3YXlzIGludm9rZWQgaW4gdGhlIG9yZGVyIHRoZXlcbiAqIHdlcmUgcmVnaXN0ZXJlZCwgZXZlbiB3aGVuIGFkZGl0aW9uYWwge0Bjb2RlIHRoZW59IGNhbGxzIGFyZSBtYWRlIGZyb20gaW5zaWRlXG4gKiBhbm90aGVyIGNhbGxiYWNrLiBBIGNhbGxiYWNrIGlzIGFsd2F5cyBydW4gYXN5bmNocm9ub3VzbHkgc29tZXRpbWUgYWZ0ZXIgdGhlXG4gKiBzY29wZSBjb250YWluaW5nIHRoZSByZWdpc3RlcmluZyB7QGNvZGUgdGhlbn0gaW52b2NhdGlvbiBoYXMgcmV0dXJuZWQuXG4gKlxuICogSWYgYSBQcm9taXNlIGlzIHJlc29sdmVkIHdpdGggYW5vdGhlciBQcm9taXNlLCB0aGUgZmlyc3QgUHJvbWlzZSB3aWxsIGJsb2NrXG4gKiB1bnRpbCB0aGUgc2Vjb25kIGlzIHJlc29sdmVkLCBhbmQgdGhlbiBhc3N1bWVzIHRoZSBzYW1lIHJlc3VsdCBhcyB0aGUgc2Vjb25kXG4gKiBQcm9taXNlLiBUaGlzIGFsbG93cyBQcm9taXNlcyB0byBkZXBlbmQgb24gdGhlIHJlc3VsdHMgb2Ygb3RoZXIgUHJvbWlzZXMsXG4gKiBsaW5raW5nIHRvZ2V0aGVyIG11bHRpcGxlIGFzeW5jaHJvbm91cyBvcGVyYXRpb25zLlxuICpcbiAqIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBQcm9taXNlcy9BKyBzcGVjaWZpY2F0aW9uIGFuZFxuICogcGFzc2VzIHRoYXQgc3BlY2lmaWNhdGlvbidzIGNvbmZvcm1hbmNlIHRlc3Qgc3VpdGUuIEEgQ2xvc3VyZSBQcm9taXNlIG1heSBiZVxuICogcmVzb2x2ZWQgd2l0aCBhIFByb21pc2UgaW5zdGFuY2UgKG9yIHN1ZmZpY2llbnRseSBjb21wYXRpYmxlIFByb21pc2UtbGlrZVxuICogb2JqZWN0KSBjcmVhdGVkIGJ5IG90aGVyIFByb21pc2UgaW1wbGVtZW50YXRpb25zLiBGcm9tIHRoZSBzcGVjaWZpY2F0aW9uLFxuICogUHJvbWlzZS1saWtlIG9iamVjdHMgYXJlIGtub3duIGFzIFwiVGhlbmFibGVzXCIuXG4gKlxuICogQHNlZSBodHRwOi8vcHJvbWlzZXNhcGx1cy5jb20vXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbihcbiAqICAgICAgICAgICAgIHRoaXM6UkVTT0xWRVJfQ09OVEVYVCxcbiAqICAgICAgICAgICAgIGZ1bmN0aW9uKChUWVBFfElUaGVuYWJsZS48VFlQRT58VGhlbmFibGUpKSxcbiAqICAgICAgICAgICAgIGZ1bmN0aW9uKCopKTogdm9pZH0gcmVzb2x2ZXJcbiAqICAgICBJbml0aWFsaXphdGlvbiBmdW5jdGlvbiB0aGF0IGlzIGludm9rZWQgaW1tZWRpYXRlbHkgd2l0aCB7QGNvZGUgcmVzb2x2ZX1cbiAqICAgICBhbmQge0Bjb2RlIHJlamVjdH0gZnVuY3Rpb25zIGFzIGFyZ3VtZW50cy4gVGhlIFByb21pc2UgaXMgcmVzb2x2ZWQgb3JcbiAqICAgICByZWplY3RlZCB3aXRoIHRoZSBmaXJzdCBhcmd1bWVudCBwYXNzZWQgdG8gZWl0aGVyIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtSRVNPTFZFUl9DT05URVhUPX0gb3B0X2NvbnRleHQgQW4gb3B0aW9uYWwgY29udGV4dCBmb3IgZXhlY3V0aW5nIHRoZVxuICogICAgIHJlc29sdmVyIGZ1bmN0aW9uLiBJZiB1bnNwZWNpZmllZCwgdGhlIHJlc29sdmVyIGZ1bmN0aW9uIHdpbGwgYmUgZXhlY3V0ZWRcbiAqICAgICBpbiB0aGUgZGVmYXVsdCBzY29wZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHN0cnVjdFxuICogQGZpbmFsXG4gKiBAaW1wbGVtZW50cyB7VGhlbmFibGUuPFRZUEU+fVxuICogQHRlbXBsYXRlIFRZUEUsUkVTT0xWRVJfQ09OVEVYVFxuICovXG52YXIgQ2FuY2VsbGFibGVQcm9taXNlID0gZnVuY3Rpb24ocmVzb2x2ZXIsIG9wdF9jb250ZXh0KSB7XG4gIC8qKlxuICAgKiBUaGUgaW50ZXJuYWwgc3RhdGUgb2YgdGhpcyBQcm9taXNlLiBFaXRoZXIgUEVORElORywgRlVMRklMTEVELCBSRUpFQ1RFRCwgb3JcbiAgICogQkxPQ0tFRC5cbiAgICogQHByaXZhdGUge0NhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV99XG4gICAqL1xuICB0aGlzLnN0YXRlXyA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUEVORElORztcblxuICAvKipcbiAgICogVGhlIHJlc29sdmVkIHJlc3VsdCBvZiB0aGUgUHJvbWlzZS4gSW1tdXRhYmxlIG9uY2Ugc2V0IHdpdGggZWl0aGVyIGFcbiAgICogZnVsZmlsbG1lbnQgdmFsdWUgb3IgcmVqZWN0aW9uIHJlYXNvbi5cbiAgICogQHByaXZhdGUgeyp9XG4gICAqL1xuICB0aGlzLnJlc3VsdF8gPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEZvciBQcm9taXNlcyBjcmVhdGVkIGJ5IGNhbGxpbmcge0Bjb2RlIHRoZW4oKX0sIHRoZSBvcmlnaW5hdGluZyBwYXJlbnQuXG4gICAqIEBwcml2YXRlIHtDYW5jZWxsYWJsZVByb21pc2V9XG4gICAqL1xuICB0aGlzLnBhcmVudF8gPSBudWxsO1xuXG4gIC8qKlxuICAgKiBUaGUgbGlzdCBvZiB7QGNvZGUgb25GdWxmaWxsZWR9IGFuZCB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tzIGFkZGVkIHRvXG4gICAqIHRoaXMgUHJvbWlzZSBieSBjYWxscyB0byB7QGNvZGUgdGhlbigpfS5cbiAgICogQHByaXZhdGUge0FycmF5LjxDYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV8+fVxuICAgKi9cbiAgdGhpcy5jYWxsYmFja0VudHJpZXNfID0gbnVsbDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgUHJvbWlzZSBpcyBpbiB0aGUgcXVldWUgb2YgUHJvbWlzZXMgdG8gZXhlY3V0ZS5cbiAgICogQHByaXZhdGUge2Jvb2xlYW59XG4gICAqL1xuICB0aGlzLmV4ZWN1dGluZ18gPSBmYWxzZTtcblxuICBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPiAwKSB7XG4gICAgLyoqXG4gICAgICogQSB0aW1lb3V0IElEIHVzZWQgd2hlbiB0aGUge0Bjb2RlIFVOSEFORExFRF9SRUpFQ1RJT05fREVMQVl9IGlzIGdyZWF0ZXJcbiAgICAgKiB0aGFuIDAgbWlsbGlzZWNvbmRzLiBUaGUgSUQgaXMgc2V0IHdoZW4gdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQsIGFuZFxuICAgICAqIGNsZWFyZWQgb25seSBpZiBhbiB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgaXMgaW52b2tlZCBmb3IgdGhlXG4gICAgICogUHJvbWlzZSAob3Igb25lIG9mIGl0cyBkZXNjZW5kYW50cykgYmVmb3JlIHRoZSBkZWxheSBpcyBleGNlZWRlZC5cbiAgICAgKlxuICAgICAqIElmIHRoZSByZWplY3Rpb24gaXMgbm90IGhhbmRsZWQgYmVmb3JlIHRoZSB0aW1lb3V0IGNvbXBsZXRlcywgdGhlXG4gICAgICogcmVqZWN0aW9uIHJlYXNvbiBpcyBwYXNzZWQgdG8gdGhlIHVuaGFuZGxlZCByZWplY3Rpb24gaGFuZGxlci5cbiAgICAgKiBAcHJpdmF0ZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMudW5oYW5kbGVkUmVqZWN0aW9uSWRfID0gMDtcbiAgfSBlbHNlIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA9PT0gMCkge1xuICAgIC8qKlxuICAgICAqIFdoZW4gdGhlIHtAY29kZSBVTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZfSBpcyBzZXQgdG8gMCBtaWxsaXNlY29uZHMsIGFcbiAgICAgKiBib29sZWFuIHRoYXQgaXMgc2V0IGlmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBhbmQgcmVzZXQgdG8gZmFsc2UgaWYgYW5cbiAgICAgKiB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgaXMgaW52b2tlZCBmb3IgdGhlIFByb21pc2UgKG9yIG9uZSBvZiBpdHNcbiAgICAgKiBkZXNjZW5kYW50cykuIElmIHRoZSByZWplY3Rpb24gaXMgbm90IGhhbmRsZWQgYmVmb3JlIHRoZSBuZXh0IHRpbWVzdGVwLFxuICAgICAqIHRoZSByZWplY3Rpb24gcmVhc29uIGlzIHBhc3NlZCB0byB0aGUgdW5oYW5kbGVkIHJlamVjdGlvbiBoYW5kbGVyLlxuICAgICAqIEBwcml2YXRlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMuaGFkVW5oYW5kbGVkUmVqZWN0aW9uXyA9IGZhbHNlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgcmVzb2x2ZXIuY2FsbChcbiAgICAgIG9wdF9jb250ZXh0LCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBzZWxmLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uRlVMRklMTEVELCB2YWx1ZSk7XG4gICAgICB9LCBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAgICAgc2VsZi5yZXNvbHZlXyhDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVELCByZWFzb24pO1xuICAgICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQsIGUpO1xuICB9XG59O1xuXG4vKipcbiAqIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIGEgcmVqZWN0ZWQgUHJvbWlzZSdzIHJlYXNvbiBpcyBwYXNzZWQgdG9cbiAqIHRoZSByZWplY3Rpb24gaGFuZGxlci4gQnkgZGVmYXVsdCwgdGhlIHJlamVjdGlvbiBoYW5kbGVyIHJldGhyb3dzIHRoZVxuICogcmVqZWN0aW9uIHJlYXNvbiBzbyB0aGF0IGl0IGFwcGVhcnMgaW4gdGhlIGRldmVsb3BlciBjb25zb2xlIG9yXG4gKiB7QGNvZGUgd2luZG93Lm9uZXJyb3J9IGhhbmRsZXIuXG4gKiBSZWplY3Rpb25zIGFyZSByZXRocm93biBhcyBxdWlja2x5IGFzIHBvc3NpYmxlIGJ5IGRlZmF1bHQuIEEgbmVnYXRpdmUgdmFsdWVcbiAqIGRpc2FibGVzIHJlamVjdGlvbiBoYW5kbGluZyBlbnRpcmVseS5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5VTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZID0gMDtcblxuXG4vKipcbiAqIFRoZSBwb3NzaWJsZSBpbnRlcm5hbCBzdGF0ZXMgZm9yIGEgUHJvbWlzZS4gVGhlc2Ugc3RhdGVzIGFyZSBub3QgZGlyZWN0bHlcbiAqIG9ic2VydmFibGUgdG8gZXh0ZXJuYWwgY2FsbGVycy5cbiAqIEBlbnVtIHtudW1iZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfID0ge1xuICAvKiogVGhlIFByb21pc2UgaXMgd2FpdGluZyBmb3IgcmVzb2x1dGlvbi4gKi9cbiAgUEVORElORzogMCxcblxuICAvKiogVGhlIFByb21pc2UgaXMgYmxvY2tlZCB3YWl0aW5nIGZvciB0aGUgcmVzdWx0IG9mIGFub3RoZXIgVGhlbmFibGUuICovXG4gIEJMT0NLRUQ6IDEsXG5cbiAgLyoqIFRoZSBQcm9taXNlIGhhcyBiZWVuIHJlc29sdmVkIHdpdGggYSBmdWxmaWxsbWVudCB2YWx1ZS4gKi9cbiAgRlVMRklMTEVEOiAyLFxuXG4gIC8qKiBUaGUgUHJvbWlzZSBoYXMgYmVlbiByZXNvbHZlZCB3aXRoIGEgcmVqZWN0aW9uIHJlYXNvbi4gKi9cbiAgUkVKRUNURUQ6IDNcbn07XG5cblxuLyoqXG4gKiBUeXBlZGVmIGZvciBlbnRyaWVzIGluIHRoZSBjYWxsYmFjayBjaGFpbi4gRWFjaCBjYWxsIHRvIHtAY29kZSB0aGVufSxcbiAqIHtAY29kZSB0aGVuQ2F0Y2h9LCBvciB7QGNvZGUgdGhlbkFsd2F5c30gY3JlYXRlcyBhbiBlbnRyeSBjb250YWluaW5nIHRoZVxuICogZnVuY3Rpb25zIHRoYXQgbWF5IGJlIGludm9rZWQgb25jZSB0aGUgUHJvbWlzZSBpcyByZXNvbHZlZC5cbiAqXG4gKiBAdHlwZWRlZiB7e1xuICogICBjaGlsZDogQ2FuY2VsbGFibGVQcm9taXNlLFxuICogICBvbkZ1bGZpbGxlZDogZnVuY3Rpb24oKiksXG4gKiAgIG9uUmVqZWN0ZWQ6IGZ1bmN0aW9uKCopXG4gKiB9fVxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLkNhbGxiYWNrRW50cnlfID0gbnVsbDtcblxuXG4vKipcbiAqIEBwYXJhbSB7KFRZUEV8VGhlbmFibGUuPFRZUEU+fFRoZW5hYmxlKT19IG9wdF92YWx1ZVxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48VFlQRT59IEEgbmV3IFByb21pc2UgdGhhdCBpcyBpbW1lZGlhdGVseSByZXNvbHZlZFxuICogICAgIHdpdGggdGhlIGdpdmVuIHZhbHVlLlxuICogQHRlbXBsYXRlIFRZUEVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUgPSBmdW5jdGlvbihvcHRfdmFsdWUpIHtcbiAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZShvcHRfdmFsdWUpO1xuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7Kj19IG9wdF9yZWFzb25cbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9IEEgbmV3IFByb21pc2UgdGhhdCBpcyBpbW1lZGlhdGVseSByZWplY3RlZCB3aXRoIHRoZVxuICogICAgIGdpdmVuIHJlYXNvbi5cbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnJlamVjdCA9IGZ1bmN0aW9uKG9wdF9yZWFzb24pIHtcbiAgcmV0dXJuIG5ldyBDYW5jZWxsYWJsZVByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICByZWplY3Qob3B0X3JlYXNvbik7XG4gICAgfSk7XG59O1xuXG5cbi8qKlxuICogQHBhcmFtIHshQXJyYXkuPCEoVGhlbmFibGUuPFRZUEU+fFRoZW5hYmxlKT59IHByb21pc2VzXG4gKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlLjxUWVBFPn0gQSBQcm9taXNlIHRoYXQgcmVjZWl2ZXMgdGhlIHJlc3VsdCBvZiB0aGVcbiAqICAgICBmaXJzdCBQcm9taXNlIChvciBQcm9taXNlLWxpa2UpIGlucHV0IHRvIGNvbXBsZXRlLlxuICogQHRlbXBsYXRlIFRZUEVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnJhY2UgPSBmdW5jdGlvbihwcm9taXNlcykge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIGlmICghcHJvbWlzZXMubGVuZ3RoKSB7XG4gICAgICAgIHJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwLCBwcm9taXNlOyAocHJvbWlzZSA9IHByb21pc2VzW2ldKTsgaSsrKSB7XG4gICAgICAgIHByb21pc2UudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7IUFycmF5LjwhKFRoZW5hYmxlLjxUWVBFPnxUaGVuYWJsZSk+fSBwcm9taXNlc1xuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48IUFycmF5LjxUWVBFPj59IEEgUHJvbWlzZSB0aGF0IHJlY2VpdmVzIGEgbGlzdCBvZlxuICogICAgIGV2ZXJ5IGZ1bGZpbGxlZCB2YWx1ZSBvbmNlIGV2ZXJ5IGlucHV0IFByb21pc2UgKG9yIFByb21pc2UtbGlrZSkgaXNcbiAqICAgICBzdWNjZXNzZnVsbHkgZnVsZmlsbGVkLCBvciBpcyByZWplY3RlZCBieSB0aGUgZmlyc3QgcmVqZWN0aW9uIHJlc3VsdC5cbiAqIEB0ZW1wbGF0ZSBUWVBFXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5hbGwgPSBmdW5jdGlvbihwcm9taXNlcykge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciB0b0Z1bGZpbGwgPSBwcm9taXNlcy5sZW5ndGg7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG5cbiAgICAgIGlmICghdG9GdWxmaWxsKSB7XG4gICAgICAgIHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgb25GdWxmaWxsID0gZnVuY3Rpb24oaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIHRvRnVsZmlsbC0tO1xuICAgICAgICB2YWx1ZXNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgIGlmICh0b0Z1bGZpbGwgPT09IDApIHtcbiAgICAgICAgICByZXNvbHZlKHZhbHVlcyk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHZhciBvblJlamVjdCA9IGZ1bmN0aW9uKHJlYXNvbikge1xuICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgIH07XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBwcm9taXNlOyAocHJvbWlzZSA9IHByb21pc2VzW2ldKTsgaSsrKSB7XG4gICAgICAgIHByb21pc2UudGhlbihwYXJ0aWFsKG9uRnVsZmlsbCwgaSksIG9uUmVqZWN0KTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBAcGFyYW0geyFBcnJheS48IShUaGVuYWJsZS48VFlQRT58VGhlbmFibGUpPn0gcHJvbWlzZXNcbiAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2UuPFRZUEU+fSBBIFByb21pc2UgdGhhdCByZWNlaXZlcyB0aGUgdmFsdWUgb2ZcbiAqICAgICB0aGUgZmlyc3QgaW5wdXQgdG8gYmUgZnVsZmlsbGVkLCBvciBpcyByZWplY3RlZCB3aXRoIGEgbGlzdCBvZiBldmVyeVxuICogICAgIHJlamVjdGlvbiByZWFzb24gaWYgYWxsIGlucHV0cyBhcmUgcmVqZWN0ZWQuXG4gKiBAdGVtcGxhdGUgVFlQRVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UuZmlyc3RGdWxmaWxsZWQgPSBmdW5jdGlvbihwcm9taXNlcykge1xuICByZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciB0b1JlamVjdCA9IHByb21pc2VzLmxlbmd0aDtcbiAgICAgIHZhciByZWFzb25zID0gW107XG5cbiAgICAgIGlmICghdG9SZWplY3QpIHtcbiAgICAgICAgcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBvbkZ1bGZpbGwgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciBvblJlamVjdCA9IGZ1bmN0aW9uKGluZGV4LCByZWFzb24pIHtcbiAgICAgICAgdG9SZWplY3QtLTtcbiAgICAgICAgcmVhc29uc1tpbmRleF0gPSByZWFzb247XG4gICAgICAgIGlmICh0b1JlamVjdCA9PT0gMCkge1xuICAgICAgICAgIHJlamVjdChyZWFzb25zKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIHByb21pc2U7IChwcm9taXNlID0gcHJvbWlzZXNbaV0pOyBpKyspIHtcbiAgICAgICAgcHJvbWlzZS50aGVuKG9uRnVsZmlsbCwgcGFydGlhbChvblJlamVjdCwgaSkpO1xuICAgICAgfVxuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIEFkZHMgY2FsbGJhY2tzIHRoYXQgd2lsbCBvcGVyYXRlIG9uIHRoZSByZXN1bHQgb2YgdGhlIFByb21pc2UsIHJldHVybmluZyBhXG4gKiBuZXcgY2hpbGQgUHJvbWlzZS5cbiAqXG4gKiBJZiB0aGUgUHJvbWlzZSBpcyBmdWxmaWxsZWQsIHRoZSB7QGNvZGUgb25GdWxmaWxsZWR9IGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZFxuICogd2l0aCB0aGUgZnVsZmlsbG1lbnQgdmFsdWUgYXMgYXJndW1lbnQsIGFuZCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlXG4gKiBmdWxmaWxsZWQgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjay4gSWYgdGhlIGNhbGxiYWNrIHRocm93cyBhblxuICogZXhjZXB0aW9uLCB0aGUgY2hpbGQgUHJvbWlzZSB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHRocm93biB2YWx1ZSBpbnN0ZWFkLlxuICpcbiAqIElmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCB0aGUge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZFxuICogd2l0aCB0aGUgcmVqZWN0aW9uIHJlYXNvbiBhcyBhcmd1bWVudCwgYW5kIHRoZSBjaGlsZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWRcbiAqIHdpdGggdGhlIHJldHVybiB2YWx1ZSAob3IgdGhyb3duIHZhbHVlKSBvZiB0aGUgY2FsbGJhY2suXG4gKlxuICogQG92ZXJyaWRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbiA9IGZ1bmN0aW9uKG9wdF9vbkZ1bGZpbGxlZCwgb3B0X29uUmVqZWN0ZWQsIG9wdF9jb250ZXh0KSB7XG4gIHJldHVybiB0aGlzLmFkZENoaWxkUHJvbWlzZV8oXG4gICAgaXNGdW5jdGlvbihvcHRfb25GdWxmaWxsZWQpID8gb3B0X29uRnVsZmlsbGVkIDogbnVsbCxcbiAgICBpc0Z1bmN0aW9uKG9wdF9vblJlamVjdGVkKSA/IG9wdF9vblJlamVjdGVkIDogbnVsbCxcbiAgICBvcHRfY29udGV4dCk7XG59O1xuVGhlbmFibGUuYWRkSW1wbGVtZW50YXRpb24oQ2FuY2VsbGFibGVQcm9taXNlKTtcblxuXG4vKipcbiAqIEFkZHMgYSBjYWxsYmFjayB0aGF0IHdpbGwgYmUgaW52b2tlZCB3aGV0aGVyIHRoZSBQcm9taXNlIGlzIGZ1bGZpbGxlZCBvclxuICogcmVqZWN0ZWQuIFRoZSBjYWxsYmFjayByZWNlaXZlcyBubyBhcmd1bWVudCwgYW5kIG5vIG5ldyBjaGlsZCBQcm9taXNlIGlzXG4gKiBjcmVhdGVkLiBUaGlzIGlzIHVzZWZ1bCBmb3IgZW5zdXJpbmcgdGhhdCBjbGVhbnVwIHRha2VzIHBsYWNlIGFmdGVyIGNlcnRhaW5cbiAqIGFzeW5jaHJvbm91cyBvcGVyYXRpb25zLiBDYWxsYmFja3MgYWRkZWQgd2l0aCB7QGNvZGUgdGhlbkFsd2F5c30gd2lsbCBiZVxuICogZXhlY3V0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgd2l0aCBvdGhlciBjYWxscyB0byB7QGNvZGUgdGhlbn0sXG4gKiB7QGNvZGUgdGhlbkFsd2F5c30sIG9yIHtAY29kZSB0aGVuQ2F0Y2h9LlxuICpcbiAqIFNpbmNlIGl0IGRvZXMgbm90IHByb2R1Y2UgYSBuZXcgY2hpbGQgUHJvbWlzZSwgY2FuY2VsbGF0aW9uIHByb3BhZ2F0aW9uIGlzXG4gKiBub3QgcHJldmVudGVkIGJ5IGFkZGluZyBjYWxsYmFja3Mgd2l0aCB7QGNvZGUgdGhlbkFsd2F5c30uIEEgUHJvbWlzZSB0aGF0IGhhc1xuICogYSBjbGVhbnVwIGhhbmRsZXIgYWRkZWQgd2l0aCB7QGNvZGUgdGhlbkFsd2F5c30gd2lsbCBiZSBjYW5jZWxlZCBpZiBhbGwgb2ZcbiAqIGl0cyBjaGlsZHJlbiBjcmVhdGVkIGJ5IHtAY29kZSB0aGVufSAob3Ige0Bjb2RlIHRoZW5DYXRjaH0pIGFyZSBjYW5jZWxlZC5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6VEhJUyk6IHZvaWR9IG9uUmVzb2x2ZWQgQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgaW52b2tlZFxuICogICAgIHdoZW4gdGhlIFByb21pc2UgaXMgcmVzb2x2ZWQuXG4gKiBAcGFyYW0ge1RISVM9fSBvcHRfY29udGV4dCBBbiBvcHRpb25hbCBjb250ZXh0IG9iamVjdCB0aGF0IHdpbGwgYmUgdGhlXG4gKiAgICAgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRoZSBjYWxsYmFja3MuIEJ5IGRlZmF1bHQsIGZ1bmN0aW9ucyBhcmUgZXhlY3V0ZWRcbiAqICAgICBpbiB0aGUgZ2xvYmFsIHNjb3BlLlxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZS48VFlQRT59IFRoaXMgUHJvbWlzZSwgZm9yIGNoYWluaW5nIGFkZGl0aW9uYWwgY2FsbHMuXG4gKiBAdGVtcGxhdGUgVEhJU1xuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnRoZW5BbHdheXMgPSBmdW5jdGlvbihvblJlc29sdmVkLCBvcHRfY29udGV4dCkge1xuICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgLy8gRW5zdXJlIHRoYXQgbm8gYXJndW1lbnRzIGFyZSBwYXNzZWQgdG8gb25SZXNvbHZlZC5cbiAgICAgIG9uUmVzb2x2ZWQuY2FsbChvcHRfY29udGV4dCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBDYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXy5jYWxsKG51bGwsIGVycik7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuYWRkQ2FsbGJhY2tFbnRyeV8oe1xuICAgIGNoaWxkOiBudWxsLFxuICAgIG9uUmVqZWN0ZWQ6IGNhbGxiYWNrLFxuICAgIG9uRnVsZmlsbGVkOiBjYWxsYmFja1xuICB9KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbi8qKlxuICogQWRkcyBhIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBpbnZva2VkIG9ubHkgaWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQuIFRoaXNcbiAqIGlzIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHRoZW4obnVsbCwgb25SZWplY3RlZCl9LlxuICpcbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKHRoaXM6VEhJUywgKik6ICp9IG9uUmVqZWN0ZWQgQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmVcbiAqICAgICBpbnZva2VkIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb24gaWYgdGhlIFByb21pc2UgaXMgcmVqZWN0ZWQuXG4gKiBAcGFyYW0ge1RISVM9fSBvcHRfY29udGV4dCBBbiBvcHRpb25hbCBjb250ZXh0IG9iamVjdCB0aGF0IHdpbGwgYmUgdGhlXG4gKiAgICAgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRoZSBjYWxsYmFja3MuIEJ5IGRlZmF1bHQsIGZ1bmN0aW9ucyBhcmUgZXhlY3V0ZWRcbiAqICAgICBpbiB0aGUgZ2xvYmFsIHNjb3BlLlxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gQSBuZXcgUHJvbWlzZSB0aGF0IHdpbGwgcmVjZWl2ZSB0aGUgcmVzdWx0IG9mIHRoZVxuICogICAgIGNhbGxiYWNrLlxuICogQHRlbXBsYXRlIFRISVNcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50aGVuQ2F0Y2ggPSBmdW5jdGlvbihvblJlamVjdGVkLCBvcHRfY29udGV4dCkge1xuICByZXR1cm4gdGhpcy5hZGRDaGlsZFByb21pc2VfKG51bGwsIG9uUmVqZWN0ZWQsIG9wdF9jb250ZXh0KTtcbn07XG5cbi8qKlxuICogQWxpYXMgb2Yge0BsaW5rIENhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudGhlbkNhdGNofVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmNhdGNoID0gQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS50aGVuQ2F0Y2g7XG5cblxuLyoqXG4gKiBDYW5jZWxzIHRoZSBQcm9taXNlIGlmIGl0IGlzIHN0aWxsIHBlbmRpbmcgYnkgcmVqZWN0aW5nIGl0IHdpdGggYSBjYW5jZWxcbiAqIEVycm9yLiBObyBhY3Rpb24gaXMgcGVyZm9ybWVkIGlmIHRoZSBQcm9taXNlIGlzIGFscmVhZHkgcmVzb2x2ZWQuXG4gKlxuICogQWxsIGNoaWxkIFByb21pc2VzIG9mIHRoZSBjYW5jZWxlZCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgc2FtZVxuICogY2FuY2VsIGVycm9yLCBhcyB3aXRoIG5vcm1hbCBQcm9taXNlIHJlamVjdGlvbi4gSWYgdGhlIFByb21pc2UgdG8gYmUgY2FuY2VsZWRcbiAqIGlzIHRoZSBvbmx5IGNoaWxkIG9mIGEgcGVuZGluZyBQcm9taXNlLCB0aGUgcGFyZW50IFByb21pc2Ugd2lsbCBhbHNvIGJlXG4gKiBjYW5jZWxlZC4gQ2FuY2VsbGF0aW9uIG1heSBwcm9wYWdhdGUgdXB3YXJkIHRocm91Z2ggbXVsdGlwbGUgZ2VuZXJhdGlvbnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfbWVzc2FnZSBBbiBvcHRpb25hbCBkZWJ1Z2dpbmcgbWVzc2FnZSBmb3IgZGVzY3JpYmluZyB0aGVcbiAqICAgICBjYW5jZWxsYXRpb24gcmVhc29uLlxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uKG9wdF9tZXNzYWdlKSB7XG4gIGlmICh0aGlzLnN0YXRlXyA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HKSB7XG4gICAgYXN5bmMucnVuKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVyciA9IG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3Iob3B0X21lc3NhZ2UpO1xuICAgICAgZXJyLklTX0NBTkNFTExBVElPTl9FUlJPUiA9IHRydWU7XG4gICAgICB0aGlzLmNhbmNlbEludGVybmFsXyhlcnIpO1xuICAgIH0sIHRoaXMpO1xuICB9XG59O1xuXG5cbi8qKlxuICogQ2FuY2VscyB0aGlzIFByb21pc2Ugd2l0aCB0aGUgZ2l2ZW4gZXJyb3IuXG4gKlxuICogQHBhcmFtIHshRXJyb3J9IGVyciBUaGUgY2FuY2VsbGF0aW9uIGVycm9yLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5jYW5jZWxJbnRlcm5hbF8gPSBmdW5jdGlvbihlcnIpIHtcbiAgaWYgKHRoaXMuc3RhdGVfID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkcpIHtcbiAgICBpZiAodGhpcy5wYXJlbnRfKSB7XG4gICAgICAvLyBDYW5jZWwgdGhlIFByb21pc2UgYW5kIHJlbW92ZSBpdCBmcm9tIHRoZSBwYXJlbnQncyBjaGlsZCBsaXN0LlxuICAgICAgdGhpcy5wYXJlbnRfLmNhbmNlbENoaWxkXyh0aGlzLCBlcnIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlc29sdmVfKENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQsIGVycik7XG4gICAgfVxuICB9XG59O1xuXG5cbi8qKlxuICogQ2FuY2VscyBhIGNoaWxkIFByb21pc2UgZnJvbSB0aGUgbGlzdCBvZiBjYWxsYmFjayBlbnRyaWVzLiBJZiB0aGUgUHJvbWlzZSBoYXNcbiAqIG5vdCBhbHJlYWR5IGJlZW4gcmVzb2x2ZWQsIHJlamVjdCBpdCB3aXRoIGEgY2FuY2VsIGVycm9yLiBJZiB0aGVyZSBhcmUgbm9cbiAqIG90aGVyIGNoaWxkcmVuIGluIHRoZSBsaXN0IG9mIGNhbGxiYWNrIGVudHJpZXMsIHByb3BhZ2F0ZSB0aGUgY2FuY2VsbGF0aW9uXG4gKiBieSBjYW5jZWxpbmcgdGhpcyBQcm9taXNlIGFzIHdlbGwuXG4gKlxuICogQHBhcmFtIHshQ2FuY2VsbGFibGVQcm9taXNlfSBjaGlsZFByb21pc2UgVGhlIFByb21pc2UgdG8gY2FuY2VsLlxuICogQHBhcmFtIHshRXJyb3J9IGVyciBUaGUgY2FuY2VsIGVycm9yIHRvIHVzZSBmb3IgcmVqZWN0aW5nIHRoZSBQcm9taXNlLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5jYW5jZWxDaGlsZF8gPSBmdW5jdGlvbihjaGlsZFByb21pc2UsIGVycikge1xuICBpZiAoIXRoaXMuY2FsbGJhY2tFbnRyaWVzXykge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgY2hpbGRDb3VudCA9IDA7XG4gIHZhciBjaGlsZEluZGV4ID0gLTE7XG5cbiAgLy8gRmluZCB0aGUgY2FsbGJhY2sgZW50cnkgZm9yIHRoZSBjaGlsZFByb21pc2UsIGFuZCBjb3VudCB3aGV0aGVyIHRoZXJlIGFyZVxuICAvLyBhZGRpdGlvbmFsIGNoaWxkIFByb21pc2VzLlxuICBmb3IgKHZhciBpID0gMCwgZW50cnk7IChlbnRyeSA9IHRoaXMuY2FsbGJhY2tFbnRyaWVzX1tpXSk7IGkrKykge1xuICAgIHZhciBjaGlsZCA9IGVudHJ5LmNoaWxkO1xuICAgIGlmIChjaGlsZCkge1xuICAgICAgY2hpbGRDb3VudCsrO1xuICAgICAgaWYgKGNoaWxkID09PSBjaGlsZFByb21pc2UpIHtcbiAgICAgICAgY2hpbGRJbmRleCA9IGk7XG4gICAgICB9XG4gICAgICBpZiAoY2hpbGRJbmRleCA+PSAwICYmIGNoaWxkQ291bnQgPiAxKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIElmIHRoZSBjaGlsZCBQcm9taXNlIHdhcyB0aGUgb25seSBjaGlsZCwgY2FuY2VsIHRoaXMgUHJvbWlzZSBhcyB3ZWxsLlxuICAvLyBPdGhlcndpc2UsIHJlamVjdCBvbmx5IHRoZSBjaGlsZCBQcm9taXNlIHdpdGggdGhlIGNhbmNlbCBlcnJvci5cbiAgaWYgKGNoaWxkSW5kZXggPj0gMCkge1xuICAgIGlmICh0aGlzLnN0YXRlXyA9PT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HICYmIGNoaWxkQ291bnQgPT09IDEpIHtcbiAgICAgIHRoaXMuY2FuY2VsSW50ZXJuYWxfKGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBjYWxsYmFja0VudHJ5ID0gdGhpcy5jYWxsYmFja0VudHJpZXNfLnNwbGljZShjaGlsZEluZGV4LCAxKVswXTtcbiAgICAgIHRoaXMuZXhlY3V0ZUNhbGxiYWNrXyhcbiAgICAgICAgY2FsbGJhY2tFbnRyeSwgQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCwgZXJyKTtcbiAgICB9XG4gIH1cbn07XG5cblxuLyoqXG4gKiBBZGRzIGEgY2FsbGJhY2sgZW50cnkgdG8gdGhlIGN1cnJlbnQgUHJvbWlzZSwgYW5kIHNjaGVkdWxlcyBjYWxsYmFja1xuICogZXhlY3V0aW9uIGlmIHRoZSBQcm9taXNlIGhhcyBhbHJlYWR5IGJlZW4gcmVzb2x2ZWQuXG4gKlxuICogQHBhcmFtIHtDYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV99IGNhbGxiYWNrRW50cnkgUmVjb3JkIGNvbnRhaW5pbmdcbiAqICAgICB7QGNvZGUgb25GdWxmaWxsZWR9IGFuZCB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2tzIHRvIGV4ZWN1dGUgYWZ0ZXJcbiAqICAgICB0aGUgUHJvbWlzZSBpcyByZXNvbHZlZC5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuYWRkQ2FsbGJhY2tFbnRyeV8gPSBmdW5jdGlvbihjYWxsYmFja0VudHJ5KSB7XG4gIGlmICgoIXRoaXMuY2FsbGJhY2tFbnRyaWVzXyB8fCAhdGhpcy5jYWxsYmFja0VudHJpZXNfLmxlbmd0aCkgJiZcbiAgICAodGhpcy5zdGF0ZV8gPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uRlVMRklMTEVEIHx8XG4gICAgdGhpcy5zdGF0ZV8gPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQpKSB7XG4gICAgdGhpcy5zY2hlZHVsZUNhbGxiYWNrc18oKTtcbiAgfVxuICBpZiAoIXRoaXMuY2FsbGJhY2tFbnRyaWVzXykge1xuICAgIHRoaXMuY2FsbGJhY2tFbnRyaWVzXyA9IFtdO1xuICB9XG4gIHRoaXMuY2FsbGJhY2tFbnRyaWVzXy5wdXNoKGNhbGxiYWNrRW50cnkpO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYSBjaGlsZCBQcm9taXNlIGFuZCBhZGRzIGl0IHRvIHRoZSBjYWxsYmFjayBlbnRyeSBsaXN0LiBUaGUgcmVzdWx0IG9mXG4gKiB0aGUgY2hpbGQgUHJvbWlzZSBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBzdGF0ZSBvZiB0aGUgcGFyZW50IFByb21pc2UgYW5kIHRoZVxuICogcmVzdWx0IG9mIHRoZSB7QGNvZGUgb25GdWxmaWxsZWR9IG9yIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFja3MgYXNcbiAqIHNwZWNpZmllZCBpbiB0aGUgUHJvbWlzZSByZXNvbHV0aW9uIHByb2NlZHVyZS5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9wcm9taXNlc2FwbHVzLmNvbS8jdGhlX19tZXRob2RcbiAqXG4gKiBAcGFyYW0gez9mdW5jdGlvbih0aGlzOlRISVMsIFRZUEUpOlxuICogICAgICAgICAgKFJFU1VMVHxDYW5jZWxsYWJsZVByb21pc2UuPFJFU1VMVD58VGhlbmFibGUpfSBvbkZ1bGZpbGxlZCBBIGNhbGxiYWNrIHRoYXRcbiAqICAgICB3aWxsIGJlIGludm9rZWQgaWYgdGhlIFByb21pc2UgaXMgZnVsbGZpbGxlZCwgb3IgbnVsbC5cbiAqIEBwYXJhbSB7P2Z1bmN0aW9uKHRoaXM6VEhJUywgKik6ICp9IG9uUmVqZWN0ZWQgQSBjYWxsYmFjayB0aGF0IHdpbGwgYmVcbiAqICAgICBpbnZva2VkIGlmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBvciBudWxsLlxuICogQHBhcmFtIHtUSElTPX0gb3B0X2NvbnRleHQgQW4gb3B0aW9uYWwgZXhlY3V0aW9uIGNvbnRleHQgZm9yIHRoZSBjYWxsYmFja3MuXG4gKiAgICAgaW4gdGhlIGRlZmF1bHQgY2FsbGluZyBjb250ZXh0LlxuICogQHJldHVybiB7IUNhbmNlbGxhYmxlUHJvbWlzZX0gVGhlIGNoaWxkIFByb21pc2UuXG4gKiBAdGVtcGxhdGUgUkVTVUxULFRISVNcbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUuYWRkQ2hpbGRQcm9taXNlXyA9IGZ1bmN0aW9uKFxub25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9wdF9jb250ZXh0KSB7XG5cbiAgdmFyIGNhbGxiYWNrRW50cnkgPSB7XG4gICAgY2hpbGQ6IG51bGwsXG4gICAgb25GdWxmaWxsZWQ6IG51bGwsXG4gICAgb25SZWplY3RlZDogbnVsbFxuICB9O1xuXG4gIGNhbGxiYWNrRW50cnkuY2hpbGQgPSBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIC8vIEludm9rZSBvbkZ1bGZpbGxlZCwgb3IgcmVzb2x2ZSB3aXRoIHRoZSBwYXJlbnQncyB2YWx1ZSBpZiBhYnNlbnQuXG4gICAgY2FsbGJhY2tFbnRyeS5vbkZ1bGZpbGxlZCA9IG9uRnVsZmlsbGVkID8gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBvbkZ1bGZpbGxlZC5jYWxsKG9wdF9jb250ZXh0LCB2YWx1ZSk7XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgIH1cbiAgICB9IDogcmVzb2x2ZTtcblxuICAgIC8vIEludm9rZSBvblJlamVjdGVkLCBvciByZWplY3Qgd2l0aCB0aGUgcGFyZW50J3MgcmVhc29uIGlmIGFic2VudC5cbiAgICBjYWxsYmFja0VudHJ5Lm9uUmVqZWN0ZWQgPSBvblJlamVjdGVkID8gZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gb25SZWplY3RlZC5jYWxsKG9wdF9jb250ZXh0LCByZWFzb24pO1xuICAgICAgICBpZiAoIWlzRGVmKHJlc3VsdCkgJiYgcmVhc29uLklTX0NBTkNFTExBVElPTl9FUlJPUikge1xuICAgICAgICAgIC8vIFByb3BhZ2F0ZSBjYW5jZWxsYXRpb24gdG8gY2hpbGRyZW4gaWYgbm8gb3RoZXIgcmVzdWx0IGlzIHJldHVybmVkLlxuICAgICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfVxuICAgIH0gOiByZWplY3Q7XG4gIH0pO1xuXG4gIGNhbGxiYWNrRW50cnkuY2hpbGQucGFyZW50XyA9IHRoaXM7XG4gIHRoaXMuYWRkQ2FsbGJhY2tFbnRyeV8oXG4gICAgLyoqIEB0eXBlIHtDYW5jZWxsYWJsZVByb21pc2UuQ2FsbGJhY2tFbnRyeV99ICovIChjYWxsYmFja0VudHJ5KSk7XG4gIHJldHVybiBjYWxsYmFja0VudHJ5LmNoaWxkO1xufTtcblxuXG4vKipcbiAqIFVuYmxvY2tzIHRoZSBQcm9taXNlIGFuZCBmdWxmaWxscyBpdCB3aXRoIHRoZSBnaXZlbiB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge1RZUEV9IHZhbHVlXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnVuYmxvY2tBbmRGdWxmaWxsXyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGlmICh0aGlzLnN0YXRlXyAhPT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5CTE9DS0VEKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5jZWxsYWJsZVByb21pc2UgaXMgbm90IGJsb2NrZWQuJyk7XG4gIH1cbiAgdGhpcy5zdGF0ZV8gPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkc7XG4gIHRoaXMucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5GVUxGSUxMRUQsIHZhbHVlKTtcbn07XG5cblxuLyoqXG4gKiBVbmJsb2NrcyB0aGUgUHJvbWlzZSBhbmQgcmVqZWN0cyBpdCB3aXRoIHRoZSBnaXZlbiByZWplY3Rpb24gcmVhc29uLlxuICpcbiAqIEBwYXJhbSB7Kn0gcmVhc29uXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnVuYmxvY2tBbmRSZWplY3RfID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gIGlmICh0aGlzLnN0YXRlXyAhPT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5CTE9DS0VEKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5jZWxsYWJsZVByb21pc2UgaXMgbm90IGJsb2NrZWQuJyk7XG4gIH1cbiAgdGhpcy5zdGF0ZV8gPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlBFTkRJTkc7XG4gIHRoaXMucmVzb2x2ZV8oQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5SRUpFQ1RFRCwgcmVhc29uKTtcbn07XG5cblxuLyoqXG4gKiBBdHRlbXB0cyB0byByZXNvbHZlIGEgUHJvbWlzZSB3aXRoIGEgZ2l2ZW4gcmVzb2x1dGlvbiBzdGF0ZSBhbmQgdmFsdWUuIFRoaXNcbiAqIGlzIGEgbm8tb3AgaWYgdGhlIGdpdmVuIFByb21pc2UgaGFzIGFscmVhZHkgYmVlbiByZXNvbHZlZC5cbiAqXG4gKiBJZiB0aGUgZ2l2ZW4gcmVzdWx0IGlzIGEgVGhlbmFibGUgKHN1Y2ggYXMgYW5vdGhlciBQcm9taXNlKSwgdGhlIFByb21pc2Ugd2lsbFxuICogYmUgcmVzb2x2ZWQgd2l0aCB0aGUgc2FtZSBzdGF0ZSBhbmQgcmVzdWx0IGFzIHRoZSBUaGVuYWJsZSBvbmNlIGl0IGlzIGl0c2VsZlxuICogcmVzb2x2ZWQuXG4gKlxuICogSWYgdGhlIGdpdmVuIHJlc3VsdCBpcyBub3QgYSBUaGVuYWJsZSwgdGhlIFByb21pc2Ugd2lsbCBiZSBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkIHdpdGggdGhhdCByZXN1bHQgYmFzZWQgb24gdGhlIGdpdmVuIHN0YXRlLlxuICpcbiAqIEBzZWUgaHR0cDovL3Byb21pc2VzYXBsdXMuY29tLyN0aGVfcHJvbWlzZV9yZXNvbHV0aW9uX3Byb2NlZHVyZVxuICpcbiAqIEBwYXJhbSB7Q2FuY2VsbGFibGVQcm9taXNlLlN0YXRlX30gc3RhdGVcbiAqIEBwYXJhbSB7Kn0geCBUaGUgcmVzdWx0IHRvIGFwcGx5IHRvIHRoZSBQcm9taXNlLlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5yZXNvbHZlXyA9IGZ1bmN0aW9uKHN0YXRlLCB4KSB7XG4gIGlmICh0aGlzLnN0YXRlXyAhPT0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5QRU5ESU5HKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHRoaXMgPT09IHgpIHtcbiAgICBzdGF0ZSA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQ7XG4gICAgeCA9IG5ldyBUeXBlRXJyb3IoJ0NhbmNlbGxhYmxlUHJvbWlzZSBjYW5ub3QgcmVzb2x2ZSB0byBpdHNlbGYnKTtcblxuICB9IGVsc2UgaWYgKFRoZW5hYmxlLmlzSW1wbGVtZW50ZWRCeSh4KSkge1xuICAgIHggPSAvKiogQHR5cGUgeyFUaGVuYWJsZX0gKi8gKHgpO1xuICAgIHRoaXMuc3RhdGVfID0gQ2FuY2VsbGFibGVQcm9taXNlLlN0YXRlXy5CTE9DS0VEO1xuICAgIHgudGhlbih0aGlzLnVuYmxvY2tBbmRGdWxmaWxsXywgdGhpcy51bmJsb2NrQW5kUmVqZWN0XywgdGhpcyk7XG4gICAgcmV0dXJuO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoeCkpIHtcbiAgICB0cnkge1xuICAgICAgdmFyIHRoZW4gPSB4LnRoZW47XG4gICAgICBpZiAoaXNGdW5jdGlvbih0aGVuKSkge1xuICAgICAgICB0aGlzLnRyeVRoZW5fKHgsIHRoZW4pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc3RhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLlJFSkVDVEVEO1xuICAgICAgeCA9IGU7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5yZXN1bHRfID0geDtcbiAgdGhpcy5zdGF0ZV8gPSBzdGF0ZTtcbiAgdGhpcy5zY2hlZHVsZUNhbGxiYWNrc18oKTtcblxuICBpZiAoc3RhdGUgPT09IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uUkVKRUNURUQgJiYgIXguSVNfQ0FOQ0VMTEFUSU9OX0VSUk9SKSB7XG4gICAgQ2FuY2VsbGFibGVQcm9taXNlLmFkZFVuaGFuZGxlZFJlamVjdGlvbl8odGhpcywgeCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBBdHRlbXB0cyB0byBjYWxsIHRoZSB7QGNvZGUgdGhlbn0gbWV0aG9kIG9uIGFuIG9iamVjdCBpbiB0aGUgaG9wZXMgdGhhdCBpdCBpc1xuICogYSBQcm9taXNlLWNvbXBhdGlibGUgaW5zdGFuY2UuIFRoaXMgYWxsb3dzIGludGVyb3BlcmF0aW9uIGJldHdlZW4gZGlmZmVyZW50XG4gKiBQcm9taXNlIGltcGxlbWVudGF0aW9ucywgaG93ZXZlciBhIG5vbi1jb21wbGlhbnQgb2JqZWN0IG1heSBjYXVzZSBhIFByb21pc2VcbiAqIHRvIGhhbmcgaW5kZWZpbml0ZWx5LiBJZiB0aGUge0Bjb2RlIHRoZW59IG1ldGhvZCB0aHJvd3MgYW4gZXhjZXB0aW9uLCB0aGVcbiAqIGRlcGVuZGVudCBQcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgdGhyb3duIHZhbHVlLlxuICpcbiAqIEBzZWUgaHR0cDovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC03MFxuICpcbiAqIEBwYXJhbSB7VGhlbmFibGV9IHRoZW5hYmxlIEFuIG9iamVjdCB3aXRoIGEge0Bjb2RlIHRoZW59IG1ldGhvZCB0aGF0IG1heSBiZVxuICogICAgIGNvbXBhdGlibGUgd2l0aCB0aGUgUHJvbWlzZS9BKyBzcGVjaWZpY2F0aW9uLlxuICogQHBhcmFtIHshRnVuY3Rpb259IHRoZW4gVGhlIHtAY29kZSB0aGVufSBtZXRob2Qgb2YgdGhlIFRoZW5hYmxlIG9iamVjdC5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5wcm90b3R5cGUudHJ5VGhlbl8gPSBmdW5jdGlvbih0aGVuYWJsZSwgdGhlbikge1xuICB0aGlzLnN0YXRlXyA9IENhbmNlbGxhYmxlUHJvbWlzZS5TdGF0ZV8uQkxPQ0tFRDtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG5cbiAgdmFyIHJlc29sdmUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgcHJvbWlzZS51bmJsb2NrQW5kRnVsZmlsbF8odmFsdWUpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgcmVqZWN0ID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICBwcm9taXNlLnVuYmxvY2tBbmRSZWplY3RfKHJlYXNvbik7XG4gICAgfVxuICB9O1xuXG4gIHRyeSB7XG4gICAgdGhlbi5jYWxsKHRoZW5hYmxlLCByZXNvbHZlLCByZWplY3QpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmVqZWN0KGUpO1xuICB9XG59O1xuXG5cbi8qKlxuICogRXhlY3V0ZXMgdGhlIHBlbmRpbmcgY2FsbGJhY2tzIG9mIGEgcmVzb2x2ZWQgUHJvbWlzZSBhZnRlciBhIHRpbWVvdXQuXG4gKlxuICogU2VjdGlvbiAyLjIuNCBvZiB0aGUgUHJvbWlzZXMvQSsgc3BlY2lmaWNhdGlvbiByZXF1aXJlcyB0aGF0IFByb21pc2VcbiAqIGNhbGxiYWNrcyBtdXN0IG9ubHkgYmUgaW52b2tlZCBmcm9tIGEgY2FsbCBzdGFjayB0aGF0IG9ubHkgY29udGFpbnMgUHJvbWlzZVxuICogaW1wbGVtZW50YXRpb24gY29kZSwgd2hpY2ggd2UgYWNjb21wbGlzaCBieSBpbnZva2luZyBjYWxsYmFjayBleGVjdXRpb24gYWZ0ZXJcbiAqIGEgdGltZW91dC4gSWYge0Bjb2RlIHN0YXJ0RXhlY3V0aW9uX30gaXMgY2FsbGVkIG11bHRpcGxlIHRpbWVzIGZvciB0aGUgc2FtZVxuICogUHJvbWlzZSwgdGhlIGNhbGxiYWNrIGNoYWluIHdpbGwgYmUgZXZhbHVhdGVkIG9ubHkgb25jZS4gQWRkaXRpb25hbCBjYWxsYmFja3NcbiAqIG1heSBiZSBhZGRlZCBkdXJpbmcgdGhlIGV2YWx1YXRpb24gcGhhc2UsIGFuZCB3aWxsIGJlIGV4ZWN1dGVkIGluIHRoZSBzYW1lXG4gKiBldmVudCBsb29wLlxuICpcbiAqIEFsbCBQcm9taXNlcyBhZGRlZCB0byB0aGUgd2FpdGluZyBsaXN0IGR1cmluZyB0aGUgc2FtZSBicm93c2VyIGV2ZW50IGxvb3BcbiAqIHdpbGwgYmUgZXhlY3V0ZWQgaW4gb25lIGJhdGNoIHRvIGF2b2lkIHVzaW5nIGEgc2VwYXJhdGUgdGltZW91dCBwZXIgUHJvbWlzZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLnNjaGVkdWxlQ2FsbGJhY2tzXyA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuZXhlY3V0aW5nXykge1xuICAgIHRoaXMuZXhlY3V0aW5nXyA9IHRydWU7XG4gICAgYXN5bmMucnVuKHRoaXMuZXhlY3V0ZUNhbGxiYWNrc18sIHRoaXMpO1xuICB9XG59O1xuXG5cbi8qKlxuICogRXhlY3V0ZXMgYWxsIHBlbmRpbmcgY2FsbGJhY2tzIGZvciB0aGlzIFByb21pc2UuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5leGVjdXRlQ2FsbGJhY2tzXyA9IGZ1bmN0aW9uKCkge1xuICB3aGlsZSAodGhpcy5jYWxsYmFja0VudHJpZXNfICYmIHRoaXMuY2FsbGJhY2tFbnRyaWVzXy5sZW5ndGgpIHtcbiAgICB2YXIgZW50cmllcyA9IHRoaXMuY2FsbGJhY2tFbnRyaWVzXztcbiAgICB0aGlzLmNhbGxiYWNrRW50cmllc18gPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5leGVjdXRlQ2FsbGJhY2tfKGVudHJpZXNbaV0sIHRoaXMuc3RhdGVfLCB0aGlzLnJlc3VsdF8pO1xuICAgIH1cbiAgfVxuICB0aGlzLmV4ZWN1dGluZ18gPSBmYWxzZTtcbn07XG5cblxuLyoqXG4gKiBFeGVjdXRlcyBhIHBlbmRpbmcgY2FsbGJhY2sgZm9yIHRoaXMgUHJvbWlzZS4gSW52b2tlcyBhbiB7QGNvZGUgb25GdWxmaWxsZWR9XG4gKiBvciB7QGNvZGUgb25SZWplY3RlZH0gY2FsbGJhY2sgYmFzZWQgb24gdGhlIHJlc29sdmVkIHN0YXRlIG9mIHRoZSBQcm9taXNlLlxuICpcbiAqIEBwYXJhbSB7IUNhbmNlbGxhYmxlUHJvbWlzZS5DYWxsYmFja0VudHJ5X30gY2FsbGJhY2tFbnRyeSBBbiBlbnRyeSBjb250YWluaW5nIHRoZVxuICogICAgIG9uRnVsZmlsbGVkIGFuZC9vciBvblJlamVjdGVkIGNhbGxiYWNrcyBmb3IgdGhpcyBzdGVwLlxuICogQHBhcmFtIHtDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVffSBzdGF0ZSBUaGUgcmVzb2x1dGlvbiBzdGF0dXMgb2YgdGhlIFByb21pc2UsXG4gKiAgICAgZWl0aGVyIEZVTEZJTExFRCBvciBSRUpFQ1RFRC5cbiAqIEBwYXJhbSB7Kn0gcmVzdWx0IFRoZSByZXNvbHZlZCByZXN1bHQgb2YgdGhlIFByb21pc2UuXG4gKiBAcHJpdmF0ZVxuICovXG5DYW5jZWxsYWJsZVByb21pc2UucHJvdG90eXBlLmV4ZWN1dGVDYWxsYmFja18gPSBmdW5jdGlvbihcbmNhbGxiYWNrRW50cnksIHN0YXRlLCByZXN1bHQpIHtcbiAgaWYgKHN0YXRlID09PSBDYW5jZWxsYWJsZVByb21pc2UuU3RhdGVfLkZVTEZJTExFRCkge1xuICAgIGNhbGxiYWNrRW50cnkub25GdWxmaWxsZWQocmVzdWx0KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnJlbW92ZVVuaGFuZGxlZFJlamVjdGlvbl8oKTtcbiAgICBjYWxsYmFja0VudHJ5Lm9uUmVqZWN0ZWQocmVzdWx0KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIE1hcmtzIHRoaXMgcmVqZWN0ZWQgUHJvbWlzZSBhcyBoYXZpbmcgYmVpbmcgaGFuZGxlZC4gQWxzbyBtYXJrcyBhbnkgcGFyZW50XG4gKiBQcm9taXNlcyBpbiB0aGUgcmVqZWN0ZWQgc3RhdGUgYXMgaGFuZGxlZC4gVGhlIHJlamVjdGlvbiBoYW5kbGVyIHdpbGwgbm9cbiAqIGxvbmdlciBiZSBpbnZva2VkIGZvciB0aGlzIFByb21pc2UgKGlmIGl0IGhhcyBub3QgYmVlbiBjYWxsZWQgYWxyZWFkeSkuXG4gKlxuICogQHByaXZhdGVcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLnByb3RvdHlwZS5yZW1vdmVVbmhhbmRsZWRSZWplY3Rpb25fID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwO1xuICBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPiAwKSB7XG4gICAgZm9yIChwID0gdGhpczsgcCAmJiBwLnVuaGFuZGxlZFJlamVjdGlvbklkXzsgcCA9IHAucGFyZW50Xykge1xuICAgICAgY2xlYXJUaW1lb3V0KHAudW5oYW5kbGVkUmVqZWN0aW9uSWRfKTtcbiAgICAgIHAudW5oYW5kbGVkUmVqZWN0aW9uSWRfID0gMDtcbiAgICB9XG4gIH0gZWxzZSBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPT09IDApIHtcbiAgICBmb3IgKHAgPSB0aGlzOyBwICYmIHAuaGFkVW5oYW5kbGVkUmVqZWN0aW9uXzsgcCA9IHAucGFyZW50Xykge1xuICAgICAgcC5oYWRVbmhhbmRsZWRSZWplY3Rpb25fID0gZmFsc2U7XG4gICAgfVxuICB9XG59O1xuXG5cbi8qKlxuICogTWFya3MgdGhpcyByZWplY3RlZCBQcm9taXNlIGFzIHVuaGFuZGxlZC4gSWYgbm8ge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrXG4gKiBpcyBjYWxsZWQgZm9yIHRoaXMgUHJvbWlzZSBiZWZvcmUgdGhlIHtAY29kZSBVTkhBTkRMRURfUkVKRUNUSU9OX0RFTEFZfVxuICogZXhwaXJlcywgdGhlIHJlYXNvbiB3aWxsIGJlIHBhc3NlZCB0byB0aGUgdW5oYW5kbGVkIHJlamVjdGlvbiBoYW5kbGVyLiBUaGVcbiAqIGhhbmRsZXIgdHlwaWNhbGx5IHJldGhyb3dzIHRoZSByZWplY3Rpb24gcmVhc29uIHNvIHRoYXQgaXQgYmVjb21lcyB2aXNpYmxlIGluXG4gKiB0aGUgZGV2ZWxvcGVyIGNvbnNvbGUuXG4gKlxuICogQHBhcmFtIHshQ2FuY2VsbGFibGVQcm9taXNlfSBwcm9taXNlIFRoZSByZWplY3RlZCBQcm9taXNlLlxuICogQHBhcmFtIHsqfSByZWFzb24gVGhlIFByb21pc2UgcmVqZWN0aW9uIHJlYXNvbi5cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5hZGRVbmhhbmRsZWRSZWplY3Rpb25fID0gZnVuY3Rpb24ocHJvbWlzZSwgcmVhc29uKSB7XG4gIGlmIChDYW5jZWxsYWJsZVByb21pc2UuVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSA+IDApIHtcbiAgICBwcm9taXNlLnVuaGFuZGxlZFJlamVjdGlvbklkXyA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBDYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXy5jYWxsKG51bGwsIHJlYXNvbik7XG4gICAgfSwgQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkpO1xuXG4gIH0gZWxzZSBpZiAoQ2FuY2VsbGFibGVQcm9taXNlLlVOSEFORExFRF9SRUpFQ1RJT05fREVMQVkgPT09IDApIHtcbiAgICBwcm9taXNlLmhhZFVuaGFuZGxlZFJlamVjdGlvbl8gPSB0cnVlO1xuICAgIGFzeW5jLnJ1bihmdW5jdGlvbigpIHtcbiAgICAgIGlmIChwcm9taXNlLmhhZFVuaGFuZGxlZFJlamVjdGlvbl8pIHtcbiAgICAgICAgQ2FuY2VsbGFibGVQcm9taXNlLmhhbmRsZVJlamVjdGlvbl8uY2FsbChudWxsLCByZWFzb24pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5cbi8qKlxuICogQSBtZXRob2QgdGhhdCBpcyBpbnZva2VkIHdpdGggdGhlIHJlamVjdGlvbiByZWFzb25zIGZvciBQcm9taXNlcyB0aGF0IGFyZVxuICogcmVqZWN0ZWQgYnV0IGhhdmUgbm8ge0Bjb2RlIG9uUmVqZWN0ZWR9IGNhbGxiYWNrcyByZWdpc3RlcmVkIHlldC5cbiAqIEB0eXBlIHtmdW5jdGlvbigqKX1cbiAqIEBwcml2YXRlXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5oYW5kbGVSZWplY3Rpb25fID0gYXN5bmMudGhyb3dFeGNlcHRpb247XG5cblxuLyoqXG4gKiBTZXRzIGEgaGFuZGxlciB0aGF0IHdpbGwgYmUgY2FsbGVkIHdpdGggcmVhc29ucyBmcm9tIHVuaGFuZGxlZCByZWplY3RlZFxuICogUHJvbWlzZXMuIElmIHRoZSByZWplY3RlZCBQcm9taXNlIChvciBvbmUgb2YgaXRzIGRlc2NlbmRhbnRzKSBoYXMgYW5cbiAqIHtAY29kZSBvblJlamVjdGVkfSBjYWxsYmFjayByZWdpc3RlcmVkLCB0aGUgcmVqZWN0aW9uIHdpbGwgYmUgY29uc2lkZXJlZFxuICogaGFuZGxlZCwgYW5kIHRoZSByZWplY3Rpb24gaGFuZGxlciB3aWxsIG5vdCBiZSBjYWxsZWQuXG4gKlxuICogQnkgZGVmYXVsdCwgdW5oYW5kbGVkIHJlamVjdGlvbnMgYXJlIHJldGhyb3duIHNvIHRoYXQgdGhlIGVycm9yIG1heSBiZVxuICogY2FwdHVyZWQgYnkgdGhlIGRldmVsb3BlciBjb25zb2xlIG9yIGEge0Bjb2RlIHdpbmRvdy5vbmVycm9yfSBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKil9IGhhbmRsZXIgQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdpdGggcmVhc29ucyBmcm9tXG4gKiAgICAgcmVqZWN0ZWQgUHJvbWlzZXMuIERlZmF1bHRzIHRvIHtAY29kZSBhc3luYy50aHJvd0V4Y2VwdGlvbn0uXG4gKi9cbkNhbmNlbGxhYmxlUHJvbWlzZS5zZXRVbmhhbmRsZWRSZWplY3Rpb25IYW5kbGVyID0gZnVuY3Rpb24oaGFuZGxlcikge1xuICBDYW5jZWxsYWJsZVByb21pc2UuaGFuZGxlUmVqZWN0aW9uXyA9IGhhbmRsZXI7XG59O1xuXG5cblxuLyoqXG4gKiBFcnJvciB1c2VkIGFzIGEgcmVqZWN0aW9uIHJlYXNvbiBmb3IgY2FuY2VsZWQgUHJvbWlzZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfbWVzc2FnZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyB7RXJyb3J9XG4gKiBAZmluYWxcbiAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG9wdF9tZXNzYWdlKSB7XG4gICAgIHN1cGVyKG9wdF9tZXNzYWdlKTtcblxuICAgICBpZiAob3B0X21lc3NhZ2UpIHtcbiAgICAgICB0aGlzLm1lc3NhZ2UgPSBvcHRfbWVzc2FnZTtcbiAgICAgfVxuICAgfVxufTtcblxuLyoqIEBvdmVycmlkZSAqL1xuQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yLnByb3RvdHlwZS5uYW1lID0gJ2NhbmNlbCc7XG5cbmV4cG9ydCB7Q2FuY2VsbGFibGVQcm9taXNlfTtcbmV4cG9ydCBkZWZhdWx0IENhbmNlbGxhYmxlUHJvbWlzZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gICogRGVib3VuY2VzIGZ1bmN0aW9uIGV4ZWN1dGlvbi5cbiAgKiBAcGFyYW0geyFmdW5jdGlvbigpfSBmblxuICAqIEBwYXJhbSB7bnVtYmVyfSBkZWxheVxuICAqIEByZXR1cm4geyFmdW5jdGlvbigpfVxuICAqL1xuZnVuY3Rpb24gZGVib3VuY2UoZm4sIGRlbGF5KSB7XG5cdHJldHVybiBmdW5jdGlvbiBkZWJvdW5jZWQoKSB7XG5cdFx0dmFyIGFyZ3MgPSBhcmd1bWVudHM7XG5cdFx0Y2FuY2VsRGVib3VuY2UoZGVib3VuY2VkKTtcblx0XHRkZWJvdW5jZWQuaWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0Zm4uYXBwbHkobnVsbCwgYXJncyk7XG5cdFx0fSwgZGVsYXkpO1xuXHR9O1xufVxuXG4vKipcbiAqIENhbmNlbHMgdGhlIHNjaGVkdWxlZCBkZWJvdW5jZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNhbmNlbERlYm91bmNlKGRlYm91bmNlZCkge1xuXHRjbGVhclRpbWVvdXQoZGVib3VuY2VkLmlkKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZGVib3VuY2U7XG5leHBvcnQgeyBjYW5jZWxEZWJvdW5jZSwgZGVib3VuY2UgfTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IGNvcmUgZnJvbSAnbWV0YWwnO1xuXG5jb25zdCBSRUdFWCA9IC8oW1xcL10pPyg/Oig/OlxcOihcXHcrKSg/OlxcKCgoPzpcXFxcLnxbXlxcXFwoKV0pKilcXCkpP3xcXCgoKD86XFxcXC58W15cXFxcKCldKSspXFwpKShbKyo/XSk/KS9nO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBhcnJheSBvZiByZWdleCBtYXRjaGVzIHRvIGEgbW9yZSByZWFkYWJsZSBvYmplY3QgZm9ybWF0LlxuICogQHBhcmFtIHshQXJyYXk8c3RyaW5nPn0gbWF0Y2hlc1xuICogQHJldHVybiB7IU9iamVjdH1cbiAqL1xuZnVuY3Rpb24gY29udmVydE1hdGNoZXNUb09iaihtYXRjaGVzKSB7XG5cdHJldHVybiB7XG5cdFx0bWF0Y2g6IG1hdGNoZXNbMF0sXG5cdFx0cHJlZml4OiBtYXRjaGVzWzFdLFxuXHRcdG5hbWU6IG1hdGNoZXNbMl0sXG5cdFx0cGFyYW1QYXR0ZXJuOiBtYXRjaGVzWzNdLFxuXHRcdHVubmFtZWRQYXR0ZXJuOiBtYXRjaGVzWzRdLFxuXHRcdG1vZGlmaWVyOiBtYXRjaGVzWzVdXG5cdH07XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIHRva2VucyBwYXJzZWQgZnJvbSBhIHJvdXRlIGZvcm1hdCBzdHJpbmcgdG8gYSByZWdleC5cbiAqIEBwYXJhbSB7IUFycmF5PHN0cmluZ3whT2JqZWN0Pn0gdG9rZW5zXG4gKiBAcmV0dXJuIHshUmVnRXhwfVxuICovXG5mdW5jdGlvbiBjb252ZXJ0VG9rZW5zVG9SZWdleCh0b2tlbnMpIHtcblx0bGV0IHJlZ2V4ID0gJyc7XG5cdGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKGNvcmUuaXNTdHJpbmcodG9rZW5zW2ldKSkge1xuXHRcdFx0cmVnZXggKz0gZXNjYXBlKHRva2Vuc1tpXSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxldCBjYXB0dXJlID0gZW5jbG9zZU5vbkNhcHR1cmluZ0dyb3VwKHRva2Vuc1tpXS5wYXR0ZXJuKTtcblx0XHRcdGlmICh0b2tlbnNbaV0ucmVwZWF0KSB7XG5cdFx0XHRcdGNhcHR1cmUgKz0gZW5jbG9zZU5vbkNhcHR1cmluZ0dyb3VwKCdcXFxcLycgKyBjYXB0dXJlKSArICcqJztcblx0XHRcdH1cblx0XHRcdGNhcHR1cmUgPSBlc2NhcGUodG9rZW5zW2ldLnByZWZpeCkgKyBgKCR7Y2FwdHVyZX0pYDtcblx0XHRcdGlmICh0b2tlbnNbaV0ub3B0aW9uYWwpIHtcblx0XHRcdFx0aWYgKCF0b2tlbnNbaV0ucGFydGlhbCkge1xuXHRcdFx0XHRcdGNhcHR1cmUgPSBlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAoY2FwdHVyZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y2FwdHVyZSArPSAnPyc7XG5cdFx0XHR9XG5cdFx0XHRyZWdleCArPSBjYXB0dXJlO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbmV3IFJlZ0V4cCgnXicgKyBtYWtlVHJhaWxpbmdTbGFzaE9wdGlvbmFsKHJlZ2V4KSArICckJyk7XG59XG5cbi8qKlxuICogRW5jbG9zZXMgdGhlIGdpdmVuIHJlZ2V4IHBhdHRlcm4gaW50byBhIG5vbiBjYXB0dXJpbmcgZ3JvdXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0dGVyblxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAocGF0dGVybikge1xuXHRyZXR1cm4gYCg/OiR7cGF0dGVybn0pYDtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHRoZSBnaXZlbiBzdHJpbmcgdG8gc2hvdyB1cCBpbiB0aGUgcGF0aCByZWdleC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZXNjYXBlKHN0cikge1xuXHRyZXR1cm4gc3RyLnJlcGxhY2UoLyhbLisqPz1eIToke30oKVtcXF18XFwvXFxcXF0pL2csICdcXFxcJDEnKTtcbn1cblxuLyoqXG4gKiBNYWtlcyB0cmFpbGluZyBzbGFzaCBvcHRpb25hbCBvbiBwYXRocy5cbiAqIEBwYXJhbSB7c3RyaW5nfSByZWdleFxuICogQHBhcmFtIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIG1ha2VUcmFpbGluZ1NsYXNoT3B0aW9uYWwocmVnZXgpIHtcblx0aWYgKC9cXC8kLy50ZXN0KHJlZ2V4KSkge1xuXHRcdHJlZ2V4ICs9ICc/Jztcblx0fSBlbHNlIHtcblx0XHRyZWdleCArPSAnXFxcXC8/Jztcblx0fVxuXHRyZXR1cm4gcmVnZXg7XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBnaXZlbiByb3V0ZSBmb3JtYXQgc3RyaW5nIGludG8gdG9rZW5zIHJlcHJlc2VudGluZyBpdHMgY29udGVudHMuXG4gKiBAcGFyYW0geyFBcnJheXxzdHJpbmd9IHJvdXRlT3JUb2tlbnMgRWl0aGVyIGEgcm91dGUgZm9ybWF0IHN0cmluZyBvciB0b2tlbnNcbiAqICAgICBwcmV2aW91c2x5IHBhcnNlZCB2aWEgdGhlIGBwYXJzZWAgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHshQXJyYXk8c3RyaW5nfCFPYmplY3Q+fSBBbiBhcnJheSBvZiB0b2tlbnMgdGhhdCBjYW4gYmUgZWl0aGVyIHBsYWluXG4gKiAgICAgc3RyaW5ncyAocGFydCBvZiB0aGUgcm91dGUpIG9yIG9iamVjdHMgY29udGFpbmluZyBpbmZvcm1hdGlvbnMgb24gcGFyYW1zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2Uocm91dGVPclRva2Vucykge1xuXHRpZiAoIWNvcmUuaXNTdHJpbmcocm91dGVPclRva2VucykpIHtcblx0XHRyZXR1cm4gcm91dGVPclRva2Vucztcblx0fVxuXG5cdGNvbnN0IHJvdXRlID0gcm91dGVPclRva2Vucztcblx0bGV0IHVubmFtZWRDb3VudCA9IDA7XG5cdGNvbnN0IHRva2VucyA9IFtdO1xuXHRsZXQgY3VyclBhdGggPSAnJztcblx0bGV0IGluZGV4ID0gMDtcblxuXHRsZXQgbWF0Y2hlcyA9IFJFR0VYLmV4ZWMocm91dGUpO1xuXHR3aGlsZSAobWF0Y2hlcykge1xuXHRcdGNvbnN0IGRhdGEgPSBjb252ZXJ0TWF0Y2hlc1RvT2JqKG1hdGNoZXMpO1xuXG5cdFx0Y3VyclBhdGggPSByb3V0ZS5zbGljZShpbmRleCwgbWF0Y2hlcy5pbmRleCk7XG5cdFx0aW5kZXggPSBtYXRjaGVzLmluZGV4ICsgZGF0YS5tYXRjaC5sZW5ndGg7XG5cdFx0dG9rZW5zLnB1c2goY3VyclBhdGgpO1xuXG5cdFx0dG9rZW5zLnB1c2goe1xuXHRcdFx0bmFtZTogZGF0YS5uYW1lID8gZGF0YS5uYW1lIDogJycgKyB1bm5hbWVkQ291bnQrKyxcblx0XHRcdHBhcnRpYWw6IHJvdXRlW2luZGV4XSAmJiByb3V0ZVtpbmRleF0gIT09IGRhdGEucHJlZml4LFxuXHRcdFx0cHJlZml4OiBkYXRhLnByZWZpeCB8fCAnJyxcblx0XHRcdHBhdHRlcm46IGRhdGEucGFyYW1QYXR0ZXJuIHx8IGRhdGEudW5uYW1lZFBhdHRlcm4gfHwgJ1teXFxcXC9dKycsXG5cdFx0XHRyZXBlYXQ6IGRhdGEubW9kaWZpZXIgPT09ICcqJyB8fCBkYXRhLm1vZGlmaWVyID09PSAnKycsXG5cdFx0XHRvcHRpb25hbDogZGF0YS5tb2RpZmllciA9PT0gJyonIHx8IGRhdGEubW9kaWZpZXIgPT09ICc/J1xuXHRcdH0pO1xuXG5cdFx0bWF0Y2hlcyA9IFJFR0VYLmV4ZWMocm91dGUpO1xuXHR9XG5cblx0aWYgKGluZGV4IDwgcm91dGUubGVuZ3RoKSB7XG5cdFx0dG9rZW5zLnB1c2gocm91dGUuc3Vic3RyKGluZGV4KSk7XG5cdH1cblx0cmV0dXJuIHRva2Vucztcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gcm91dGUgZm9ybWF0IHN0cmluZyB0byBhIHJlZ2V4IHRoYXQgY2FuIGV4dHJhY3QgcGFyYW1cbiAqIGRhdGEgZnJvbSBwYXRocyBtYXRjaGluZyBpdC5cbiAqIEBwYXJhbSB7IUFycmF5fHN0cmluZ30gcm91dGVPclRva2VucyBFaXRoZXIgYSByb3V0ZSBmb3JtYXQgc3RyaW5nIG9yIHRva2Vuc1xuICogICAgIHByZXZpb3VzbHkgcGFyc2VkIHZpYSB0aGUgYHBhcnNlYCBmdW5jdGlvbi5cbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1JlZ2V4KHJvdXRlT3JUb2tlbnMpIHtcblx0cmV0dXJuIGNvbnZlcnRUb2tlbnNUb1JlZ2V4KHBhcnNlKHJvdXRlT3JUb2tlbnMpKTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0cyBkYXRhIGZyb20gdGhlIGdpdmVuIHBhdGggYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgcm91dGUgZm9ybWF0LlxuICogQHBhcmFtIHshQXJyYXl8c3RyaW5nfSByb3V0ZU9yVG9rZW5zIEVpdGhlciBhIHJvdXRlIGZvcm1hdCBzdHJpbmcgb3IgdG9rZW5zXG4gKiAgICAgcHJldmlvdXNseSBwYXJzZWQgdmlhIHRoZSBgcGFyc2VgIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IFRoZSBwYXRoIHRvIGV4dHJhY3QgcGFyYW0gZGF0YSBmcm9tLlxuICogQHJldHVybiB7T2JqZWN0PHN0cmluZywgc3RyaW5nPn0gVGhlIGRhdGEgb2JqZWN0LCBvciBudWxsIGlmIHRoZSBwYXRoIGRvZXNuJ3RcbiAqICAgICBtYXRjaCB0aGUgZ2l2ZW4gZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdERhdGEocm91dGVPclRva2VucywgcGF0aCkge1xuXHRjb25zdCBkYXRhID0ge307XG5cdGNvbnN0IHRva2VucyA9IHBhcnNlKHJvdXRlT3JUb2tlbnMpO1xuXHRjb25zdCBtYXRjaCA9IHBhdGgubWF0Y2goY29udmVydFRva2Vuc1RvUmVnZXgodG9rZW5zKSk7XG5cblx0aWYgKCFtYXRjaCkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0bGV0IHBhcmFtSW5kZXggPSAxO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuXHRcdGlmICghY29yZS5pc1N0cmluZyh0b2tlbnNbaV0pKSB7XG5cdFx0XHRsZXQgdmFsdWUgPSBtYXRjaFtwYXJhbUluZGV4KytdO1xuXHRcdFx0aWYgKGNvcmUuaXNEZWYodmFsdWUpKSB7XG5cdFx0XHRcdGlmICh0b2tlbnNbaV0ucmVwZWF0KSB7XG5cdFx0XHRcdFx0dmFsdWUgPSB2YWx1ZS5zcGxpdCgnLycpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRhdGFbdG9rZW5zW2ldLm5hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiBkYXRhO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0RlZkFuZE5vdE51bGwsIGlzRnVuY3Rpb24sIGlzU3RyaW5nIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgZXh0cmFjdERhdGEsIHBhcnNlLCB0b1JlZ2V4IH0gZnJvbSAnbWV0YWwtcGF0aC1wYXJzZXInO1xuXG5jbGFzcyBSb3V0ZSB7XG5cblx0LyoqXG5cdCAqIFJvdXRlIGNsYXNzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd8UmVnRXhwfEZ1bmN0aW9ufSBwYXRoXG5cdCAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBoYW5kbGVyXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IocGF0aCwgaGFuZGxlcikge1xuXHRcdGlmICghaXNEZWZBbmROb3ROdWxsKHBhdGgpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1JvdXRlIHBhdGggbm90IHNwZWNpZmllZC4nKTtcblx0XHR9XG5cdFx0aWYgKCFpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1JvdXRlIGhhbmRsZXIgaXMgbm90IGEgZnVuY3Rpb24uJyk7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogRGVmaW5lcyB0aGUgaGFuZGxlciB3aGljaCB3aWxsIGV4ZWN1dGUgb25jZSBhIFVSTCBpbiB0aGUgYXBwbGljYXRpb25cblx0XHQgKiBtYXRjaGVzIHRoZSBwYXRoLlxuXHRcdCAqIEB0eXBlIHshRnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG5cblx0XHQvKipcblx0XHQgKiBEZWZpbmVzIHRoZSBwYXRoIHdoaWNoIHdpbGwgdHJpZ2dlciB0aGUgcm91dGUgaGFuZGxlci5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ3xSZWdFeHB8RnVuY3Rpb259XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucGF0aCA9IHBhdGg7XG5cdH1cblxuXHQvKipcblx0KiBCdWlsZHMgcGFyc2VkIGRhdGEgKHJlZ2V4IGFuZCB0b2tlbnMpIGZvciB0aGlzIHJvdXRlLlxuXHQqIEByZXR1cm4geyFPYmplY3R9XG5cdCogQHByb3RlY3RlZFxuXHQqL1xuXHRidWlsZFBhcnNlZERhdGFfKCkge1xuXHRcdGlmICghdGhpcy5wYXJzZWREYXRhXykge1xuXHRcdFx0dmFyIHRva2VucyA9IHBhcnNlKHRoaXMucGF0aCk7XG5cdFx0XHR2YXIgcmVnZXggPSB0b1JlZ2V4KHRva2Vucyk7XG5cdFx0XHR0aGlzLnBhcnNlZERhdGFfID0ge1xuXHRcdFx0XHRyZWdleCxcblx0XHRcdFx0dG9rZW5zXG5cdFx0XHR9O1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5wYXJzZWREYXRhXztcblx0fVxuXG5cdC8qKlxuXHQgKiBFeHRyYWN0cyBwYXJhbSBkYXRhIGZyb20gdGhlIGdpdmVuIHBhdGgsIGFjY29yZGluZyB0byB0aGlzIHJvdXRlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgdXJsIHBhdGggdG8gZXh0cmFjdCBwYXJhbXMgZnJvbS5cblx0ICogQHJldHVybiB7T2JqZWN0fSBUaGUgZXh0cmFjdGVkIGRhdGEsIGlmIHRoZSBwYXRoIG1hdGNoZXMgdGhpcyByb3V0ZSwgb3Jcblx0ICogICAgIG51bGwgb3RoZXJ3aXNlLlxuXHQgKi9cblx0ZXh0cmFjdFBhcmFtcyhwYXRoKSB7XG5cdFx0aWYgKGlzU3RyaW5nKHRoaXMucGF0aCkpIHtcblx0XHRcdHJldHVybiBleHRyYWN0RGF0YSh0aGlzLmJ1aWxkUGFyc2VkRGF0YV8oKS50b2tlbnMsIHBhdGgpO1xuXHRcdH1cblx0XHRyZXR1cm4ge307XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcm91dGUgaGFuZGxlci5cblx0ICogQHJldHVybiB7IUZ1bmN0aW9ufVxuXHQgKi9cblx0Z2V0SGFuZGxlcigpIHtcblx0XHRyZXR1cm4gdGhpcy5oYW5kbGVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHJvdXRlIHBhdGguXG5cdCAqIEByZXR1cm4geyFzdHJpbmd8UmVnRXhwfEZ1bmN0aW9ufVxuXHQgKi9cblx0Z2V0UGF0aCgpIHtcblx0XHRyZXR1cm4gdGhpcy5wYXRoO1xuXHR9XG5cblx0LyoqXG4gXHQgKiBNYXRjaGVzIGlmIHRoZSByb3V0ZXIgY2FuIGhhbmRsZSB0aGUgdGVzdGVkIHBhdGguXG4gXHQgKiBAcGFyYW0geyFzdHJpbmd9IHZhbHVlIFBhdGggdG8gdGVzdCAobWF5IGNvbnRhaW4gdGhlIHF1ZXJ5c3RyaW5nIHBhcnQpLlxuXHQgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgbWF0Y2hlcyBhbnkgcm91dGUuXG5cdCAqL1xuXHRtYXRjaGVzUGF0aCh2YWx1ZSkge1xuXHRcdHZhciBwYXRoID0gdGhpcy5wYXRoO1xuXG5cdFx0aWYgKGlzRnVuY3Rpb24ocGF0aCkpIHtcblx0XHRcdHJldHVybiBwYXRoKHZhbHVlKTtcblx0XHR9XG5cdFx0aWYgKGlzU3RyaW5nKHBhdGgpKSB7XG5cdFx0XHRwYXRoID0gdGhpcy5idWlsZFBhcnNlZERhdGFfKCkucmVnZXg7XG5cdFx0fVxuXHRcdGlmIChwYXRoIGluc3RhbmNlb2YgUmVnRXhwKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWUuc2VhcmNoKHBhdGgpID4gLTE7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgUm91dGU7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IERpc3Bvc2FibGUgfSBmcm9tICdtZXRhbCc7XG5cbmNsYXNzIENhY2hlYWJsZSBleHRlbmRzIERpc3Bvc2FibGUge1xuXG5cdC8qKlxuXHQgKiBBYnN0cmFjdCBjbGFzcyBmb3IgZGVmaW5pbmcgY2FjaGVhYmxlIGJlaGF2aW9yLlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgY2FjaGVkIGRhdGEuXG5cdFx0ICogQHR5cGUgeyFPYmplY3R9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmNhY2hlID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHdoZXRoZXIgY2xhc3MgaXMgY2FjaGVhYmxlLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBkZWZhdWx0IGZhbHNlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuY2FjaGVhYmxlID0gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBjb250ZW50IHRvIHRoZSBjYWNoZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnQgQ29udGVudCB0byBiZSBjYWNoZWQuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZENhY2hlKGNvbnRlbnQpIHtcblx0XHRpZiAodGhpcy5jYWNoZWFibGUpIHtcblx0XHRcdHRoaXMuY2FjaGUgPSBjb250ZW50O1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDbGVhcnMgdGhlIGNhY2hlLlxuXHQgKiBAY2hhaW5hYmxlXG5cdCAqL1xuXHRjbGVhckNhY2hlKCkge1xuXHRcdHRoaXMuY2FjaGUgPSBudWxsO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0dGhpcy5jbGVhckNhY2hlKCk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgY2FjaGVkIGNvbnRlbnQuXG5cdCAqIEByZXR1cm4ge09iamVjdH0gQ2FjaGVkIGNvbnRlbnQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGdldENhY2hlKCkge1xuXHRcdHJldHVybiB0aGlzLmNhY2hlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdoZXRoZXIgdGhlIGNsYXNzIGlzIGNhY2hlYWJsZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIHdoZW4gY2xhc3MgaXMgY2FjaGVhYmxlLCBmYWxzZSBvdGhlcndpc2UuXG5cdCAqL1xuXHRpc0NhY2hlYWJsZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5jYWNoZWFibGU7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB3aGV0aGVyIHRoZSBjbGFzcyBpcyBjYWNoZWFibGUuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gY2FjaGVhYmxlXG5cdCAqL1xuXHRzZXRDYWNoZWFibGUoY2FjaGVhYmxlKSB7XG5cdFx0aWYgKCFjYWNoZWFibGUpIHtcblx0XHRcdHRoaXMuY2xlYXJDYWNoZSgpO1xuXHRcdH1cblx0XHR0aGlzLmNhY2hlYWJsZSA9IGNhY2hlYWJsZTtcblx0fVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IENhY2hlYWJsZTtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgZ2xvYmFsRXZhbCB9IGZyb20gJ21ldGFsLWRvbSc7XG5pbXBvcnQgQ2FjaGVhYmxlIGZyb20gJy4uL2NhY2hlYWJsZS9DYWNoZWFibGUnO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcblxuY2xhc3MgU2NyZWVuIGV4dGVuZHMgQ2FjaGVhYmxlIHtcblxuXHQvKipcblx0ICogU2NyZWVuIGNsYXNzIGlzIGEgc3BlY2lhbCB0eXBlIG9mIHJvdXRlIGhhbmRsZXIgdGhhdCBwcm92aWRlcyBoZWxwZXJcblx0ICogdXRpbGl0aWVzIHRoYXQgYWRkcyBsaWZlY3ljbGUgYW5kIG1ldGhvZHMgdG8gcHJvdmlkZSBjb250ZW50IHRvIGVhY2hcblx0ICogcmVnaXN0ZXJlZCBzdXJmYWNlLlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQGV4dGVuZHMge0NhY2hlYWJsZX1cblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgc2NyZWVuIGlkLlxuXHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaWQgPSB0aGlzLm1ha2VJZF8oZ2V0VWlkKCkpO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHNjcmVlbiBtZXRhIHRhZ3MuIFJlbGV2YW50IHdoZW4gdGhlIG1ldGEgdGFnc1xuXHRcdCAqIHNob3VsZCBiZSB1cGRhdGVkIHdoZW4gc2NyZWVuIGlzIHJlbmRlcmVkLlxuXHRcdCAqL1xuXHRcdHRoaXMubWV0YXMgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHNjcmVlbiB0aXRsZS4gUmVsZXZhbnQgd2hlbiB0aGUgcGFnZSB0aXRsZSBzaG91bGQgYmVcblx0XHQgKiB1cGFkYXRlZCB3aGVuIHNjcmVlbiBpcyByZW5kZXJlZC5cblx0XHQgKiBAdHlwZSB7P3N0cmluZz19XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnRpdGxlID0gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaXJlcyB3aGVuIHRoZSBzY3JlZW4gaXMgYWN0aXZlLiBBbGxvd3MgYSBzY3JlZW4gdG8gcGVyZm9ybSBhbnkgc2V0dXBcblx0ICogdGhhdCByZXF1aXJlcyBpdHMgRE9NIHRvIGJlIHZpc2libGUuIExpZmVjeWNsZS5cblx0ICovXG5cdGFjdGl2YXRlKCkge1xuXHRcdGNvbnNvbGUubG9nKCdTY3JlZW4gWycgKyB0aGlzICsgJ10gYWN0aXZhdGUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHaXZlcyB0aGUgU2NyZWVuIGEgY2hhbmNlIHRvIGNhbmNlbCB0aGUgbmF2aWdhdGlvbiBhbmQgc3RvcCBpdHNlbGYgZnJvbVxuXHQgKiBhY3RpdmF0aW5nLiBDYW4gYmUgdXNlZCwgZm9yIGV4YW1wbGUsIHRvIHByZXZlbnQgbmF2aWdhdGlvbiBpZiBhIHVzZXJcblx0ICogaXMgbm90IGF1dGhlbnRpY2F0ZWQuIExpZmVjeWNsZS5cblx0ICogQHJldHVybiB7Ym9vbGVhbj18P0NhbmNlbGxhYmxlUHJvbWlzZT19IElmIHJldHVybnMgb3IgcmVzb2x2ZXMgdG8gdHJ1ZSxcblx0ICogICAgIHRoZSBjdXJyZW50IHNjcmVlbiBpcyBsb2NrZWQgYW5kIHRoZSBuZXh0IG5hZ2l2YXRpb24gaW50ZXJydXB0ZWQuXG5cdCAqL1xuXHRiZWZvcmVBY3RpdmF0ZSgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGJlZm9yZUFjdGl2YXRlJyk7XG5cdH1cblxuXHQvKipcblx0ICogR2l2ZXMgdGhlIFNjcmVlbiBhIGNoYW5jZSB0byBjYW5jZWwgdGhlIG5hdmlnYXRpb24gYW5kIHN0b3AgaXRzZWxmIGZyb21cblx0ICogYmVpbmcgZGVhY3RpdmF0ZWQuIENhbiBiZSB1c2VkLCBmb3IgZXhhbXBsZSwgaWYgdGhlIHNjcmVlbiBoYXMgdW5zYXZlZFxuXHQgKiBzdGF0ZS4gTGlmZWN5Y2xlLiBDbGVhbi11cCBzaG91bGQgbm90IGJlIHByZWZvcm1lZCBoZXJlLCBzaW5jZSB0aGVcblx0ICogbmF2aWdhdGlvbiBtYXkgc3RpbGwgYmUgY2FuY2VsbGVkLiBEbyBjbGVhbi11cCBpbiBkZWFjdGl2YXRlLlxuXHQgKiBAcmV0dXJuIHtib29sZWFuPXw/Q2FuY2VsbGFibGVQcm9taXNlPX0gSWYgcmV0dXJucyBvciByZXNvbHZlcyB0byB0cnVlLFxuXHQgKiAgICAgdGhlIGN1cnJlbnQgc2NyZWVuIGlzIGxvY2tlZCBhbmQgdGhlIG5leHQgbmFnaXZhdGlvbiBpbnRlcnJ1cHRlZC5cblx0ICovXG5cdGJlZm9yZURlYWN0aXZhdGUoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBiZWZvcmVEZWFjdGl2YXRlJyk7XG5cdH1cblxuXHQvKipcblx0ICogR2l2ZXMgdGhlIFNjcmVlbiBhIGNoYW5jZSBmb3JtYXQgdGhlIHBhdGggYmVmb3JlIGhpc3RvcnkgdXBkYXRlLlxuXHQgKiBAcGF0aCB7IXN0cmluZ30gcGF0aCBOYXZpZ2F0aW9uIHBhdGguXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9IE5hdmlnYXRpb24gcGF0aCB0byB1c2Ugb24gaGlzdG9yeS5cblx0ICovXG5cdGJlZm9yZVVwZGF0ZUhpc3RvcnlQYXRoKHBhdGgpIHtcblx0XHRyZXR1cm4gcGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHaXZlcyB0aGUgU2NyZWVuIGEgY2hhbmNlIGZvcm1hdCB0aGUgc3RhdGUgYmVmb3JlIGhpc3RvcnkgdXBkYXRlLlxuXHQgKiBAcGF0aCB7IW9iamVjdH0gc3RhdGUgSGlzdG9yeSBzdGF0ZS5cblx0ICogQHJldHVybiB7IW9iamVjdH0gSGlzdG9yeSBzdGF0ZSB0byB1c2Ugb24gaGlzdG9yeS5cblx0ICovXG5cdGJlZm9yZVVwZGF0ZUhpc3RvcnlTdGF0ZShzdGF0ZSkge1xuXHRcdHJldHVybiBzdGF0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gZG8gYW55IGNsZWFudXAgbmVjZXNzYXJ5IGFmdGVyIGl0IGhhcyBiZWVuXG5cdCAqIGRlYWN0aXZhdGVkLCBmb3IgZXhhbXBsZSBjYW5jZWxsaW5nIG91dHN0YW5kaW5nIHJlcXVlc3RzIG9yIHN0b3BwaW5nXG5cdCAqIHRpbWVycy4gTGlmZWN5Y2xlLlxuXHQgKi9cblx0ZGVhY3RpdmF0ZSgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGRlYWN0aXZhdGUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlIGEgc2NyZWVuLCBlaXRoZXIgYWZ0ZXIgaXQgaXMgZGVhY3RpdmF0ZWQgKGluIHRoZSBjYXNlIG9mIGFcblx0ICogbm9uLWNhY2hlYWJsZSB2aWV3KSBvciB3aGVuIHRoZSBBcHAgaXMgaXRzZWxmIGRpc3Bvc2VkIGZvciB3aGF0ZXZlclxuXHQgKiByZWFzb24uIExpZmVjeWNsZS5cblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHRzdXBlci5kaXNwb3NlSW50ZXJuYWwoKTtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGRpc3Bvc2UnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gZXZhbHVhdGUgc2NyaXB0cyBiZWZvcmUgdGhlIGVsZW1lbnQgaXMgbWFkZSB2aXNpYmxlLlxuXHQgKiBMaWZlY3ljbGUuXG5cdCAqIEBwYXJhbSB7IW9iamVjdH0gc3VyZmFjZXMgTWFwIG9mIHN1cmZhY2VzIHRvIGZsaXAga2V5ZWQgYnkgc3VyZmFjZSBpZC5cblx0ICogQHJldHVybiB7P0NhbmNlbGxhYmxlUHJvbWlzZT19IFRoaXMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIHdpbGxcblx0ICogICAgIHBhdXNlIHRoZSBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0ZXZhbHVhdGVTY3JpcHRzKHN1cmZhY2VzKSB7XG5cdFx0T2JqZWN0LmtleXMoc3VyZmFjZXMpLmZvckVhY2goc0lkID0+IHtcblx0XHRcdGlmIChzdXJmYWNlc1tzSWRdLmFjdGl2ZUNoaWxkKSB7XG5cdFx0XHRcdGdsb2JhbEV2YWwucnVuU2NyaXB0c0luRWxlbWVudChzdXJmYWNlc1tzSWRdLmFjdGl2ZUNoaWxkKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gZXZhbHVhdGUgc3R5bGVzIGJlZm9yZSB0aGUgZWxlbWVudCBpcyBtYWRlIHZpc2libGUuXG5cdCAqIExpZmVjeWNsZS5cblx0ICogQHBhcmFtIHshb2JqZWN0fSBzdXJmYWNlcyBNYXAgb2Ygc3VyZmFjZXMgdG8gZmxpcCBrZXllZCBieSBzdXJmYWNlIGlkLlxuXHQgKiBAcmV0dXJuIHs/Q2FuY2VsbGFibGVQcm9taXNlPX0gVGhpcyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggd2lsbFxuXHQgKiAgICAgcGF1c2UgdGhlIG5hdmlnYXRpb24gdW50aWwgaXQgaXMgcmVzb2x2ZWQuXG5cdCAqL1xuXHRldmFsdWF0ZVN0eWxlcygpIHtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBbGxvd3MgYSBzY3JlZW4gdG8gcGVyZm9ybSBhbnkgc2V0dXAgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBlbGVtZW50IGlzXG5cdCAqIG1hZGUgdmlzaWJsZS4gTGlmZWN5Y2xlLlxuXHQgKiBAcGFyYW0geyFvYmplY3R9IHN1cmZhY2VzIE1hcCBvZiBzdXJmYWNlcyB0byBmbGlwIGtleWVkIGJ5IHN1cmZhY2UgaWQuXG5cdCAqIEByZXR1cm4gez9DYW5jZWxsYWJsZVByb21pc2U9fSBUaGlzIGNhbiByZXR1cm4gYSBwcm9taXNlLCB3aGljaCB3aWxsIHBhdXNlIHRoZVxuXHQgKiAgICAgbmF2aWdhdGlvbiB1bnRpbCBpdCBpcyByZXNvbHZlZC5cblx0ICovXG5cdGZsaXAoc3VyZmFjZXMpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGZsaXAnKTtcblxuXHRcdHZhciB0cmFuc2l0aW9ucyA9IFtdO1xuXG5cdFx0T2JqZWN0LmtleXMoc3VyZmFjZXMpLmZvckVhY2goc0lkID0+IHtcblx0XHRcdHZhciBzdXJmYWNlID0gc3VyZmFjZXNbc0lkXTtcblx0XHRcdHZhciBkZWZlcnJlZCA9IHN1cmZhY2Uuc2hvdyh0aGlzLmlkKTtcblx0XHRcdHRyYW5zaXRpb25zLnB1c2goZGVmZXJyZWQpO1xuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5hbGwodHJhbnNpdGlvbnMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHNjcmVlbiBpZC5cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cblx0Z2V0SWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2NyZWVuIG1ldGEgdGFncy5cblx0ICogQHJldHVybiB7Tm9kZUxpc3R8Tm9kZX1cblx0ICovXG5cdGdldE1ldGFzKCkge1xuXHRcdHJldHVybiB0aGlzLm1ldGFzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGNvbnRlbnQgZm9yIHRoZSBnaXZlbiBzdXJmYWNlLCBvciBudWxsIGlmIHRoZSBzdXJmYWNlIGlzbid0XG5cdCAqIHVzZWQgYnkgdGhpcyBzY3JlZW4uIFRoaXMgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHNjcmVlbiBpcyBpbml0aWFsbHlcblx0ICogY29uc3RydWN0ZWQgb3IsIGlmIGEgc2NyZWVuIGlzIG5vbi1jYWNoZWFibGUsIHdoZW4gbmF2aWdhdGVkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHN1cmZhY2VJZCBUaGUgaWQgb2YgdGhlIHN1cmZhY2UgRE9NIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7IU9iamVjdH0gcGFyYW1zIFBhcmFtcyBleHRyYWN0ZWQgZnJvbSB0aGUgY3VycmVudCBwYXRoLlxuXHQgKiBAcmV0dXJuIHs/c3RyaW5nfEVsZW1lbnQ9fSBUaGlzIGNhbiByZXR1cm4gYSBzdHJpbmcgb3Igbm9kZSByZXByZXNlbnRpbmdcblx0ICogICAgIHRoZSBjb250ZW50IG9mIHRoZSBzdXJmYWNlLiBJZiByZXR1cm5zIGZhbHN5IHZhbHVlcyBzdXJmYWNlIGRlZmF1bHRcblx0ICogICAgIGNvbnRlbnQgaXMgcmVzdG9yZWQuXG5cdCAqL1xuXHRnZXRTdXJmYWNlQ29udGVudCgpIHtcblx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgdGhpcyArICddIGdldFN1cmZhY2VDb250ZW50Jyk7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc2NyZWVuIHRpdGxlLlxuXHQgKiBAcmV0dXJuIHs/c3RyaW5nPX1cblx0ICovXG5cdGdldFRpdGxlKCkge1xuXHRcdHJldHVybiB0aGlzLnRpdGxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYWxsIGNvbnRlbnRzIGZvciB0aGUgc3VyZmFjZXMuIFRoaXMgd2lsbCBwYXNzIHRoZSBsb2FkZWQgY29udGVudFxuXHQgKiB0byA8Y29kZT5TY3JlZW4ubG9hZDwvY29kZT4gd2l0aCBhbGwgaW5mb3JtYXRpb24geW91XG5cdCAqIG5lZWQgdG8gZnVsZmlsbCB0aGUgc3VyZmFjZXMuIExpZmVjeWNsZS5cblx0ICogQHBhcmFtIHshc3RyaW5nPX0gcGF0aCBUaGUgcmVxdWVzdGVkIHBhdGguXG5cdCAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9IFRoaXMgY2FuIHJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlXG5cdCAqICAgICBjb250ZW50cyBvZiB0aGUgc3VyZmFjZXMgb3IgYSBwcm9taXNlLCB3aGljaCB3aWxsIHBhdXNlIHRoZSBuYXZpZ2F0aW9uXG5cdCAqICAgICB1bnRpbCBpdCBpcyByZXNvbHZlZC4gVGhpcyBpcyB1c2VmdWwgZm9yIGxvYWRpbmcgYXN5bmMgY29udGVudC5cblx0ICovXG5cdGxvYWQoKSB7XG5cdFx0Y29uc29sZS5sb2coJ1NjcmVlbiBbJyArIHRoaXMgKyAnXSBsb2FkJyk7XG5cdFx0cmV0dXJuIENhbmNlbGxhYmxlUHJvbWlzZS5yZXNvbHZlKCk7XG5cdH1cblxuXHQvKipcblx0ICogTWFrZXMgdGhlIGlkIGZvciB0aGUgc2NyZWVuLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGlkIFRoZSBzY3JlZW4gaWQgdGhlIGNvbnRlbnQgYmVsb25ncyB0b28uXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICogQHByaXZhdGVcblx0ICovXG5cdG1ha2VJZF8oaWQpIHtcblx0XHRyZXR1cm4gJ3NjcmVlbl8nICsgaWQ7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgc2NyZWVuIGlkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGlkXG5cdCAqL1xuXHRzZXRJZChpZCkge1xuXHRcdHRoaXMuaWQgPSBpZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzY3JlZW4gbWV0YSB0YWdzLlxuXHQgKiBAcGFyYW0ge05vZGVMaXN0fE5vZGV9IG1ldGFzXG5cdCAqL1xuXHRzZXRNZXRhcyhtZXRhcykge1xuXHRcdHRoaXMubWV0YXMgPSBtZXRhcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzY3JlZW4gdGl0bGUuXG5cdCAqIEBwYXJhbSB7P3N0cmluZz19IHRpdGxlXG5cdCAqL1xuXHRzZXRUaXRsZSh0aXRsZSkge1xuXHRcdHRoaXMudGl0bGUgPSB0aXRsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gdGhpcy5pZDtcblx0fVxuXG59XG5cbi8qKlxuICogQHBhcmFtIHsqfSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgYSBnaXZlbiBpbnN0YW5jZSBpbXBsZW1lbnRzXG4gKiA8Y29kZT5TY3JlZW48L2NvZGU+LlxuICovXG5TY3JlZW4uaXNJbXBsZW1lbnRlZEJ5ID0gZnVuY3Rpb24ob2JqZWN0KSB7XG5cdHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBTY3JlZW47XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTY3JlZW47XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgeyBEaXNwb3NhYmxlLCBpc0RlZkFuZE5vdE51bGwgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgeyBhcHBlbmQsIHJlbW92ZUNoaWxkcmVuLCBleGl0RG9jdW1lbnQgfSBmcm9tICdtZXRhbC1kb20nO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcblxuY2xhc3MgU3VyZmFjZSBleHRlbmRzIERpc3Bvc2FibGUge1xuXG5cdC8qKlxuXHQgKiBTdXJmYWNlIGNsYXNzIHJlcHJlc2VudGluZyB0aGUgcmVmZXJlbmNlcyB0byBlbGVtZW50cyBvbiB0aGUgcGFnZSB0aGF0XG5cdCAqIGNhbiBwb3RlbnRpYWxseSBiZSB1cGRhdGVkIGJ5IDxjb2RlPkFwcDwvY29kZT4uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKGlkKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdGlmICghaWQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignU3VyZmFjZSBlbGVtZW50IGlkIG5vdCBzcGVjaWZpZWQuIEEgc3VyZmFjZSBlbGVtZW50IHJlcXVpcmVzIGEgdmFsaWQgaWQuJyk7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGFjdGl2ZSBjaGlsZCBlbGVtZW50LlxuXHRcdCAqIEB0eXBlIHtFbGVtZW50fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5hY3RpdmVDaGlsZCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgZGVmYXVsdCBjaGlsZCBlbGVtZW50LlxuXHRcdCAqIEB0eXBlIHtFbGVtZW50fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5kZWZhdWx0Q2hpbGQgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGVsZW1lbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHN1cmZhY2UgaWQsIGlmIG5vdCBmb3VuZCBjcmVhdGVzIGFcblx0XHQgKiBuZXcgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgaWQuXG5cdFx0ICogQHR5cGUge0VsZW1lbnR9XG5cdFx0ICogQGRlZmF1bHQgbnVsbFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmVsZW1lbnQgPSBudWxsO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHN1cmZhY2UgaWQuXG5cdFx0ICogQHR5cGUge1N0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuaWQgPSBpZDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBkZWZhdWx0IHRyYW5zaXRpb25GbiBmb3IgdGhlIHN1cmZhY2VzLlxuXHRcdCAqIEBwYXJhbSB7P0VsZW1lbnQ9fSBmcm9tIFRoZSB2aXNpYmxlIHN1cmZhY2UgZWxlbWVudC5cblx0XHQgKiBAcGFyYW0gez9FbGVtZW50PX0gdG8gVGhlIHN1cmZhY2UgZWxlbWVudCB0byBiZSBmbGlwcGVkLlxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKi9cblx0XHR0aGlzLnRyYW5zaXRpb25GbiA9IG51bGw7XG5cblx0XHR0aGlzLmRlZmF1bHRDaGlsZCA9IHRoaXMuZ2V0Q2hpbGQoU3VyZmFjZS5ERUZBVUxUKTtcblx0XHR0aGlzLm1heWJlV3JhcENvbnRlbnRBc0RlZmF1bHRfKCk7XG5cdFx0dGhpcy5hY3RpdmVDaGlsZCA9IHRoaXMuZGVmYXVsdENoaWxkO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgc2NyZWVuIGNvbnRlbnQgdG8gYSBzdXJmYWNlLiBJZiBjb250ZW50IGhhc24ndCBiZWVuIHBhc3NlZCwgc2VlIGlmXG5cdCAqIGFuIGVsZW1lbnQgZXhpc3RzIGluIHRoZSBET00gdGhhdCBtYXRjaGVzIHRoZSBpZC4gQnkgY29udmVudGlvbiwgdGhlXG5cdCAqIGVsZW1lbnQgc2hvdWxkIGFscmVhZHkgYmUgbmVzdGVkIGluIHRoZSByaWdodCBlbGVtZW50IGFuZCBzaG91bGQgaGF2ZSBhblxuXHQgKiBpZCB0aGF0IGlzIGEgY29uY2F0ZW50YXRpb24gb2YgdGhlIHN1cmZhY2UgaWQgKyAnLScgKyB0aGUgc2NyZWVuIGlkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQgdGhlIGNvbnRlbnQgYmVsb25ncyB0b28uXG5cdCAqIEBwYXJhbSB7P3N0cmluZ3xFbGVtZW50PX0gb3B0X2NvbnRlbnQgVGhlIHN0cmluZyBjb250ZW50IG9yIGVsZW1lbnQgdG9cblx0ICogICAgIGFkZCBiZSBhZGRlZCBhcyBzdXJmYWNlIGNvbnRlbnQuXG5cdCAqIEByZXR1cm4ge0VsZW1lbnR9XG5cdCAqL1xuXHRhZGRDb250ZW50KHNjcmVlbklkLCBvcHRfY29udGVudCkge1xuXHRcdHZhciBjaGlsZCA9IHRoaXMuZGVmYXVsdENoaWxkO1xuXG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChvcHRfY29udGVudCkpIHtcblx0XHRcdGNoaWxkID0gdGhpcy5nZXRDaGlsZChzY3JlZW5JZCk7XG5cdFx0XHRpZiAoY2hpbGQpIHtcblx0XHRcdFx0cmVtb3ZlQ2hpbGRyZW4oY2hpbGQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2hpbGQgPSB0aGlzLmNyZWF0ZUNoaWxkKHNjcmVlbklkKTtcblx0XHRcdFx0dGhpcy50cmFuc2l0aW9uKGNoaWxkLCBudWxsKTtcblx0XHRcdH1cblx0XHRcdGFwcGVuZChjaGlsZCwgb3B0X2NvbnRlbnQpO1xuXHRcdH1cblxuXHRcdHZhciBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KCk7XG5cblx0XHRpZiAoZWxlbWVudCAmJiBjaGlsZCkge1xuXHRcdFx0YXBwZW5kKGVsZW1lbnQsIGNoaWxkKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gY2hpbGQ7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBjaGlsZCBub2RlIGZvciB0aGUgc3VyZmFjZS5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkLlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fVxuXHQgKi9cblx0Y3JlYXRlQ2hpbGQoc2NyZWVuSWQpIHtcblx0XHR2YXIgY2hpbGQgPSBnbG9iYWxzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdGNoaWxkLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLm1ha2VJZF8oc2NyZWVuSWQpKTtcblx0XHRyZXR1cm4gY2hpbGQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyBjaGlsZCBub2RlIG9mIHRoZSBzdXJmYWNlLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNjcmVlbklkIFRoZSBzY3JlZW4gaWQuXG5cdCAqIEByZXR1cm4gez9FbGVtZW50fVxuXHQgKi9cblx0Z2V0Q2hpbGQoc2NyZWVuSWQpIHtcblx0XHRyZXR1cm4gZ2xvYmFscy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm1ha2VJZF8oc2NyZWVuSWQpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBzdXJmYWNlIGVsZW1lbnQgZnJvbSBlbGVtZW50LCBhbmQgc2V0cyBpdCB0byB0aGUgZWwgcHJvcGVydHkgb2Zcblx0ICogdGhlIGN1cnJlbnQgaW5zdGFuY2UuXG5cdCAqIDxjb2RlPnRoaXMuZWxlbWVudDwvY29kZT4gd2lsbCBiZSB1c2VkLlxuXHQgKiBAcmV0dXJuIHs/RWxlbWVudH0gVGhlIGN1cnJlbnQgc3VyZmFjZSBlbGVtZW50LlxuXHQgKi9cblx0Z2V0RWxlbWVudCgpIHtcblx0XHRpZiAodGhpcy5lbGVtZW50KSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lbGVtZW50O1xuXHRcdH1cblx0XHR0aGlzLmVsZW1lbnQgPSBnbG9iYWxzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuaWQpO1xuXHRcdHJldHVybiB0aGlzLmVsZW1lbnQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc3VyZmFjZSBpZC5cblx0ICogQHJldHVybiB7U3RyaW5nfVxuXHQgKi9cblx0Z2V0SWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQ7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgc3VyZmFjZSB0cmFuc2l0aW9uIGZ1bmN0aW9uLlxuXHQgKiBTZWUgPGNvZGU+U3VyZmFjZS5kZWZhdWx0VHJhbnNpdGlvbjwvY29kZT4uXG5cdCAqIEByZXR1cm4gez9GdW5jdGlvbj19IFRoZSB0cmFuc2l0aW9uIGZ1bmN0aW9uLlxuXHQgKi9cblx0Z2V0VHJhbnNpdGlvbkZuKCkge1xuXHRcdHJldHVybiB0aGlzLnRyYW5zaXRpb25Gbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYWtlcyB0aGUgaWQgZm9yIHRoZSBlbGVtZW50IHRoYXQgaG9sZHMgY29udGVudCBmb3IgYSBzY3JlZW4uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2NyZWVuSWQgVGhlIHNjcmVlbiBpZCB0aGUgY29udGVudCBiZWxvbmdzIHRvby5cblx0ICogQHJldHVybiB7U3RyaW5nfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0bWFrZUlkXyhzY3JlZW5JZCkge1xuXHRcdHJldHVybiB0aGlzLmlkICsgJy0nICsgc2NyZWVuSWQ7XG5cdH1cblxuXHQvKipcblx0ICogSWYgZGVmYXVsdCBjaGlsZCBpcyBtaXNzaW5nLCB3cmFwcyBzdXJmYWNlIGNvbnRlbnQgYXMgZGVmYXVsdCBjaGlsZC4gSWZcblx0ICogc3VyZmFjZSBoYXZlIHN0YXRpYyBjb250ZW50LCBtYWtlIHN1cmUgdG8gcGxhY2UgYVxuXHQgKiA8Y29kZT5zdXJmYWNlSWQtZGVmYXVsdDwvY29kZT4gZWxlbWVudCBpbnNpZGUgc3VyZmFjZSwgb25seSBjb250ZW50c1xuXHQgKiBpbnNpZGUgdGhlIGRlZmF1bHQgY2hpbGQgd2lsbCBiZSByZXBsYWNlZCBieSBuYXZpZ2F0aW9uLlxuXHQgKi9cblx0bWF5YmVXcmFwQ29udGVudEFzRGVmYXVsdF8oKSB7XG5cdFx0dmFyIGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnQoKTtcblx0XHRpZiAoZWxlbWVudCAmJiAhdGhpcy5kZWZhdWx0Q2hpbGQpIHtcblx0XHRcdHZhciBmcmFnbWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuXHRcdFx0d2hpbGUgKGVsZW1lbnQuZmlyc3RDaGlsZCkge1xuXHRcdFx0XHRmcmFnbWVudC5hcHBlbmRDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5kZWZhdWx0Q2hpbGQgPSB0aGlzLmFkZENvbnRlbnQoU3VyZmFjZS5ERUZBVUxULCBmcmFnbWVudCk7XG5cdFx0XHR0aGlzLnRyYW5zaXRpb24obnVsbCwgdGhpcy5kZWZhdWx0Q2hpbGQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzdXJmYWNlIGlkLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGlkXG5cdCAqL1xuXHRzZXRJZChpZCkge1xuXHRcdHRoaXMuaWQgPSBpZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBzdXJmYWNlIHRyYW5zaXRpb24gZnVuY3Rpb24uXG5cdCAqIFNlZSA8Y29kZT5TdXJmYWNlLmRlZmF1bHRUcmFuc2l0aW9uPC9jb2RlPi5cblx0ICogQHBhcmFtIHs/RnVuY3Rpb249fSB0cmFuc2l0aW9uRm4gVGhlIHRyYW5zaXRpb24gZnVuY3Rpb24uXG5cdCAqL1xuXHRzZXRUcmFuc2l0aW9uRm4odHJhbnNpdGlvbkZuKSB7XG5cdFx0dGhpcy50cmFuc2l0aW9uRm4gPSB0cmFuc2l0aW9uRm47XG5cdH1cblxuXHQvKipcblx0ICogU2hvd3Mgc2NyZWVuIGNvbnRlbnQgZnJvbSBhIHN1cmZhY2UuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkIHRvIHNob3cuXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUGF1c2VzIHRoZSBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0c2hvdyhzY3JlZW5JZCkge1xuXHRcdHZhciBmcm9tID0gdGhpcy5hY3RpdmVDaGlsZDtcblx0XHR2YXIgdG8gPSB0aGlzLmdldENoaWxkKHNjcmVlbklkKTtcblx0XHRpZiAoIXRvKSB7XG5cdFx0XHR0byA9IHRoaXMuZGVmYXVsdENoaWxkO1xuXHRcdH1cblx0XHR0aGlzLmFjdGl2ZUNoaWxkID0gdG87XG5cdFx0cmV0dXJuIHRoaXMudHJhbnNpdGlvbihmcm9tLCB0bykudGhlbkFsd2F5cygoKSA9PiB7XG5cdFx0XHRpZiAoZnJvbSAmJiBmcm9tICE9PSB0bykge1xuXHRcdFx0XHRleGl0RG9jdW1lbnQoZnJvbSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyBzY3JlZW4gY29udGVudCBmcm9tIGEgc3VyZmFjZS5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzY3JlZW5JZCBUaGUgc2NyZWVuIGlkIHRvIHJlbW92ZS5cblx0ICovXG5cdHJlbW92ZShzY3JlZW5JZCkge1xuXHRcdHZhciBjaGlsZCA9IHRoaXMuZ2V0Q2hpbGQoc2NyZWVuSWQpO1xuXHRcdGlmIChjaGlsZCkge1xuXHRcdFx0ZXhpdERvY3VtZW50KGNoaWxkKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQHJldHVybiB7U3RyaW5nfVxuXHQgKi9cblx0dG9TdHJpbmcoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaWQ7XG5cdH1cblxuXHQvKipcblx0ICogSW52b2tlcyB0aGUgdHJhbnNpdGlvbiBmdW5jdGlvbiBzcGVjaWZpZWQgb24gPGNvZGU+dHJhbnNpdGlvbjwvY29kZT4gYXR0cmlidXRlLlxuXHQgKiBAcGFyYW0gez9FbGVtZW50PX0gZnJvbVxuXHQgKiBAcGFyYW0gez9FbGVtZW50PX0gdG9cblx0ICogQHJldHVybiB7P0NhbmNlbGxhYmxlUHJvbWlzZT19IFRoaXMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIHdpbGwgcGF1c2UgdGhlXG5cdCAqICAgICBuYXZpZ2F0aW9uIHVudGlsIGl0IGlzIHJlc29sdmVkLlxuXHQgKi9cblx0dHJhbnNpdGlvbihmcm9tLCB0bykge1xuXHRcdHZhciB0cmFuc2l0aW9uRm4gPSB0aGlzLnRyYW5zaXRpb25GbiB8fCBTdXJmYWNlLmRlZmF1bHRUcmFuc2l0aW9uO1xuXHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVzb2x2ZSh0cmFuc2l0aW9uRm4uY2FsbCh0aGlzLCBmcm9tLCB0bykpO1xuXHR9XG5cbn1cblxuLyoqXG4gICAqIEhvbGRzIHRoZSBkZWZhdWx0IHN1cmZhY2UgbmFtZS4gRWxlbWVudHMgb24gdGhlIHBhZ2UgbXVzdCBjb250YWluIGEgY2hpbGRcbiAgICogZWxlbWVudCBjb250YWluaW5nIHRoZSBkZWZhdWx0IGNvbnRlbnQsIHRoaXMgZWxlbWVudCBtdXN0IGJlIGFzIGZvbGxvd2luZzpcbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogPGNvZGU+XG4gICAqICAgPGRpdiBpZD1cIm15c3VyZmFjZVwiPlxuICAgKiAgICAgPGRpdiBpZD1cIm15c3VyZmFjZS1kZWZhdWx0XCI+RGVmYXVsdCBzdXJmYWNlIGNvbnRlbnQuPC9kaXY+XG4gICAqICAgPC9kaXY+XG4gICAqIDwvY29kZT5cbiAgICpcbiAgICogVGhlIGRlZmF1bHQgY29udGVudCBpcyByZWxldmFudCBmb3IgdGhlIGluaXRpYWwgcGFnZSBjb250ZW50LiBXaGVuIGFcbiAgICogc2NyZWVuIGRvZXNuJ3QgcHJvdmlkZSBjb250ZW50IGZvciB0aGUgc3VyZmFjZSB0aGUgZGVmYXVsdCBjb250ZW50IGlzXG4gICAqIHJlc3RvcmVkIGludG8gdGhlIHBhZ2UuXG4gICAqXG4gICAqIEB0eXBlIHshU3RyaW5nfVxuICAgKiBAZGVmYXVsdCBkZWZhdWx0XG4gICAqIEBzdGF0aWNcbiAgICovXG5TdXJmYWNlLkRFRkFVTFQgPSAnZGVmYXVsdCc7XG5cbi8qKlxuICogSG9sZHMgdGhlIGRlZmF1bHQgdHJhbnNpdGlvbiBmb3IgYWxsIHN1cmZhY2VzLiBFYWNoIHN1cmZhY2UgY291bGQgaGF2ZSBpdHNcbiAqIG93biB0cmFuc2l0aW9uLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogPGNvZGU+XG4gKiBzdXJmYWNlLnNldFRyYW5zaXRpb25GbihmdW5jdGlvbihmcm9tLCB0bykge1xuICogICBpZiAoZnJvbSkge1xuICogICAgIGZyb20uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAqICAgICBmcm9tLmNsYXNzTGlzdC5yZW1vdmUoJ2ZsaXBwZWQnKTtcbiAqICAgfVxuICogICBpZiAodG8pIHtcbiAqICAgICB0by5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAqICAgICB0by5jbGFzc0xpc3QuYWRkKCdmbGlwcGVkJyk7XG4gKiAgIH1cbiAqICAgcmV0dXJuIG51bGw7XG4gKiB9KTtcbiAqIDwvY29kZT5cbiAqXG4gKiBAcGFyYW0gez9FbGVtZW50PX0gZnJvbSBUaGUgdmlzaWJsZSBzdXJmYWNlIGVsZW1lbnQuXG4gKiBAcGFyYW0gez9FbGVtZW50PX0gdG8gVGhlIHN1cmZhY2UgZWxlbWVudCB0byBiZSBmbGlwcGVkLlxuICogQHN0YXRpY1xuICovXG5TdXJmYWNlLmRlZmF1bHRUcmFuc2l0aW9uID0gZnVuY3Rpb24oZnJvbSwgdG8pIHtcblx0aWYgKGZyb20pIHtcblx0XHRmcm9tLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0ZnJvbS5jbGFzc0xpc3QucmVtb3ZlKCdmbGlwcGVkJyk7XG5cdH1cblx0aWYgKHRvKSB7XG5cdFx0dG8uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cdFx0dG8uY2xhc3NMaXN0LmFkZCgnZmxpcHBlZCcpO1xuXHR9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTdXJmYWNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBhZGRDbGFzc2VzLCBkZWxlZ2F0ZSwgbWF0Y2gsIG9uLCByZW1vdmVDbGFzc2VzIH0gZnJvbSAnbWV0YWwtZG9tJztcbmltcG9ydCB7IGFycmF5LCBhc3luYywgaXNEZWZBbmROb3ROdWxsLCBpc1N0cmluZywgb2JqZWN0IH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBFdmVudEhhbmRsZXIgfSBmcm9tICdtZXRhbC1ldmVudHMnO1xuaW1wb3J0IENhbmNlbGxhYmxlUHJvbWlzZSBmcm9tICdtZXRhbC1wcm9taXNlJztcbmltcG9ydCBkZWJvdW5jZSBmcm9tICdtZXRhbC1kZWJvdW5jZSc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFJvdXRlIGZyb20gJy4uL3JvdXRlL1JvdXRlJztcbmltcG9ydCBTY3JlZW4gZnJvbSAnLi4vc2NyZWVuL1NjcmVlbic7XG5pbXBvcnQgU3VyZmFjZSBmcm9tICcuLi9zdXJmYWNlL1N1cmZhY2UnO1xuaW1wb3J0IFVyaSBmcm9tICdtZXRhbC11cmknO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uL3V0aWxzL3V0aWxzJztcblxuY29uc3QgTmF2aWdhdGlvblN0cmF0ZWd5ID0ge1xuXHRJTU1FRElBVEU6ICdpbW1lZGlhdGUnLFxuXHRTQ0hFRFVMRV9MQVNUOiAnc2NoZWR1bGVMYXN0J1xufTtcblxuY2xhc3MgQXBwIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcblxuXHQvKipcblx0ICogQXBwIGNsYXNzIHRoYXQgaGFuZGxlIHJvdXRlcyBhbmQgc2NyZWVucyBsaWZlY3ljbGUuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAZXh0ZW5kcyB7RXZlbnRFbWl0dGVyfVxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBhY3RpdmUgc2NyZWVuLlxuXHRcdCAqIEB0eXBlIHs/U2NyZWVufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmFjdGl2ZVNjcmVlbiA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgYWN0aXZlIHBhdGggY29udGFpbmluZyB0aGUgcXVlcnkgcGFyYW1ldGVycy5cblx0XHQgKiBAdHlwZSB7P3N0cmluZ31cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5hY3RpdmVQYXRoID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEFsbG93cyBwcmV2ZW50IG5hdmlnYXRlIGZyb20gZG9tIHByZXZlbnRlZCBldmVudC5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCB0cnVlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuYWxsb3dQcmV2ZW50TmF2aWdhdGUgPSB0cnVlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgbGluayBiYXNlIHBhdGguXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgJydcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5iYXNlUGF0aCA9ICcnO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHZhbHVlIG9mIHRoZSBicm93c2VyIHBhdGggYmVmb3JlIGEgbmF2aWdhdGlvbiBpcyBwZXJmb3JtZWQuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgdGhlIGN1cnJlbnQgYnJvd3NlciBwYXRoLlxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmJyb3dzZXJQYXRoQmVmb3JlTmF2aWdhdGUgPSB1dGlscy5nZXRDdXJyZW50QnJvd3NlclBhdGhXaXRob3V0SGFzaCgpO1xuXG5cdFx0LyoqXG5cdFx0ICogQ2FwdHVyZXMgc2Nyb2xsIHBvc2l0aW9uIGZyb20gc2Nyb2xsIGV2ZW50LlxuXHRcdCAqIEB0eXBlIHshYm9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCB0cnVlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuY2FwdHVyZVNjcm9sbFBvc2l0aW9uRnJvbVNjcm9sbEV2ZW50ID0gdHJ1ZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBkZWZhdWx0IHBhZ2UgdGl0bGUuXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuZGVmYXVsdFRpdGxlID0gZ2xvYmFscy5kb2N1bWVudC50aXRsZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBmb3JtIHNlbGVjdG9yIHRvIGRlZmluZSBmb3JtcyB0aGF0IGFyZSByb3V0ZWQuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgZm9ybVtlbmN0eXBlPVwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXTpub3QoW2RhdGEtc2VubmEtb2ZmXSlcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5mb3JtU2VsZWN0b3IgPSAnZm9ybVtlbmN0eXBlPVwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXTpub3QoW2RhdGEtc2VubmEtb2ZmXSknO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBlbmFibGVkLCB0aGUgcm91dGUgbWF0Y2hpbmcgaWdub3JlcyBxdWVyeSBzdHJpbmcgZnJvbSB0aGUgcGF0aC5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCBmYWxzZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCA9IGZhbHNlO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGxpbmsgc2VsZWN0b3IgdG8gZGVmaW5lIGxpbmtzIHRoYXQgYXJlIHJvdXRlZC5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCBhOm5vdChbZGF0YS1zZW5uYS1vZmZdKVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmxpbmtTZWxlY3RvciA9ICdhOm5vdChbZGF0YS1zZW5uYS1vZmZdKTpub3QoW3RhcmdldD1cIl9ibGFua1wiXSknO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIGxvYWRpbmcgY3NzIGNsYXNzLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IHNlbm5hLWxvYWRpbmdcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5sb2FkaW5nQ3NzQ2xhc3MgPSAnc2VubmEtbG9hZGluZyc7XG5cblx0XHQvKipcblx0XHQgKiBVc2luZyB0aGUgSGlzdG9yeSBBUEkgdG8gbWFuYWdlIHlvdXIgVVJMcyBpcyBhd2Vzb21lIGFuZCwgYXMgaXQgaGFwcGVucyxcblx0XHQgKiBhIGNydWNpYWwgZmVhdHVyZSBvZiBnb29kIHdlYiBhcHBzLiBPbmUgb2YgaXRzIGRvd25zaWRlcywgaG93ZXZlciwgaXNcblx0XHQgKiB0aGF0IHNjcm9sbCBwb3NpdGlvbnMgYXJlIHN0b3JlZCBhbmQgdGhlbiwgbW9yZSBpbXBvcnRhbnRseSwgcmVzdG9yZWRcblx0XHQgKiB3aGVuZXZlciB5b3UgdHJhdmVyc2UgdGhlIGhpc3RvcnkuIFRoaXMgb2Z0ZW4gbWVhbnMgdW5zaWdodGx5IGp1bXBzIGFzXG5cdFx0ICogdGhlIHNjcm9sbCBwb3NpdGlvbiBjaGFuZ2VzIGF1dG9tYXRpY2FsbHksIGFuZCBlc3BlY2lhbGx5IHNvIGlmIHlvdXIgYXBwXG5cdFx0ICogZG9lcyB0cmFuc2l0aW9ucywgb3IgY2hhbmdlcyB0aGUgY29udGVudHMgb2YgdGhlIHBhZ2UgaW4gYW55IHdheS5cblx0XHQgKiBVbHRpbWF0ZWx5IHRoaXMgbGVhZHMgdG8gYW4gaG9ycmlibGUgdXNlciBleHBlcmllbmNlLiBUaGUgZ29vZCBuZXdzIGlzLFxuXHRcdCAqIGhvd2V2ZXIsIHRoYXQgdGhlcmXigJlzIGEgcG90ZW50aWFsIGZpeDogaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbi5cblx0XHQgKiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS93ZWIvdXBkYXRlcy8yMDE1LzA5L2hpc3RvcnktYXBpLXNjcm9sbC1yZXN0b3JhdGlvblxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uU3VwcG9ydGVkID0gKCdzY3JvbGxSZXN0b3JhdGlvbicgaW4gZ2xvYmFscy53aW5kb3cuaGlzdG9yeSk7XG5cblx0XHQvKipcblx0XHQgKiBXaGVuIHNldCB0byBOYXZpZ2F0aW9uU3RyYXRlZ3kuU0NIRURVTEVfTEFTVCBtZWFucyB0aGF0IHRoZSBjdXJyZW50IG5hdmlnYXRpb25cblx0XHQgKiBjYW5ub3QgYmUgQ2FuY2VsbGVkIHRvIHN0YXJ0IGFub3RoZXIgYW5kIHdpbGwgYmUgcXVldWVkIGluXG5cdFx0ICogc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLiBXaGVuIE5hdmlnYXRpb25TdHJhdGVneS5JTU1FRElBVEUgbWVhbnMgdGhhdCBhbGxcblx0XHQgKiBuYXZpZ2F0aW9uIHdpbGwgYmUgY2FuY2VsbGVkIHRvIHN0YXJ0IGFub3RoZXIuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgaW1tZWRpYXRlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMubmF2aWdhdGlvblN0cmF0ZWd5ID0gTmF2aWdhdGlvblN0cmF0ZWd5LklNTUVESUFURTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZW4gc2V0IHRvIHRydWUgdGhlcmUgaXMgYSBwZW5kaW5nTmF2aWdhdGUgdGhhdCBoYXMgbm90IHlldCBiZWVuXG5cdFx0ICogcmVzb2x2ZWQgb3IgcmVqZWN0ZWQuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgZmFsc2Vcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5pc05hdmlnYXRpb25QZW5kaW5nID0gZmFsc2U7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBhIGRlZmVycmVkIHdpdGggdGhlIGN1cnJlbnQgbmF2aWdhdGlvbi5cblx0XHQgKiBAdHlwZSB7P0NhbmNlbGxhYmxlUHJvbWlzZX1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSB3aW5kb3cgaG9yaXpvbnRhbCBzY3JvbGwgcG9zaXRpb24gd2hlbiB0aGUgbmF2aWdhdGlvbiB1c2luZ1xuXHRcdCAqIGJhY2sgb3IgZm9yd2FyZCBoYXBwZW5zIHRvIGJlIHJlc3RvcmVkIGFmdGVyIHRoZSBzdXJmYWNlcyBhcmUgdXBkYXRlZC5cblx0XHQgKiBAdHlwZSB7IU51bWJlcn1cblx0XHQgKiBAZGVmYXVsdCAwXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucG9wc3RhdGVTY3JvbGxMZWZ0ID0gMDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSB3aW5kb3cgdmVydGljYWwgc2Nyb2xsIHBvc2l0aW9uIHdoZW4gdGhlIG5hdmlnYXRpb24gdXNpbmdcblx0XHQgKiBiYWNrIG9yIGZvcndhcmQgaGFwcGVucyB0byBiZSByZXN0b3JlZCBhZnRlciB0aGUgc3VyZmFjZXMgYXJlIHVwZGF0ZWQuXG5cdFx0ICogQHR5cGUgeyFOdW1iZXJ9XG5cdFx0ICogQGRlZmF1bHQgMFxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnBvcHN0YXRlU2Nyb2xsVG9wID0gMDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSByZWRpcmVjdCBwYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5IHBhcmFtZXRlcnMuXG5cdFx0ICogQHR5cGUgez9zdHJpbmd9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMucmVkaXJlY3RQYXRoID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBzY3JlZW4gcm91dGVzIGNvbmZpZ3VyYXRpb24uXG5cdFx0ICogQHR5cGUgez9BcnJheX1cblx0XHQgKiBAZGVmYXVsdCBbXVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnJvdXRlcyA9IFtdO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgYSBxdWV1ZSB0aGF0IHN0b3JlcyBldmVyeSBET00gZXZlbnQgdGhhdCBjYW4gaW5pdGlhdGUgYSBuYXZpZ2F0aW9uLlxuXHRcdCAqIEB0eXBlIHshRXZlbnR9XG5cdFx0ICogQGRlZmF1bHQgW11cblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5zY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUgPSBbXTtcblxuXHRcdC8qKlxuXHRcdCAqIE1hcHMgdGhlIHNjcmVlbiBpbnN0YW5jZXMgYnkgdGhlIHVybCBjb250YWluaW5nIHRoZSBwYXJhbWV0ZXJzLlxuXHRcdCAqIEB0eXBlIHs/T2JqZWN0fVxuXHRcdCAqIEBkZWZhdWx0IHt9XG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMuc2NyZWVucyA9IHt9O1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBzZXQgdG8gdHJ1ZSB0aGUgZmlyc3QgZXJyb25lb3VzIHBvcHN0YXRlIGZpcmVkIG9uIHBhZ2UgbG9hZCB3aWxsIGJlXG5cdFx0ICogaWdub3JlZCwgb25seSBpZiA8Y29kZT5nbG9iYWxzLndpbmRvdy5oaXN0b3J5LnN0YXRlPC9jb2RlPiBpcyBhbHNvXG5cdFx0ICogPGNvZGU+bnVsbDwvY29kZT4uXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQGRlZmF1bHQgZmFsc2Vcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5za2lwTG9hZFBvcHN0YXRlID0gZmFsc2U7XG5cblx0XHQvKipcblx0XHQgKiBNYXBzIHRoYXQgaW5kZXggdGhlIHN1cmZhY2VzIGluc3RhbmNlcyBieSB0aGUgc3VyZmFjZSBpZC5cblx0XHQgKiBAdHlwZSB7P09iamVjdH1cblx0XHQgKiBAZGVmYXVsdCB7fVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnN1cmZhY2VzID0ge307XG5cblx0XHQvKipcblx0XHQgKiBXaGVuIHNldCB0byB0cnVlLCBtb3ZlcyB0aGUgc2Nyb2xsIHBvc2l0aW9uIGFmdGVyIHBvcHN0YXRlLCBvciB0byB0aGVcblx0XHQgKiB0b3Agb2YgdGhlIHZpZXdwb3J0IGZvciBuZXcgbmF2aWdhdGlvbi4gSWYgZmFsc2UsIHRoZSBicm93c2VyIHdpbGxcblx0XHQgKiB0YWtlIGNhcmUgb2Ygc2Nyb2xsIHJlc3RvcmF0aW9uLlxuXHRcdCAqIEB0eXBlIHshYm9vbGVhbn1cblx0XHQgKiBAZGVmYXVsdCB0cnVlXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMudXBkYXRlU2Nyb2xsUG9zaXRpb24gPSB0cnVlO1xuXG5cdFx0dGhpcy5hcHBFdmVudEhhbmRsZXJzXyA9IG5ldyBFdmVudEhhbmRsZXIoKTtcblxuXHRcdHRoaXMuYXBwRXZlbnRIYW5kbGVyc18uYWRkKFxuXHRcdFx0b24oZ2xvYmFscy53aW5kb3csICdzY3JvbGwnLCBkZWJvdW5jZSh0aGlzLm9uU2Nyb2xsXy5iaW5kKHRoaXMpLCAxMDApKSxcblx0XHRcdG9uKGdsb2JhbHMud2luZG93LCAnbG9hZCcsIHRoaXMub25Mb2FkXy5iaW5kKHRoaXMpKSxcblx0XHRcdG9uKGdsb2JhbHMud2luZG93LCAncG9wc3RhdGUnLCB0aGlzLm9uUG9wc3RhdGVfLmJpbmQodGhpcykpXG5cdFx0KTtcblxuXHRcdHRoaXMub24oJ3N0YXJ0TmF2aWdhdGUnLCB0aGlzLm9uU3RhcnROYXZpZ2F0ZV8pO1xuXHRcdHRoaXMub24oJ2JlZm9yZU5hdmlnYXRlJywgdGhpcy5vbkJlZm9yZU5hdmlnYXRlXyk7XG5cdFx0dGhpcy5vbignYmVmb3JlTmF2aWdhdGUnLCB0aGlzLm9uQmVmb3JlTmF2aWdhdGVEZWZhdWx0XywgdHJ1ZSk7XG5cdFx0dGhpcy5vbignYmVmb3JlVW5sb2FkJywgdGhpcy5vbkJlZm9yZVVubG9hZERlZmF1bHRfKTtcblxuXHRcdHRoaXMuc2V0TGlua1NlbGVjdG9yKHRoaXMubGlua1NlbGVjdG9yKTtcblx0XHR0aGlzLnNldEZvcm1TZWxlY3Rvcih0aGlzLmZvcm1TZWxlY3Rvcik7XG5cblx0XHR0aGlzLm1heWJlT3ZlcmxvYWRCZWZvcmVVbmxvYWRfKCk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBvbmUgb3IgbW9yZSBzY3JlZW5zIHRvIHRoZSBhcHBsaWNhdGlvbi5cblx0ICpcblx0ICogRXhhbXBsZTpcblx0ICpcblx0ICogPGNvZGU+XG5cdCAqICAgYXBwLmFkZFJvdXRlcyh7IHBhdGg6ICcvZm9vJywgaGFuZGxlcjogRm9vU2NyZWVuIH0pO1xuXHQgKiAgIG9yXG5cdCAqICAgYXBwLmFkZFJvdXRlcyhbeyBwYXRoOiAnL2ZvbycsIGhhbmRsZXI6IGZ1bmN0aW9uKHJvdXRlKSB7IHJldHVybiBuZXcgRm9vU2NyZWVuKCk7IH0gfV0pO1xuXHQgKiA8L2NvZGU+XG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvciB7QXJyYXl9IHJvdXRlcyBTaW5nbGUgb2JqZWN0IG9yIGFuIGFycmF5IG9mIG9iamVjdC5cblx0ICogICAgIEVhY2ggb2JqZWN0IHNob3VsZCBjb250YWluIDxjb2RlPnBhdGg8L2NvZGU+IGFuZCA8Y29kZT5zY3JlZW48L2NvZGU+LlxuXHQgKiAgICAgVGhlIDxjb2RlPnBhdGg8L2NvZGU+IHNob3VsZCBiZSBhIHN0cmluZyBvciBhIHJlZ2V4IHRoYXQgbWFwcyB0aGVcblx0ICogICAgIG5hdmlnYXRpb24gcm91dGUgdG8gYSBzY3JlZW4gY2xhc3MgZGVmaW5pdGlvbiAobm90IGFuIGluc3RhbmNlKSwgZS5nOlxuXHQgKiAgICAgICAgIDxjb2RlPnsgcGF0aDogXCIvaG9tZTpwYXJhbTFcIiwgaGFuZGxlcjogTXlTY3JlZW4gfTwvY29kZT5cblx0ICogICAgICAgICA8Y29kZT57IHBhdGg6IC9mb28uKy8sIGhhbmRsZXI6IE15U2NyZWVuIH08L2NvZGU+XG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFJvdXRlcyhyb3V0ZXMpIHtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkocm91dGVzKSkge1xuXHRcdFx0cm91dGVzID0gW3JvdXRlc107XG5cdFx0fVxuXHRcdHJvdXRlcy5mb3JFYWNoKChyb3V0ZSkgPT4ge1xuXHRcdFx0aWYgKCEocm91dGUgaW5zdGFuY2VvZiBSb3V0ZSkpIHtcblx0XHRcdFx0cm91dGUgPSBuZXcgUm91dGUocm91dGUucGF0aCwgcm91dGUuaGFuZGxlcik7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnJvdXRlcy5wdXNoKHJvdXRlKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGRzIG9uZSBvciBtb3JlIHN1cmZhY2VzIHRvIHRoZSBhcHBsaWNhdGlvbi5cblx0ICogQHBhcmFtIHtTdXJmYWNlfFN0cmluZ3xBcnJheS48U3VyZmFjZXxTdHJpbmc+fSBzdXJmYWNlc1xuXHQgKiAgICAgU3VyZmFjZSBlbGVtZW50IGlkIG9yIHN1cmZhY2UgaW5zdGFuY2UuIFlvdSBjYW4gYWxzbyBwYXNzIGFuIEFycmF5XG5cdCAqICAgICB3aGljaGNvbnRhaW5zIHN1cmZhY2UgaW5zdGFuY2VzIG9yIGlkLiBJbiBjYXNlIG9mIElELCB0aGVzZSBzaG91bGQgYmVcblx0ICogICAgIHRoZSBpZCBvZiBzdXJmYWNlIGVsZW1lbnQuXG5cdCAqIEBjaGFpbmFibGVcblx0ICovXG5cdGFkZFN1cmZhY2VzKHN1cmZhY2VzKSB7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KHN1cmZhY2VzKSkge1xuXHRcdFx0c3VyZmFjZXMgPSBbc3VyZmFjZXNdO1xuXHRcdH1cblx0XHRzdXJmYWNlcy5mb3JFYWNoKChzdXJmYWNlKSA9PiB7XG5cdFx0XHRpZiAoaXNTdHJpbmcoc3VyZmFjZSkpIHtcblx0XHRcdFx0c3VyZmFjZSA9IG5ldyBTdXJmYWNlKHN1cmZhY2UpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5zdXJmYWNlc1tzdXJmYWNlLmdldElkKCldID0gc3VyZmFjZTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGlmIGNhbiBuYXZpZ2F0ZSB0byBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHVybFxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKi9cblx0Y2FuTmF2aWdhdGUodXJsKSB7XG5cdFx0Y29uc3QgdXJpID0gdXRpbHMuaXNXZWJVcmkodXJsKTtcblxuXHRcdGlmICghdXJpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Y29uc3QgcGF0aCA9IHV0aWxzLmdldFVybFBhdGgodXJsKTtcblxuXHRcdGlmICghdGhpcy5pc0xpbmtTYW1lT3JpZ2luXyh1cmkuZ2V0SG9zdCgpKSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ09mZnNpdGUgbGluayBjbGlja2VkJyk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5pc1NhbWVCYXNlUGF0aF8ocGF0aCkpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdMaW5rIGNsaWNrZWQgb3V0c2lkZSBhcHBcXCdzIGJhc2UgcGF0aCcpO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHQvLyBQcmV2ZW50cyBuYXZpZ2F0aW9uIGlmIGl0J3MgYSBoYXNoIGNoYW5nZSBvbiB0aGUgc2FtZSB1cmwuXG5cdFx0aWYgKHVyaS5nZXRIYXNoKCkgJiYgdXRpbHMuaXNDdXJyZW50QnJvd3NlclBhdGgocGF0aCkpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKCF0aGlzLmZpbmRSb3V0ZShwYXRoKSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ05vIHJvdXRlIGZvciAnICsgcGF0aCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQ2xlYXIgc2NyZWVucyBjYWNoZS5cblx0ICogQGNoYWluYWJsZVxuXHQgKi9cblx0Y2xlYXJTY3JlZW5zQ2FjaGUoKSB7XG5cdFx0T2JqZWN0LmtleXModGhpcy5zY3JlZW5zKS5mb3JFYWNoKChwYXRoKSA9PiB7XG5cdFx0XHRpZiAocGF0aCA9PT0gdGhpcy5hY3RpdmVQYXRoKSB7XG5cdFx0XHRcdHRoaXMuYWN0aXZlU2NyZWVuLmNsZWFyQ2FjaGUoKTtcblx0XHRcdH0gZWxzZSBpZiAoISh0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgJiYgdGhpcy5wZW5kaW5nTmF2aWdhdGUucGF0aCA9PT0gcGF0aCkpIHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTY3JlZW4ocGF0aCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIG9yIGNyZWF0ZSBhIHNjcmVlbiBpbnN0YW5jZSB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEByZXR1cm4ge1NjcmVlbn1cblx0ICovXG5cdGNyZWF0ZVNjcmVlbkluc3RhbmNlKHBhdGgsIHJvdXRlKSB7XG5cdFx0aWYgKCF0aGlzLnBlbmRpbmdOYXZpZ2F0ZSAmJiBwYXRoID09PSB0aGlzLmFjdGl2ZVBhdGgpIHtcblx0XHRcdGNvbnNvbGUubG9nKCdBbHJlYWR5IGF0IGRlc3RpbmF0aW9uLCByZWZyZXNoIG5hdmlnYXRpb24nKTtcblx0XHRcdHJldHVybiB0aGlzLmFjdGl2ZVNjcmVlbjtcblx0XHR9XG5cdFx0LyoganNoaW50IG5ld2NhcDogZmFsc2UgKi9cblx0XHR2YXIgc2NyZWVuID0gdGhpcy5zY3JlZW5zW3BhdGhdO1xuXHRcdGlmICghc2NyZWVuKSB7XG5cdFx0XHR2YXIgaGFuZGxlciA9IHJvdXRlLmdldEhhbmRsZXIoKTtcblx0XHRcdGlmIChoYW5kbGVyID09PSBTY3JlZW4gfHwgU2NyZWVuLmlzSW1wbGVtZW50ZWRCeShoYW5kbGVyLnByb3RvdHlwZSkpIHtcblx0XHRcdFx0c2NyZWVuID0gbmV3IGhhbmRsZXIoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNjcmVlbiA9IGhhbmRsZXIocm91dGUpIHx8IG5ldyBTY3JlZW4oKTtcblx0XHRcdH1cblx0XHRcdGNvbnNvbGUubG9nKCdDcmVhdGUgc2NyZWVuIGZvciBbJyArIHBhdGggKyAnXSBbJyArIHNjcmVlbiArICddJyk7XG5cdFx0fVxuXHRcdHJldHVybiBzY3JlZW47XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGRpc3Bvc2VJbnRlcm5hbCgpIHtcblx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4pIHtcblx0XHRcdHRoaXMucmVtb3ZlU2NyZWVuKHRoaXMuYWN0aXZlUGF0aCk7XG5cdFx0fVxuXHRcdHRoaXMuY2xlYXJTY3JlZW5zQ2FjaGUoKTtcblx0XHR0aGlzLmZvcm1FdmVudEhhbmRsZXJfLnJlbW92ZUxpc3RlbmVyKCk7XG5cdFx0dGhpcy5saW5rRXZlbnRIYW5kbGVyXy5yZW1vdmVMaXN0ZW5lcigpO1xuXHRcdHRoaXMuYXBwRXZlbnRIYW5kbGVyc18ucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cdFx0c3VwZXIuZGlzcG9zZUludGVybmFsKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGlzcGF0Y2hlcyB0byB0aGUgZmlyc3Qgcm91dGUgaGFuZGxlciB0aGF0IG1hdGNoZXMgdGhlIGN1cnJlbnQgcGF0aCwgaWZcblx0ICogYW55LlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IFJldHVybnMgYSBwZW5kaW5nIHJlcXVlc3QgY2FuY2VsbGFibGUgcHJvbWlzZS5cblx0ICovXG5cdGRpc3BhdGNoKCkge1xuXHRcdHJldHVybiB0aGlzLm5hdmlnYXRlKHV0aWxzLmdldEN1cnJlbnRCcm93c2VyUGF0aCgpLCB0cnVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgbmF2aWdhdGlvbiB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZXBsYWNlSGlzdG9yeSBSZXBsYWNlcyBicm93c2VyIGhpc3RvcnkuXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUmV0dXJucyBhIHBlbmRpbmcgcmVxdWVzdCBjYW5jZWxsYWJsZSBwcm9taXNlLlxuXHQgKi9cblx0ZG9OYXZpZ2F0ZV8ocGF0aCwgb3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0dmFyIHJvdXRlID0gdGhpcy5maW5kUm91dGUocGF0aCk7XG5cdFx0aWYgKCFyb3V0ZSkge1xuXHRcdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IoJ05vIHJvdXRlIGZvciAnICsgcGF0aCkpO1xuXHRcdFx0cmV0dXJuIHRoaXMucGVuZGluZ05hdmlnYXRlO1xuXHRcdH1cblxuXHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0ZSB0byBbJyArIHBhdGggKyAnXScpO1xuXG5cdFx0dGhpcy5zdG9wUGVuZGluZ05hdmlnYXRlXygpO1xuXHRcdHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyA9IHRydWU7XG5cblx0XHR2YXIgbmV4dFNjcmVlbiA9IHRoaXMuY3JlYXRlU2NyZWVuSW5zdGFuY2UocGF0aCwgcm91dGUpO1xuXG5cdFx0cmV0dXJuIHRoaXMubWF5YmVQcmV2ZW50RGVhY3RpdmF0ZV8oKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5tYXliZVByZXZlbnRBY3RpdmF0ZV8obmV4dFNjcmVlbikpXG5cdFx0XHQudGhlbigoKSA9PiBuZXh0U2NyZWVuLmxvYWQocGF0aCkpXG5cdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdC8vIEF0IHRoaXMgcG9pbnQgd2UgY2Fubm90IHN0b3AgbmF2aWdhdGlvbiBhbmQgYWxsIHJlY2VpdmVkXG5cdFx0XHRcdC8vIG5hdmlnYXRlIGNhbmRpZGF0ZXMgd2lsbCBiZSBxdWV1ZWQgYXQgc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLlxuXHRcdFx0XHR0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9IE5hdmlnYXRpb25TdHJhdGVneS5TQ0hFRFVMRV9MQVNUO1xuXG5cdFx0XHRcdGlmICh0aGlzLmFjdGl2ZVNjcmVlbikge1xuXHRcdFx0XHRcdHRoaXMuYWN0aXZlU2NyZWVuLmRlYWN0aXZhdGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLnByZXBhcmVOYXZpZ2F0ZUhpc3RvcnlfKHBhdGgsIG5leHRTY3JlZW4sIG9wdF9yZXBsYWNlSGlzdG9yeSk7XG5cdFx0XHRcdHRoaXMucHJlcGFyZU5hdmlnYXRlU3VyZmFjZXNfKFxuXHRcdFx0XHRcdG5leHRTY3JlZW4sXG5cdFx0XHRcdFx0dGhpcy5zdXJmYWNlcyxcblx0XHRcdFx0XHR0aGlzLmV4dHJhY3RQYXJhbXMocm91dGUsIHBhdGgpXG5cdFx0XHRcdCk7XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4oKCkgPT4gbmV4dFNjcmVlbi5ldmFsdWF0ZVN0eWxlcyh0aGlzLnN1cmZhY2VzKSlcblx0XHRcdC50aGVuKCgpID0+IG5leHRTY3JlZW4uZmxpcCh0aGlzLnN1cmZhY2VzKSlcblx0XHRcdC50aGVuKCgpID0+IG5leHRTY3JlZW4uZXZhbHVhdGVTY3JpcHRzKHRoaXMuc3VyZmFjZXMpKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5tYXliZVVwZGF0ZVNjcm9sbFBvc2l0aW9uU3RhdGVfKCkpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLnN5bmNTY3JvbGxQb3NpdGlvblN5bmNUaGVuQXN5bmNfKCkpXG5cdFx0XHQudGhlbigoKSA9PiB0aGlzLmZpbmFsaXplTmF2aWdhdGVfKHBhdGgsIG5leHRTY3JlZW4pKVxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5tYXliZU92ZXJsb2FkQmVmb3JlVW5sb2FkXygpKVxuXHRcdFx0LmNhdGNoKChyZWFzb24pID0+IHtcblx0XHRcdFx0dGhpcy5pc05hdmlnYXRpb25QZW5kaW5nID0gZmFsc2U7XG5cdFx0XHRcdHRoaXMuaGFuZGxlTmF2aWdhdGVFcnJvcl8ocGF0aCwgbmV4dFNjcmVlbiwgcmVhc29uKTtcblx0XHRcdFx0dGhyb3cgcmVhc29uO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuQWx3YXlzKCgpID0+IHtcblx0XHRcdFx0dGhpcy5uYXZpZ2F0aW9uU3RyYXRlZ3kgPSBOYXZpZ2F0aW9uU3RyYXRlZ3kuSU1NRURJQVRFO1xuXG5cdFx0XHRcdGlmICh0aGlzLnNjaGVkdWxlZE5hdmlnYXRpb25RdWV1ZS5sZW5ndGgpIHtcblx0XHRcdFx0XHRjb25zdCBzY2hlZHVsZWROYXZpZ2F0aW9uID0gdGhpcy5zY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUuc2hpZnQoKTtcblx0XHRcdFx0XHR0aGlzLm1heWJlTmF2aWdhdGVfKHNjaGVkdWxlZE5hdmlnYXRpb24uaHJlZiwgc2NoZWR1bGVkTmF2aWdhdGlvbik7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4dHJhY3RzIHBhcmFtcyBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIHBhdGggYW5kIHJvdXRlLlxuXHQgKiBAcGFyYW0geyFSb3V0ZX0gcm91dGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcblx0ICogQHBhcmFtIHshT2JqZWN0fVxuXHQgKi9cblx0ZXh0cmFjdFBhcmFtcyhyb3V0ZSwgcGF0aCkge1xuXHRcdHJldHVybiByb3V0ZS5leHRyYWN0UGFyYW1zKHRoaXMuZ2V0Um91dGVQYXRoKHBhdGgpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaW5hbGl6ZXMgYSBzY3JlZW4gbmF2aWdhdGlvbi5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHBhcmFtIHshU2NyZWVufSBuZXh0U2NyZWVuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGZpbmFsaXplTmF2aWdhdGVfKHBhdGgsIG5leHRTY3JlZW4pIHtcblx0XHRuZXh0U2NyZWVuLmFjdGl2YXRlKCk7XG5cblx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4gJiYgIXRoaXMuYWN0aXZlU2NyZWVuLmlzQ2FjaGVhYmxlKCkpIHtcblx0XHRcdGlmICh0aGlzLmFjdGl2ZVNjcmVlbiAhPT0gbmV4dFNjcmVlbikge1xuXHRcdFx0XHR0aGlzLnJlbW92ZVNjcmVlbih0aGlzLmFjdGl2ZVBhdGgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuYWN0aXZlUGF0aCA9IHBhdGg7XG5cdFx0dGhpcy5hY3RpdmVTY3JlZW4gPSBuZXh0U2NyZWVuO1xuXHRcdHRoaXMuYnJvd3NlclBhdGhCZWZvcmVOYXZpZ2F0ZSA9IHV0aWxzLmdldEN1cnJlbnRCcm93c2VyUGF0aFdpdGhvdXRIYXNoKCk7XG5cdFx0dGhpcy5zY3JlZW5zW3BhdGhdID0gbmV4dFNjcmVlbjtcblx0XHR0aGlzLmlzTmF2aWdhdGlvblBlbmRpbmcgPSBmYWxzZTtcblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IG51bGw7XG5cdFx0Z2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50ID0gbnVsbDtcblx0XHRnbG9iYWxzLmNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQgPSBudWxsO1xuXHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0aW9uIGRvbmUnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGaW5kcyBhIHJvdXRlIGZvciB0aGUgdGVzdCBwYXRoLiBSZXR1cm5zIHRydWUgaWYgbWF0Y2hlcyBoYXMgYSByb3V0ZSxcblx0ICogb3RoZXJ3aXNlIHJldHVybnMgbnVsbC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHJldHVybiB7P09iamVjdH0gUm91dGUgaGFuZGxlciBpZiBtYXRjaCBhbnkgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlXG5cdCAqICAgICBwYXRoIGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IHVybCBhbmQgdGhlIHBhdGggY29udGFpbnMgYSBmcmFnbWVudC5cblx0ICovXG5cdGZpbmRSb3V0ZShwYXRoKSB7XG5cdFx0cGF0aCA9IHRoaXMuZ2V0Um91dGVQYXRoKHBhdGgpO1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5yb3V0ZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciByb3V0ZSA9IHRoaXMucm91dGVzW2ldO1xuXHRcdFx0aWYgKHJvdXRlLm1hdGNoZXNQYXRoKHBhdGgpKSB7XG5cdFx0XHRcdHJldHVybiByb3V0ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIGFsbG93IHByZXZlbnQgbmF2aWdhdGUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRnZXRBbGxvd1ByZXZlbnROYXZpZ2F0ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIGxpbmsgYmFzZSBwYXRoLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0QmFzZVBhdGgoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYmFzZVBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgZGVmYXVsdCBwYWdlIHRpdGxlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IGRlZmF1bHRUaXRsZVxuXHQgKi9cblx0Z2V0RGVmYXVsdFRpdGxlKCkge1xuXHRcdHJldHVybiB0aGlzLmRlZmF1bHRUaXRsZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBmb3JtIHNlbGVjdG9yLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfVxuXHQgKi9cblx0Z2V0Rm9ybVNlbGVjdG9yKCkge1xuXHRcdHJldHVybiB0aGlzLmZvcm1TZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVjayBpZiByb3V0ZSBtYXRjaGluZyBpcyBpZ25vcmluZyBxdWVyeSBzdHJpbmcgZnJvbSB0aGUgcm91dGUgcGF0aC5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGdldElnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCgpIHtcblx0XHRyZXR1cm4gdGhpcy5pZ25vcmVRdWVyeVN0cmluZ0Zyb21Sb3V0ZVBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbGluayBzZWxlY3Rvci5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldExpbmtTZWxlY3RvcigpIHtcblx0XHRyZXR1cm4gdGhpcy5saW5rU2VsZWN0b3I7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbG9hZGluZyBjc3MgY2xhc3MuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRMb2FkaW5nQ3NzQ2xhc3MoKSB7XG5cdFx0cmV0dXJuIHRoaXMubG9hZGluZ0Nzc0NsYXNzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGdpdmVuIHBhdGggZm9ybWF0dGVkIHRvIGJlIG1hdGNoZWQgYnkgYSByb3V0ZS4gVGhpcyB3aWxsLFxuXHQgKiBmb3IgZXhhbXBsZSwgcmVtb3ZlIHRoZSBiYXNlIHBhdGggZnJvbSBpdCwgYnV0IG1ha2Ugc3VyZSBpdCB3aWxsIGVuZFxuXHQgKiB3aXRoIGEgJy8nLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuXHRnZXRSb3V0ZVBhdGgocGF0aCkge1xuXHRcdGlmICh0aGlzLmdldElnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCgpKSB7XG5cdFx0XHRwYXRoID0gdXRpbHMuZ2V0VXJsUGF0aFdpdGhvdXRIYXNoQW5kU2VhcmNoKHBhdGgpO1xuXHRcdFx0cmV0dXJuIHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaChwYXRoLnN1YnN0cih0aGlzLmJhc2VQYXRoLmxlbmd0aCkpO1xuXHRcdH1cblxuXHRcdHBhdGggPSB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2gocGF0aCk7XG5cdFx0cmV0dXJuIHV0aWxzLmdldFVybFBhdGhXaXRob3V0SGFzaChwYXRoLnN1YnN0cih0aGlzLmJhc2VQYXRoLmxlbmd0aCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gdmFsdWUuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuXHRnZXRVcGRhdGVTY3JvbGxQb3NpdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy51cGRhdGVTY3JvbGxQb3NpdGlvbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGUgbmF2aWdhdGlvbiBlcnJvci5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyB0aGUgcXVlcnlzdHJpbmcgcGFydC5cblx0ICogQHBhcmFtIHshU2NyZWVufSBuZXh0U2NyZWVuXG5cdCAqIEBwYXJhbSB7IUVycm9yfSBlcnJvclxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRoYW5kbGVOYXZpZ2F0ZUVycm9yXyhwYXRoLCBuZXh0U2NyZWVuLCBlcnJvcikge1xuXHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0aW9uIGVycm9yIGZvciBbJyArIG5leHRTY3JlZW4gKyAnXSAoJyArIGVycm9yLnN0YWNrICsgJyknKTtcblx0XHR0aGlzLmVtaXQoJ25hdmlnYXRpb25FcnJvcicsIHtcblx0XHRcdGVycm9yLFxuXHRcdFx0bmV4dFNjcmVlbixcblx0XHRcdHBhdGhcblx0XHR9KTtcblx0XHRpZiAoIXV0aWxzLmlzQ3VycmVudEJyb3dzZXJQYXRoKHBhdGgpKSB7XG5cdFx0XHRpZiAodGhpcy5pc05hdmlnYXRpb25QZW5kaW5nICYmIHRoaXMucGVuZGluZ05hdmlnYXRlKSB7XG5cdFx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlLnRoZW5BbHdheXMoKCkgPT4gdGhpcy5yZW1vdmVTY3JlZW4ocGF0aCksIHRoaXMpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTY3JlZW4ocGF0aCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiBhcHAgaGFzIHJvdXRlcy5cblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG5cdGhhc1JvdXRlcygpIHtcblx0XHRyZXR1cm4gdGhpcy5yb3V0ZXMubGVuZ3RoID4gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBUZXN0cyBpZiBob3N0IGlzIGFuIG9mZnNpdGUgbGluay5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBob3N0IExpbmsgaG9zdCB0byBjb21wYXJlIHdpdGhcblx0ICogICAgIDxjb2RlPmdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhvc3Q8L2NvZGU+LlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRpc0xpbmtTYW1lT3JpZ2luXyhob3N0KSB7XG5cdFx0Y29uc3QgaG9zdFVyaSA9IG5ldyBVcmkoaG9zdCk7XG5cdFx0Y29uc3QgbG9jYXRpb25Ib3N0VXJpID0gbmV3IFVyaShnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ob3N0KTtcblxuXHRcdHJldHVybiBob3N0VXJpLmdldFBvcnQoKSA9PT0gbG9jYXRpb25Ib3N0VXJpLmdldFBvcnQoKSAmJiBob3N0VXJpLmdldEhvc3RuYW1lKCkgPT09IGxvY2F0aW9uSG9zdFVyaS5nZXRIb3N0bmFtZSgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIGlmIGxpbmsgZWxlbWVudCBoYXMgdGhlIHNhbWUgYXBwJ3MgYmFzZSBwYXRoLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggTGluayBwYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGlzU2FtZUJhc2VQYXRoXyhwYXRoKSB7XG5cdFx0cmV0dXJuIHBhdGguaW5kZXhPZih0aGlzLmJhc2VQYXRoKSA9PT0gMDtcblx0fVxuXG5cdC8qKlxuXHQgKiBMb2NrIHRoZSBkb2N1bWVudCBzY3JvbGwgaW4gb3JkZXIgdG8gYXZvaWQgdGhlIGJyb3dzZXIgbmF0aXZlIGJhY2sgYW5kXG5cdCAqIGZvcndhcmQgbmF2aWdhdGlvbiB0byBjaGFuZ2UgdGhlIHNjcm9sbCBwb3NpdGlvbi4gSW4gdGhlIGVuZCBvZlxuXHQgKiBuYXZpZ2F0aW9uIGxpZmVjeWNsZSBzY3JvbGwgaXMgcmVwb3NpdGlvbmVkLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRsb2NrSGlzdG9yeVNjcm9sbFBvc2l0aW9uXygpIHtcblx0XHR2YXIgc3RhdGUgPSBnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnN0YXRlO1xuXHRcdGlmICghc3RhdGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Ly8gQnJvd3NlcnMgYXJlIGluY29uc2lzdGVudCB3aGVuIHJlLXBvc2l0aW9uaW5nIHRoZSBzY3JvbGwgaGlzdG9yeSBvblxuXHRcdC8vIHBvcHN0YXRlLiBBdCBzb21lIGJyb3dzZXJzLCBoaXN0b3J5IHNjcm9sbCBoYXBwZW5zIGJlZm9yZSBwb3BzdGF0ZSwgdGhlblxuXHRcdC8vIGxvY2sgdGhlIHNjcm9sbCBvbiB0aGUgbGFzdCBrbm93biBwb3NpdGlvbiBhcyBzb29uIGFzIHBvc3NpYmxlIGFmdGVyIHRoZVxuXHRcdC8vIGN1cnJlbnQgSlMgZXhlY3V0aW9uIGNvbnRleHQgYW5kIGNhcHR1cmUgdGhlIGN1cnJlbnQgdmFsdWUuIFNvbWUgb3RoZXJzLFxuXHRcdC8vIGhpc3Rvcnkgc2Nyb2xsIGhhcHBlbnMgYWZ0ZXIgcG9wc3RhdGUsIGluIHRoaXMgY2FzZSwgd2UgYmluZCBhbiBvbmNlXG5cdFx0Ly8gc2Nyb2xsIGV2ZW50IHRvIGxvY2sgdGhlIGxhcyBrbm93biBwb3NpdGlvbi4gTGFzdGx5LCB0aGUgcHJldmlvdXMgdHdvXG5cdFx0Ly8gYmVoYXZpb3JzIGNhbiBoYXBwZW4gZXZlbiBvbiB0aGUgc2FtZSBicm93c2VyLCBoZW5jZSB0aGUgcmFjZSB3aWxsIGRlY2lkZVxuXHRcdC8vIHRoZSB3aW5uZXIuXG5cdFx0dmFyIHdpbm5lciA9IGZhbHNlO1xuXHRcdHZhciBzd2l0Y2hTY3JvbGxQb3NpdGlvblJhY2UgPSBmdW5jdGlvbigpIHtcblx0XHRcdGdsb2JhbHMuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgc3dpdGNoU2Nyb2xsUG9zaXRpb25SYWNlLCBmYWxzZSk7XG5cdFx0XHRpZiAoIXdpbm5lcikge1xuXHRcdFx0XHRnbG9iYWxzLndpbmRvdy5zY3JvbGxUbyhzdGF0ZS5zY3JvbGxMZWZ0LCBzdGF0ZS5zY3JvbGxUb3ApO1xuXHRcdFx0XHR3aW5uZXIgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0YXN5bmMubmV4dFRpY2soc3dpdGNoU2Nyb2xsUG9zaXRpb25SYWNlKTtcblx0XHRnbG9iYWxzLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHN3aXRjaFNjcm9sbFBvc2l0aW9uUmFjZSwgZmFsc2UpO1xuXHR9XG5cblx0LyoqXG5cdCAqIElmIHN1cHBvcnRlZCBieSB0aGUgYnJvd3NlciwgZGlzYWJsZXMgbmF0aXZlIHNjcm9sbCByZXN0b3JhdGlvbiBhbmRcblx0ICogc3RvcmVzIGN1cnJlbnQgdmFsdWUuXG5cdCAqL1xuXHRtYXliZURpc2FibGVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbigpIHtcblx0XHRpZiAodGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvblN1cHBvcnRlZCkge1xuXHRcdFx0dGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvbl8gPSBnbG9iYWxzLndpbmRvdy5oaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uO1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9ICdtYW51YWwnO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGV2YWx1YXRlIGlmIGlzIHBvc3NpYmxlIHRvIHF1ZXVlIHJlY2VpdmVkXG5cdCAqICBkb20gZXZlbnQgdG8gc2NoZWR1bGVOYXZpZ2F0aW9uUXVldWUgYW5kIGVucXVldWUgaXQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIEluZm9ybWF0aW9uIGFib3V0IHRoZSBsaW5rJ3MgaHJlZi5cblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnQgRG9tIGV2ZW50IHRoYXQgaW5pdGlhdGVkIHRoZSBuYXZpZ2F0aW9uLlxuXHQgKi9cblx0bWF5YmVTY2hlZHVsZU5hdmlnYXRpb25fKGhyZWYsIGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuaXNOYXZpZ2F0aW9uUGVuZGluZyAmJiB0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9PT0gTmF2aWdhdGlvblN0cmF0ZWd5LlNDSEVEVUxFX0xBU1QpIHtcblx0XHRcdHRoaXMuc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlID0gW29iamVjdC5taXhpbih7XG5cdFx0XHRcdGhyZWYsXG5cdFx0XHRcdGlzU2NoZWR1bGVkTmF2aWdhdGlvbjogdHJ1ZVxuXHRcdFx0fSwgZXZlbnQpXTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgbmF2aWdhdGUgdG8gYSBwYXRoLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaHJlZiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgbGluaydzIGhyZWYuXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IERvbSBldmVudCB0aGF0IGluaXRpYXRlZCB0aGUgbmF2aWdhdGlvbi5cblx0ICovXG5cdG1heWJlTmF2aWdhdGVfKGhyZWYsIGV2ZW50KSB7XG5cdFx0aWYgKCF0aGlzLmNhbk5hdmlnYXRlKGhyZWYpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgaXNOYXZpZ2F0aW9uU2NoZWR1bGVkID0gdGhpcy5tYXliZVNjaGVkdWxlTmF2aWdhdGlvbl8oaHJlZiwgZXZlbnQpO1xuXG5cdFx0aWYgKGlzTmF2aWdhdGlvblNjaGVkdWxlZCkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgbmF2aWdhdGVGYWlsZWQgPSBmYWxzZTtcblx0XHR0cnkge1xuXHRcdFx0dGhpcy5uYXZpZ2F0ZSh1dGlscy5nZXRVcmxQYXRoKGhyZWYpLCBmYWxzZSwgZXZlbnQpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Ly8gRG8gbm90IHByZXZlbnQgbGluayBuYXZpZ2F0aW9uIGluIGNhc2Ugc29tZSBzeW5jaHJvbm91cyBlcnJvciBvY2N1cnNcblx0XHRcdG5hdmlnYXRlRmFpbGVkID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoIW5hdmlnYXRlRmFpbGVkICYmICFldmVudC5pc1NjaGVkdWxlZE5hdmlnYXRpb24pIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyB3aGV0aGVyIHRoZSBvbmJlZm9yZXVubG9hZCBnbG9iYWwgZXZlbnQgaGFuZGxlciBpcyBvdmVybG9hZGVkXG5cdCAqIGJ5IGNsaWVudCBjb2RlLiBJZiBzbywgaXQgcmVwbGFjZXMgd2l0aCBhIGZ1bmN0aW9uIHRoYXQgaGFsdHMgdGhlIG5vcm1hbFxuXHQgKiBldmVudCBmbG93IGluIHJlbGF0aW9uIHdpdGggdGhlIGNsaWVudCBvbmJlZm9yZXVubG9hZCBmdW5jdGlvbi5cblx0ICogVGhpcyBjYW4gYmUgaW4gbW9zdCBwYXJ0IHVzZWQgdG8gcHJlbWF0dXJlbHkgdGVybWluYXRlIG5hdmlnYXRpb24gdG8gb3RoZXIgcGFnZXNcblx0ICogYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBjb25zdHJhaXQocykuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG1heWJlT3ZlcmxvYWRCZWZvcmVVbmxvYWRfKCkge1xuXHRcdGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2Ygd2luZG93Lm9uYmVmb3JldW5sb2FkKSB7XG5cdFx0XHR3aW5kb3cuX29uYmVmb3JldW5sb2FkID0gd2luZG93Lm9uYmVmb3JldW5sb2FkO1xuXG5cdFx0XHR3aW5kb3cub25iZWZvcmV1bmxvYWQgPSBldmVudCA9PiB7XG5cdFx0XHRcdHRoaXMuZW1pdCgnYmVmb3JlVW5sb2FkJywgZXZlbnQpO1xuXHRcdFx0XHRpZiAoZXZlbnQgJiYgZXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBtYXJrIHRoZSB1cGRhdGVkIGhhbmRsZXIgZHVlIHVud2FudGVkIHJlY3Vyc2lvblxuXHRcdFx0d2luZG93Lm9uYmVmb3JldW5sb2FkLl9vdmVybG9hZGVkID0gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQ2FuY2VscyBuYXZpZ2F0aW9uIGlmIG5leHRTY3JlZW4ncyBiZWZvcmVBY3RpdmF0ZSBsaWZlY3ljbGUgbWV0aG9kXG5cdCAqIHJlc29sdmVzIHRvIHRydWUuXG5cdCAqIEBwYXJhbSB7IVNjcmVlbn0gbmV4dFNjcmVlblxuXHQgKiBAcmV0dXJuIHshQ2FuY2VsbGFibGVQcm9taXNlfVxuXHQgKi9cblx0bWF5YmVQcmV2ZW50QWN0aXZhdGVfKG5leHRTY3JlZW4pIHtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gbmV4dFNjcmVlbi5iZWZvcmVBY3RpdmF0ZSgpO1xuXHRcdFx0fSlcblx0XHRcdC50aGVuKHByZXZlbnQgPT4ge1xuXHRcdFx0XHRpZiAocHJldmVudCkge1xuXHRcdFx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlID0gQ2FuY2VsbGFibGVQcm9taXNlLnJlamVjdChuZXcgQ2FuY2VsbGFibGVQcm9taXNlLkNhbmNlbGxhdGlvbkVycm9yKCdDYW5jZWxsZWQgYnkgbmV4dCBzY3JlZW4nKSk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMucGVuZGluZ05hdmlnYXRlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDYW5jZWxzIG5hdmlnYXRpb24gaWYgYWN0aXZlU2NyZWVuJ3MgYmVmb3JlRGVhY3RpdmF0ZSBsaWZlY3ljbGVcblx0ICogbWV0aG9kIHJlc29sdmVzIHRvIHRydWUuXG5cdCAqIEByZXR1cm4geyFDYW5jZWxsYWJsZVByb21pc2V9XG5cdCAqL1xuXHRtYXliZVByZXZlbnREZWFjdGl2YXRlXygpIHtcblx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5hY3RpdmVTY3JlZW4pIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5hY3RpdmVTY3JlZW4uYmVmb3JlRGVhY3RpdmF0ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LnRoZW4ocHJldmVudCA9PiB7XG5cdFx0XHRcdGlmIChwcmV2ZW50KSB7XG5cdFx0XHRcdFx0dGhpcy5wZW5kaW5nTmF2aWdhdGUgPSBDYW5jZWxsYWJsZVByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IoJ0NhbmNlbGxlZCBieSBhY3RpdmUgc2NyZWVuJykpO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgcmVwb3NpdGlvbiBzY3JvbGwgdG8gaGFzaGVkIGFuY2hvci5cblx0ICovXG5cdG1heWJlUmVwb3NpdGlvblNjcm9sbFRvSGFzaGVkQW5jaG9yKCkge1xuXHRcdGNvbnN0IGhhc2ggPSBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdGlmIChoYXNoKSB7XG5cdFx0XHRsZXQgYW5jaG9yRWxlbWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGFzaC5zdWJzdHJpbmcoMSkpO1xuXHRcdFx0aWYgKGFuY2hvckVsZW1lbnQpIHtcblx0XHRcdFx0Y29uc3Qge29mZnNldExlZnQsIG9mZnNldFRvcH0gPSB1dGlscy5nZXROb2RlT2Zmc2V0KGFuY2hvckVsZW1lbnQpO1xuXHRcdFx0XHRnbG9iYWxzLndpbmRvdy5zY3JvbGxUbyhvZmZzZXRMZWZ0LCBvZmZzZXRUb3ApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBJZiBzdXBwb3J0ZWQgYnkgdGhlIGJyb3dzZXIsIHJlc3RvcmVzIG5hdGl2ZSBzY3JvbGwgcmVzdG9yYXRpb24gdG8gdGhlXG5cdCAqIHZhbHVlIGNhcHR1cmVkIGJ5IGBtYXliZURpc2FibGVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbmAuXG5cdCAqL1xuXHRtYXliZVJlc3RvcmVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbigpIHtcblx0XHRpZiAodGhpcy5uYXRpdmVTY3JvbGxSZXN0b3JhdGlvblN1cHBvcnRlZCAmJiB0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uXykge1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IHRoaXMubmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25fO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSByZXN0b3JlIHJlZGlyZWN0ZWQgcGF0aCBoYXNoIGluIGNhc2UgYm90aCB0aGUgY3VycmVudCBwYXRoIGFuZFxuXHQgKiB0aGUgZ2l2ZW4gcGF0aCBhcmUgdGhlIHNhbWUuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGJlZm9yZSBuYXZpZ2F0aW9uLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHJlZGlyZWN0UGF0aCBQYXRoIGFmdGVyIG5hdmlnYXRpb24uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaGFzaCBIYXNoIHRvIGJlIGFkZGVkIHRvIHRoZSBwYXRoLlxuXHQgKiBAcmV0dXJuIHshc3RyaW5nfSBSZXR1cm5zIHRoZSBwYXRoIHdpdGggdGhlIGhhc2ggcmVzdG9yZWQuXG5cdCAqL1xuXHRtYXliZVJlc3RvcmVSZWRpcmVjdFBhdGhIYXNoXyhwYXRoLCByZWRpcmVjdFBhdGgsIGhhc2gpIHtcblx0XHRpZiAocmVkaXJlY3RQYXRoID09PSB1dGlscy5nZXRVcmxQYXRoV2l0aG91dEhhc2gocGF0aCkpIHtcblx0XHRcdHJldHVybiByZWRpcmVjdFBhdGggKyBoYXNoO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVkaXJlY3RQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1heWJlIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gaW4gaGlzdG9yeSBzdGF0ZSB0byBhbmNob3Igb24gcGF0aC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBwYXRoIFBhdGggY29udGFpbmluZyBhbmNob3Jcblx0ICovXG5cdG1heWJlVXBkYXRlU2Nyb2xsUG9zaXRpb25TdGF0ZV8oKSB7XG5cdFx0dmFyIGhhc2ggPSBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdHZhciBhbmNob3JFbGVtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChoYXNoLnN1YnN0cmluZygxKSk7XG5cdFx0aWYgKGFuY2hvckVsZW1lbnQpIHtcblx0XHRcdGNvbnN0IHtvZmZzZXRMZWZ0LCBvZmZzZXRUb3B9ID0gdXRpbHMuZ2V0Tm9kZU9mZnNldChhbmNob3JFbGVtZW50KTtcblx0XHRcdHRoaXMuc2F2ZUhpc3RvcnlDdXJyZW50UGFnZVNjcm9sbFBvc2l0aW9uXyhvZmZzZXRUb3AsIG9mZnNldExlZnQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBOYXZpZ2F0ZXMgdG8gdGhlIHNwZWNpZmllZCBwYXRoIGlmIHRoZXJlIGlzIGEgcm91dGUgaGFuZGxlciB0aGF0IG1hdGNoZXMuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIHRvIG5hdmlnYXRlIGNvbnRhaW5pbmcgdGhlIGJhc2UgcGF0aC5cblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JlcGxhY2VIaXN0b3J5IFJlcGxhY2VzIGJyb3dzZXIgaGlzdG9yeS5cblx0ICogQHBhcmFtIHtFdmVudD19IGV2ZW50IE9wdGlvbmFsIGV2ZW50IG9iamVjdCB0aGF0IHRyaWdnZXJlZCB0aGUgbmF2aWdhdGlvbi5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfSBSZXR1cm5zIGEgcGVuZGluZyByZXF1ZXN0IGNhbmNlbGxhYmxlIHByb21pc2UuXG5cdCAqL1xuXHRuYXZpZ2F0ZShwYXRoLCBvcHRfcmVwbGFjZUhpc3RvcnksIG9wdF9ldmVudCkge1xuXHRcdGlmICghdXRpbHMuaXNIdG1sNUhpc3RvcnlTdXBwb3J0ZWQoKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdIVE1MNSBIaXN0b3J5IGlzIG5vdCBzdXBwb3J0ZWQuIFNlbm5hIHdpbGwgbm90IGludGVyY2VwdCBuYXZpZ2F0aW9uLicpO1xuXHRcdH1cblxuXHRcdGlmIChvcHRfZXZlbnQpIHtcblx0XHRcdGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCA9IG9wdF9ldmVudC5jYXB0dXJlZEZvcm1FbGVtZW50O1xuXHRcdFx0Z2xvYmFscy5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50ID0gb3B0X2V2ZW50LmNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gV2hlbiByZWxvYWRpbmcgdGhlIHNhbWUgcGF0aCBkbyByZXBsYWNlU3RhdGUgaW5zdGVhZCBvZiBwdXNoU3RhdGUgdG9cblx0XHQvLyBhdm9pZCBwb2xsdXRpbmcgaGlzdG9yeSB3aXRoIHN0YXRlcyB3aXRoIHRoZSBzYW1lIHBhdGguXG5cdFx0aWYgKHBhdGggPT09IHRoaXMuYWN0aXZlUGF0aCkge1xuXHRcdFx0b3B0X3JlcGxhY2VIaXN0b3J5ID0gdHJ1ZTtcblx0XHR9XG5cblx0XHR0aGlzLmVtaXQoJ2JlZm9yZU5hdmlnYXRlJywge1xuXHRcdFx0ZXZlbnQ6IG9wdF9ldmVudCxcblx0XHRcdHBhdGg6IHBhdGgsXG5cdFx0XHRyZXBsYWNlSGlzdG9yeTogISFvcHRfcmVwbGFjZUhpc3Rvcnlcblx0XHR9KTtcblxuXHRcdHJldHVybiB0aGlzLnBlbmRpbmdOYXZpZ2F0ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBCZWZvcmVzIG5hdmlnYXRpb24gdG8gYSBwYXRoLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlIGNvbnRhaW5pbmcgPGNvZGU+cGF0aDwvY29kZT4gYW5kXG5cdCAqICAgICA8Y29kZT5yZXBsYWNlSGlzdG9yeTwvY29kZT4uXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uQmVmb3JlTmF2aWdhdGVfKGV2ZW50KSB7XG5cdFx0aWYgKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCkge1xuXHRcdFx0ZXZlbnQuZm9ybSA9IGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudDtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQmVmb3JlcyBuYXZpZ2F0aW9uIHRvIGEgcGF0aC4gUnVucyBhZnRlciBleHRlcm5hbCBsaXN0ZW5lcnMuXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGUgY29udGFpbmluZyA8Y29kZT5wYXRoPC9jb2RlPiBhbmRcblx0ICogICAgIDxjb2RlPnJlcGxhY2VIaXN0b3J5PC9jb2RlPi5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25CZWZvcmVOYXZpZ2F0ZURlZmF1bHRfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMucGVuZGluZ05hdmlnYXRlKSB7XG5cdFx0XHRpZiAodGhpcy5wZW5kaW5nTmF2aWdhdGUucGF0aCA9PT0gZXZlbnQucGF0aCB8fCB0aGlzLm5hdmlnYXRpb25TdHJhdGVneSA9PT0gTmF2aWdhdGlvblN0cmF0ZWd5LlNDSEVEVUxFX0xBU1QpIHtcblx0XHRcdFx0Y29uc29sZS5sb2coJ1dhaXRpbmcuLi4nKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuZW1pdCgnYmVmb3JlVW5sb2FkJywgZXZlbnQpO1xuXG5cdFx0dGhpcy5lbWl0KCdzdGFydE5hdmlnYXRlJywge1xuXHRcdFx0Zm9ybTogZXZlbnQuZm9ybSxcblx0XHRcdHBhdGg6IGV2ZW50LnBhdGgsXG5cdFx0XHRyZXBsYWNlSGlzdG9yeTogZXZlbnQucmVwbGFjZUhpc3Rvcnlcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDdXN0b20gZXZlbnQgaGFuZGxlciB0aGF0IGV4ZWN1dGVzIHRoZSBvcmlnaW5hbCBsaXN0ZW5lciB0aGF0IGhhcyBiZWVuXG5cdCAqIGFkZGVkIGJ5IHRoZSBjbGllbnQgY29kZSBhbmQgdGVybWluYXRlcyB0aGUgbmF2aWdhdGlvbiBhY2NvcmRpbmdseS5cblx0ICogQHBhcmFtIHshRXZlbnR9IGV2ZW50IG9yaWdpbmFsIEV2ZW50IGZhY2FkZS5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25CZWZvcmVVbmxvYWREZWZhdWx0XyhldmVudCkge1xuXHRcdHZhciBmdW5jID0gd2luZG93Ll9vbmJlZm9yZXVubG9hZDtcblx0XHRpZiAoZnVuYyAmJiAhZnVuYy5fb3ZlcmxvYWRlZCAmJiBmdW5jKCkpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEludGVyY2VwdHMgZG9jdW1lbnQgY2xpY2tzIGFuZCB0ZXN0IGxpbmsgZWxlbWVudHMgaW4gb3JkZXIgdG8gZGVjaWRlXG5cdCAqIHdoZXRoZXIgU3VyZmFjZSBhcHAgY2FuIG5hdmlnYXRlLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uRG9jQ2xpY2tEZWxlZ2F0ZV8oZXZlbnQpIHtcblx0XHRpZiAoZXZlbnQuYWx0S2V5IHx8IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBldmVudC5zaGlmdEtleSB8fCBldmVudC5idXR0b24pIHtcblx0XHRcdGNvbnNvbGUubG9nKCdOYXZpZ2F0ZSBhYm9ydGVkLCBpbnZhbGlkIG1vdXNlIGJ1dHRvbiBvciBtb2RpZmllciBrZXkgcHJlc3NlZC4nKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5tYXliZU5hdmlnYXRlXyhldmVudC5kZWxlZ2F0ZVRhcmdldC5ocmVmLCBldmVudCk7XG5cdH1cblxuXHQvKipcblx0ICogSW50ZXJjZXB0cyBkb2N1bWVudCBmb3JtIHN1Ym1pdHMgYW5kIHRlc3QgYWN0aW9uIHBhdGggaW4gb3JkZXIgdG8gZGVjaWRlXG5cdCAqIHdoZXRoZXIgU3VyZmFjZSBhcHAgY2FuIG5hdmlnYXRlLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uRG9jU3VibWl0RGVsZWdhdGVfKGV2ZW50KSB7XG5cdFx0dmFyIGZvcm0gPSBldmVudC5kZWxlZ2F0ZVRhcmdldDtcblx0XHRpZiAoZm9ybS5tZXRob2QgPT09ICdnZXQnKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnR0VUIG1ldGhvZCBub3Qgc3VwcG9ydGVkJyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGV2ZW50LmNhcHR1cmVkRm9ybUVsZW1lbnQgPSBmb3JtO1xuXHRcdGNvbnN0IGJ1dHRvblNlbGVjdG9yID0gJ2J1dHRvbjpub3QoW3R5cGVdKSxidXR0b25bdHlwZT1zdWJtaXRdLGlucHV0W3R5cGU9c3VibWl0XSc7XG5cdFx0aWYgKG1hdGNoKGdsb2JhbHMuZG9jdW1lbnQuYWN0aXZlRWxlbWVudCwgYnV0dG9uU2VsZWN0b3IpKSB7XG5cdFx0XHRldmVudC5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50ID0gZ2xvYmFscy5kb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRldmVudC5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50ID0gZm9ybS5xdWVyeVNlbGVjdG9yKGJ1dHRvblNlbGVjdG9yKTtcblx0XHR9XG5cdFx0dGhpcy5tYXliZU5hdmlnYXRlXyhmb3JtLmFjdGlvbiwgZXZlbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIExpc3RlbnMgdG8gdGhlIHdpbmRvdydzIGxvYWQgZXZlbnQgaW4gb3JkZXIgdG8gYXZvaWQgaXNzdWVzIHdpdGggc29tZSBicm93c2Vyc1xuXHQgKiB0aGF0IHRyaWdnZXIgcG9wc3RhdGUgY2FsbHMgb24gdGhlIGZpcnN0IGxvYWQuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZVxuXHQgKiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzY0MjE3NjkvcG9wc3RhdGUtb24tcGFnZXMtbG9hZC1pbi1jaHJvbWUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uTG9hZF8oKSB7XG5cdFx0dGhpcy5za2lwTG9hZFBvcHN0YXRlID0gdHJ1ZTtcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdC8vIFRoZSB0aW1lb3V0IGVuc3VyZXMgdGhhdCBwb3BzdGF0ZSBldmVudHMgd2lsbCBiZSB1bmJsb2NrZWQgcmlnaHRcblx0XHRcdC8vIGFmdGVyIHRoZSBsb2FkIGV2ZW50IG9jY3VyZWQsIGJ1dCBub3QgaW4gdGhlIHNhbWUgZXZlbnQtbG9vcCBjeWNsZS5cblx0XHRcdHRoaXMuc2tpcExvYWRQb3BzdGF0ZSA9IGZhbHNlO1xuXHRcdH0sIDApO1xuXHRcdC8vIFRyeSB0byByZXBvc2l0aW9uIHNjcm9sbCB0byB0aGUgaGFzaGVkIGFuY2hvciB3aGVuIHBhZ2UgbG9hZHMuXG5cdFx0dGhpcy5tYXliZVJlcG9zaXRpb25TY3JvbGxUb0hhc2hlZEFuY2hvcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhhbmRsZXMgYnJvd3NlciBoaXN0b3J5IGNoYW5nZXMgYW5kIGZpcmVzIGFwcCdzIG5hdmlnYXRpb24gaWYgdGhlIHN0YXRlXG5cdCAqIGJlbG93cyB0byB1cy4gSWYgd2UgZGV0ZWN0IGEgcG9wc3RhdGUgYW5kIHRoZSBzdGF0ZSBpcyA8Y29kZT5udWxsPC9jb2RlPixcblx0ICogYXNzdW1lIGl0IGlzIG5hdmlnYXRpbmcgdG8gYW4gZXh0ZXJuYWwgcGFnZSBvciB0byBhIHBhZ2Ugd2UgZG9uJ3QgaGF2ZVxuXHQgKiByb3V0ZSwgdGhlbiA8Y29kZT5nbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTwvY29kZT4gaXMgaW52b2tlZCBpbiBvcmRlciB0b1xuXHQgKiByZWxvYWQgdGhlIGNvbnRlbnQgdG8gdGhlIGN1cnJlbnQgdXJsLlxuXHQgKiBAcGFyYW0geyFFdmVudH0gZXZlbnQgRXZlbnQgZmFjYWRlXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uUG9wc3RhdGVfKGV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuc2tpcExvYWRQb3BzdGF0ZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERvIG5vdCBuYXZpZ2F0ZSBpZiB0aGUgcG9wc3RhdGUgd2FzIHRyaWdnZXJlZCBieSBhIGhhc2ggY2hhbmdlLlxuXHRcdGlmICh1dGlscy5pc0N1cnJlbnRCcm93c2VyUGF0aCh0aGlzLmJyb3dzZXJQYXRoQmVmb3JlTmF2aWdhdGUpKSB7XG5cdFx0XHR0aGlzLm1heWJlUmVwb3NpdGlvblNjcm9sbFRvSGFzaGVkQW5jaG9yKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIHN0YXRlID0gZXZlbnQuc3RhdGU7XG5cblx0XHRpZiAoIXN0YXRlKSB7XG5cdFx0XHRpZiAoZ2xvYmFscy53aW5kb3cubG9jYXRpb24uaGFzaCkge1xuXHRcdFx0XHQvLyBJZiBzZW5uYSBpcyBvbiBhbiByZWRpcmVjdCBwYXRoIGFuZCBhIGhhc2ggcG9wc3RhdGUgaGFwcGVuc1xuXHRcdFx0XHQvLyB0byBhIGRpZmZlcmVudCB1cmwsIHJlbG9hZCB0aGUgYnJvd3Nlci4gVGhpcyBiZWhhdmlvciBkb2Vzbid0XG5cdFx0XHRcdC8vIHJlcXVpcmUgc2VubmEgdG8gcm91dGUgaGFzaGVkIGxpbmtzIGFuZCBpcyBjbG9zZXIgdG8gbmF0aXZlXG5cdFx0XHRcdC8vIGJyb3dzZXIgYmVoYXZpb3IuXG5cdFx0XHRcdGlmICh0aGlzLnJlZGlyZWN0UGF0aCAmJiAhdXRpbHMuaXNDdXJyZW50QnJvd3NlclBhdGgodGhpcy5yZWRpcmVjdFBhdGgpKSB7XG5cdFx0XHRcdFx0dGhpcy5yZWxvYWRQYWdlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gQWx3YXlzIHRyeSB0byByZXBvc2l0aW9uIHNjcm9sbCB0byB0aGUgaGFzaGVkIGFuY2hvciB3aGVuXG5cdFx0XHRcdC8vIGhhc2ggcG9wc3RhdGUgaGFwcGVucy5cblx0XHRcdFx0dGhpcy5tYXliZVJlcG9zaXRpb25TY3JvbGxUb0hhc2hlZEFuY2hvcigpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5yZWxvYWRQYWdlKCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKHN0YXRlLnNlbm5hKSB7XG5cdFx0XHRjb25zb2xlLmxvZygnSGlzdG9yeSBuYXZpZ2F0aW9uIHRvIFsnICsgc3RhdGUucGF0aCArICddJyk7XG5cdFx0XHR0aGlzLnBvcHN0YXRlU2Nyb2xsVG9wID0gc3RhdGUuc2Nyb2xsVG9wO1xuXHRcdFx0dGhpcy5wb3BzdGF0ZVNjcm9sbExlZnQgPSBzdGF0ZS5zY3JvbGxMZWZ0O1xuXHRcdFx0aWYgKCF0aGlzLm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uU3VwcG9ydGVkKSB7XG5cdFx0XHRcdHRoaXMubG9ja0hpc3RvcnlTY3JvbGxQb3NpdGlvbl8oKTtcblx0XHRcdH1cblx0XHRcdHRoaXMub25jZSgnZW5kTmF2aWdhdGUnLCAoKSA9PiB7XG5cdFx0XHRcdGlmIChzdGF0ZS5yZWZlcnJlcikge1xuXHRcdFx0XHRcdHV0aWxzLnNldFJlZmVycmVyKHN0YXRlLnJlZmVycmVyKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRjb25zdCB1cmkgPSBuZXcgVXJpKHN0YXRlLnBhdGgpO1xuXHRcdFx0dXJpLnNldEhvc3RuYW1lKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLmhvc3RuYW1lKTtcblx0XHRcdHVyaS5zZXRQb3J0KGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnBvcnQpO1xuXHRcdFx0Y29uc3QgaXNOYXZpZ2F0aW9uU2NoZWR1bGVkID0gdGhpcy5tYXliZVNjaGVkdWxlTmF2aWdhdGlvbl8odXJpLnRvU3RyaW5nKCksIHt9KTtcblx0XHRcdGlmIChpc05hdmlnYXRpb25TY2hlZHVsZWQpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5uYXZpZ2F0ZShzdGF0ZS5wYXRoLCB0cnVlKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTGlzdGVucyBkb2N1bWVudCBzY3JvbGwgY2hhbmdlcyBpbiBvcmRlciB0byBjYXB0dXJlIHRoZSBwb3NzaWJsZSBsb2NrXG5cdCAqIHNjcm9sbCBwb3NpdGlvbiBmb3IgaGlzdG9yeSBzY3JvbGxpbmcuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdG9uU2Nyb2xsXygpIHtcblx0XHRpZiAodGhpcy5jYXB0dXJlU2Nyb2xsUG9zaXRpb25Gcm9tU2Nyb2xsRXZlbnQpIHtcblx0XHRcdHRoaXMuc2F2ZUhpc3RvcnlDdXJyZW50UGFnZVNjcm9sbFBvc2l0aW9uXyhnbG9iYWxzLndpbmRvdy5wYWdlWU9mZnNldCwgZ2xvYmFscy53aW5kb3cucGFnZVhPZmZzZXQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTdGFydHMgbmF2aWdhdGlvbiB0byBhIHBhdGguXG5cdCAqIEBwYXJhbSB7IUV2ZW50fSBldmVudCBFdmVudCBmYWNhZGUgY29udGFpbmluZyA8Y29kZT5wYXRoPC9jb2RlPiBhbmRcblx0ICogICAgIDxjb2RlPnJlcGxhY2VIaXN0b3J5PC9jb2RlPi5cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cblx0b25TdGFydE5hdmlnYXRlXyhldmVudCkge1xuXHRcdHRoaXMubWF5YmVEaXNhYmxlTmF0aXZlU2Nyb2xsUmVzdG9yYXRpb24oKTtcblx0XHR0aGlzLmNhcHR1cmVTY3JvbGxQb3NpdGlvbkZyb21TY3JvbGxFdmVudCA9IGZhbHNlO1xuXHRcdGFkZENsYXNzZXMoZ2xvYmFscy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIHRoaXMubG9hZGluZ0Nzc0NsYXNzKTtcblxuXHRcdHZhciBlbmROYXZpZ2F0ZVBheWxvYWQgPSB7XG5cdFx0XHRmb3JtOiBldmVudC5mb3JtLFxuXHRcdFx0cGF0aDogZXZlbnQucGF0aFxuXHRcdH07XG5cblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IHRoaXMuZG9OYXZpZ2F0ZV8oZXZlbnQucGF0aCwgZXZlbnQucmVwbGFjZUhpc3RvcnkpXG5cdFx0XHQuY2F0Y2goKHJlYXNvbikgPT4ge1xuXHRcdFx0XHRlbmROYXZpZ2F0ZVBheWxvYWQuZXJyb3IgPSByZWFzb247XG5cdFx0XHRcdHRocm93IHJlYXNvbjtcblx0XHRcdH0pXG5cdFx0XHQudGhlbkFsd2F5cygoKSA9PiB7XG5cdFx0XHRcdGlmICghdGhpcy5wZW5kaW5nTmF2aWdhdGUgJiYgIXRoaXMuc2NoZWR1bGVkTmF2aWdhdGlvblF1ZXVlLmxlbmd0aCkge1xuXHRcdFx0XHRcdHJlbW92ZUNsYXNzZXMoZ2xvYmFscy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIHRoaXMubG9hZGluZ0Nzc0NsYXNzKTtcblx0XHRcdFx0XHR0aGlzLm1heWJlUmVzdG9yZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uKCk7XG5cdFx0XHRcdFx0dGhpcy5jYXB0dXJlU2Nyb2xsUG9zaXRpb25Gcm9tU2Nyb2xsRXZlbnQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuZW1pdCgnZW5kTmF2aWdhdGUnLCBlbmROYXZpZ2F0ZVBheWxvYWQpO1xuXHRcdFx0fSk7XG5cblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZS5wYXRoID0gZXZlbnQucGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQcmVmZXRjaGVzIHRoZSBzcGVjaWZpZWQgcGF0aCBpZiB0aGVyZSBpcyBhIHJvdXRlIGhhbmRsZXIgdGhhdCBtYXRjaGVzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCB0byBuYXZpZ2F0ZSBjb250YWluaW5nIHRoZSBiYXNlIHBhdGguXG5cdCAqIEByZXR1cm4ge0NhbmNlbGxhYmxlUHJvbWlzZX0gUmV0dXJucyBhIHBlbmRpbmcgcmVxdWVzdCBjYW5jZWxsYWJsZSBwcm9taXNlLlxuXHQgKi9cblx0cHJlZmV0Y2gocGF0aCkge1xuXHRcdHZhciByb3V0ZSA9IHRoaXMuZmluZFJvdXRlKHBhdGgpO1xuXHRcdGlmICghcm91dGUpIHtcblx0XHRcdHJldHVybiBDYW5jZWxsYWJsZVByb21pc2UucmVqZWN0KG5ldyBDYW5jZWxsYWJsZVByb21pc2UuQ2FuY2VsbGF0aW9uRXJyb3IoJ05vIHJvdXRlIGZvciAnICsgcGF0aCkpO1xuXHRcdH1cblxuXHRcdGNvbnNvbGUubG9nKCdQcmVmZXRjaGluZyBbJyArIHBhdGggKyAnXScpO1xuXG5cdFx0dmFyIG5leHRTY3JlZW4gPSB0aGlzLmNyZWF0ZVNjcmVlbkluc3RhbmNlKHBhdGgsIHJvdXRlKTtcblxuXHRcdHJldHVybiBuZXh0U2NyZWVuLmxvYWQocGF0aClcblx0XHRcdC50aGVuKCgpID0+IHRoaXMuc2NyZWVuc1twYXRoXSA9IG5leHRTY3JlZW4pXG5cdFx0XHQuY2F0Y2goKHJlYXNvbikgPT4ge1xuXHRcdFx0XHR0aGlzLmhhbmRsZU5hdmlnYXRlRXJyb3JfKHBhdGgsIG5leHRTY3JlZW4sIHJlYXNvbik7XG5cdFx0XHRcdHRocm93IHJlYXNvbjtcblx0XHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFByZXBhcmVzIHNjcmVlbiBmbGlwLiBVcGRhdGVzIGhpc3Rvcnkgc3RhdGUgYW5kIHN1cmZhY2VzIGNvbnRlbnQuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqIEBwYXJhbSB7IVNjcmVlbn0gbmV4dFNjcmVlblxuXHQgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmVwbGFjZUhpc3RvcnkgUmVwbGFjZXMgYnJvd3NlciBoaXN0b3J5LlxuXHQgKi9cblx0cHJlcGFyZU5hdmlnYXRlSGlzdG9yeV8ocGF0aCwgbmV4dFNjcmVlbiwgb3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0bGV0IHRpdGxlID0gbmV4dFNjcmVlbi5nZXRUaXRsZSgpO1xuXHRcdGlmICghaXNTdHJpbmcodGl0bGUpKSB7XG5cdFx0XHR0aXRsZSA9IHRoaXMuZ2V0RGVmYXVsdFRpdGxlKCk7XG5cdFx0fVxuXHRcdGxldCByZWRpcmVjdFBhdGggPSBuZXh0U2NyZWVuLmJlZm9yZVVwZGF0ZUhpc3RvcnlQYXRoKHBhdGgpO1xuXHRcdGNvbnN0IGhpc3RvcnlTdGF0ZSA9IHtcblx0XHRcdGZvcm06IGlzRGVmQW5kTm90TnVsbChnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQpLFxuXHRcdFx0cGF0aCxcblx0XHRcdHJlZGlyZWN0UGF0aCxcblx0XHRcdHNjcm9sbExlZnQ6IDAsXG5cdFx0XHRzY3JvbGxUb3A6IDAsXG5cdFx0XHRzZW5uYTogdHJ1ZVxuXHRcdH07XG5cdFx0aWYgKG9wdF9yZXBsYWNlSGlzdG9yeSkge1xuXHRcdFx0aGlzdG9yeVN0YXRlLnNjcm9sbFRvcCA9IHRoaXMucG9wc3RhdGVTY3JvbGxUb3A7XG5cdFx0XHRoaXN0b3J5U3RhdGUuc2Nyb2xsTGVmdCA9IHRoaXMucG9wc3RhdGVTY3JvbGxMZWZ0O1xuXHRcdH1cblx0XHRjb25zdCBoYXNoID0gbmV3IFVyaShwYXRoKS5nZXRIYXNoKCk7XG5cdFx0cmVkaXJlY3RQYXRoID0gdGhpcy5tYXliZVJlc3RvcmVSZWRpcmVjdFBhdGhIYXNoXyhwYXRoLCByZWRpcmVjdFBhdGgsIGhhc2gpO1xuXHRcdHRoaXMudXBkYXRlSGlzdG9yeV8odGl0bGUsIHJlZGlyZWN0UGF0aCwgbmV4dFNjcmVlbi5iZWZvcmVVcGRhdGVIaXN0b3J5U3RhdGUoaGlzdG9yeVN0YXRlKSwgb3B0X3JlcGxhY2VIaXN0b3J5KTtcblx0XHR0aGlzLnJlZGlyZWN0UGF0aCA9IHJlZGlyZWN0UGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBQcmVwYXJlcyBzY3JlZW4gZmxpcC4gVXBkYXRlcyBoaXN0b3J5IHN0YXRlIGFuZCBzdXJmYWNlcyBjb250ZW50LlxuXHQgKiBAcGFyYW0geyFTY3JlZW59IG5leHRTY3JlZW5cblx0ICogQHBhcmFtIHshT2JqZWN0fSBzdXJmYWNlcyBNYXAgb2Ygc3VyZmFjZXMgdG8gZmxpcCBrZXllZCBieSBzdXJmYWNlIGlkLlxuXHQgKiBAcGFyYW0geyFPYmplY3R9IHBhcmFtcyBQYXJhbXMgZXh0cmFjdGVkIGZyb20gdGhlIGN1cnJlbnQgcGF0aC5cblx0ICovXG5cdHByZXBhcmVOYXZpZ2F0ZVN1cmZhY2VzXyhuZXh0U2NyZWVuLCBzdXJmYWNlcywgcGFyYW1zKSB7XG5cdFx0T2JqZWN0LmtleXMoc3VyZmFjZXMpLmZvckVhY2goKGlkKSA9PiB7XG5cdFx0XHR2YXIgc3VyZmFjZUNvbnRlbnQgPSBuZXh0U2NyZWVuLmdldFN1cmZhY2VDb250ZW50KGlkLCBwYXJhbXMpO1xuXHRcdFx0c3VyZmFjZXNbaWRdLmFkZENvbnRlbnQobmV4dFNjcmVlbi5nZXRJZCgpLCBzdXJmYWNlQ29udGVudCk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2NyZWVuIFsnICsgbmV4dFNjcmVlbi5nZXRJZCgpICsgJ10gYWRkIGNvbnRlbnQgdG8gc3VyZmFjZSAnICtcblx0XHRcdFx0J1snICsgc3VyZmFjZXNbaWRdICsgJ10gWycgKyAoaXNEZWZBbmROb3ROdWxsKHN1cmZhY2VDb250ZW50KSA/ICcuLi4nIDogJ2VtcHR5JykgKyAnXScpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbG9hZHMgdGhlIHBhZ2UgYnkgcGVyZm9ybWluZyBgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpYC5cblx0ICovXG5cdHJlbG9hZFBhZ2UoKSB7XG5cdFx0Z2xvYmFscy53aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlcyByb3V0ZSBpbnN0YW5jZSBmcm9tIGFwcCByb3V0ZXMuXG5cdCAqIEBwYXJhbSB7Um91dGV9IHJvdXRlXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgYW4gZWxlbWVudCB3YXMgcmVtb3ZlZC5cblx0ICovXG5cdHJlbW92ZVJvdXRlKHJvdXRlKSB7XG5cdFx0cmV0dXJuIGFycmF5LnJlbW92ZSh0aGlzLnJvdXRlcywgcm91dGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYSBzY3JlZW4uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aCBQYXRoIGNvbnRhaW5pbmcgdGhlIHF1ZXJ5c3RyaW5nIHBhcnQuXG5cdCAqL1xuXHRyZW1vdmVTY3JlZW4ocGF0aCkge1xuXHRcdHZhciBzY3JlZW4gPSB0aGlzLnNjcmVlbnNbcGF0aF07XG5cdFx0aWYgKHNjcmVlbikge1xuXHRcdFx0T2JqZWN0LmtleXModGhpcy5zdXJmYWNlcykuZm9yRWFjaCgoc3VyZmFjZUlkKSA9PiB0aGlzLnN1cmZhY2VzW3N1cmZhY2VJZF0ucmVtb3ZlKHNjcmVlbi5nZXRJZCgpKSk7XG5cdFx0XHRzY3JlZW4uZGlzcG9zZSgpO1xuXHRcdFx0ZGVsZXRlIHRoaXMuc2NyZWVuc1twYXRoXTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2F2ZXMgZ2l2ZW4gc2Nyb2xsIHBvc2l0aW9uIGludG8gaGlzdG9yeSBzdGF0ZS5cblx0ICogQHBhcmFtIHshbnVtYmVyfSBzY3JvbGxUb3AgTnVtYmVyIGNvbnRhaW5pbmcgdGhlIHRvcCBzY3JvbGwgcG9zaXRpb24gdG8gYmUgc2F2ZWQuXG5cdCAqIEBwYXJhbSB7IW51bWJlcn0gc2Nyb2xsTGVmdCBOdW1iZXIgY29udGFpbmluZyB0aGUgbGVmdCBzY3JvbGwgcG9zaXRpb24gdG8gYmUgc2F2ZWQuXG5cdCAqL1xuXHRzYXZlSGlzdG9yeUN1cnJlbnRQYWdlU2Nyb2xsUG9zaXRpb25fKHNjcm9sbFRvcCwgc2Nyb2xsTGVmdCkge1xuXHRcdHZhciBzdGF0ZSA9IGdsb2JhbHMud2luZG93Lmhpc3Rvcnkuc3RhdGU7XG5cdFx0aWYgKHN0YXRlICYmIHN0YXRlLnNlbm5hKSB7XG5cdFx0XHRbc3RhdGUuc2Nyb2xsVG9wLCBzdGF0ZS5zY3JvbGxMZWZ0XSA9IFtzY3JvbGxUb3AsIHNjcm9sbExlZnRdO1xuXHRcdFx0Z2xvYmFscy53aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoc3RhdGUsIG51bGwsIG51bGwpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIGFsbG93IHByZXZlbnQgbmF2aWdhdGUuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gYWxsb3dQcmV2ZW50TmF2aWdhdGVcblx0ICovXG5cdHNldEFsbG93UHJldmVudE5hdmlnYXRlKGFsbG93UHJldmVudE5hdmlnYXRlKSB7XG5cdFx0dGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZSA9IGFsbG93UHJldmVudE5hdmlnYXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgbGluayBiYXNlIHBhdGguXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gcGF0aFxuXHQgKi9cblx0c2V0QmFzZVBhdGgoYmFzZVBhdGgpIHtcblx0XHR0aGlzLmJhc2VQYXRoID0gdXRpbHMucmVtb3ZlUGF0aFRyYWlsaW5nU2xhc2goYmFzZVBhdGgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGRlZmF1bHQgcGFnZSB0aXRsZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGRlZmF1bHRUaXRsZVxuXHQgKi9cblx0c2V0RGVmYXVsdFRpdGxlKGRlZmF1bHRUaXRsZSkge1xuXHRcdHRoaXMuZGVmYXVsdFRpdGxlID0gZGVmYXVsdFRpdGxlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGZvcm0gc2VsZWN0b3IuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gZm9ybVNlbGVjdG9yXG5cdCAqL1xuXHRzZXRGb3JtU2VsZWN0b3IoZm9ybVNlbGVjdG9yKSB7XG5cdFx0dGhpcy5mb3JtU2VsZWN0b3IgPSBmb3JtU2VsZWN0b3I7XG5cdFx0aWYgKHRoaXMuZm9ybUV2ZW50SGFuZGxlcl8pIHtcblx0XHRcdHRoaXMuZm9ybUV2ZW50SGFuZGxlcl8ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR9XG5cdFx0dGhpcy5mb3JtRXZlbnRIYW5kbGVyXyA9IGRlbGVnYXRlKGRvY3VtZW50LCAnc3VibWl0JywgdGhpcy5mb3JtU2VsZWN0b3IsIHRoaXMub25Eb2NTdWJtaXREZWxlZ2F0ZV8uYmluZCh0aGlzKSwgdGhpcy5hbGxvd1ByZXZlbnROYXZpZ2F0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBpZiByb3V0ZSBtYXRjaGluZyBzaG91bGQgaWdub3JlIHF1ZXJ5IHN0cmluZyBmcm9tIHRoZSByb3V0ZSBwYXRoLlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aFxuXHQgKi9cblx0c2V0SWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoKGlnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCkge1xuXHRcdHRoaXMuaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoID0gaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGxpbmsgc2VsZWN0b3IuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gbGlua1NlbGVjdG9yXG5cdCAqL1xuXHRzZXRMaW5rU2VsZWN0b3IobGlua1NlbGVjdG9yKSB7XG5cdFx0dGhpcy5saW5rU2VsZWN0b3IgPSBsaW5rU2VsZWN0b3I7XG5cdFx0aWYgKHRoaXMubGlua0V2ZW50SGFuZGxlcl8pIHtcblx0XHRcdHRoaXMubGlua0V2ZW50SGFuZGxlcl8ucmVtb3ZlTGlzdGVuZXIoKTtcblx0XHR9XG5cdFx0dGhpcy5saW5rRXZlbnRIYW5kbGVyXyA9IGRlbGVnYXRlKGRvY3VtZW50LCAnY2xpY2snLCB0aGlzLmxpbmtTZWxlY3RvciwgdGhpcy5vbkRvY0NsaWNrRGVsZWdhdGVfLmJpbmQodGhpcyksIHRoaXMuYWxsb3dQcmV2ZW50TmF2aWdhdGUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGxvYWRpbmcgY3NzIGNsYXNzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IGxvYWRpbmdDc3NDbGFzc1xuXHQgKi9cblx0c2V0TG9hZGluZ0Nzc0NsYXNzKGxvYWRpbmdDc3NDbGFzcykge1xuXHRcdHRoaXMubG9hZGluZ0Nzc0NsYXNzID0gbG9hZGluZ0Nzc0NsYXNzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIHVwZGF0ZSBzY3JvbGwgcG9zaXRpb24gdmFsdWUuXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gdXBkYXRlU2Nyb2xsUG9zaXRpb25cblx0ICovXG5cdHNldFVwZGF0ZVNjcm9sbFBvc2l0aW9uKHVwZGF0ZVNjcm9sbFBvc2l0aW9uKSB7XG5cdFx0dGhpcy51cGRhdGVTY3JvbGxQb3NpdGlvbiA9IHVwZGF0ZVNjcm9sbFBvc2l0aW9uO1xuXHR9XG5cblx0LyoqXG5cdCAqIENhbmNlbHMgcGVuZGluZyBuYXZpZ2F0ZSB3aXRoIDxjb2RlPkNhbmNlbCBwZW5kaW5nIG5hdmlnYXRpb248L2NvZGU+IGVycm9yLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRzdG9wUGVuZGluZ05hdmlnYXRlXygpIHtcblx0XHRpZiAodGhpcy5wZW5kaW5nTmF2aWdhdGUpIHtcblx0XHRcdHRoaXMucGVuZGluZ05hdmlnYXRlLmNhbmNlbCgnQ2FuY2VsIHBlbmRpbmcgbmF2aWdhdGlvbicpO1xuXHRcdH1cblx0XHR0aGlzLnBlbmRpbmdOYXZpZ2F0ZSA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogU3luYyBkb2N1bWVudCBzY3JvbGwgcG9zaXRpb24gdHdpY2UsIHRoZSBmaXJzdCBvbmUgc3luY2hyb25vdXMgYW5kIHRoZW5cblx0ICogb25lIGluc2lkZSA8Y29kZT5hc3luYy5uZXh0VGljazwvY29kZT4uIFJlbGV2YW50IHRvIGJyb3dzZXJzIHRoYXQgZmlyZXNcblx0ICogc2Nyb2xsIHJlc3RvcmF0aW9uIGFzeW5jaHJvbm91c2x5IGFmdGVyIHBvcHN0YXRlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEByZXR1cm4gez9DYW5jZWxsYWJsZVByb21pc2U9fVxuXHQgKi9cblx0c3luY1Njcm9sbFBvc2l0aW9uU3luY1RoZW5Bc3luY18oKSB7XG5cdFx0dmFyIHN0YXRlID0gZ2xvYmFscy53aW5kb3cuaGlzdG9yeS5zdGF0ZTtcblx0XHRpZiAoIXN0YXRlKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIHNjcm9sbFRvcCA9IHN0YXRlLnNjcm9sbFRvcDtcblx0XHR2YXIgc2Nyb2xsTGVmdCA9IHN0YXRlLnNjcm9sbExlZnQ7XG5cblx0XHR2YXIgc3luYyA9ICgpID0+IHtcblx0XHRcdGlmICh0aGlzLnVwZGF0ZVNjcm9sbFBvc2l0aW9uKSB7XG5cdFx0XHRcdGdsb2JhbHMud2luZG93LnNjcm9sbFRvKHNjcm9sbExlZnQsIHNjcm9sbFRvcCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiBzeW5jKCkgJiBhc3luYy5uZXh0VGljaygoKSA9PiBzeW5jKCkgJiByZXNvbHZlKCkpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIG9yIHJlcGxhY2UgYnJvd3NlciBoaXN0b3J5LlxuXHQgKiBAcGFyYW0gez9zdHJpbmd9IHRpdGxlIERvY3VtZW50IHRpdGxlLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHBhdGggUGF0aCBjb250YWluaW5nIHRoZSBxdWVyeXN0cmluZyBwYXJ0LlxuXHQgKiBAcGFyYW0geyFvYmplY3R9IHN0YXRlXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZXBsYWNlSGlzdG9yeSBSZXBsYWNlcyBicm93c2VyIGhpc3RvcnkuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHVwZGF0ZUhpc3RvcnlfKHRpdGxlLCBwYXRoLCBzdGF0ZSwgb3B0X3JlcGxhY2VIaXN0b3J5KSB7XG5cdFx0Y29uc3QgcmVmZXJyZXIgPSBnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ocmVmO1xuXG5cdFx0aWYgKHN0YXRlKSB7XG5cdFx0XHRzdGF0ZS5yZWZlcnJlciA9IHJlZmVycmVyO1xuXHRcdH1cblxuXHRcdGlmIChvcHRfcmVwbGFjZUhpc3RvcnkpIHtcblx0XHRcdGdsb2JhbHMud2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHN0YXRlLCB0aXRsZSwgcGF0aCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGdsb2JhbHMud2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKHN0YXRlLCB0aXRsZSwgcGF0aCk7XG5cdFx0fVxuXG5cdFx0dXRpbHMuc2V0UmVmZXJyZXIocmVmZXJyZXIpO1xuXG5cdFx0bGV0IHRpdGxlTm9kZSA9IGdsb2JhbHMuZG9jdW1lbnQucXVlcnlTZWxlY3RvcigndGl0bGUnKTtcblx0XHRpZiAodGl0bGVOb2RlKSB7XG5cdFx0XHR0aXRsZU5vZGUuaW5uZXJIVE1MID0gdGl0bGU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGdsb2JhbHMuZG9jdW1lbnQudGl0bGUgPSB0aXRsZTtcblx0XHR9XG5cdH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBBcHA7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGlzRGVmLCBpc0RlZkFuZE5vdE51bGwgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgVXJpIGZyb20gJ21ldGFsLXVyaSc7XG5pbXBvcnQgeyBDYW5jZWxsYWJsZVByb21pc2UgYXMgUHJvbWlzZSB9IGZyb20gJ21ldGFsLXByb21pc2UnO1xuXG5jbGFzcyBBamF4IHtcblxuXHQvKipcblx0ICogWG1sSHR0cFJlcXVlc3QncyBnZXRBbGxSZXNwb25zZUhlYWRlcnMoKSBtZXRob2QgcmV0dXJucyBhIHN0cmluZyBvZlxuXHQgKiByZXNwb25zZSBoZWFkZXJzIGFjY29yZGluZyB0byB0aGUgZm9ybWF0IGRlc2NyaWJlZCBvbiB0aGUgc3BlYzpcblx0ICoge0BsaW5rIGh0dHA6Ly93d3cudzMub3JnL1RSL1hNTEh0dHBSZXF1ZXN0LyN0aGUtZ2V0YWxscmVzcG9uc2VoZWFkZXJzLW1ldGhvZH0uXG5cdCAqIFRoaXMgbWV0aG9kIHBhcnNlcyB0aGF0IHN0cmluZyBpbnRvIGEgdXNlci1mcmllbmRseSBuYW1lL3ZhbHVlIHBhaXJcblx0ICogb2JqZWN0LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gYWxsSGVhZGVycyBBbGwgaGVhZGVycyBhcyBzdHJpbmcuXG5cdCAqIEByZXR1cm4geyFBcnJheS48T2JqZWN0PHN0cmluZywgc3RyaW5nPj59XG5cdCAqL1xuXHRzdGF0aWMgcGFyc2VSZXNwb25zZUhlYWRlcnMoYWxsSGVhZGVycykge1xuXHRcdHZhciBoZWFkZXJzID0gW107XG5cdFx0aWYgKCFhbGxIZWFkZXJzKSB7XG5cdFx0XHRyZXR1cm4gaGVhZGVycztcblx0XHR9XG5cdFx0dmFyIHBhaXJzID0gYWxsSGVhZGVycy5zcGxpdCgnXFx1MDAwZFxcdTAwMGEnKTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHBhaXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgaW5kZXggPSBwYWlyc1tpXS5pbmRleE9mKCdcXHUwMDNhXFx1MDAyMCcpO1xuXHRcdFx0aWYgKGluZGV4ID4gMCkge1xuXHRcdFx0XHR2YXIgbmFtZSA9IHBhaXJzW2ldLnN1YnN0cmluZygwLCBpbmRleCk7XG5cdFx0XHRcdHZhciB2YWx1ZSA9IHBhaXJzW2ldLnN1YnN0cmluZyhpbmRleCArIDIpO1xuXHRcdFx0XHRoZWFkZXJzLnB1c2goe1xuXHRcdFx0XHRcdG5hbWU6IG5hbWUsXG5cdFx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gaGVhZGVycztcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXF1ZXN0cyB0aGUgdXJsIHVzaW5nIFhNTEh0dHBSZXF1ZXN0LlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHVybFxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IG1ldGhvZFxuXHQgKiBAcGFyYW0gez9zdHJpbmd9IGJvZHlcblx0ICogQHBhcmFtIHtNdWx0aU1hcD19IG9wdF9oZWFkZXJzXG5cdCAqIEBwYXJhbSB7TXVsdGlNYXA9fSBvcHRfcGFyYW1zXG5cdCAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3RpbWVvdXRcblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3N5bmNcblx0ICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3dpdGhDcmVkZW50aWFsc1xuXHQgKiBAcmV0dXJuIHtQcm9taXNlfSBEZWZlcnJlZCBhamF4IHJlcXVlc3QuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdHN0YXRpYyByZXF1ZXN0KHVybCwgbWV0aG9kLCBib2R5LCBvcHRfaGVhZGVycywgb3B0X3BhcmFtcywgb3B0X3RpbWVvdXQsIG9wdF9zeW5jLCBvcHRfd2l0aENyZWRlbnRpYWxzKSB7XG5cdFx0dXJsID0gdXJsIHx8ICcnO1xuXHRcdG1ldGhvZCA9IG1ldGhvZCB8fCAnR0VUJztcblxuXHRcdHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cdFx0dmFyIHByZXZpb3VzUmVhZHlTdGF0ZSA9IDA7XG5cblx0XHR2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuXHRcdFx0cmVxdWVzdC5vbmxvYWQgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKHJlcXVlc3QuYWJvcnRlZCkge1xuXHRcdFx0XHRcdHJlcXVlc3Qub25lcnJvcigpO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXNvbHZlKHJlcXVlc3QpO1xuXHRcdFx0fTtcblx0XHRcdHJlcXVlc3Qub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmIChwcmV2aW91c1JlYWR5U3RhdGUgJiYgcHJldmlvdXNSZWFkeVN0YXRlIDwgMyAmJiA0ID09PSByZXF1ZXN0LnJlYWR5U3RhdGUpIHtcblx0XHRcdFx0XHRyZXF1ZXN0LnRlcm1pbmF0ZWRQcmVtYXR1cmVseSA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0cHJldmlvdXNSZWFkeVN0YXRlID0gcmVxdWVzdC5yZWFkeVN0YXRlO1xuXHRcdFx0fTtcblx0XHRcdHJlcXVlc3Qub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgbWVzc2FnZSA9ICdSZXF1ZXN0IGVycm9yJztcblx0XHRcdFx0aWYgKHJlcXVlc3QudGVybWluYXRlZFByZW1hdHVyZWx5KSB7XG5cdFx0XHRcdFx0bWVzc2FnZSA9ICdSZXF1ZXN0IHRlcm1pbmF0ZWQgcHJlbWF0dXJlbHknO1xuXHRcdFx0XHR9IFxuXHRcdFx0XHR2YXIgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSk7XG5cdFx0XHRcdGVycm9yLnJlcXVlc3QgPSByZXF1ZXN0O1xuXHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0fTtcblx0XHR9KS50aGVuQ2F0Y2goZnVuY3Rpb24ocmVhc29uKSB7XG5cdFx0XHRyZXF1ZXN0LmFib3J0KCk7XG5cdFx0XHR0aHJvdyByZWFzb247XG5cdFx0fSkudGhlbkFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblx0XHR9KTtcblxuXHRcdHVybCA9IG5ldyBVcmkodXJsKTtcblxuXHRcdGlmIChvcHRfcGFyYW1zKSB7XG5cdFx0XHR1cmwuYWRkUGFyYW1ldGVyc0Zyb21NdWx0aU1hcChvcHRfcGFyYW1zKS50b1N0cmluZygpO1xuXHRcdH1cblxuXHRcdHVybCA9IHVybC50b1N0cmluZygpO1xuXG5cdFx0cmVxdWVzdC5vcGVuKG1ldGhvZCwgdXJsLCAhb3B0X3N5bmMpO1xuXG5cdFx0aWYgKG9wdF93aXRoQ3JlZGVudGlhbHMpIHtcblx0XHRcdHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAob3B0X2hlYWRlcnMpIHtcblx0XHRcdG9wdF9oZWFkZXJzLm5hbWVzKCkuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG5cdFx0XHRcdHJlcXVlc3Quc2V0UmVxdWVzdEhlYWRlcihuYW1lLCBvcHRfaGVhZGVycy5nZXRBbGwobmFtZSkuam9pbignLCAnKSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRyZXF1ZXN0LnNlbmQoaXNEZWYoYm9keSkgPyBib2R5IDogbnVsbCk7XG5cblx0XHRpZiAoaXNEZWZBbmROb3ROdWxsKG9wdF90aW1lb3V0KSkge1xuXHRcdFx0dmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRwcm9taXNlLmNhbmNlbCgnUmVxdWVzdCB0aW1lb3V0Jyk7XG5cdFx0XHR9LCBvcHRfdGltZW91dCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHByb21pc2U7XG5cdH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBBamF4O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEhvbGRzIHZhbHVlIGVycm9yIG1lc3NhZ2VzLlxuICogQGNvbnN0XG4gKi9cbmNsYXNzIGVycm9ycyB7XG59XG5cbi8qKlxuICogSW52YWxpZCBzdGF0dXMgZXJyb3IgbWVzc2FnZS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cbmVycm9ycy5JTlZBTElEX1NUQVRVUyA9ICdJbnZhbGlkIHN0YXR1cyBjb2RlJztcblxuLyoqXG4gKiBSZXF1ZXN0IGVycm9yIG1lc3NhZ2UuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQHN0YXRpY1xuICovXG5lcnJvcnMuUkVRVUVTVF9FUlJPUiA9ICdSZXF1ZXN0IGVycm9yJztcblxuLyoqXG4gKiBSZXF1ZXN0IHRpbWVvdXQgZXJyb3IgbWVzc2FnZS5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAc3RhdGljXG4gKi9cbmVycm9ycy5SRVFVRVNUX1RJTUVPVVQgPSAnUmVxdWVzdCB0aW1lb3V0JztcblxuLyoqXG4gKiBSZXF1ZXN0IGlzIGJsb2NrZWQgYnkgQ09SUyBpc3N1ZSBtZXNzYWdlLlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBzdGF0aWNcbiAqL1xuZXJyb3JzLlJFUVVFU1RfUFJFTUFUVVJFX1RFUk1JTkFUSU9OID0gJ1JlcXVlc3QgdGVybWluYXRlZCBwcmVtYXR1cmVseSc7XG5cbmV4cG9ydCBkZWZhdWx0IGVycm9ycztcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHtpc1NlcnZlclNpZGV9IGZyb20gJ21ldGFsJztcblxuLyoqXG4gKiBNZXRhbC5qcyBicm93c2VyIHVzZXIgYWdlbnQgZGV0ZWN0aW9uLiBJdCdzIGV4dHJlbWVseSByZWNvbW1lbmRlZCB0aGUgdXNhZ2VcbiAqIG9mIGZlYXR1cmUgY2hlY2tpbmcgb3ZlciBicm93c2VyIHVzZXIgYWdlbnQgc25pZmZpbmcuIFVuZm9ydHVuYXRlbHksIGluIHNvbWVcbiAqIHNpdHVhdGlvbnMgZmVhdHVyZSBjaGVja2luZyBjYW4gYmUgc2xvdyBvciBldmVuIGltcG9zc2libGUsIHRoZXJlZm9yZSB1c2VcbiAqIHRoaXMgdXRpbGl0eSB3aXRoIGNhdXRpb24uXG4gKiBAc2VlIDxhIGhyZWY9XCJodHRwOi8vd3d3LnVzZXJhZ2VudHN0cmluZy5jb20vXCI+VXNlciBhZ2VudCBzdHJpbmdzPC9hPi5cbiAqL1xuY2xhc3MgVUEge1xuXHQvKipcblx0ICogR2V0cyB0aGUgbmF0aXZlIHVzZXJBZ2VudCBzdHJpbmcgZnJvbSBuYXZpZ2F0b3IgaWYgaXQgZXhpc3RzLiBJZlxuXHQgKiBuYXZpZ2F0b3Igb3IgbmF2aWdhdG9yLnVzZXJBZ2VudCBzdHJpbmcgaXMgbWlzc2luZywgcmV0dXJucyBhbiBlbXB0eVxuXHQgKiBzdHJpbmcuXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICogQHByaXZhdGVcblx0ICogQHN0YXRpY1xuXHQgKi9cblx0c3RhdGljIGdldE5hdGl2ZVVzZXJBZ2VudCgpIHtcblx0XHRsZXQgbmF2aWdhdG9yID0gVUEuZ2xvYmFscy53aW5kb3cgJiYgVUEuZ2xvYmFscy53aW5kb3cubmF2aWdhdG9yO1xuXHRcdGlmIChuYXZpZ2F0b3IpIHtcblx0XHRcdGxldCB1c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuXHRcdFx0aWYgKHVzZXJBZ2VudCkge1xuXHRcdFx0XHRyZXR1cm4gdXNlckFnZW50O1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gJyc7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgbmF0aXZlIHBsYXRmb3JtIHN0cmluZyBmcm9tIG5hdmlnYXRvciBpZiBpdCBleGlzdHMuIElmXG5cdCAqIG5hdmlnYXRvciBvciBuYXZpZ2F0b3IucGxhdGZvcm0gc3RyaW5nIGlzIG1pc3NpbmcsIHJldHVybnMgYW4gZW1wdHlcblx0ICogc3RyaW5nLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBnZXROYXRpdmVQbGF0Zm9ybSgpIHtcblx0XHRsZXQgbmF2aWdhdG9yID0gVUEuZ2xvYmFscy53aW5kb3cgJiYgVUEuZ2xvYmFscy53aW5kb3cubmF2aWdhdG9yO1xuXHRcdGlmIChuYXZpZ2F0b3IpIHtcblx0XHRcdGxldCBwbGF0Zm9ybSA9IG5hdmlnYXRvci5wbGF0Zm9ybTtcblx0XHRcdGlmIChwbGF0Zm9ybSkge1xuXHRcdFx0XHRyZXR1cm4gcGxhdGZvcm07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAnJztcblx0fVxuXG5cdC8qKlxuXHQgKiBXaGV0aGVyIHRoZSBwbGF0Zm9ybSBjb250YWlucyB0aGUgZ2l2ZW4gc3RyaW5nLCBpZ25vcmluZyBjYXNlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqIEBwcml2YXRlXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyBtYXRjaFBsYXRmb3JtKHN0cikge1xuXHRcdHJldHVybiBVQS5wbGF0Zm9ybS5pbmRleE9mKHN0cikgIT09IC0xO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdoZXRoZXIgdGhlIHVzZXIgYWdlbnQgY29udGFpbnMgdGhlIGdpdmVuIHN0cmluZywgaWdub3JpbmcgY2FzZS5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0clxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAc3RhdGljXG5cdCAqL1xuXHRzdGF0aWMgbWF0Y2hVc2VyQWdlbnQoc3RyKSB7XG5cdFx0cmV0dXJuIFVBLnVzZXJBZ2VudC5pbmRleE9mKHN0cikgIT09IC0xO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRlc3RzIHRoZSB1c2VyIGFnZW50LlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdXNlckFnZW50IFRoZSB1c2VyIGFnZW50IHN0cmluZy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHBsYXRmb3JtXG5cdCAqIEBzdGF0aWNcblx0ICovXG5cdHN0YXRpYyB0ZXN0VXNlckFnZW50KHVzZXJBZ2VudCA9ICcnLCBwbGF0Zm9ybSA9ICcnKSB7XG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHVzZXIgYWdlbnQgdmFsdWUgZXh0cmFjdGVkIGZyb20gYnJvd3NlciBuYXRpdmUgdXNlciBhZ2VudC5cblx0XHQgKiBAdHlwZSB7c3RyaW5nfVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS51c2VyQWdlbnQgPSB1c2VyQWdlbnQ7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgcGxhdGZvcm0gdmFsdWUgZXh0cmFjdGVkIGZyb20gYnJvd3NlciBuYXRpdmUgcGxhdGZvcm0uXG5cdFx0ICogQHR5cGUge3N0cmluZ31cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEucGxhdGZvcm0gPSBwbGF0Zm9ybTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBPUyBpcyBNYWMuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzTWFjID0gVUEubWF0Y2hQbGF0Zm9ybSgnTWFjJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgT1MgaXMgV2luLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc1dpbiA9IFVBLm1hdGNoUGxhdGZvcm0oJ1dpbicpO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciB0aGUgdXNlcidzIGJyb3dzZXIgaXMgT3BlcmEuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzT3BlcmEgPSBVQS5tYXRjaFVzZXJBZ2VudCgnT3BlcmEnKSB8fCBVQS5tYXRjaFVzZXJBZ2VudCgnT1BSJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBJRS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNJZSA9IFVBLm1hdGNoVXNlckFnZW50KCdUcmlkZW50JykgfHwgVUEubWF0Y2hVc2VyQWdlbnQoJ01TSUUnKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIEVkZ2UuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzRWRnZSA9IFVBLm1hdGNoVXNlckFnZW50KCdFZGdlJyk7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBJRSBvciBFZGdlLlxuXHRcdCAqIEB0eXBlIHtib29sZWFufVxuXHRcdCAqIEBzdGF0aWNcblx0XHQgKi9cblx0XHRVQS5pc0llT3JFZGdlID0gVUEuaXNJZSB8fCBVQS5pc0VkZ2U7XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIHRoZSB1c2VyJ3MgYnJvd3NlciBpcyBDaHJvbWUuXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzQ2hyb21lID1cblx0XHRcdChVQS5tYXRjaFVzZXJBZ2VudCgnQ2hyb21lJykgfHwgVUEubWF0Y2hVc2VyQWdlbnQoJ0NyaU9TJykpICYmXG5cdFx0XHQhVUEuaXNPcGVyYSAmJlxuXHRcdFx0IVVBLmlzRWRnZTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIFNhZmFyaS5cblx0XHQgKiBAdHlwZSB7Ym9vbGVhbn1cblx0XHQgKiBAc3RhdGljXG5cdFx0ICovXG5cdFx0VUEuaXNTYWZhcmkgPVxuXHRcdFx0VUEubWF0Y2hVc2VyQWdlbnQoJ1NhZmFyaScpICYmXG5cdFx0XHQhKFVBLmlzQ2hyb21lIHx8IFVBLmlzT3BlcmEgfHwgVUEuaXNFZGdlKTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZXRoZXIgdGhlIHVzZXIncyBicm93c2VyIGlzIEZpcmVmb3guXG5cdFx0ICogQHR5cGUge2Jvb2xlYW59XG5cdFx0ICogQHN0YXRpY1xuXHRcdCAqL1xuXHRcdFVBLmlzRmlyZWZveCA9IFVBLm1hdGNoVXNlckFnZW50KCdGaXJlZm94Jyk7XG5cdH1cbn1cblxuLyoqXG4gKiBFeHBvc2VzIGdsb2JhbCByZWZlcmVuY2VzLlxuICogQHR5cGUge29iamVjdH1cbiAqIEBzdGF0aWNcbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFVBLCAnZ2xvYmFscycsIHtcblx0d3JpdGFibGU6IHRydWUsXG5cdHZhbHVlOiB7XG5cdFx0d2luZG93OiBpc1NlcnZlclNpZGUoKSA/IG51bGwgOiB3aW5kb3csXG5cdH0sXG59KTtcblxuVUEudGVzdFVzZXJBZ2VudChVQS5nZXROYXRpdmVVc2VyQWdlbnQoKSwgVUEuZ2V0TmF0aXZlUGxhdGZvcm0oKSk7XG5cbmV4cG9ydCBkZWZhdWx0IFVBO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBpc0RlZkFuZE5vdE51bGwgfSBmcm9tICdtZXRhbCc7XG5pbXBvcnQgQWpheCBmcm9tICdtZXRhbC1hamF4JztcbmltcG9ydCB7IE11bHRpTWFwIH0gZnJvbSAnbWV0YWwtc3RydWN0cyc7XG5pbXBvcnQgQ2FuY2VsbGFibGVQcm9taXNlIGZyb20gJ21ldGFsLXByb21pc2UnO1xuaW1wb3J0IGVycm9ycyBmcm9tICcuLi9lcnJvcnMvZXJyb3JzJztcbmltcG9ydCB1dGlscyBmcm9tICcuLi91dGlscy91dGlscyc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFNjcmVlbiBmcm9tICcuL1NjcmVlbic7XG5pbXBvcnQgVXJpIGZyb20gJ21ldGFsLXVyaSc7XG5pbXBvcnQgVUEgZnJvbSAnbWV0YWwtdXNlcmFnZW50JztcblxuY2xhc3MgUmVxdWVzdFNjcmVlbiBleHRlbmRzIFNjcmVlbiB7XG5cblx0LyoqXG5cdCAqIFJlcXVlc3Qgc2NyZWVuIGFic3RyYWN0IGNsYXNzIHRvIHBlcmZvcm0gaW8gb3BlcmF0aW9ucyBvbiBkZXNjZW5kYW50XG5cdCAqIHNjcmVlbnMuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAZXh0ZW5kcyB7U2NyZWVufVxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEBpbmhlcml0RG9jXG5cdFx0ICogQGRlZmF1bHQgdHJ1ZVxuXHRcdCAqL1xuXHRcdHRoaXMuY2FjaGVhYmxlID0gdHJ1ZTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIGRlZmF1bHQgaHR0cCBoZWFkZXJzIHRvIHNldCBvbiByZXF1ZXN0LlxuXHRcdCAqIEB0eXBlIHs/T2JqZWN0PX1cblx0XHQgKiBAZGVmYXVsdCB7XG5cdFx0ICogICAnWC1QSkFYJzogJ3RydWUnLFxuXHRcdCAqICAgJ1gtUmVxdWVzdGVkLVdpdGgnOiAnWE1MSHR0cFJlcXVlc3QnXG5cdFx0ICogfVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLmh0dHBIZWFkZXJzID0ge1xuXHRcdFx0J1gtUEpBWCc6ICd0cnVlJyxcblx0XHRcdCdYLVJlcXVlc3RlZC1XaXRoJzogJ1hNTEh0dHBSZXF1ZXN0J1xuXHRcdH07XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyBkZWZhdWx0IGh0dHAgbWV0aG9kIHRvIHBlcmZvcm0gdGhlIHJlcXVlc3QuXG5cdFx0ICogQHR5cGUgeyFzdHJpbmd9XG5cdFx0ICogQGRlZmF1bHQgUmVxdWVzdFNjcmVlbi5HRVRcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5odHRwTWV0aG9kID0gUmVxdWVzdFNjcmVlbi5HRVQ7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgWEhSIG9iamVjdCByZXNwb25zaWJsZSBmb3IgdGhlIHJlcXVlc3QuXG5cdFx0ICogQHR5cGUge1hNTEh0dHBSZXF1ZXN0fVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5yZXF1ZXN0ID0gbnVsbDtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuXHRcdCAqIEB0eXBlIHshbnVtYmVyfVxuXHRcdCAqIEBkZWZhdWx0IDMwMDAwXG5cdFx0ICogQHByb3RlY3RlZFxuXHRcdCAqL1xuXHRcdHRoaXMudGltZW91dCA9IDMwMDAwO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFzc2VydHMgdGhhdCByZXNwb25zZSBzdGF0dXMgY29kZSBpcyB2YWxpZC5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXR1c1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRhc3NlcnRWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZShzdGF0dXMpIHtcblx0XHRpZiAoIXRoaXMuaXNWYWxpZFJlc3BvbnNlU3RhdHVzQ29kZShzdGF0dXMpKSB7XG5cdFx0XHR2YXIgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3JzLklOVkFMSURfU1RBVFVTKTtcblx0XHRcdGVycm9yLmludmFsaWRTdGF0dXMgPSB0cnVlO1xuXHRcdFx0ZXJyb3Iuc3RhdHVzQ29kZSA9IHN0YXR1cztcblx0XHRcdHRocm93IGVycm9yO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0YmVmb3JlVXBkYXRlSGlzdG9yeVBhdGgocGF0aCkge1xuXHRcdHZhciByZWRpcmVjdFBhdGggPSB0aGlzLmdldFJlcXVlc3RQYXRoKCk7XG5cdFx0aWYgKHJlZGlyZWN0UGF0aCAmJiByZWRpcmVjdFBhdGggIT09IHBhdGgpIHtcblx0XHRcdHJldHVybiByZWRpcmVjdFBhdGg7XG5cdFx0fVxuXHRcdHJldHVybiBwYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRiZWZvcmVVcGRhdGVIaXN0b3J5U3RhdGUoc3RhdGUpIHtcblx0XHQvLyBJZiBzdGF0ZSBpcyBvdXJzIGFuZCBuYXZpZ2F0ZSB0byBwb3N0LXdpdGhvdXQtcmVkaXJlY3QtZ2V0IHNldFxuXHRcdC8vIGhpc3Rvcnkgc3RhdGUgdG8gbnVsbCwgdGhhdCB3YXkgU2VubmEgd2lsbCByZWxvYWQgdGhlIHBhZ2Ugb25cblx0XHQvLyBwb3BzdGF0ZSBzaW5jZSBpdCBjYW5ub3QgcHJlZGljdCBwb3N0IGRhdGEuXG5cdFx0aWYgKHN0YXRlLnNlbm5hICYmIHN0YXRlLmZvcm0gJiYgc3RhdGUucmVkaXJlY3RQYXRoID09PSBzdGF0ZS5wYXRoKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cdFx0cmV0dXJuIHN0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEZvcm1hdHMgbG9hZCBwYXRoIGJlZm9yZSBpbnZva2luZyBhamF4IGNhbGwuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gRm9ybWF0dGVkIHBhdGg7XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG5cdGZvcm1hdExvYWRQYXRoKHBhdGgpIHtcblx0XHR2YXIgdXJpID0gbmV3IFVyaShwYXRoKTtcblxuXHRcdHVyaS5zZXRIb3N0bmFtZShnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSk7XG5cdFx0dXJpLnNldFByb3RvY29sKGdsb2JhbHMud2luZG93LmxvY2F0aW9uLnByb3RvY29sKTtcblxuXHRcdGlmIChnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wb3J0KSB7XG5cdFx0XHR1cmkuc2V0UG9ydChnbG9iYWxzLndpbmRvdy5sb2NhdGlvbi5wb3J0KTtcblx0XHR9XG5cblx0XHRpZiAoVUEuaXNJZU9yRWRnZSAmJiB0aGlzLmh0dHBNZXRob2QgPT09IFJlcXVlc3RTY3JlZW4uR0VUKSB7XG5cdFx0XHRyZXR1cm4gdXJpLm1ha2VVbmlxdWUoKS50b1N0cmluZygpO1xuXHRcdH1cblxuXHRcdHJldHVybiB1cmkudG9TdHJpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBodHRwIGhlYWRlcnMuXG5cdCAqIEByZXR1cm4gez9PYmplY3Q9fVxuXHQgKi9cblx0Z2V0SHR0cEhlYWRlcnMoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaHR0cEhlYWRlcnM7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgaHR0cCBtZXRob2QuXG5cdCAqIEByZXR1cm4geyFzdHJpbmd9XG5cdCAqL1xuXHRnZXRIdHRwTWV0aG9kKCkge1xuXHRcdHJldHVybiB0aGlzLmh0dHBNZXRob2Q7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyByZXF1ZXN0IHBhdGguXG5cdCAqIEByZXR1cm4ge3N0cmluZz19XG5cdCAqL1xuXHRnZXRSZXF1ZXN0UGF0aCgpIHtcblx0XHR2YXIgcmVxdWVzdCA9IHRoaXMuZ2V0UmVxdWVzdCgpO1xuXHRcdGlmIChyZXF1ZXN0KSB7XG5cdFx0XHR2YXIgcmVxdWVzdFBhdGggPSByZXF1ZXN0LnJlcXVlc3RQYXRoO1xuXHRcdFx0dmFyIHJlc3BvbnNlVXJsID0gdGhpcy5tYXliZUV4dHJhY3RSZXNwb25zZVVybEZyb21SZXF1ZXN0KHJlcXVlc3QpO1xuXHRcdFx0aWYgKHJlc3BvbnNlVXJsKSB7XG5cdFx0XHRcdHJlcXVlc3RQYXRoID0gcmVzcG9uc2VVcmw7XG5cdFx0XHR9XG5cdFx0XHRpZiAoVUEuaXNJZU9yRWRnZSAmJiB0aGlzLmh0dHBNZXRob2QgPT09IFJlcXVlc3RTY3JlZW4uR0VUKSB7XG5cdFx0XHRcdHJlcXVlc3RQYXRoID0gbmV3IFVyaShyZXF1ZXN0UGF0aCkucmVtb3ZlVW5pcXVlKCkudG9TdHJpbmcoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB1dGlscy5nZXRVcmxQYXRoKHJlcXVlc3RQYXRoKTtcblx0XHR9XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcmVxdWVzdCBvYmplY3QuXG5cdCAqIEByZXR1cm4gez9PYmplY3R9XG5cdCAqL1xuXHRnZXRSZXF1ZXN0KCkge1xuXHRcdHJldHVybiB0aGlzLnJlcXVlc3Q7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgcmVxdWVzdCB0aW1lb3V0LlxuXHQgKiBAcmV0dXJuIHshbnVtYmVyfVxuXHQgKi9cblx0Z2V0VGltZW91dCgpIHtcblx0XHRyZXR1cm4gdGhpcy50aW1lb3V0O1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrcyBpZiByZXNwb25zZSBzdWNjZWVkZWQuIEFueSBzdGF0dXMgY29kZSAyeHggb3IgM3h4IGlzIGNvbnNpZGVyZWRcblx0ICogdmFsaWQuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGF0dXNDb2RlXG5cdCAqL1xuXHRpc1ZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlKHN0YXR1c0NvZGUpIHtcblx0XHRyZXR1cm4gc3RhdHVzQ29kZSA+PSAyMDAgJiYgc3RhdHVzQ29kZSA8PSAzOTk7XG5cdH1cblxuXHQvKipcblx0ICogQGluaGVyaXREb2Ncblx0ICovXG5cdGxvYWQocGF0aCkge1xuXHRcdGNvbnN0IGNhY2hlID0gdGhpcy5nZXRDYWNoZSgpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwoY2FjaGUpKSB7XG5cdFx0XHRyZXR1cm4gQ2FuY2VsbGFibGVQcm9taXNlLnJlc29sdmUoY2FjaGUpO1xuXHRcdH1cblx0XHRsZXQgYm9keSA9IG51bGw7XG5cdFx0bGV0IGh0dHBNZXRob2QgPSB0aGlzLmh0dHBNZXRob2Q7XG5cdFx0Y29uc3QgaGVhZGVycyA9IG5ldyBNdWx0aU1hcCgpO1xuXHRcdE9iamVjdC5rZXlzKHRoaXMuaHR0cEhlYWRlcnMpLmZvckVhY2goaGVhZGVyID0+IGhlYWRlcnMuYWRkKGhlYWRlciwgdGhpcy5odHRwSGVhZGVyc1toZWFkZXJdKSk7XG5cdFx0aWYgKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCkge1xuXHRcdFx0dGhpcy5hZGRTYWZhcmlYSFJQb2x5ZmlsbCgpO1xuXHRcdFx0Ym9keSA9IG5ldyBGb3JtRGF0YShnbG9iYWxzLmNhcHR1cmVkRm9ybUVsZW1lbnQpO1xuXHRcdFx0dGhpcy5tYXliZUFwcGVuZFN1Ym1pdEJ1dHRvblZhbHVlXyhib2R5KTtcblx0XHRcdGh0dHBNZXRob2QgPSBSZXF1ZXN0U2NyZWVuLlBPU1Q7XG5cdFx0XHRpZiAoVUEuaXNJZU9yRWRnZSkge1xuXHRcdFx0XHRoZWFkZXJzLmFkZCgnSWYtTm9uZS1NYXRjaCcsICdcIjBcIicpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRjb25zdCByZXF1ZXN0UGF0aCA9IHRoaXMuZm9ybWF0TG9hZFBhdGgocGF0aCk7XG5cdFx0cmV0dXJuIEFqYXhcblx0XHRcdC5yZXF1ZXN0KHJlcXVlc3RQYXRoLCBodHRwTWV0aG9kLCBib2R5LCBoZWFkZXJzLCBudWxsLCB0aGlzLnRpbWVvdXQpXG5cdFx0XHQudGhlbih4aHIgPT4ge1xuXHRcdFx0XHR0aGlzLnJlbW92ZVNhZmFyaVhIUlBvbHlmaWxsKCk7XG5cdFx0XHRcdHRoaXMuc2V0UmVxdWVzdCh4aHIpO1xuXHRcdFx0XHR0aGlzLmFzc2VydFZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlKHhoci5zdGF0dXMpO1xuXHRcdFx0XHRpZiAoaHR0cE1ldGhvZCA9PT0gUmVxdWVzdFNjcmVlbi5HRVQgJiYgdGhpcy5pc0NhY2hlYWJsZSgpKSB7XG5cdFx0XHRcdFx0dGhpcy5hZGRDYWNoZSh4aHIucmVzcG9uc2VUZXh0KTtcblx0XHRcdFx0fVxuXHRcdFx0XHR4aHIucmVxdWVzdFBhdGggPSByZXF1ZXN0UGF0aDtcblx0XHRcdFx0cmV0dXJuIHhoci5yZXNwb25zZVRleHQ7XG5cdFx0XHR9KVxuXHRcdFx0LmNhdGNoKChyZWFzb24pID0+IHtcblx0XHRcdFx0dGhpcy5yZW1vdmVTYWZhcmlYSFJQb2x5ZmlsbCgpO1xuXHRcdFx0XHRzd2l0Y2ggKHJlYXNvbi5tZXNzYWdlKSB7XG5cdFx0XHRcdFx0Y2FzZSBlcnJvcnMuUkVRVUVTVF9USU1FT1VUOlxuXHRcdFx0XHRcdFx0cmVhc29uLnRpbWVvdXQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBlcnJvcnMuUkVRVUVTVF9FUlJPUjpcblx0XHRcdFx0XHRcdHJlYXNvbi5yZXF1ZXN0RXJyb3IgPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBlcnJvcnMuUkVRVUVTVF9QUkVNQVRVUkVfVEVSTUlOQVRJT046XG5cdFx0XHRcdFx0XHRyZWFzb24ucmVxdWVzdEVycm9yID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHJlYXNvbi5yZXF1ZXN0UHJlbWF0dXJlVGVybWluYXRpb24gPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhyb3cgcmVhc29uO1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhZGl0aW9uYWwgZGF0YSB0byB0aGUgYm9keSBvZiB0aGUgcmVxdWVzdCBpbiBjYXNlIGEgc3VibWl0IGJ1dHRvblxuXHQgKiBpcyBjYXB0dXJlZCBkdXJpbmcgZm9ybSBzdWJtaXNzaW9uLlxuXHQgKiBAcGFyYW0geyFGb3JtRGF0YX0gYm9keSBUaGUgRm9ybURhdGEgY29udGFpbmluZyB0aGUgcmVxdWVzdCBib2R5LlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuXHRtYXliZUFwcGVuZFN1Ym1pdEJ1dHRvblZhbHVlXyhib2R5KSB7XG5cdFx0Y29uc3QgYnV0dG9uID0gZ2xvYmFscy5jYXB0dXJlZEZvcm1CdXR0b25FbGVtZW50O1xuXHRcdGlmIChidXR0b24gJiYgYnV0dG9uLm5hbWUpIHtcblx0XHRcdGJvZHkuYXBwZW5kKGJ1dHRvbi5uYW1lLCBidXR0b24udmFsdWUpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgZm9sbG93aW5nIG1ldGhvZCB0cmllcyB0byBleHRyYWN0IHRoZSByZXNwb25zZSB1cmwgdmFsdWUgYnkgY2hlY2tpbmdcblx0ICogdGhlIGN1c3RvbSByZXNwb25zZSBoZWFkZXIgJ1gtUmVxdWVzdC1VUkwnIGlmIHByb3BlciB2YWx1ZSBpcyBub3QgcHJlc2VudFxuXHQgKiBpbiBYTUxIdHRwUmVxdWVzdC4gVGhlIHZhbHVlIG9mIHJlc3BvbnNlVVJMIHdpbGwgYmUgdGhlIGZpbmFsIFVSTFxuXHQgKiBvYnRhaW5lZCBhZnRlciBhbnkgcmVkaXJlY3RzLiBJbnRlcm5ldCBFeHBsb3JlciwgRWRnZSBhbmQgU2FmYXJpIDw9IDdcblx0ICogZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGZlYXR1cmUuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZTpcblx0ICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1hNTEh0dHBSZXF1ZXN0L3Jlc3BvbnNlVVJMXG5cdCAqIGh0dHBzOi8veGhyLnNwZWMud2hhdHdnLm9yZy8jdGhlLXJlc3BvbnNldXJsLWF0dHJpYnV0ZVxuXHQgKiBAcGFyYW0ge1hNTEh0dHBSZXF1ZXN0fSByZXF1ZXN0XG5cdCAqIEByZXR1cm4gez9zdHJpbmd9IFJlc3BvbnNlIHVybCBiZXN0IG1hdGNoLlxuXHQgKi9cblx0bWF5YmVFeHRyYWN0UmVzcG9uc2VVcmxGcm9tUmVxdWVzdChyZXF1ZXN0KSB7XG5cdFx0dmFyIHJlc3BvbnNlVXJsID0gcmVxdWVzdC5yZXNwb25zZVVSTDtcblx0XHRpZiAocmVzcG9uc2VVcmwpIHtcblx0XHRcdHJldHVybiByZXNwb25zZVVybDtcblx0XHR9XG5cdFx0cmV0dXJuIHJlcXVlc3QuZ2V0UmVzcG9uc2VIZWFkZXIoUmVxdWVzdFNjcmVlbi5YX1JFUVVFU1RfVVJMX0hFQURFUik7XG5cdH1cblxuXHQvKipcblx0ICogVGhpcyBmdW5jdGlvbiBzZXQgYXR0cmlidXRlIGRhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWQgdG8gXG5cdCAqIHRydWUgYW5kIHNldCBkaXNhYmxlIGF0dHJpYnV0ZSBvZiBhbiBpbnB1dCB0eXBlPVwiZmlsZVwiIHRhZ1xuXHQgKiBpcyB1c2VkIGFzIGEgcG9seWZpbGwgZm9yIGlPUyAxMS4zIFNhZmFyaSAvIG1hY09TIFNhZmFyaSAxMS4xIFxuXHQgKiBlbXB0eSA8aW5wdXQgdHlwZT1cImZpbGVcIj4gWEhSIGJ1Zy5cblx0ICogaHR0cHM6Ly9naXRodWIuY29tL3JhaWxzL3JhaWxzL2lzc3Vlcy8zMjQ0MFxuXHQgKiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTg0NDkwXG5cdCAqL1xuXHRhZGRTYWZhcmlYSFJQb2x5ZmlsbCgpIHtcblx0XHRpZiAoZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50ICYmIFVBLmlzU2FmYXJpKSB7XG5cdFx0XHRsZXQgaW5wdXRzID0gZ2xvYmFscy5jYXB0dXJlZEZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9XCJmaWxlXCJdOm5vdChbZGlzYWJsZWRdKScpO1xuXHRcdFx0Zm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGlucHV0cy5sZW5ndGg7IGluZGV4KyspIHtcblx0XHRcdFx0bGV0IGlucHV0ID0gaW5wdXRzW2luZGV4XTtcblx0XHRcdFx0aWYgKGlucHV0LmZpbGVzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCdkYXRhLXNhZmFyaS10ZW1wLWRpc2FibGVkJywgJ3RydWUnKTtcblx0XHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsICcnKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogVGhpcyBmdW5jdGlvbiByZW1vdmUgYXR0cmlidXRlIGRhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWQgYW5kIGRpc2FibGUgYXR0cmlidXRlXG5cdCAqIG9mIGFuIGlucHV0IHR5cGU9XCJmaWxlXCIgdGFnIGlzIHVzZWQgYXMgYSBwb2x5ZmlsbCBmb3IgaU9TIDExLjMgU2FmYXJpIC8gbWFjT1MgU2FmYXJpIDExLjFcblx0ICogZW1wdHkgPGlucHV0IHR5cGU9XCJmaWxlXCI+IFhIUiBidWcuXG5cdCAqIGh0dHBzOi8vZ2l0aHViLmNvbS9yYWlscy9yYWlscy9pc3N1ZXMvMzI0NDBcblx0ICogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE4NDQ5MFxuXHQgKi9cblx0cmVtb3ZlU2FmYXJpWEhSUG9seWZpbGwoKSB7XG5cdFx0aWYgKGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudCAmJiBVQS5pc1NhZmFyaSkge1xuXHRcdFx0bGV0IGlucHV0cyA9IGdsb2JhbHMuY2FwdHVyZWRGb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwiZmlsZVwiXVtkYXRhLXNhZmFyaS10ZW1wLWRpc2FibGVkXScpO1xuXHRcdFx0Zm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGlucHV0cy5sZW5ndGg7IGluZGV4KyspIHtcblx0XHRcdFx0Y29uc3QgaW5wdXQgPSBpbnB1dHNbaW5kZXhdO1xuXHRcdFx0XHRpbnB1dC5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtc2FmYXJpLXRlbXAtZGlzYWJsZWQnKTtcblx0XHRcdFx0aW5wdXQucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBodHRwIGhlYWRlcnMuXG5cdCAqIEBwYXJhbSB7P09iamVjdD19IGh0dHBIZWFkZXJzXG5cdCAqL1xuXHRzZXRIdHRwSGVhZGVycyhodHRwSGVhZGVycykge1xuXHRcdHRoaXMuaHR0cEhlYWRlcnMgPSBodHRwSGVhZGVycztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBodHRwIG1ldGhvZC5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBodHRwTWV0aG9kXG5cdCAqL1xuXHRzZXRIdHRwTWV0aG9kKGh0dHBNZXRob2QpIHtcblx0XHR0aGlzLmh0dHBNZXRob2QgPSBodHRwTWV0aG9kLnRvTG93ZXJDYXNlKCk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgcmVxdWVzdCBvYmplY3QuXG5cdCAqIEBwYXJhbSB7P09iamVjdH0gcmVxdWVzdFxuXHQgKi9cblx0c2V0UmVxdWVzdChyZXF1ZXN0KSB7XG5cdFx0dGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuXHQgKiBAcGFyYW0geyFudW1iZXJ9IHRpbWVvdXRcblx0ICovXG5cdHNldFRpbWVvdXQodGltZW91dCkge1xuXHRcdHRoaXMudGltZW91dCA9IHRpbWVvdXQ7XG5cdH1cblxufVxuXG4vKipcbiAqIEhvbGRzIHZhbHVlIGZvciBtZXRob2QgZ2V0LlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBkZWZhdWx0ICdnZXQnXG4gKiBAc3RhdGljXG4gKi9cblJlcXVlc3RTY3JlZW4uR0VUID0gJ2dldCc7XG5cbi8qKlxuICogSG9sZHMgdmFsdWUgZm9yIG1ldGhvZCBwb3N0LlxuICogQHR5cGUge3N0cmluZ31cbiAqIEBkZWZhdWx0ICdwb3N0J1xuICogQHN0YXRpY1xuICovXG5SZXF1ZXN0U2NyZWVuLlBPU1QgPSAncG9zdCc7XG5cbi8qKlxuICogRmFsbGJhY2sgaHR0cCBoZWFkZXIgdG8gcmV0cmlldmUgcmVzcG9uc2UgcmVxdWVzdCB1cmwuXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQGRlZmF1bHQgJ1gtUmVxdWVzdC1VUkwnXG4gKiBAc3RhdGljXG4gKi9cblJlcXVlc3RTY3JlZW4uWF9SRVFVRVNUX1VSTF9IRUFERVIgPSAnWC1SZXF1ZXN0LVVSTCc7XG5cbmV4cG9ydCBkZWZhdWx0IFJlcXVlc3RTY3JlZW47XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJ21ldGFsJztcbmltcG9ydCB7IGJ1aWxkRnJhZ21lbnQsIGdsb2JhbEV2YWwsIGdsb2JhbEV2YWxTdHlsZXMsIG1hdGNoIH0gZnJvbSAnbWV0YWwtZG9tJztcbmltcG9ydCBDYW5jZWxsYWJsZVByb21pc2UgZnJvbSAnbWV0YWwtcHJvbWlzZSc7XG5pbXBvcnQgZ2xvYmFscyBmcm9tICcuLi9nbG9iYWxzL2dsb2JhbHMnO1xuaW1wb3J0IFJlcXVlc3RTY3JlZW4gZnJvbSAnLi9SZXF1ZXN0U2NyZWVuJztcbmltcG9ydCBTdXJmYWNlIGZyb20gJy4uL3N1cmZhY2UvU3VyZmFjZSc7XG5pbXBvcnQgVUEgZnJvbSAnbWV0YWwtdXNlcmFnZW50JztcbmltcG9ydCBVcmkgZnJvbSAnbWV0YWwtdXJpJztcbmltcG9ydCB1dGlscyBmcm9tICcuLi91dGlscy91dGlscyc7XG5cbmNsYXNzIEh0bWxTY3JlZW4gZXh0ZW5kcyBSZXF1ZXN0U2NyZWVuIHtcblxuXHQvKipcblx0ICogU2NyZWVuIGNsYXNzIHRoYXQgcGVyZm9ybSBhIHJlcXVlc3QgYW5kIGV4dHJhY3RzIHN1cmZhY2UgY29udGVudHMgZnJvbVxuXHQgKiB0aGUgcmVzcG9uc2UgY29udGVudC5cblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqIEBleHRlbmRzIHtSZXF1ZXN0U2NyZWVufVxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBtZXRhIHNlbGVjdG9yLiBSZWxldmFudCB0byBleHRyYWN0IDxjb2RlPm1ldGE8L2NvZGU+IHRhZ3Ncblx0XHQgKiBlbGVtZW50cyBmcm9tIHJlcXVlc3QgZnJhZ21lbnRzIHRvIHVzZSBhcyB0aGUgc2NyZWVuLlxuXHRcdCAqIEB0eXBlIHshc3RyaW5nfVxuXHRcdCAqIEBkZWZhdWx0IG1ldGFcblx0XHQgKiBAcHJvdGVjdGVkXG5cdFx0ICovXG5cdFx0dGhpcy5tZXRhVGFnc1NlbGVjdG9yID0gJ21ldGEnO1xuXG5cdFx0LyoqXG5cdFx0ICogSG9sZHMgdGhlIHRpdGxlIHNlbGVjdG9yLiBSZWxldmFudCB0byBleHRyYWN0IHRoZSA8Y29kZT48dGl0bGU+PC9jb2RlPlxuXHRcdCAqIGVsZW1lbnQgZnJvbSByZXF1ZXN0IGZyYWdtZW50cyB0byB1c2UgYXMgdGhlIHNjcmVlbiB0aXRsZS5cblx0XHQgKiBAdHlwZSB7IXN0cmluZ31cblx0XHQgKiBAZGVmYXVsdCB0aXRsZVxuXHRcdCAqIEBwcm90ZWN0ZWRcblx0XHQgKi9cblx0XHR0aGlzLnRpdGxlU2VsZWN0b3IgPSAndGl0bGUnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRhY3RpdmF0ZSgpIHtcblx0XHRzdXBlci5hY3RpdmF0ZSgpO1xuXHRcdHRoaXMucmVsZWFzZVZpcnR1YWxEb2N1bWVudCgpO1xuXHRcdHRoaXMucGVuZGluZ1N0eWxlcyA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb2NhdGVzIHZpcnR1YWwgZG9jdW1lbnQgZm9yIGNvbnRlbnQuIEFmdGVyIGFsbG9jYXRlZCB2aXJ0dWFsIGRvY3VtZW50XG5cdCAqIGNhbiBiZSBhY2Nlc3NlZCBieSA8Y29kZT50aGlzLnZpcnR1YWxEb2N1bWVudDwvY29kZT4uXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gaHRtbFN0cmluZ1xuXHQgKi9cblx0YWxsb2NhdGVWaXJ0dWFsRG9jdW1lbnRGb3JDb250ZW50KGh0bWxTdHJpbmcpIHtcblx0XHRpZiAoIXRoaXMudmlydHVhbERvY3VtZW50KSB7XG5cdFx0XHR0aGlzLnZpcnR1YWxEb2N1bWVudCA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaHRtbCcpO1xuXHRcdH1cblxuXHRcdHRoaXMuY29weU5vZGVBdHRyaWJ1dGVzRnJvbUNvbnRlbnRfKGh0bWxTdHJpbmcsIHRoaXMudmlydHVhbERvY3VtZW50KTtcblxuXHRcdHRoaXMudmlydHVhbERvY3VtZW50LmlubmVySFRNTCA9IGh0bWxTdHJpbmc7XG5cdH1cblxuXHQvKipcblx0ICogQ3VzdG9taXplcyBsb2dpYyB0byBhcHBlbmQgc3R5bGVzIGludG8gZG9jdW1lbnQuIFJlbGV2YW50IHRvIHdoZW5cblx0ICogdHJhY2tpbmcgYSBzdHlsZSBieSBpZCBtYWtlIHN1cmUgdG8gcmUtcG9zaXRpb25zIHRoZSBuZXcgc3R5bGUgaW4gdGhlXG5cdCAqIHNhbWUgZG9tIG9yZGVyLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IG5ld1N0eWxlXG5cdCAqL1xuXHRhcHBlbmRTdHlsZUludG9Eb2N1bWVudF8obmV3U3R5bGUpIHtcblx0XHR2YXIgaXNUZW1wb3JhcnlTdHlsZSA9IG1hdGNoKG5ld1N0eWxlLCBIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXNUZW1wb3JhcnkpO1xuXHRcdGlmIChpc1RlbXBvcmFyeVN0eWxlKSB7XG5cdFx0XHR0aGlzLnBlbmRpbmdTdHlsZXMucHVzaChuZXdTdHlsZSk7XG5cdFx0fVxuXHRcdGlmIChuZXdTdHlsZS5pZCkge1xuXHRcdFx0dmFyIHN0eWxlSW5Eb2MgPSBnbG9iYWxzLmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG5ld1N0eWxlLmlkKTtcblx0XHRcdGlmIChzdHlsZUluRG9jKSB7XG5cdFx0XHRcdHN0eWxlSW5Eb2MucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3U3R5bGUsIHN0eWxlSW5Eb2MubmV4dFNpYmxpbmcpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGdsb2JhbHMuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChuZXdTdHlsZSk7XG5cdH1cblxuXHQvKipcblx0ICogSWYgYm9keSBpcyB1c2VkIGFzIHN1cmZhY2UgZm9yY2VzIHRoZSByZXF1ZXN0ZWQgZG9jdW1lbnRzIHRvIGhhdmUgc2FtZSBpZFxuXHQgKiBvZiB0aGUgaW5pdGlhbCBwYWdlLlxuXHQgKi9cblx0YXNzZXJ0U2FtZUJvZHlJZEluVmlydHVhbERvY3VtZW50KCkge1xuXHRcdHZhciBib2R5U3VyZmFjZSA9IHRoaXMudmlydHVhbERvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKTtcblx0XHRpZiAoIWdsb2JhbHMuZG9jdW1lbnQuYm9keS5pZCkge1xuXHRcdFx0Z2xvYmFscy5kb2N1bWVudC5ib2R5LmlkID0gJ3Nlbm5hX3N1cmZhY2VfJyArIGdldFVpZCgpO1xuXHRcdH1cblx0XHRpZiAoYm9keVN1cmZhY2UpIHtcblx0XHRcdGJvZHlTdXJmYWNlLmlkID0gZ2xvYmFscy5kb2N1bWVudC5ib2R5LmlkO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDb3BpZXMgYXR0cmlidXRlcyBmcm9tIHRoZSA8aHRtbD4gdGFnIG9mIGNvbnRlbnQgdG8gdGhlIGdpdmVuIG5vZGUuXG5cdCAqL1xuXHRjb3B5Tm9kZUF0dHJpYnV0ZXNGcm9tQ29udGVudF8oY29udGVudCwgbm9kZSkge1xuXHRcdGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UoL1s8XVxccypodG1sL2lnLCAnPHNlbm5hJyk7XG5cdFx0Y29udGVudCA9IGNvbnRlbnQucmVwbGFjZSgvXFwvaHRtbFxccypcXD4vaWcsICcvc2VubmE+Jyk7XG5cdFx0bGV0IHBsYWNlaG9sZGVyO1xuXHRcdGlmIChVQS5pc0llKSB7XG5cdFx0XHRjb25zdCB0ZW1wTm9kZSA9IGdsb2JhbHMuZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoY29udGVudCk7XG5cdFx0XHRwbGFjZWhvbGRlciA9IHRlbXBOb2RlLnF1ZXJ5U2VsZWN0b3IoJ3Nlbm5hJyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG5vZGUuaW5uZXJIVE1MID0gY29udGVudDtcblx0XHRcdHBsYWNlaG9sZGVyID0gbm9kZS5xdWVyeVNlbGVjdG9yKCdzZW5uYScpO1xuXHRcdH1cblxuXHRcdGlmIChwbGFjZWhvbGRlcikge1xuXHRcdFx0dXRpbHMuY2xlYXJOb2RlQXR0cmlidXRlcyhub2RlKTtcblx0XHRcdHV0aWxzLmNvcHlOb2RlQXR0cmlidXRlcyhwbGFjZWhvbGRlciwgbm9kZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEBPdmVycmlkZVxuXHQgKi9cblx0ZGlzcG9zZUludGVybmFsKCkge1xuXHRcdHRoaXMuZGlzcG9zZVBlbmRpbmdTdHlsZXMoKTtcblx0XHRzdXBlci5kaXNwb3NlSW50ZXJuYWwoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEaXNwb3NlcyBwZW5kaW5nIHN0eWxlcyBpZiBzY3JlZW4gZ2V0IGRpc3Bvc2VkIHByaW9yIHRvIGl0cyBsb2FkaW5nLlxuXHQgKi9cblx0ZGlzcG9zZVBlbmRpbmdTdHlsZXMoKSB7XG5cdFx0aWYgKHRoaXMucGVuZGluZ1N0eWxlcykge1xuXHRcdFx0dXRpbHMucmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQodGhpcy5wZW5kaW5nU3R5bGVzKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQE92ZXJyaWRlXG5cdCAqL1xuXHRldmFsdWF0ZVNjcmlwdHMoc3VyZmFjZXMpIHtcblx0XHR2YXIgZXZhbHVhdGVUcmFja2VkU2NyaXB0cyA9IHRoaXMuZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyhcblx0XHRcdGdsb2JhbEV2YWwucnVuU2NyaXB0c0luRWxlbWVudCwgSHRtbFNjcmVlbi5zZWxlY3RvcnMuc2NyaXB0cyxcblx0XHRcdEh0bWxTY3JlZW4uc2VsZWN0b3JzLnNjcmlwdHNUZW1wb3JhcnksIEh0bWxTY3JlZW4uc2VsZWN0b3JzLnNjcmlwdHNQZXJtYW5lbnQpO1xuXG5cdFx0cmV0dXJuIGV2YWx1YXRlVHJhY2tlZFNjcmlwdHMudGhlbigoKSA9PiBzdXBlci5ldmFsdWF0ZVNjcmlwdHMoc3VyZmFjZXMpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAT3ZlcnJpZGVcblx0ICovXG5cdGV2YWx1YXRlU3R5bGVzKHN1cmZhY2VzKSB7XG5cdFx0dGhpcy5wZW5kaW5nU3R5bGVzID0gW107XG5cdFx0dmFyIGV2YWx1YXRlVHJhY2tlZFN0eWxlcyA9IHRoaXMuZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyhcblx0XHRcdGdsb2JhbEV2YWxTdHlsZXMucnVuU3R5bGVzSW5FbGVtZW50LCBIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXMsXG5cdFx0XHRIdG1sU2NyZWVuLnNlbGVjdG9ycy5zdHlsZXNUZW1wb3JhcnksIEh0bWxTY3JlZW4uc2VsZWN0b3JzLnN0eWxlc1Blcm1hbmVudCxcblx0XHRcdHRoaXMuYXBwZW5kU3R5bGVJbnRvRG9jdW1lbnRfLmJpbmQodGhpcykpO1xuXG5cdFx0cmV0dXJuIGV2YWx1YXRlVHJhY2tlZFN0eWxlcy50aGVuKCgpID0+IHN1cGVyLmV2YWx1YXRlU3R5bGVzKHN1cmZhY2VzKSk7XG5cdH1cblxuXHQvKipcblx0ICogQWxsb3dzIGEgc2NyZWVuIHRvIGV2YWx1YXRlIHRoZSBmYXZpY29uIHN0eWxlIGJlZm9yZSB0aGUgc2NyZWVuIGJlY29tZXMgdmlzaWJsZS5cblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfVxuXHQgKi9cblx0ZXZhbHVhdGVGYXZpY29uXygpIHtcblx0XHRjb25zdCByZXNvdXJjZXNJblZpcnR1YWwgPSB0aGlzLnZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyhIdG1sU2NyZWVuLnNlbGVjdG9ycy5mYXZpY29uKTtcblx0XHRjb25zdCByZXNvdXJjZXNJbkRvY3VtZW50ID0gdGhpcy5xdWVyeVNlbGVjdG9yQWxsXyhIdG1sU2NyZWVuLnNlbGVjdG9ycy5mYXZpY29uKTtcblxuXHRcdHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdFx0XHR1dGlscy5yZW1vdmVFbGVtZW50c0Zyb21Eb2N1bWVudChyZXNvdXJjZXNJbkRvY3VtZW50KTtcblx0XHRcdHRoaXMucnVuRmF2aWNvbkluRWxlbWVudF8ocmVzb3VyY2VzSW5WaXJ0dWFsKS50aGVuKCgpID0+IHJlc29sdmUoKSk7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogRXZhbHVhdGVzIHRyYWNrZWQgcmVzb3VyY2VzIGluc2lkZSBpbmNvbWluZyBmcmFnbWVudCBhbmQgcmVtb3ZlIGV4aXN0aW5nXG5cdCAqIHRlbXBvcmFyeSByZXNvdXJjZXMuXG5cdCAqIEBwYXJhbSB7P2Z1bmN0aW9uKCl9IGFwcGVuZEZuIEZ1bmN0aW9uIHRvIGFwcGVuZCB0aGUgbm9kZSBpbnRvIGRvY3VtZW50LlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yIFNlbGVjdG9yIHVzZWQgdG8gZmluZCByZXNvdXJjZXMgdG8gdHJhY2suXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gc2VsZWN0b3JUZW1wb3JhcnkgU2VsZWN0b3IgdXNlZCB0byBmaW5kIHRlbXBvcmFyeVxuXHQgKiAgICAgcmVzb3VyY2VzIHRvIHRyYWNrLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yUGVybWFuZW50IFNlbGVjdG9yIHVzZWQgdG8gZmluZCBwZXJtYW5lbnRcblx0ICogICAgIHJlc291cmNlcyB0byB0cmFjay5cblx0ICogQHBhcmFtIHshZnVuY3Rpb259IG9wdF9hcHBlbmRSZXNvdXJjZUZuIE9wdGlvbmFsIGZ1bmN0aW9uIHVzZWQgdG9cblx0ICogICAgIGV2YWx1YXRlIGZyYWdtZW50IGNvbnRhaW5pbmcgcmVzb3VyY2VzLlxuXHQgKiBAcmV0dXJuIHtDYW5jZWxsYWJsZVByb21pc2V9IERlZmVycmVkIHRoYXQgd2FpdHMgcmVzb3VyY2VzIGV2YWx1YXRpb24gdG9cblx0ICogICAgIGNvbXBsZXRlLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyhldmFsdWF0b3JGbiwgc2VsZWN0b3IsIHNlbGVjdG9yVGVtcG9yYXJ5LCBzZWxlY3RvclBlcm1hbmVudCwgb3B0X2FwcGVuZFJlc291cmNlRm4pIHtcblx0XHR2YXIgdHJhY2tlZCA9IHRoaXMudmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yKTtcblx0XHR2YXIgdGVtcG9yYXJpZXNJbkRvYyA9IHRoaXMucXVlcnlTZWxlY3RvckFsbF8oc2VsZWN0b3JUZW1wb3JhcnkpO1xuXHRcdHZhciBwZXJtYW5lbnRzSW5Eb2MgPSB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yUGVybWFuZW50KTtcblxuXHRcdC8vIEFkZHMgcGVybWFuZW50IHJlc291cmNlcyBpbiBkb2N1bWVudCB0byBjYWNoZS5cblx0XHRwZXJtYW5lbnRzSW5Eb2MuZm9yRWFjaCgocmVzb3VyY2UpID0+IHtcblx0XHRcdHZhciByZXNvdXJjZUtleSA9IHRoaXMuZ2V0UmVzb3VyY2VLZXlfKHJlc291cmNlKTtcblx0XHRcdGlmIChyZXNvdXJjZUtleSkge1xuXHRcdFx0XHRIdG1sU2NyZWVuLnBlcm1hbmVudFJlc291cmNlc0luRG9jW3Jlc291cmNlS2V5XSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR2YXIgZnJhZyA9IGJ1aWxkRnJhZ21lbnQoKTtcblx0XHR0cmFja2VkLmZvckVhY2goKHJlc291cmNlKSA9PiB7XG5cdFx0XHR2YXIgcmVzb3VyY2VLZXkgPSB0aGlzLmdldFJlc291cmNlS2V5XyhyZXNvdXJjZSk7XG5cdFx0XHQvLyBEbyBub3QgbG9hZCBwZXJtYW5lbnQgcmVzb3VyY2VzIGlmIGFscmVhZHkgaW4gZG9jdW1lbnQuXG5cdFx0XHRpZiAoIUh0bWxTY3JlZW4ucGVybWFuZW50UmVzb3VyY2VzSW5Eb2NbcmVzb3VyY2VLZXldKSB7XG5cdFx0XHRcdGZyYWcuYXBwZW5kQ2hpbGQocmVzb3VyY2UpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gSWYgcmVzb3VyY2UgaGFzIGtleSBhbmQgaXMgcGVybWFuZW50IGFkZCB0byBjYWNoZS5cblx0XHRcdGlmIChyZXNvdXJjZUtleSAmJiBtYXRjaChyZXNvdXJjZSwgc2VsZWN0b3JQZXJtYW5lbnQpKSB7XG5cdFx0XHRcdEh0bWxTY3JlZW4ucGVybWFuZW50UmVzb3VyY2VzSW5Eb2NbcmVzb3VyY2VLZXldID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHJldHVybiBuZXcgQ2FuY2VsbGFibGVQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdFx0XHRldmFsdWF0b3JGbihmcmFnLCAoKSA9PiB7XG5cdFx0XHRcdHV0aWxzLnJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50KHRlbXBvcmFyaWVzSW5Eb2MpO1xuXHRcdFx0XHRyZXNvbHZlKCk7XG5cdFx0XHR9LCBvcHRfYXBwZW5kUmVzb3VyY2VGbik7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQE92ZXJyaWRlXG5cdCAqL1xuXHRmbGlwKHN1cmZhY2VzKSB7XG5cdFx0cmV0dXJuIHN1cGVyLmZsaXAoc3VyZmFjZXMpLnRoZW4oKCkgPT4ge1xuXHRcdFx0dXRpbHMuY2xlYXJOb2RlQXR0cmlidXRlcyhnbG9iYWxzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCk7XG5cdFx0XHR1dGlscy5jb3B5Tm9kZUF0dHJpYnV0ZXModGhpcy52aXJ0dWFsRG9jdW1lbnQsIGdsb2JhbHMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KTtcblx0XHRcdHRoaXMuZXZhbHVhdGVGYXZpY29uXygpO1xuXHRcdFx0dGhpcy51cGRhdGVNZXRhVGFnc18oKTtcblx0XHR9KTtcblx0fVxuXG5cdHVwZGF0ZU1ldGFUYWdzXygpIHtcblx0XHRjb25zdCBjdXJyZW50TWV0YU5vZGVzID0gdGhpcy5xdWVyeVNlbGVjdG9yQWxsXygnbWV0YScpO1xuXHRcdGNvbnN0IG1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudCA9IHRoaXMubWV0YXM7XG5cdFx0aWYgKGN1cnJlbnRNZXRhTm9kZXMpIHtcblx0XHRcdHV0aWxzLnJlbW92ZUVsZW1lbnRzRnJvbURvY3VtZW50KGN1cnJlbnRNZXRhTm9kZXMpO1xuXHRcdFx0aWYgKG1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudCkge1xuXHRcdFx0XHRtZXRhc0Zyb21WaXJ0dWFsRG9jdW1lbnQuZm9yRWFjaCgobWV0YSkgPT4gZ2xvYmFscy5kb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGEpKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRXh0cmFjdHMgYSBrZXkgdG8gaWRlbnRpZnkgdGhlIHJlc291cmNlIGJhc2VkIG9uIGl0cyBhdHRyaWJ1dGVzLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IHJlc291cmNlXG5cdCAqIEByZXR1cm4ge3N0cmluZ30gRXh0cmFjdGVkIGtleSBiYXNlZCBvbiByZXNvdXJjZSBhdHRyaWJ1dGVzIGluIG9yZGVyIG9mXG5cdCAqICAgICBwcmVmZXJlbmNlOiBpZCwgaHJlZiwgc3JjLlxuXHQgKi9cblx0Z2V0UmVzb3VyY2VLZXlfKHJlc291cmNlKSB7XG5cdFx0cmV0dXJuIHJlc291cmNlLmlkIHx8IHJlc291cmNlLmhyZWYgfHwgcmVzb3VyY2Uuc3JjIHx8ICcnO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbmhlcml0RG9jXG5cdCAqL1xuXHRnZXRTdXJmYWNlQ29udGVudChzdXJmYWNlSWQpIHtcblx0XHR2YXIgc3VyZmFjZSA9IHRoaXMudmlydHVhbERvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyMnICsgc3VyZmFjZUlkKTtcblx0XHRpZiAoc3VyZmFjZSkge1xuXHRcdFx0dmFyIGRlZmF1bHRDaGlsZCA9IHN1cmZhY2UucXVlcnlTZWxlY3RvcignIycgKyBzdXJmYWNlSWQgKyAnLScgKyBTdXJmYWNlLkRFRkFVTFQpO1xuXHRcdFx0aWYgKGRlZmF1bHRDaGlsZCkge1xuXHRcdFx0XHRyZXR1cm4gZGVmYXVsdENoaWxkLmlubmVySFRNTDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBzdXJmYWNlLmlubmVySFRNTDsgLy8gSWYgZGVmYXVsdCBjb250ZW50IG5vdCBmb3VuZCwgdXNlIHN1cmZhY2UgY29udGVudFxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSB0aXRsZSBzZWxlY3Rvci5cblx0ICogQHJldHVybiB7IXN0cmluZ31cblx0ICovXG5cdGdldFRpdGxlU2VsZWN0b3IoKSB7XG5cdFx0cmV0dXJuIHRoaXMudGl0bGVTZWxlY3Rvcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW5oZXJpdERvY1xuXHQgKi9cblx0bG9hZChwYXRoKSB7XG5cdFx0cmV0dXJuIHN1cGVyLmxvYWQocGF0aClcblx0XHRcdC50aGVuKGNvbnRlbnQgPT4ge1xuXHRcdFx0XHR0aGlzLmFsbG9jYXRlVmlydHVhbERvY3VtZW50Rm9yQ29udGVudChjb250ZW50KTtcblx0XHRcdFx0dGhpcy5yZXNvbHZlVGl0bGVGcm9tVmlydHVhbERvY3VtZW50KCk7XG5cdFx0XHRcdHRoaXMucmVzb2x2ZU1ldGFUYWdzRnJvbVZpcnR1YWxEb2N1bWVudCgpO1xuXHRcdFx0XHR0aGlzLmFzc2VydFNhbWVCb2R5SWRJblZpcnR1YWxEb2N1bWVudCgpO1xuXHRcdFx0XHRpZiAoVUEuaXNJZSkge1xuXHRcdFx0XHRcdHRoaXMubWFrZVRlbXBvcmFyeVN0eWxlc0hyZWZzVW5pcXVlXygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb250ZW50O1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUXVlcmllcyB0ZW1wb3Jhcnkgc3R5bGVzIGZyb20gdmlydHVhbCBkb2N1bWVudCwgYW5kIG1ha2VzIHRoZW0gdW5pcXVlLlxuXHQgKiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3IgY2FjaGluZyBhbmQgbG9hZCBldmVudCBmaXJpbmcgaXNzdWVzIHNwZWNpZmljIHRvXG5cdCAqIElFMTEuIGh0dHBzOi8vZGV2ZWxvcGVyLm1pY3Jvc29mdC5jb20vZW4tdXMvbWljcm9zb2Z0LWVkZ2UvcGxhdGZvcm0vaXNzdWVzLzc5NDAxNzEvXG5cdCAqL1xuXHRtYWtlVGVtcG9yYXJ5U3R5bGVzSHJlZnNVbmlxdWVfKCkge1xuXHRcdHZhciB0ZW1wb3Jhcmllc0luRG9jID0gdGhpcy52aXJ0dWFsUXVlcnlTZWxlY3RvckFsbF8oSHRtbFNjcmVlbi5zZWxlY3RvcnMuc3R5bGVzVGVtcG9yYXJ5KTtcblx0XHR0ZW1wb3Jhcmllc0luRG9jLmZvckVhY2goKHN0eWxlKSA9PiB0aGlzLnJlcGxhY2VTdHlsZUFuZE1ha2VVbmlxdWVfKHN0eWxlKSk7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBlbGVtZW50IGZyb20gZ2l2ZW4sIGNvcGllcyBhdHRyaWJ1dGVzLCBtdXRhdGVzIGhyZWYgdG8gYmVcblx0ICogdW5pcXVlIHRvIHByZXZlbnQgY2FjaGluZyBhbmQgbW9yZSB0aGFuIG9uZSBsb2FkL2Vycm9yIGV2ZW50IGZyb20gZmlyaW5nLlxuXHQgKi9cblx0cmVwbGFjZVN0eWxlQW5kTWFrZVVuaXF1ZV8oc3R5bGUpIHtcblx0XHRpZiAoc3R5bGUuaHJlZikge1xuXHRcdFx0dmFyIG5ld1N0eWxlID0gZ2xvYmFscy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KHN0eWxlLnRhZ05hbWUpO1xuXHRcdFx0c3R5bGUuaHJlZiA9IG5ldyBVcmkoc3R5bGUuaHJlZikubWFrZVVuaXF1ZSgpLnRvU3RyaW5nKCk7XG5cdFx0XHR1dGlscy5jb3B5Tm9kZUF0dHJpYnV0ZXMoc3R5bGUsIG5ld1N0eWxlKTtcblx0XHRcdHN0eWxlLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld1N0eWxlLCBzdHlsZSk7XG5cdFx0XHRzdHlsZS5kaXNhYmxlZCA9IHRydWU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgdGhlIGZhdmljb24gZWxlbWVudHMgdG8gdGhlIGRvY3VtZW50LlxuXHQgKiBAcGFyYW0geyFBcnJheTxFbGVtZW50Pn0gZWxlbWVudHNcblx0ICogQHByaXZhdGVcblx0ICogQHJldHVybiB7Q2FuY2VsbGFibGVQcm9taXNlfVxuXHQgKi9cblx0cnVuRmF2aWNvbkluRWxlbWVudF8oZWxlbWVudHMpIHtcblx0XHRyZXR1cm4gbmV3IENhbmNlbGxhYmxlUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuXHRcdFx0ZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4gZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChcblx0XHRcdFx0VUEuaXNJZSA/IGVsZW1lbnQgOiB1dGlscy5zZXRFbGVtZW50V2l0aFJhbmRvbUhyZWYoZWxlbWVudClcblx0XHRcdCkpO1xuXHRcdFx0cmVzb2x2ZSgpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFF1ZXJpZXMgZWxlbWVudHMgZnJvbSB2aXJ0dWFsIGRvY3VtZW50IGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGVsZW1lbnRzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yXG5cdCAqIEByZXR1cm4ge2FycmF5LjxFbGVtZW50Pn1cblx0ICovXG5cdHZpcnR1YWxRdWVyeVNlbGVjdG9yQWxsXyhzZWxlY3Rvcikge1xuXHRcdHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLnZpcnR1YWxEb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG5cdH1cblxuXHQvKipcblx0ICogUXVlcmllcyBlbGVtZW50cyBmcm9tIGRvY3VtZW50IGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGVsZW1lbnRzLlxuXHQgKiBAcGFyYW0geyFzdHJpbmd9IHNlbGVjdG9yXG5cdCAqIEByZXR1cm4ge2FycmF5LjxFbGVtZW50Pn1cblx0ICovXG5cdHF1ZXJ5U2VsZWN0b3JBbGxfKHNlbGVjdG9yKSB7XG5cdFx0cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGdsb2JhbHMuZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbGVhc2VzIHZpcnR1YWwgZG9jdW1lbnQgYWxsb2NhdGVkIGZvciBjb250ZW50LlxuXHQgKi9cblx0cmVsZWFzZVZpcnR1YWxEb2N1bWVudCgpIHtcblx0XHR0aGlzLnZpcnR1YWxEb2N1bWVudCA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogUmVzb2x2ZXMgdGl0bGUgZnJvbSBhbGxvY2F0ZWQgdmlydHVhbCBkb2N1bWVudC5cblx0ICovXG5cdHJlc29sdmVUaXRsZUZyb21WaXJ0dWFsRG9jdW1lbnQoKSB7XG5cdFx0Y29uc3QgdGl0bGUgPSB0aGlzLnZpcnR1YWxEb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMudGl0bGVTZWxlY3Rvcik7XG5cdFx0aWYgKHRpdGxlKSB7XG5cdFx0XHR0aGlzLnNldFRpdGxlKHRpdGxlLnRleHRDb250ZW50LnRyaW0oKSk7XG5cdFx0fVxuXHR9XG5cblx0cmVzb2x2ZU1ldGFUYWdzRnJvbVZpcnR1YWxEb2N1bWVudCgpIHtcblx0XHRjb25zdCBtZXRhcyA9IHRoaXMudmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfKHRoaXMubWV0YVRhZ3NTZWxlY3Rvcik7XG5cdFx0aWYgKG1ldGFzKSB7XG5cdFx0XHR0aGlzLnNldE1ldGFzKG1ldGFzKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgdGl0bGUgc2VsZWN0b3IuXG5cdCAqIEBwYXJhbSB7IXN0cmluZ30gdGl0bGVTZWxlY3RvclxuXHQgKi9cblx0c2V0VGl0bGVTZWxlY3Rvcih0aXRsZVNlbGVjdG9yKSB7XG5cdFx0dGhpcy50aXRsZVNlbGVjdG9yID0gdGl0bGVTZWxlY3Rvcjtcblx0fVxuXG59XG5cbi8qKlxuICogSGVscGVyIHNlbGVjdG9yIGZvciBpZ25vcmUgZmF2aWNvbiB3aGVuIGV4aXN0IGRhdGEtc2VubmEtdHJhY2suXG4gKi9cbmNvbnN0IGlnbm9yZUZhdmljb24gPSAnOm5vdChbcmVsPVwiU2hvcnRjdXQgSWNvblwiXSk6bm90KFtyZWw9XCJzaG9ydGN1dCBpY29uXCJdKTpub3QoW3JlbD1cImljb25cIl0pOm5vdChbaHJlZiQ9XCJmYXZpY29uLmljb25cIl0pJztcblxuLyoqXG4gKiBIZWxwZXIgc2VsZWN0b3JzIGZvciB0cmFja2luZyByZXNvdXJjZXMuXG4gKiBAdHlwZSB7b2JqZWN0fVxuICogQHByb3RlY3RlZFxuICogQHN0YXRpY1xuICovXG5IdG1sU2NyZWVuLnNlbGVjdG9ycyA9IHtcblx0ZmF2aWNvbjogJ2xpbmtbcmVsPVwiU2hvcnRjdXQgSWNvblwiXSxsaW5rW3JlbD1cInNob3J0Y3V0IGljb25cIl0sbGlua1tyZWw9XCJpY29uXCJdLGxpbmtbaHJlZiQ9XCJmYXZpY29uLmljb25cIl0nLFxuXHRzY3JpcHRzOiAnc2NyaXB0W2RhdGEtc2VubmEtdHJhY2tdJyxcblx0c2NyaXB0c1Blcm1hbmVudDogJ3NjcmlwdFtkYXRhLXNlbm5hLXRyYWNrPVwicGVybWFuZW50XCJdJyxcblx0c2NyaXB0c1RlbXBvcmFyeTogJ3NjcmlwdFtkYXRhLXNlbm5hLXRyYWNrPVwidGVtcG9yYXJ5XCJdJyxcblx0c3R5bGVzOiBgc3R5bGVbZGF0YS1zZW5uYS10cmFja10sbGlua1tkYXRhLXNlbm5hLXRyYWNrXSR7aWdub3JlRmF2aWNvbn1gLFxuXHRzdHlsZXNQZXJtYW5lbnQ6IGBzdHlsZVtkYXRhLXNlbm5hLXRyYWNrPVwicGVybWFuZW50XCJdLGxpbmtbZGF0YS1zZW5uYS10cmFjaz1cInBlcm1hbmVudFwiXSR7aWdub3JlRmF2aWNvbn1gLFxuXHRzdHlsZXNUZW1wb3Jhcnk6IGBzdHlsZVtkYXRhLXNlbm5hLXRyYWNrPVwidGVtcG9yYXJ5XCJdLGxpbmtbZGF0YS1zZW5uYS10cmFjaz1cInRlbXBvcmFyeVwiXSR7aWdub3JlRmF2aWNvbn1gXG59O1xuXG4vKipcbiAqIENhY2hlcyBwZXJtYW5lbnQgcmVzb3VyY2Uga2V5cy5cbiAqIEB0eXBlIHtvYmplY3R9XG4gKiBAcHJvdGVjdGVkXG4gKiBAc3RhdGljXG4gKi9cbkh0bWxTY3JlZW4ucGVybWFuZW50UmVzb3VyY2VzSW5Eb2MgPSB7fTtcblxuZXhwb3J0IGRlZmF1bHQgSHRtbFNjcmVlbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuaW1wb3J0IHsgRGlzcG9zYWJsZSwgZ2V0VWlkLCBpc0RlZkFuZE5vdE51bGwsIGlzRWxlbWVudCwgb2JqZWN0IH0gZnJvbSAnbWV0YWwnO1xuaW1wb3J0IGRhdGFBdHRyaWJ1dGVzIGZyb20gJy4vZGF0YUF0dHJpYnV0ZXMnO1xuaW1wb3J0IGdsb2JhbHMgZnJvbSAnLi4vZ2xvYmFscy9nbG9iYWxzJztcbmltcG9ydCBBcHAgZnJvbSAnLi9BcHAnO1xuaW1wb3J0IEh0bWxTY3JlZW4gZnJvbSAnLi4vc2NyZWVuL0h0bWxTY3JlZW4nO1xuaW1wb3J0IFJvdXRlIGZyb20gJy4uL3JvdXRlL1JvdXRlJztcblxuY2xhc3MgQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXIgZXh0ZW5kcyBEaXNwb3NhYmxlIHtcblxuXHQvKipcblx0ICogSW5pdGlsaXplcyBBcHAsIHJlZ2lzdGVyIHN1cmZhY2VzIGFuZCByb3V0ZXMgZnJvbSBkYXRhIGF0dHJpYnV0ZXMuXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKi9cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdC8qKlxuXHRcdCAqIEhvbGRzIHRoZSBhcHAgcmVmZXJlbmNlIGluaXRpYWxpemVkIGJ5IGRhdGEgYXR0cmlidXRlcy5cblx0XHQgKiBAdHlwZSB7QXBwfVxuXHRcdCAqIEBkZWZhdWx0IG51bGxcblx0XHQgKi9cblx0XHR0aGlzLmFwcCA9IG51bGw7XG5cblx0XHQvKipcblx0XHQgKiBIb2xkcyB0aGUgYmFzZSBlbGVtZW50IHRvIHNlYXJjaCBpbml0aWFsaXphdGlvbiBkYXRhIGF0dHJpYnV0ZXMuIFRoaXNcblx0XHQgKiBlbGVtZW50IGlzIHRoZSBjb250YWluZXIgdXNlZCB0byBlbmFibGUgaW5pdGlhbGl6YXRpb24gYmFzZWQgb24gdGhlXG5cdFx0ICogcHJlc2VuY2Ugb2YgYGRhdGEtc2VubmFgIGF0dHJpYnV0ZS5cblx0XHQgKiBAdHlwZSB7RWxlbWVudH1cblx0XHQgKiBAZGVmYXVsdCBudWxsXG5cdFx0ICovXG5cdFx0dGhpcy5iYXNlRWxlbWVudCA9IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogSW5pdHMgYXBwbGljYXRpb24gYmFzZWQgb24gaW5mb3JtYXRpb24gc2Nhbm5lZCBmcm9tIGRvY3VtZW50LlxuXHQgKi9cblx0aGFuZGxlKCkge1xuXHRcdGlmICghaXNFbGVtZW50KHRoaXMuYmFzZUVsZW1lbnQpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1Nlbm5hIGRhdGEgYXR0cmlidXRlIGhhbmRsZXIgYmFzZSBlbGVtZW50ICcgK1xuXHRcdFx0XHQnbm90IHNldCBvciBpbnZhbGlkLCB0cnkgc2V0dGluZyBhIHZhbGlkIGVsZW1lbnQgdGhhdCAnICtcblx0XHRcdFx0J2NvbnRhaW5zIGEgYGRhdGEtc2VubmFgIGF0dHJpYnV0ZS4nKTtcblx0XHR9XG5cblx0XHRpZiAoIXRoaXMuYmFzZUVsZW1lbnQuaGFzQXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLnNlbm5hKSkge1xuXHRcdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHdhcyBub3QgaW5pdGlhbGl6ZWQgZnJvbSBkYXRhIGF0dHJpYnV0ZXMuICcgK1xuXHRcdFx0XHQnSW4gb3JkZXIgdG8gZW5hYmxlIGl0cyB1c2FnZSBmcm9tIGRhdGEgYXR0cmlidXRlcyB0cnkgc2V0dGluZyAnICtcblx0XHRcdFx0J2luIHRoZSBiYXNlIGVsZW1lbnQsIGUuZy4gYDxib2R5IGRhdGEtc2VubmE+YC4nKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5hcHApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignU2VubmEgYXBwIHdhcyBhbHJlYWR5IGluaXRpYWxpemVkLicpO1xuXHRcdH1cblxuXHRcdGNvbnNvbGUubG9nKCdTZW5uYSBpbml0aWFsaXplZCBmcm9tIGRhdGEgYXR0cmlidXRlLicpO1xuXG5cdFx0dGhpcy5hcHAgPSBuZXcgQXBwKCk7XG5cdFx0dGhpcy5tYXliZUFkZFJvdXRlc18oKTtcblx0XHR0aGlzLm1heWJlQWRkU3VyZmFjZXNfKCk7XG5cdFx0dGhpcy5tYXliZVNldEJhc2VQYXRoXygpO1xuXHRcdHRoaXMubWF5YmVTZXRMaW5rU2VsZWN0b3JfKCk7XG5cdFx0dGhpcy5tYXliZVNldExvYWRpbmdDc3NDbGFzc18oKTtcblx0XHR0aGlzLm1heWJlU2V0VXBkYXRlU2Nyb2xsUG9zaXRpb25fKCk7XG5cdFx0dGhpcy5tYXliZURpc3BhdGNoXygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3Bvc2VzIG9mIHRoaXMgaW5zdGFuY2UncyBvYmplY3QgcmVmZXJlbmNlcy5cblx0ICogQG92ZXJyaWRlXG5cdCAqL1xuXHRkaXNwb3NlSW50ZXJuYWwoKSB7XG5cdFx0aWYgKHRoaXMuYXBwKSB7XG5cdFx0XHR0aGlzLmFwcC5kaXNwb3NlKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGFwcCByZWZlcmVuY2UuXG5cdCAqIEByZXR1cm4ge0FwcH1cblx0ICovXG5cdGdldEFwcCgpIHtcblx0XHRyZXR1cm4gdGhpcy5hcHA7XG5cdH1cblxuXHQvKipcblx0ICogR2V0cyB0aGUgYmFzZSBlbGVtZW50LlxuXHQgKiBAcmV0dXJuIHtFbGVtZW50fSBiYXNlRWxlbWVudFxuXHQgKi9cblx0Z2V0QmFzZUVsZW1lbnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuYmFzZUVsZW1lbnQ7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgYWRkcyBhcHAgcm91dGVzIGZyb20gbGluayBlbGVtZW50cyB0aGF0IGFyZSBgc2VubmEtcm91dGVgLlxuXHQgKi9cblx0bWF5YmVBZGRSb3V0ZXNfKCkge1xuXHRcdHZhciByb3V0ZXNTZWxlY3RvciA9ICdsaW5rW3JlbD1cInNlbm5hLXJvdXRlXCJdJztcblx0XHR0aGlzLnF1ZXJ5U2VsZWN0b3JBbGxBc0FycmF5Xyhyb3V0ZXNTZWxlY3RvcikuZm9yRWFjaCgobGluaykgPT4gdGhpcy5tYXliZVBhcnNlTGlua1JvdXRlXyhsaW5rKSk7XG5cdFx0aWYgKCF0aGlzLmFwcC5oYXNSb3V0ZXMoKSkge1xuXHRcdFx0dGhpcy5hcHAuYWRkUm91dGVzKG5ldyBSb3V0ZSgvLiovLCBIdG1sU2NyZWVuKSk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgY2FuXFwndCBmaW5kIHJvdXRlIGVsZW1lbnRzLCBhZGRpbmcgZGVmYXVsdC4nKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgYWRkcyBhcHAgc3VyZmFjZXMgYnkgc2Nhbm5pbmcgYGRhdGEtc2VubmEtc3VyZmFjZWAgZGF0YSBhdHRyaWJ1dGUuXG5cdCAqL1xuXHRtYXliZUFkZFN1cmZhY2VzXygpIHtcblx0XHR2YXIgc3VyZmFjZXNTZWxlY3RvciA9ICdbJyArIGRhdGFBdHRyaWJ1dGVzLnN1cmZhY2UgKyAnXSc7XG5cdFx0dGhpcy5xdWVyeVNlbGVjdG9yQWxsQXNBcnJheV8oc3VyZmFjZXNTZWxlY3RvcikuZm9yRWFjaCgoc3VyZmFjZUVsZW1lbnQpID0+IHtcblx0XHRcdHRoaXMudXBkYXRlRWxlbWVudElkSWZTcGVjaWFsU3VyZmFjZV8oc3VyZmFjZUVsZW1lbnQpO1xuXHRcdFx0dGhpcy5hcHAuYWRkU3VyZmFjZXMoc3VyZmFjZUVsZW1lbnQuaWQpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIERpc3BhdGNoZXMgYXBwIG5hdmlnYXRpb24gdG8gdGhlIGN1cnJlbnQgcGF0aCB3aGVuIGluaXRpYWxpemVzLlxuXHQgKi9cblx0bWF5YmVEaXNwYXRjaF8oKSB7XG5cdFx0aWYgKHRoaXMuYmFzZUVsZW1lbnQuaGFzQXR0cmlidXRlKGRhdGFBdHRyaWJ1dGVzLmRpc3BhdGNoKSkge1xuXHRcdFx0dGhpcy5hcHAuZGlzcGF0Y2goKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQWRkcyBhcHAgcm91dGUgYnkgcGFyc2luZyB2YWxpZCBsaW5rIGVsZW1lbnRzLiBBIHZhbGlkIGxpbmsgZWxlbWVudCBpcyBvZlxuXHQgKiB0aGUga2luZCBgcmVsPVwic2VubmEtcm91dGVcImAuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGlua1xuXHQgKi9cblx0bWF5YmVQYXJzZUxpbmtSb3V0ZV8obGluaykge1xuXHRcdHZhciByb3V0ZSA9IG5ldyBSb3V0ZSh0aGlzLm1heWJlUGFyc2VMaW5rUm91dGVQYXRoXyhsaW5rKSwgdGhpcy5tYXliZVBhcnNlTGlua1JvdXRlSGFuZGxlcl8obGluaykpO1xuXHRcdHRoaXMuYXBwLmFkZFJvdXRlcyhyb3V0ZSk7XG5cdFx0Y29uc29sZS5sb2coJ1Nlbm5hIHNjYW5uZWQgcm91dGUgJyArIHJvdXRlLmdldFBhdGgoKSk7XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgcGFyc2UgbGluayByb3V0ZSBoYW5kbGVyLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGxpbmtcblx0ICogQHJldHVybiB7P3N0cmluZ31cblx0ICovXG5cdG1heWJlUGFyc2VMaW5rUm91dGVIYW5kbGVyXyhsaW5rKSB7XG5cdFx0dmFyIGhhbmRsZXIgPSBsaW5rLmdldEF0dHJpYnV0ZSgndHlwZScpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwoaGFuZGxlcikpIHtcblx0XHRcdGhhbmRsZXIgPSBvYmplY3QuZ2V0T2JqZWN0QnlOYW1lKGhhbmRsZXIpO1xuXHRcdH1cblx0XHRyZXR1cm4gaGFuZGxlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBwYXJzZSBsaW5rIHJvdXRlIHBhdGguXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGlua1xuXHQgKiBAcmV0dXJuIHs/c3RyaW5nfVxuXHQgKi9cblx0bWF5YmVQYXJzZUxpbmtSb3V0ZVBhdGhfKGxpbmspIHtcblx0XHR2YXIgcGF0aCA9IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG5cdFx0aWYgKGlzRGVmQW5kTm90TnVsbChwYXRoKSkge1xuXHRcdFx0aWYgKHBhdGguaW5kZXhPZigncmVnZXg6JykgPT09IDApIHtcblx0XHRcdFx0cGF0aCA9IG5ldyBSZWdFeHAocGF0aC5zdWJzdHJpbmcoNikpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcGF0aDtcblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBzZXRzIGFwcCBiYXNlIHBhdGggZnJvbSBgZGF0YS1zZW5uYS1iYXNlLXBhdGhgIGRhdGEgYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRCYXNlUGF0aF8oKSB7XG5cdFx0dmFyIGJhc2VQYXRoID0gdGhpcy5iYXNlRWxlbWVudC5nZXRBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMuYmFzZVBhdGgpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwoYmFzZVBhdGgpKSB7XG5cdFx0XHR0aGlzLmFwcC5zZXRCYXNlUGF0aChiYXNlUGF0aCk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCBiYXNlIHBhdGggJyArIGJhc2VQYXRoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgc2V0cyBhcHAgbGluayBzZWxlY3RvciBmcm9tIGBkYXRhLXNlbm5hLWxpbmstc2VsZWN0b3JgIGRhdGFcblx0ICogYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRMaW5rU2VsZWN0b3JfKCkge1xuXHRcdHZhciBsaW5rU2VsZWN0b3IgPSB0aGlzLmJhc2VFbGVtZW50LmdldEF0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy5saW5rU2VsZWN0b3IpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwobGlua1NlbGVjdG9yKSkge1xuXHRcdFx0dGhpcy5hcHAuc2V0TGlua1NlbGVjdG9yKGxpbmtTZWxlY3Rvcik7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCBsaW5rIHNlbGVjdG9yICcgKyBsaW5rU2VsZWN0b3IpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYXliZSBzZXRzIGFwcCBsaW5rIGxvYWRpbmcgY3NzIGNsYXNzIGZyb20gYGRhdGEtc2VubmEtbG9hZGluZy1jc3MtY2xhc3NgXG5cdCAqIGRhdGEgYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRMb2FkaW5nQ3NzQ2xhc3NfKCkge1xuXHRcdHZhciBsb2FkaW5nQ3NzQ2xhc3MgPSB0aGlzLmJhc2VFbGVtZW50LmdldEF0dHJpYnV0ZShkYXRhQXR0cmlidXRlcy5sb2FkaW5nQ3NzQ2xhc3MpO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwobG9hZGluZ0Nzc0NsYXNzKSkge1xuXHRcdFx0dGhpcy5hcHAuc2V0TG9hZGluZ0Nzc0NsYXNzKGxvYWRpbmdDc3NDbGFzcyk7XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCBsb2FkaW5nIGNzcyBjbGFzcyAnICsgbG9hZGluZ0Nzc0NsYXNzKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogTWF5YmUgc2V0cyBhcHAgdXBkYXRlIHNjcm9sbCBwb3NpdGlvbiBmcm9tXG5cdCAqIGBkYXRhLXNlbm5hLXVwZGF0ZS1zY3JvbGwtcG9zaXRpb25gIGRhdGEgYXR0cmlidXRlLlxuXHQgKi9cblx0bWF5YmVTZXRVcGRhdGVTY3JvbGxQb3NpdGlvbl8oKSB7XG5cdFx0dmFyIHVwZGF0ZVNjcm9sbFBvc2l0aW9uID0gdGhpcy5iYXNlRWxlbWVudC5nZXRBdHRyaWJ1dGUoZGF0YUF0dHJpYnV0ZXMudXBkYXRlU2Nyb2xsUG9zaXRpb24pO1xuXHRcdGlmIChpc0RlZkFuZE5vdE51bGwodXBkYXRlU2Nyb2xsUG9zaXRpb24pKSB7XG5cdFx0XHRpZiAodXBkYXRlU2Nyb2xsUG9zaXRpb24gPT09ICdmYWxzZScpIHtcblx0XHRcdFx0dGhpcy5hcHAuc2V0VXBkYXRlU2Nyb2xsUG9zaXRpb24oZmFsc2UpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5hcHAuc2V0VXBkYXRlU2Nyb2xsUG9zaXRpb24odHJ1ZSk7XG5cdFx0XHR9XG5cdFx0XHRjb25zb2xlLmxvZygnU2VubmEgc2Nhbm5lZCB1cGRhdGUgc2Nyb2xsIHBvc2l0aW9uICcgKyB1cGRhdGVTY3JvbGxQb3NpdGlvbik7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFF1ZXJpZXMgZWxlbWVudHMgZnJvbSBkb2N1bWVudCBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBlbGVtZW50cy5cblx0ICogQHBhcmFtIHshc3RyaW5nfSBzZWxlY3RvclxuXHQgKiBAcmV0dXJuIHthcnJheS48RWxlbWVudD59XG5cdCAqL1xuXHRxdWVyeVNlbGVjdG9yQWxsQXNBcnJheV8oc2VsZWN0b3IpIHtcblx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZ2xvYmFscy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG5cdH1cblxuXHQvKipcblx0ICogVXBkYXRlcyBlbGVtZW50IGlkIGlmIGhhbmRsZWQgYXMgc3BlY2lhbCBzdXJmYWNlIGVsZW1lbnQuIFNvbWUgc3VyZmFjZXNcblx0ICogYXJlIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIG90aGVycywgbGlrZSB3aGVuIHRocmVhdGluZyA8Y29kZT5ib2R5PC9jb2RlPlxuXHQgKiBhcyBzdXJmYWNlLlxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcblx0ICovXG5cdHVwZGF0ZUVsZW1lbnRJZElmU3BlY2lhbFN1cmZhY2VfKGVsZW1lbnQpIHtcblx0XHRpZiAoIWVsZW1lbnQuaWQgJiYgZWxlbWVudCA9PT0gZ2xvYmFscy5kb2N1bWVudC5ib2R5KSB7XG5cdFx0XHRlbGVtZW50LmlkID0gJ3Nlbm5hX3N1cmZhY2VfJyArIGdldFVpZCgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBiYXNlIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gYmFzZUVsZW1lbnRcblx0ICovXG5cdHNldEJhc2VFbGVtZW50KGJhc2VFbGVtZW50KSB7XG5cdFx0dGhpcy5iYXNlRWxlbWVudCA9IGJhc2VFbGVtZW50O1xuXHR9XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBnbG9iYWxzIGZyb20gJy4uL2dsb2JhbHMvZ2xvYmFscyc7XG5pbXBvcnQgQXBwRGF0YUF0dHJpYnV0ZUhhbmRsZXIgZnJvbSAnLi9BcHBEYXRhQXR0cmlidXRlSGFuZGxlcic7XG5cbi8qKlxuICogRGF0YSBhdHRyaWJ1dGUgaGFuZGxlci5cbiAqIEB0eXBlIHtBcHBEYXRhQXR0cmlidXRlSGFuZGxlcn1cbiAqL1xudmFyIGRhdGFBdHRyaWJ1dGVIYW5kbGVyID0gbmV3IEFwcERhdGFBdHRyaWJ1dGVIYW5kbGVyKCk7XG5cbmdsb2JhbHMuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGZ1bmN0aW9uKCkge1xuXHRkYXRhQXR0cmlidXRlSGFuZGxlci5zZXRCYXNlRWxlbWVudChnbG9iYWxzLmRvY3VtZW50LmJvZHkpO1xuXHRkYXRhQXR0cmlidXRlSGFuZGxlci5oYW5kbGUoKTtcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBkYXRhQXR0cmlidXRlSGFuZGxlcjsiLCIvKipcbiAqIEByZXR1cm5zIFN0cmluZyBjb250YWluaW5nIHRoZSBjdXJyZW50IHNlbm5hIHZlcnNpb25cbiAqL1xuXG5jb25zdCB2ZXJzaW9uID0gJzwlPSB2ZXJzaW9uICU+JztcblxuZXhwb3J0IGRlZmF1bHQgdmVyc2lvbjsiXSwibmFtZXMiOlsiY29tcGF0aWJpbGl0eU1vZGVEYXRhXyIsInVuaXF1ZUlkQ291bnRlcl8iLCJVSURfUFJPUEVSVFkiLCJNYXRoIiwicmFuZG9tIiwiYWJzdHJhY3RNZXRob2QiLCJFcnJvciIsImRpc2FibGVDb21wYXRpYmlsaXR5TW9kZSIsInVuZGVmaW5lZCIsImVuYWJsZUNvbXBhdGliaWxpdHlNb2RlIiwiZGF0YSIsImdldENvbXBhdGliaWxpdHlNb2RlRGF0YSIsIndpbmRvdyIsIl9fTUVUQUxfQ09NUEFUSUJJTElUWV9fIiwiZ2V0Rmlyc3RUcnV0aHlfIiwiYSIsImIiLCJnZXRGdW5jdGlvbk5hbWUiLCJmbiIsIm5hbWUiLCJzdHIiLCJ0b1N0cmluZyIsInN1YnN0cmluZyIsImluZGV4T2YiLCJnZXRTdGF0aWNQcm9wZXJ0eSIsImN0b3IiLCJwcm9wZXJ0eU5hbWUiLCJtZXJnZUZuIiwibWVyZ2VkTmFtZSIsImhhc093blByb3BlcnR5IiwibWVyZ2VkIiwiX19wcm90b19fIiwiaXNQcm90b3R5cGVPZiIsIkZ1bmN0aW9uIiwiZ2V0VWlkIiwib2JqZWN0Iiwibm9Jbmhlcml0YW5jZSIsImlkIiwiaWRlbnRpdHlGdW5jdGlvbiIsInJldHVyblZhbHVlIiwiaXNCb29sZWFuIiwidmFsIiwiaXNEZWYiLCJpc0RlZkFuZE5vdE51bGwiLCJpc051bGwiLCJpc0RvY3VtZW50Iiwibm9kZVR5cGUiLCJpc0RvY3VtZW50RnJhZ21lbnQiLCJpc0VsZW1lbnQiLCJpc0Z1bmN0aW9uIiwiaXNOdW1iZXIiLCJpc1dpbmRvdyIsImlzT2JqZWN0IiwidHlwZSIsImlzUHJvbWlzZSIsInRoZW4iLCJpc1N0cmluZyIsIlN0cmluZyIsImlzU2VydmVyU2lkZSIsIm9wdGlvbnMiLCJjaGVja0VudiIsInNlcnZlclNpZGUiLCJwcm9jZXNzIiwiYnJvd3NlciIsImVudiIsIk5PREVfRU5WIiwibnVsbEZ1bmN0aW9uIiwiYXJyYXkiLCJhcnIxIiwiYXJyMiIsImxlbmd0aCIsImkiLCJhcnIiLCJvdXRwdXQiLCJBcnJheSIsImlzQXJyYXkiLCJmbGF0dGVuIiwicHVzaCIsIm9iaiIsInJ2IiwicmVtb3ZlQXQiLCJwcm90b3R5cGUiLCJzcGxpY2UiLCJjYWxsIiwic3RhcnQiLCJlbmQiLCJzbGljZWQiLCJhc3luYyIsInRocm93RXhjZXB0aW9uIiwiZXhjZXB0aW9uIiwibmV4dFRpY2siLCJydW4iLCJjYWxsYmFjayIsImNvbnRleHQiLCJ3b3JrUXVldWVTY2hlZHVsZWRfIiwicHJvY2Vzc1dvcmtRdWV1ZSIsIndvcmtRdWV1ZV8iLCJXb3JrSXRlbV8iLCJ3b3JrSXRlbXMiLCJ3b3JrSXRlbSIsInNjb3BlIiwiZSIsImNiIiwiYmluZCIsIndyYXBDYWxsYmFja18iLCJzZXRJbW1lZGlhdGVfIiwic2V0SW1tZWRpYXRlIiwiZ2V0U2V0SW1tZWRpYXRlRW11bGF0b3JfIiwiQ2hhbm5lbCIsIk1lc3NhZ2VDaGFubmVsIiwicG9zdE1lc3NhZ2UiLCJhZGRFdmVudExpc3RlbmVyIiwiaWZyYW1lIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50Iiwic3R5bGUiLCJkaXNwbGF5Iiwic3JjIiwidGl0bGUiLCJkb2N1bWVudEVsZW1lbnQiLCJhcHBlbmRDaGlsZCIsIndpbiIsImNvbnRlbnRXaW5kb3ciLCJkb2MiLCJvcGVuIiwid3JpdGUiLCJjbG9zZSIsIm1lc3NhZ2UiLCJvcmlnaW4iLCJsb2NhdGlvbiIsInByb3RvY29sIiwiaG9zdCIsIm9ubWVzc2FnZSIsInBvcnQxIiwicG9ydDIiLCJjaGFubmVsIiwiaGVhZCIsInRhaWwiLCJuZXh0Iiwic2NyaXB0Iiwib25yZWFkeXN0YXRlY2hhbmdlIiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwiRGlzcG9zYWJsZSIsImRpc3Bvc2VkXyIsImRpc3Bvc2VJbnRlcm5hbCIsInRhcmdldCIsImtleSIsInNvdXJjZSIsImFyZ3MiLCJwYXJ0cyIsInNwbGl0IiwicmVkdWNlIiwicGFydCIsIm1hcHBlZE9iaiIsImtleXMiLCJPYmplY3QiLCJvYmoxIiwib2JqMiIsImtleXMxIiwia2V5czIiLCJzdHJpbmciLCJzdHIxIiwic3RyMiIsInRlc3QxIiwidG9Mb3dlckNhc2UiLCJ0ZXN0MiIsInJlcGxhY2UiLCJ4IiwiZmxvb3IiLCJhYnMiLCJEYXRlIiwibm93IiwiaGFzaCIsImxlbiIsImNoYXJDb2RlQXQiLCJ2YWx1ZSIsIk1FVEFMX0RBVEEiLCJkb21EYXRhIiwiZWxlbWVudCIsImluaXRpYWxWYWx1ZSIsIkV2ZW50SGFuZGxlIiwiZW1pdHRlciIsImV2ZW50IiwibGlzdGVuZXIiLCJlbWl0dGVyXyIsImV2ZW50XyIsImxpc3RlbmVyXyIsInJlbW92ZUxpc3RlbmVyIiwiaXNEaXNwb3NlZCIsInNpbmdsZUFycmF5XyIsIkV2ZW50RW1pdHRlciIsImV2ZW50c18iLCJsaXN0ZW5lckhhbmRsZXJzXyIsInNob3VsZFVzZUZhY2FkZV8iLCJob2xkZXIiLCJoYW5kbGVyIiwiZGVmYXVsdExpc3RlbmVyIiwidmFsaWRhdGVMaXN0ZW5lcl8iLCJldmVudHMiLCJ0b0V2ZW50c0FycmF5XyIsImFkZFNpbmdsZUxpc3RlbmVyXyIsInJ1bkxpc3RlbmVySGFuZGxlcnNfIiwiYWRkSGFuZGxlcl8iLCJnZXRTaG91bGRVc2VGYWNhZGUiLCJmYWNhZGUiLCJwcmV2ZW50ZWREZWZhdWx0IiwibGlzdGVuZXJzIiwiZ2V0UmF3TGlzdGVuZXJzXyIsInNsaWNlIiwiYXJndW1lbnRzIiwicnVuTGlzdGVuZXJzXyIsImJ1aWxkRmFjYWRlXyIsImRpcmVjdExpc3RlbmVycyIsInRvQXJyYXkiLCJjb25jYXQiLCJtYXAiLCJhbW91bnQiLCJtYW55XyIsInNlbGYiLCJoYW5kbGVySW50ZXJuYWwiLCJhcHBseSIsImxpc3RlbmVyT2JqIiwicmVtb3ZlTWF0Y2hpbmdMaXN0ZW5lck9ianNfIiwiYWRkTGlzdGVuZXIiLCJtYW55IiwibGlzdGVuZXJPYmpzIiwiZmluYWxMaXN0ZW5lcnMiLCJtYXRjaGVzTGlzdGVuZXJfIiwib2ZmIiwiaGFuZGxlcnMiLCJkZWZhdWx0TGlzdGVuZXJzIiwiZGVmYXVsdCIsImoiLCJzaG91bGRVc2VGYWNhZGUiLCJUeXBlRXJyb3IiLCJFdmVudEVtaXR0ZXJQcm94eSIsIm9yaWdpbkVtaXR0ZXIiLCJ0YXJnZXRFbWl0dGVyIiwiYmxhY2tsaXN0Iiwid2hpdGVsaXN0IiwiYmxhY2tsaXN0XyIsIm9yaWdpbkVtaXR0ZXJfIiwicGVuZGluZ0V2ZW50c18iLCJwcm94aWVkRXZlbnRzXyIsInRhcmdldEVtaXR0ZXJfIiwid2hpdGVsaXN0XyIsInN0YXJ0UHJveHlfIiwib24iLCJyZW1vdmVMaXN0ZW5lcnNfIiwiZW1pdCIsInNob3VsZFByb3h5RXZlbnRfIiwidHJ5VG9BZGRMaXN0ZW5lcl8iLCJmb3JFYWNoIiwicHJveHlFdmVudCIsIm9uTGlzdGVuZXIiLCJhZGRMaXN0ZW5lcl8iLCJlbWl0T25UYXJnZXRfIiwiRXZlbnRIYW5kbGVyIiwiZXZlbnRIYW5kbGVzXyIsIkRvbURlbGVnYXRlZEV2ZW50SGFuZGxlIiwic2VsZWN0b3IiLCJzZWxlY3Rvcl8iLCJkZWxlZ2F0aW5nIiwiZ2V0Iiwic2VsZWN0b3JzIiwicmVtb3ZlIiwiRG9tRXZlbnRIYW5kbGUiLCJjYXB0dXJlIiwiY2FwdHVyZV8iLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiZWxlbWVudHNCeVRhZ18iLCJzdXBwb3J0Q2FjaGVfIiwiY3VzdG9tRXZlbnRzIiwiTEFTVF9DT05UQUlORVIiLCJVU0VfQ0FQVFVSRSIsImFkZENsYXNzZXMiLCJlbGVtZW50cyIsImNsYXNzZXMiLCJhZGRDbGFzc2VzV2l0aE5hdGl2ZV8iLCJjbGFzc05hbWUiLCJjbGFzc0xpc3QiLCJhZGQiLCJhZGRDbGFzc2VzV2l0aG91dE5hdGl2ZV8iLCJlbGVtZW50Q2xhc3NOYW1lIiwiY2xhc3Nlc1RvQXBwZW5kIiwiYWRkRWxlbWVudExpc3RlbmVyXyIsImV2ZW50TmFtZSIsImFkZFNlbGVjdG9yTGlzdGVuZXJfIiwiZGVsZWdhdGluZ0RhdGEiLCJhZGRUb0Fycl8iLCJhdHRhY2hEZWxlZ2F0ZUV2ZW50XyIsImhhbmRsZURlbGVnYXRlRXZlbnRfIiwiY2xvc2VzdCIsIm1hdGNoIiwiYXBwZW5kIiwicGFyZW50IiwiY2hpbGQiLCJidWlsZEZyYWdtZW50IiwiaXNOb2RlTGlzdExpa2UiLCJjaGlsZEFyciIsImh0bWxTdHJpbmciLCJ0ZW1wRGl2IiwiaW5uZXJIVE1MIiwiZmlyc3RDaGlsZCIsImZyYWdtZW50IiwiY3JlYXRlRG9jdW1lbnRGcmFnbWVudCIsImNvbnRhaW5zIiwiZWxlbWVudDEiLCJlbGVtZW50MiIsImRlbGVnYXRlIiwic2VsZWN0b3JPclRhcmdldCIsImN1c3RvbUNvbmZpZyIsIm9yaWdpbmFsRXZlbnQiLCJkZWZhdWx0TGlzdGVuZXJfIiwiaXNBYmxlVG9JbnRlcmFjdFdpdGhfIiwibm9kZSIsImV2ZW50T2JqIiwiYnV0dG9uIiwibWF0Y2hlc1NlbGVjdG9yIiwidGFnTmFtZSIsImRpc2FibGVkIiwiaXRlbSIsImV4aXREb2N1bWVudCIsInJldCIsImNvbnRhaW5lciIsImN1cnJlbnRUYXJnZXQiLCJkZWZGbnMiLCJ0cmlnZ2VyRGVsZWdhdGVkTGlzdGVuZXJzXyIsInRyaWdnZXJEZWZhdWx0RGVsZWdhdGVkTGlzdGVuZXJzXyIsImRlbGVnYXRlVGFyZ2V0IiwicCIsIkVsZW1lbnQiLCJtIiwibWF0Y2hlcyIsIndlYmtpdE1hdGNoZXNTZWxlY3RvciIsIm1vek1hdGNoZXNTZWxlY3RvciIsIm1zTWF0Y2hlc1NlbGVjdG9yIiwib01hdGNoZXNTZWxlY3RvciIsIm1hdGNoRmFsbGJhY2tfIiwibm9kZXMiLCJxdWVyeVNlbGVjdG9yQWxsIiwibm9ybWFsaXplRGVsZWdhdGVFdmVudF8iLCJzdG9wUHJvcGFnYXRpb24iLCJzdG9wUHJvcGFnYXRpb25fIiwic3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uIiwic3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uXyIsIm9uY2UiLCJkb21FdmVudEhhbmRsZSIsInJlZ2lzdGVyQ3VzdG9tRXZlbnQiLCJyZW1vdmVDaGlsZHJlbiIsInJlbW92ZUNsYXNzZXMiLCJyZW1vdmVDbGFzc2VzV2l0aE5hdGl2ZV8iLCJyZW1vdmVDbGFzc2VzV2l0aG91dE5hdGl2ZV8iLCJ0cmltIiwic3RvcHBlZCIsInN0b3BwZWRJbW1lZGlhdGUiLCJzdXBwb3J0c0V2ZW50IiwidGFnIiwiZGVmYXVsdFByZXZlbnRlZCIsImRlZmF1bHRGbnMiLCJjdXJyRWxlbWVudCIsImxpbWl0IiwidHJpZ2dlckVsZW1lbnRMaXN0ZW5lcnNfIiwidHJpZ2dlclNlbGVjdG9yTGlzdGVuZXJzXyIsImxhc3RDb250YWluZXIiLCJ0cmlnZ2VyTGlzdGVuZXJzXyIsIkRvbUV2ZW50RW1pdHRlclByb3h5IiwiaXNEZWxlZ2F0ZUV2ZW50XyIsImluZGV4Iiwic3Vic3RyIiwiYmFiZWxIZWxwZXJzLmdldCIsImlzU3VwcG9ydGVkRG9tRXZlbnRfIiwiZmVhdHVyZXMiLCJhbmltYXRpb25FdmVudE5hbWVfIiwiY2hlY2tBbmltYXRpb25FdmVudE5hbWVfIiwicHJlZml4ZXMiLCJ0eXBlVGl0bGVDYXNlIiwicmVwbGFjZUludGVydmFsIiwidG9VcHBlckNhc2UiLCJzdWZmaXhlcyIsImFuaW1hdGlvbkVsZW1lbnRfIiwiYXR0ck9yZGVyQ2hhbmdlXyIsIm9yaWdpbmFsQ29udGVudCIsImdsb2JhbEV2YWwiLCJ0ZXh0IiwiYXBwZW5kRm4iLCJkZWZhdWx0Rm4iLCJydW5GaWxlIiwic2NyaXB0cyIsInJ1blNjcmlwdHNJbk9yZGVyIiwicnVuU2NyaXB0IiwiZ2xvYmFsRXZhbFN0eWxlcyIsImhyZWYiLCJsaW5rIiwicmVsIiwicnVuU3R5bGUiLCJzdHlsZXMiLCJsb2FkQ291bnQiLCJyZWdpc3RlckV2ZW50cyIsIm1vdXNlRXZlbnRNYXAiLCJyZWxhdGVkIiwicmVsYXRlZFRhcmdldCIsImN1c3RvbVR5cGUiLCJhbmltYXRpb25FdmVudE1hcCIsImV2ZW50VHlwZSIsImNoZWNrQW5pbWF0aW9uRXZlbnROYW1lIiwiZ2xvYmFscyIsInBhcnNlRnJvbUFuY2hvciIsIm9wdF91cmkiLCJ0ZXN0IiwiaG9zdG5hbWUiLCJwYXNzd29yZCIsInBhdGhuYW1lIiwicG9ydCIsInNlYXJjaCIsInVzZXJuYW1lIiwicGFyc2UiLCJVUkwiLCJ1cmwiLCJjcmVhdGUiLCJNdWx0aU1hcCIsInZhbHVlcyIsInNpemUiLCJuYW1lcyIsIkpTT04iLCJzdHJpbmdpZnkiLCJzZXQiLCJUcmVlTm9kZSIsInZhbHVlXyIsInBhcmVudF8iLCJjaGlsZHJlbl8iLCJzZXRQYXJlbnQiLCJjdXJyZW50IiwiZ2V0UGFyZW50IiwiYW5jZXN0b3JzIiwiZ2V0Q2hpbGRyZW4iLCJFTVBUWV9BUlJBWSIsImRlcHRoIiwicm9vdCIsImdldENoaWxkQ291bnQiLCJvcHRfcHJlb3JkZXJGbiIsIm9wdF9wb3N0b3JkZXJGbiIsInRyYXZlcnNlIiwiYXNzZXJ0Q2hpbGRIYXNOb1BhcmVudCIsInBhcnNlRm5fIiwiVXJpIiwibWF5YmVBZGRQcm90b2NvbEFuZEhvc3RuYW1lXyIsIm11bHRpbWFwIiwiZ2V0QWxsIiwiYWRkUGFyYW1ldGVyVmFsdWUiLCJlbnN1cmVRdWVyeUluaXRpYWxpemVkXyIsInF1ZXJ5IiwicGFyYW0iLCJ1cmxEZWNvZGUiLCJnZXRIb3N0bmFtZSIsImdldFBvcnQiLCJIT1NUTkFNRV9QTEFDRUhPTERFUiIsImdldEhvc3QiLCJnZXRQcm90b2NvbCIsInF1ZXJ5c3RyaW5nIiwiZ2V0UGFyYW1ldGVyTmFtZXMiLCJnZXRQYXJhbWV0ZXJWYWx1ZXMiLCJlbmNvZGVVUklDb21wb25lbnQiLCJzZXRQYXJhbWV0ZXJWYWx1ZSIsIlJBTkRPTV9QQVJBTSIsImdldFJhbmRvbVN0cmluZyIsIkRFRkFVTFRfUFJPVE9DT0wiLCJjaGFyQXQiLCJyZW1vdmVQYXJhbWV0ZXIiLCJnZXRQYXRobmFtZSIsImdldFNlYXJjaCIsImdldEhhc2giLCJwYXJzZUZuIiwiYmFzZVBhdGgiLCJwYXRocyIsInBhdGgiLCJqb2luIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwiaXNTZWN1cmUiLCJ1dGlscyIsImF0dHJpYnV0ZXMiLCJhdHRyaWJ1dGUiLCJzZXRBdHRyaWJ1dGUiLCJnZXRDdXJyZW50QnJvd3NlclBhdGhXaXRob3V0SGFzaCIsIm9mZnNldExlZnQiLCJvZmZzZXRUb3AiLCJvZmZzZXRQYXJlbnQiLCJ1cmkiLCJjdXJyZW50QnJvd3NlclBhdGgiLCJnZXRVcmxQYXRoV2l0aG91dEhhc2giLCJnZXRVcmxQYXRoIiwiaGlzdG9yeSIsInB1c2hTdGF0ZSIsImVyciIsImVycm9yIiwicmVtb3ZlQXR0cmlidXRlIiwicmVmZXJyZXIiLCJkZWZpbmVQcm9wZXJ0eSIsIlRoZW5hYmxlIiwiSU1QTEVNRU5URURfQllfUFJPUCIsImFkZEltcGxlbWVudGF0aW9uIiwiJGdvb2dfVGhlbmFibGUiLCJpc0ltcGxlbWVudGVkQnkiLCJwYXJ0aWFsIiwibmV3QXJncyIsIkNhbmNlbGxhYmxlUHJvbWlzZSIsInJlc29sdmVyIiwib3B0X2NvbnRleHQiLCJzdGF0ZV8iLCJTdGF0ZV8iLCJQRU5ESU5HIiwicmVzdWx0XyIsImNhbGxiYWNrRW50cmllc18iLCJleGVjdXRpbmdfIiwiVU5IQU5ETEVEX1JFSkVDVElPTl9ERUxBWSIsInVuaGFuZGxlZFJlamVjdGlvbklkXyIsImhhZFVuaGFuZGxlZFJlamVjdGlvbl8iLCJyZXNvbHZlXyIsIkZVTEZJTExFRCIsInJlYXNvbiIsIlJFSkVDVEVEIiwiQ2FsbGJhY2tFbnRyeV8iLCJyZXNvbHZlIiwib3B0X3ZhbHVlIiwicmVqZWN0Iiwib3B0X3JlYXNvbiIsInJhY2UiLCJwcm9taXNlcyIsInByb21pc2UiLCJhbGwiLCJ0b0Z1bGZpbGwiLCJvbkZ1bGZpbGwiLCJvblJlamVjdCIsImZpcnN0RnVsZmlsbGVkIiwidG9SZWplY3QiLCJyZWFzb25zIiwib3B0X29uRnVsZmlsbGVkIiwib3B0X29uUmVqZWN0ZWQiLCJhZGRDaGlsZFByb21pc2VfIiwidGhlbkFsd2F5cyIsIm9uUmVzb2x2ZWQiLCJoYW5kbGVSZWplY3Rpb25fIiwiYWRkQ2FsbGJhY2tFbnRyeV8iLCJ0aGVuQ2F0Y2giLCJvblJlamVjdGVkIiwiY2F0Y2giLCJjYW5jZWwiLCJvcHRfbWVzc2FnZSIsIkNhbmNlbGxhdGlvbkVycm9yIiwiSVNfQ0FOQ0VMTEFUSU9OX0VSUk9SIiwiY2FuY2VsSW50ZXJuYWxfIiwiY2FuY2VsQ2hpbGRfIiwiY2hpbGRQcm9taXNlIiwiY2hpbGRDb3VudCIsImNoaWxkSW5kZXgiLCJlbnRyeSIsImNhbGxiYWNrRW50cnkiLCJleGVjdXRlQ2FsbGJhY2tfIiwic2NoZWR1bGVDYWxsYmFja3NfIiwib25GdWxmaWxsZWQiLCJyZXN1bHQiLCJ1bmJsb2NrQW5kRnVsZmlsbF8iLCJCTE9DS0VEIiwidW5ibG9ja0FuZFJlamVjdF8iLCJzdGF0ZSIsInRyeVRoZW5fIiwiYWRkVW5oYW5kbGVkUmVqZWN0aW9uXyIsInRoZW5hYmxlIiwiY2FsbGVkIiwiZXhlY3V0ZUNhbGxiYWNrc18iLCJlbnRyaWVzIiwicmVtb3ZlVW5oYW5kbGVkUmVqZWN0aW9uXyIsInNldFRpbWVvdXQiLCJzZXRVbmhhbmRsZWRSZWplY3Rpb25IYW5kbGVyIiwiZGVib3VuY2UiLCJkZWxheSIsImRlYm91bmNlZCIsImNhbmNlbERlYm91bmNlIiwiUkVHRVgiLCJjb252ZXJ0TWF0Y2hlc1RvT2JqIiwiY29udmVydFRva2Vuc1RvUmVnZXgiLCJ0b2tlbnMiLCJyZWdleCIsImNvcmUiLCJlc2NhcGUiLCJlbmNsb3NlTm9uQ2FwdHVyaW5nR3JvdXAiLCJwYXR0ZXJuIiwicmVwZWF0IiwicHJlZml4Iiwib3B0aW9uYWwiLCJSZWdFeHAiLCJtYWtlVHJhaWxpbmdTbGFzaE9wdGlvbmFsIiwicm91dGVPclRva2VucyIsInJvdXRlIiwidW5uYW1lZENvdW50IiwiY3VyclBhdGgiLCJleGVjIiwicGFyYW1QYXR0ZXJuIiwidW5uYW1lZFBhdHRlcm4iLCJtb2RpZmllciIsInRvUmVnZXgiLCJleHRyYWN0RGF0YSIsInBhcmFtSW5kZXgiLCJSb3V0ZSIsInBhcnNlZERhdGFfIiwiYnVpbGRQYXJzZWREYXRhXyIsIkNhY2hlYWJsZSIsImNhY2hlIiwiY2FjaGVhYmxlIiwiY29udGVudCIsImNsZWFyQ2FjaGUiLCJTY3JlZW4iLCJtYWtlSWRfIiwibWV0YXMiLCJsb2ciLCJzdXJmYWNlcyIsInNJZCIsImFjdGl2ZUNoaWxkIiwicnVuU2NyaXB0c0luRWxlbWVudCIsInRyYW5zaXRpb25zIiwic3VyZmFjZSIsImRlZmVycmVkIiwic2hvdyIsIlN1cmZhY2UiLCJkZWZhdWx0Q2hpbGQiLCJ0cmFuc2l0aW9uRm4iLCJnZXRDaGlsZCIsIkRFRkFVTFQiLCJtYXliZVdyYXBDb250ZW50QXNEZWZhdWx0XyIsInNjcmVlbklkIiwib3B0X2NvbnRlbnQiLCJjcmVhdGVDaGlsZCIsInRyYW5zaXRpb24iLCJnZXRFbGVtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJhZGRDb250ZW50IiwiZnJvbSIsInRvIiwiZGVmYXVsdFRyYW5zaXRpb24iLCJOYXZpZ2F0aW9uU3RyYXRlZ3kiLCJBcHAiLCJhY3RpdmVTY3JlZW4iLCJhY3RpdmVQYXRoIiwiYWxsb3dQcmV2ZW50TmF2aWdhdGUiLCJicm93c2VyUGF0aEJlZm9yZU5hdmlnYXRlIiwiY2FwdHVyZVNjcm9sbFBvc2l0aW9uRnJvbVNjcm9sbEV2ZW50IiwiZGVmYXVsdFRpdGxlIiwiZm9ybVNlbGVjdG9yIiwiaWdub3JlUXVlcnlTdHJpbmdGcm9tUm91dGVQYXRoIiwibGlua1NlbGVjdG9yIiwibG9hZGluZ0Nzc0NsYXNzIiwibmF0aXZlU2Nyb2xsUmVzdG9yYXRpb25TdXBwb3J0ZWQiLCJuYXZpZ2F0aW9uU3RyYXRlZ3kiLCJJTU1FRElBVEUiLCJpc05hdmlnYXRpb25QZW5kaW5nIiwicGVuZGluZ05hdmlnYXRlIiwicG9wc3RhdGVTY3JvbGxMZWZ0IiwicG9wc3RhdGVTY3JvbGxUb3AiLCJyZWRpcmVjdFBhdGgiLCJyb3V0ZXMiLCJzY2hlZHVsZWROYXZpZ2F0aW9uUXVldWUiLCJzY3JlZW5zIiwic2tpcExvYWRQb3BzdGF0ZSIsInVwZGF0ZVNjcm9sbFBvc2l0aW9uIiwiYXBwRXZlbnRIYW5kbGVyc18iLCJvblNjcm9sbF8iLCJvbkxvYWRfIiwib25Qb3BzdGF0ZV8iLCJvblN0YXJ0TmF2aWdhdGVfIiwib25CZWZvcmVOYXZpZ2F0ZV8iLCJvbkJlZm9yZU5hdmlnYXRlRGVmYXVsdF8iLCJvbkJlZm9yZVVubG9hZERlZmF1bHRfIiwic2V0TGlua1NlbGVjdG9yIiwic2V0Rm9ybVNlbGVjdG9yIiwibWF5YmVPdmVybG9hZEJlZm9yZVVubG9hZF8iLCJnZXRJZCIsImlzV2ViVXJpIiwiaXNMaW5rU2FtZU9yaWdpbl8iLCJpc1NhbWVCYXNlUGF0aF8iLCJpc0N1cnJlbnRCcm93c2VyUGF0aCIsImZpbmRSb3V0ZSIsInJlbW92ZVNjcmVlbiIsInNjcmVlbiIsImdldEhhbmRsZXIiLCJjbGVhclNjcmVlbnNDYWNoZSIsImZvcm1FdmVudEhhbmRsZXJfIiwibGlua0V2ZW50SGFuZGxlcl8iLCJyZW1vdmVBbGxMaXN0ZW5lcnMiLCJuYXZpZ2F0ZSIsImdldEN1cnJlbnRCcm93c2VyUGF0aCIsIm9wdF9yZXBsYWNlSGlzdG9yeSIsInN0b3BQZW5kaW5nTmF2aWdhdGVfIiwibmV4dFNjcmVlbiIsImNyZWF0ZVNjcmVlbkluc3RhbmNlIiwibWF5YmVQcmV2ZW50RGVhY3RpdmF0ZV8iLCJtYXliZVByZXZlbnRBY3RpdmF0ZV8iLCJsb2FkIiwiU0NIRURVTEVfTEFTVCIsImRlYWN0aXZhdGUiLCJwcmVwYXJlTmF2aWdhdGVIaXN0b3J5XyIsInByZXBhcmVOYXZpZ2F0ZVN1cmZhY2VzXyIsImV4dHJhY3RQYXJhbXMiLCJldmFsdWF0ZVN0eWxlcyIsImZsaXAiLCJldmFsdWF0ZVNjcmlwdHMiLCJtYXliZVVwZGF0ZVNjcm9sbFBvc2l0aW9uU3RhdGVfIiwic3luY1Njcm9sbFBvc2l0aW9uU3luY1RoZW5Bc3luY18iLCJmaW5hbGl6ZU5hdmlnYXRlXyIsImhhbmRsZU5hdmlnYXRlRXJyb3JfIiwic2NoZWR1bGVkTmF2aWdhdGlvbiIsInNoaWZ0IiwibWF5YmVOYXZpZ2F0ZV8iLCJnZXRSb3V0ZVBhdGgiLCJhY3RpdmF0ZSIsImlzQ2FjaGVhYmxlIiwiY2FwdHVyZWRGb3JtRWxlbWVudCIsImNhcHR1cmVkRm9ybUJ1dHRvbkVsZW1lbnQiLCJtYXRjaGVzUGF0aCIsImdldElnbm9yZVF1ZXJ5U3RyaW5nRnJvbVJvdXRlUGF0aCIsImdldFVybFBhdGhXaXRob3V0SGFzaEFuZFNlYXJjaCIsInN0YWNrIiwiaG9zdFVyaSIsImxvY2F0aW9uSG9zdFVyaSIsIndpbm5lciIsInN3aXRjaFNjcm9sbFBvc2l0aW9uUmFjZSIsInNjcm9sbFRvIiwic2Nyb2xsTGVmdCIsInNjcm9sbFRvcCIsIm5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uXyIsInNjcm9sbFJlc3RvcmF0aW9uIiwibWl4aW4iLCJjYW5OYXZpZ2F0ZSIsImlzTmF2aWdhdGlvblNjaGVkdWxlZCIsIm1heWJlU2NoZWR1bGVOYXZpZ2F0aW9uXyIsInByZXZlbnREZWZhdWx0IiwibmF2aWdhdGVGYWlsZWQiLCJpc1NjaGVkdWxlZE5hdmlnYXRpb24iLCJvbmJlZm9yZXVubG9hZCIsIl9vbmJlZm9yZXVubG9hZCIsIl9vdmVybG9hZGVkIiwiYmVmb3JlQWN0aXZhdGUiLCJwcmV2ZW50IiwiYmVmb3JlRGVhY3RpdmF0ZSIsImFuY2hvckVsZW1lbnQiLCJnZXROb2RlT2Zmc2V0Iiwic2F2ZUhpc3RvcnlDdXJyZW50UGFnZVNjcm9sbFBvc2l0aW9uXyIsIm9wdF9ldmVudCIsImlzSHRtbDVIaXN0b3J5U3VwcG9ydGVkIiwiZm9ybSIsInJlcGxhY2VIaXN0b3J5IiwiZnVuYyIsImFsdEtleSIsImN0cmxLZXkiLCJtZXRhS2V5Iiwic2hpZnRLZXkiLCJtZXRob2QiLCJidXR0b25TZWxlY3RvciIsImFjdGl2ZUVsZW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwiYWN0aW9uIiwibWF5YmVSZXBvc2l0aW9uU2Nyb2xsVG9IYXNoZWRBbmNob3IiLCJyZWxvYWRQYWdlIiwic2VubmEiLCJsb2NrSGlzdG9yeVNjcm9sbFBvc2l0aW9uXyIsInNldFJlZmVycmVyIiwic2V0SG9zdG5hbWUiLCJzZXRQb3J0IiwicGFnZVlPZmZzZXQiLCJwYWdlWE9mZnNldCIsIm1heWJlRGlzYWJsZU5hdGl2ZVNjcm9sbFJlc3RvcmF0aW9uIiwiZW5kTmF2aWdhdGVQYXlsb2FkIiwiZG9OYXZpZ2F0ZV8iLCJtYXliZVJlc3RvcmVOYXRpdmVTY3JvbGxSZXN0b3JhdGlvbiIsImdldFRpdGxlIiwiZ2V0RGVmYXVsdFRpdGxlIiwiYmVmb3JlVXBkYXRlSGlzdG9yeVBhdGgiLCJoaXN0b3J5U3RhdGUiLCJtYXliZVJlc3RvcmVSZWRpcmVjdFBhdGhIYXNoXyIsInVwZGF0ZUhpc3RvcnlfIiwiYmVmb3JlVXBkYXRlSGlzdG9yeVN0YXRlIiwicGFyYW1zIiwic3VyZmFjZUNvbnRlbnQiLCJnZXRTdXJmYWNlQ29udGVudCIsInJlbG9hZCIsInN1cmZhY2VJZCIsImRpc3Bvc2UiLCJyZXBsYWNlU3RhdGUiLCJyZW1vdmVQYXRoVHJhaWxpbmdTbGFzaCIsIm9uRG9jU3VibWl0RGVsZWdhdGVfIiwib25Eb2NDbGlja0RlbGVnYXRlXyIsInN5bmMiLCJ0aXRsZU5vZGUiLCJBamF4IiwiYWxsSGVhZGVycyIsImhlYWRlcnMiLCJwYWlycyIsImJvZHkiLCJvcHRfaGVhZGVycyIsIm9wdF9wYXJhbXMiLCJvcHRfdGltZW91dCIsIm9wdF9zeW5jIiwib3B0X3dpdGhDcmVkZW50aWFscyIsInJlcXVlc3QiLCJYTUxIdHRwUmVxdWVzdCIsInByZXZpb3VzUmVhZHlTdGF0ZSIsIlByb21pc2UiLCJvbmxvYWQiLCJhYm9ydGVkIiwib25lcnJvciIsInJlYWR5U3RhdGUiLCJ0ZXJtaW5hdGVkUHJlbWF0dXJlbHkiLCJhYm9ydCIsInRpbWVvdXQiLCJhZGRQYXJhbWV0ZXJzRnJvbU11bHRpTWFwIiwid2l0aENyZWRlbnRpYWxzIiwic2V0UmVxdWVzdEhlYWRlciIsInNlbmQiLCJlcnJvcnMiLCJJTlZBTElEX1NUQVRVUyIsIlJFUVVFU1RfRVJST1IiLCJSRVFVRVNUX1RJTUVPVVQiLCJSRVFVRVNUX1BSRU1BVFVSRV9URVJNSU5BVElPTiIsIlVBIiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwicGxhdGZvcm0iLCJpc01hYyIsIm1hdGNoUGxhdGZvcm0iLCJpc1dpbiIsImlzT3BlcmEiLCJtYXRjaFVzZXJBZ2VudCIsImlzSWUiLCJpc0VkZ2UiLCJpc0llT3JFZGdlIiwiaXNDaHJvbWUiLCJpc1NhZmFyaSIsImlzRmlyZWZveCIsInRlc3RVc2VyQWdlbnQiLCJnZXROYXRpdmVVc2VyQWdlbnQiLCJnZXROYXRpdmVQbGF0Zm9ybSIsIlJlcXVlc3RTY3JlZW4iLCJodHRwSGVhZGVycyIsImh0dHBNZXRob2QiLCJHRVQiLCJzdGF0dXMiLCJpc1ZhbGlkUmVzcG9uc2VTdGF0dXNDb2RlIiwiaW52YWxpZFN0YXR1cyIsInN0YXR1c0NvZGUiLCJnZXRSZXF1ZXN0UGF0aCIsInNldFByb3RvY29sIiwibWFrZVVuaXF1ZSIsImdldFJlcXVlc3QiLCJyZXF1ZXN0UGF0aCIsInJlc3BvbnNlVXJsIiwibWF5YmVFeHRyYWN0UmVzcG9uc2VVcmxGcm9tUmVxdWVzdCIsInJlbW92ZVVuaXF1ZSIsImdldENhY2hlIiwiaGVhZGVyIiwiYWRkU2FmYXJpWEhSUG9seWZpbGwiLCJGb3JtRGF0YSIsIm1heWJlQXBwZW5kU3VibWl0QnV0dG9uVmFsdWVfIiwiUE9TVCIsImZvcm1hdExvYWRQYXRoIiwicmVtb3ZlU2FmYXJpWEhSUG9seWZpbGwiLCJzZXRSZXF1ZXN0IiwieGhyIiwiYXNzZXJ0VmFsaWRSZXNwb25zZVN0YXR1c0NvZGUiLCJhZGRDYWNoZSIsInJlc3BvbnNlVGV4dCIsInJlcXVlc3RFcnJvciIsInJlcXVlc3RQcmVtYXR1cmVUZXJtaW5hdGlvbiIsInJlc3BvbnNlVVJMIiwiZ2V0UmVzcG9uc2VIZWFkZXIiLCJYX1JFUVVFU1RfVVJMX0hFQURFUiIsImlucHV0cyIsImlucHV0IiwiZmlsZXMiLCJIdG1sU2NyZWVuIiwibWV0YVRhZ3NTZWxlY3RvciIsInRpdGxlU2VsZWN0b3IiLCJyZWxlYXNlVmlydHVhbERvY3VtZW50IiwicGVuZGluZ1N0eWxlcyIsInZpcnR1YWxEb2N1bWVudCIsImNvcHlOb2RlQXR0cmlidXRlc0Zyb21Db250ZW50XyIsIm5ld1N0eWxlIiwiaXNUZW1wb3JhcnlTdHlsZSIsInN0eWxlc1RlbXBvcmFyeSIsInN0eWxlSW5Eb2MiLCJpbnNlcnRCZWZvcmUiLCJuZXh0U2libGluZyIsImJvZHlTdXJmYWNlIiwicGxhY2Vob2xkZXIiLCJ0ZW1wTm9kZSIsImNyZWF0ZVJhbmdlIiwiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiwiY2xlYXJOb2RlQXR0cmlidXRlcyIsImNvcHlOb2RlQXR0cmlidXRlcyIsImRpc3Bvc2VQZW5kaW5nU3R5bGVzIiwicmVtb3ZlRWxlbWVudHNGcm9tRG9jdW1lbnQiLCJldmFsdWF0ZVRyYWNrZWRTY3JpcHRzIiwiZXZhbHVhdGVUcmFja2VkUmVzb3VyY2VzXyIsInNjcmlwdHNUZW1wb3JhcnkiLCJzY3JpcHRzUGVybWFuZW50IiwiZXZhbHVhdGVUcmFja2VkU3R5bGVzIiwicnVuU3R5bGVzSW5FbGVtZW50Iiwic3R5bGVzUGVybWFuZW50IiwiYXBwZW5kU3R5bGVJbnRvRG9jdW1lbnRfIiwicmVzb3VyY2VzSW5WaXJ0dWFsIiwidmlydHVhbFF1ZXJ5U2VsZWN0b3JBbGxfIiwiZmF2aWNvbiIsInJlc291cmNlc0luRG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yQWxsXyIsInJ1bkZhdmljb25JbkVsZW1lbnRfIiwiZXZhbHVhdG9yRm4iLCJzZWxlY3RvclRlbXBvcmFyeSIsInNlbGVjdG9yUGVybWFuZW50Iiwib3B0X2FwcGVuZFJlc291cmNlRm4iLCJ0cmFja2VkIiwidGVtcG9yYXJpZXNJbkRvYyIsInBlcm1hbmVudHNJbkRvYyIsInJlc291cmNlIiwicmVzb3VyY2VLZXkiLCJnZXRSZXNvdXJjZUtleV8iLCJwZXJtYW5lbnRSZXNvdXJjZXNJbkRvYyIsImZyYWciLCJldmFsdWF0ZUZhdmljb25fIiwidXBkYXRlTWV0YVRhZ3NfIiwiY3VycmVudE1ldGFOb2RlcyIsIm1ldGFzRnJvbVZpcnR1YWxEb2N1bWVudCIsIm1ldGEiLCJhbGxvY2F0ZVZpcnR1YWxEb2N1bWVudEZvckNvbnRlbnQiLCJyZXNvbHZlVGl0bGVGcm9tVmlydHVhbERvY3VtZW50IiwicmVzb2x2ZU1ldGFUYWdzRnJvbVZpcnR1YWxEb2N1bWVudCIsImFzc2VydFNhbWVCb2R5SWRJblZpcnR1YWxEb2N1bWVudCIsIm1ha2VUZW1wb3JhcnlTdHlsZXNIcmVmc1VuaXF1ZV8iLCJyZXBsYWNlU3R5bGVBbmRNYWtlVW5pcXVlXyIsInJlcGxhY2VDaGlsZCIsInNldEVsZW1lbnRXaXRoUmFuZG9tSHJlZiIsInNldFRpdGxlIiwidGV4dENvbnRlbnQiLCJzZXRNZXRhcyIsImlnbm9yZUZhdmljb24iLCJBcHBEYXRhQXR0cmlidXRlSGFuZGxlciIsImFwcCIsImJhc2VFbGVtZW50IiwiaGFzQXR0cmlidXRlIiwiZGF0YUF0dHJpYnV0ZXMiLCJtYXliZUFkZFJvdXRlc18iLCJtYXliZUFkZFN1cmZhY2VzXyIsIm1heWJlU2V0QmFzZVBhdGhfIiwibWF5YmVTZXRMaW5rU2VsZWN0b3JfIiwibWF5YmVTZXRMb2FkaW5nQ3NzQ2xhc3NfIiwibWF5YmVTZXRVcGRhdGVTY3JvbGxQb3NpdGlvbl8iLCJtYXliZURpc3BhdGNoXyIsInJvdXRlc1NlbGVjdG9yIiwicXVlcnlTZWxlY3RvckFsbEFzQXJyYXlfIiwibWF5YmVQYXJzZUxpbmtSb3V0ZV8iLCJoYXNSb3V0ZXMiLCJhZGRSb3V0ZXMiLCJzdXJmYWNlc1NlbGVjdG9yIiwic3VyZmFjZUVsZW1lbnQiLCJ1cGRhdGVFbGVtZW50SWRJZlNwZWNpYWxTdXJmYWNlXyIsImFkZFN1cmZhY2VzIiwiZGlzcGF0Y2giLCJtYXliZVBhcnNlTGlua1JvdXRlUGF0aF8iLCJtYXliZVBhcnNlTGlua1JvdXRlSGFuZGxlcl8iLCJnZXRQYXRoIiwiZ2V0QXR0cmlidXRlIiwiZ2V0T2JqZWN0QnlOYW1lIiwic2V0QmFzZVBhdGgiLCJzZXRMb2FkaW5nQ3NzQ2xhc3MiLCJzZXRVcGRhdGVTY3JvbGxQb3NpdGlvbiIsImRhdGFBdHRyaWJ1dGVIYW5kbGVyIiwic2V0QmFzZUVsZW1lbnQiLCJoYW5kbGUiLCJ2ZXJzaW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQTs7Ozs7QUFLQSxJQUFJQSwrQkFBSjs7Ozs7OztBQU9BLElBQUlDLG1CQUFtQixDQUF2Qjs7Ozs7OztBQU9BLEFBQU8sSUFBTUMsMEJBQXdCQyxLQUFLQyxNQUFMLEtBQWdCLEdBQWpCLEtBQTBCLENBQWpELENBQU47Ozs7Ozs7Ozs7OztBQVlQLEFBQU8sU0FBU0MsY0FBVCxHQUEwQjtRQUMxQkMsTUFBTSwrQkFBTixDQUFOOzs7Ozs7QUFNRCxBQUFPLFNBQVNDLHdCQUFULEdBQW9DOzJCQUNqQkMsU0FBekI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkQsQUFBTyxTQUFTQyx1QkFBVCxHQUE0QztNQUFY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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b2f4706..218a8ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "senna", - "version": "2.7.4", + "version": "2.7.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,11 +10,11 @@ "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", "dev": true, "requires": { - "acorn": "^5.0.3", - "css": "^2.2.1", - "normalize-path": "^2.1.1", - "source-map": "^0.5.6", - "through2": "^2.0.3" + "acorn": "5.1.1", + "css": "2.2.1", + "normalize-path": "2.1.1", + "source-map": "0.5.6", + "through2": "2.0.3" } }, "@gulp-sourcemaps/map-sources": { @@ -23,8 +23,8 @@ "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", "dev": true, "requires": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" + "normalize-path": "2.1.1", + "through2": "2.0.3" } }, "abbrev": { @@ -39,7 +39,7 @@ "integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=", "dev": true, "requires": { - "mime-types": "~2.1.6", + "mime-types": "2.1.16", "negotiator": "0.5.3" } }, @@ -55,7 +55,7 @@ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { - "acorn": "^3.0.4" + "acorn": "3.3.0" }, "dependencies": { "acorn": { @@ -72,8 +72,8 @@ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "dev": true, "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" + "co": "4.6.0", + "json-stable-stringify": "1.0.1" } }, "ajv-keywords": { @@ -88,9 +88,9 @@ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" } }, "amdefine": { @@ -124,8 +124,8 @@ "dev": true, "optional": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" } }, "archy": { @@ -140,7 +140,7 @@ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "sprintf-js": "1.0.3" } }, "arr-diff": { @@ -149,7 +149,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "arr-flatten": "1.1.0" } }, "arr-flatten": { @@ -188,7 +188,7 @@ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "array-uniq": "^1.0.1" + "array-uniq": "1.0.3" } }, "array-uniq": { @@ -240,12 +240,12 @@ "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", "dev": true, "requires": { - "browserslist": "^1.7.6", - "caniuse-db": "^1.0.30000634", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^5.2.16", - "postcss-value-parser": "^3.2.3" + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000708", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "5.2.17", + "postcss-value-parser": "3.3.0" } }, "babel-cli": { @@ -254,21 +254,21 @@ "integrity": "sha1-IHzXBbumFImy6kG1MSNBz2rKIoM=", "dev": true, "requires": { - "babel-core": "^6.24.1", - "babel-polyfill": "^6.23.0", - "babel-register": "^6.24.1", - "babel-runtime": "^6.22.0", - "chokidar": "^1.6.1", - "commander": "^2.8.1", - "convert-source-map": "^1.1.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.0.0", - "lodash": "^4.2.0", - "output-file-sync": "^1.1.0", - "path-is-absolute": "^1.0.0", - "slash": "^1.0.0", - "source-map": "^0.5.0", - "v8flags": "^2.0.10" + "babel-core": "6.25.0", + "babel-polyfill": "6.23.0", + "babel-register": "6.24.1", + "babel-runtime": "6.25.0", + "chokidar": "1.7.0", + "commander": "2.11.0", + "convert-source-map": "1.5.0", + "fs-readdir-recursive": "1.0.0", + "glob": "7.1.2", + "lodash": "4.17.4", + "output-file-sync": "1.1.2", + "path-is-absolute": "1.0.1", + "slash": "1.0.0", + "source-map": "0.5.6", + "v8flags": "2.1.1" } }, "babel-code-frame": { @@ -277,9 +277,9 @@ "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", "dev": true, "requires": { - "chalk": "^1.1.0", - "esutils": "^2.0.2", - "js-tokens": "^3.0.0" + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" } }, "babel-core": { @@ -288,25 +288,25 @@ "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", "dev": true, "requires": { - "babel-code-frame": "^6.22.0", - "babel-generator": "^6.25.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.25.0", - "babel-traverse": "^6.25.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "convert-source-map": "^1.1.0", - "debug": "^2.1.1", - "json5": "^0.5.0", - "lodash": "^4.2.0", - "minimatch": "^3.0.2", - "path-is-absolute": "^1.0.0", - "private": "^0.1.6", - "slash": "^1.0.0", - "source-map": "^0.5.0" + "babel-code-frame": "6.22.0", + "babel-generator": "6.25.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.24.1", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "convert-source-map": "1.5.0", + "debug": "2.6.8", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.6" } }, "babel-generator": { @@ -315,14 +315,14 @@ "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-types": "^6.25.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.2.0", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "babel-messages": "6.23.0", + "babel-runtime": "6.25.0", + "babel-types": "6.25.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.6", + "trim-right": "1.0.1" } }, "babel-helper-call-delegate": { @@ -331,10 +331,10 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helper-define-map": { @@ -343,10 +343,10 @@ "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1", - "lodash": "^4.2.0" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.25.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" } }, "babel-helper-function-name": { @@ -355,11 +355,11 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helper-get-function-arity": { @@ -368,8 +368,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helper-hoist-variables": { @@ -378,8 +378,8 @@ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helper-optimise-call-expression": { @@ -388,8 +388,8 @@ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helper-regex": { @@ -398,9 +398,9 @@ "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1", - "lodash": "^4.2.0" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" } }, "babel-helper-replace-supers": { @@ -409,12 +409,12 @@ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helpers": { @@ -423,8 +423,8 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-template": "6.25.0" } }, "babel-messages": { @@ -433,7 +433,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-check-es2015-constants": { @@ -442,7 +442,7 @@ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-external-helpers": { @@ -451,7 +451,7 @@ "integrity": "sha1-IoX0iwK9Xe3oUXXK+MYuhq3M76E=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-search-and-replace": { @@ -466,7 +466,7 @@ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -475,7 +475,7 @@ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -484,11 +484,11 @@ "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1", - "lodash": "^4.2.0" + "babel-runtime": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" } }, "babel-plugin-transform-es2015-classes": { @@ -497,15 +497,15 @@ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "dev": true, "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-define-map": "6.24.1", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -514,8 +514,8 @@ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-destructuring": { @@ -524,7 +524,7 @@ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -533,8 +533,8 @@ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-for-of": { @@ -543,7 +543,7 @@ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -552,9 +552,9 @@ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-literals": { @@ -563,7 +563,7 @@ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -572,9 +572,9 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -583,10 +583,10 @@ "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -595,9 +595,9 @@ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -606,9 +606,9 @@ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-object-super": { @@ -617,8 +617,8 @@ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -627,12 +627,12 @@ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "dev": true, "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.25.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -641,8 +641,8 @@ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-spread": { @@ -651,7 +651,7 @@ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -660,9 +660,9 @@ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-template-literals": { @@ -671,7 +671,7 @@ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -680,7 +680,7 @@ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.25.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -689,9 +689,9 @@ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.25.0", + "regexpu-core": "2.0.0" } }, "babel-plugin-transform-node-env-inline": { @@ -721,8 +721,8 @@ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0" } }, "babel-polyfill": { @@ -731,9 +731,9 @@ "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "core-js": "^2.4.0", - "regenerator-runtime": "^0.10.0" + "babel-runtime": "6.25.0", + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" } }, "babel-preset-es2015": { @@ -742,30 +742,30 @@ "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1" } }, "babel-preset-es2015-rollup": { @@ -774,9 +774,9 @@ "integrity": "sha1-hUtj7N4u6YysQOiC9nv88YWx8ko=", "dev": true, "requires": { - "babel-plugin-external-helpers": "^6.18.0", - "babel-preset-es2015": "^6.3.13", - "require-relative": "^0.8.7" + "babel-plugin-external-helpers": "6.22.0", + "babel-preset-es2015": "6.24.1", + "require-relative": "0.8.7" } }, "babel-preset-metal": { @@ -785,7 +785,7 @@ "integrity": "sha1-WoRpOLkqmOtkDHzZpBEm/X7M25E=", "dev": true, "requires": { - "babel-preset-es2015": "^6.1.18" + "babel-preset-es2015": "6.24.1" } }, "babel-register": { @@ -794,13 +794,13 @@ "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", "dev": true, "requires": { - "babel-core": "^6.24.1", - "babel-runtime": "^6.22.0", - "core-js": "^2.4.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.2" + "babel-core": "6.25.0", + "babel-runtime": "6.25.0", + "core-js": "2.4.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.15" } }, "babel-runtime": { @@ -809,8 +809,8 @@ "integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=", "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.10.0" + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" } }, "babel-template": { @@ -819,11 +819,11 @@ "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.25.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "lodash": "^4.2.0" + "babel-runtime": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "lodash": "4.17.4" } }, "babel-traverse": { @@ -832,15 +832,15 @@ "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", "dev": true, "requires": { - "babel-code-frame": "^6.22.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "debug": "^2.2.0", - "globals": "^9.0.0", - "invariant": "^2.2.0", - "lodash": "^4.2.0" + "babel-code-frame": "6.22.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.4", + "debug": "2.6.8", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" } }, "babel-types": { @@ -849,10 +849,10 @@ "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "esutils": "^2.0.2", - "lodash": "^4.2.0", - "to-fast-properties": "^1.0.1" + "babel-runtime": "6.25.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" } }, "babylon": { @@ -898,7 +898,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "beeper": { @@ -920,7 +920,7 @@ "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", "dev": true, "requires": { - "readable-stream": "~1.0.26" + "readable-stream": "1.0.34" }, "dependencies": { "isarray": { @@ -935,10 +935,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -962,15 +962,15 @@ "dev": true, "requires": { "bytes": "2.1.0", - "content-type": "~1.0.1", - "debug": "~2.2.0", - "depd": "~1.0.1", - "http-errors": "~1.3.1", + "content-type": "1.0.2", + "debug": "2.2.0", + "depd": "1.0.1", + "http-errors": "1.3.1", "iconv-lite": "0.4.11", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "4.0.0", - "raw-body": "~2.1.2", - "type-is": "~1.6.6" + "raw-body": "2.1.7", + "type-is": "1.6.15" }, "dependencies": { "debug": { @@ -1001,7 +1001,7 @@ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -1011,9 +1011,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" } }, "browser-resolve": { @@ -1039,8 +1039,8 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "^1.0.30000639", - "electron-to-chromium": "^1.2.7" + "caniuse-db": "1.0.30000708", + "electron-to-chromium": "1.3.16" } }, "builtin-modules": { @@ -1061,7 +1061,7 @@ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { - "callsites": "^0.2.0" + "callsites": "0.2.0" } }, "callsites": { @@ -1083,8 +1083,8 @@ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "camelcase": "2.1.1", + "map-obj": "1.0.1" }, "dependencies": { "camelcase": { @@ -1107,7 +1107,7 @@ "integrity": "sha1-mMyJDKZS3S7w5ws3klMQ/56Q/Is=", "dev": true, "requires": { - "underscore-contrib": "~0.3.0" + "underscore-contrib": "0.3.0" } }, "center-align": { @@ -1117,8 +1117,8 @@ "dev": true, "optional": true, "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "align-text": "0.1.4", + "lazy-cache": "1.0.4" } }, "chai": { @@ -1137,11 +1137,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, "chokidar": { @@ -1151,15 +1151,15 @@ "dev": true, "optional": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.1.2", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" } }, "circular-json": { @@ -1174,7 +1174,7 @@ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", "dev": true, "requires": { - "restore-cursor": "^1.0.1" + "restore-cursor": "1.0.1" } }, "cli-width": { @@ -1190,8 +1190,8 @@ "dev": true, "optional": true, "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", + "center-align": "0.1.3", + "right-align": "0.1.3", "wordwrap": "0.0.2" }, "dependencies": { @@ -1240,7 +1240,7 @@ "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=", "dev": true, "requires": { - "mime-db": ">= 1.29.0 < 2" + "mime-db": "1.29.0" } }, "compression": { @@ -1249,12 +1249,12 @@ "integrity": "sha1-sDuNhub4rSloPLqN+R3cb/x3s5U=", "dev": true, "requires": { - "accepts": "~1.2.12", + "accepts": "1.2.13", "bytes": "2.1.0", - "compressible": "~2.0.5", - "debug": "~2.2.0", - "on-headers": "~1.0.0", - "vary": "~1.0.1" + "compressible": "2.0.11", + "debug": "2.2.0", + "on-headers": "1.0.1", + "vary": "1.0.1" }, "dependencies": { "debug": { @@ -1286,9 +1286,9 @@ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", "dev": true, "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" } }, "concat-with-sourcemaps": { @@ -1297,7 +1297,7 @@ "integrity": "sha1-9Vs74q60dgGxCi1SWcz7cP0vHdY=", "dev": true, "requires": { - "source-map": "^0.5.1" + "source-map": "0.5.6" } }, "connect": { @@ -1307,36 +1307,36 @@ "dev": true, "requires": { "basic-auth-connect": "1.0.0", - "body-parser": "~1.13.3", + "body-parser": "1.13.3", "bytes": "2.1.0", - "compression": "~1.5.2", - "connect-timeout": "~1.6.2", - "content-type": "~1.0.1", + "compression": "1.5.2", + "connect-timeout": "1.6.2", + "content-type": "1.0.2", "cookie": "0.1.3", - "cookie-parser": "~1.3.5", + "cookie-parser": "1.3.5", "cookie-signature": "1.0.6", - "csurf": "~1.8.3", - "debug": "~2.2.0", - "depd": "~1.0.1", - "errorhandler": "~1.4.2", - "express-session": "~1.11.3", + "csurf": "1.8.3", + "debug": "2.2.0", + "depd": "1.0.1", + "errorhandler": "1.4.3", + "express-session": "1.11.3", "finalhandler": "0.4.0", "fresh": "0.3.0", - "http-errors": "~1.3.1", - "method-override": "~2.3.5", - "morgan": "~1.6.1", + "http-errors": "1.3.1", + "method-override": "2.3.9", + "morgan": "1.6.1", "multiparty": "3.3.2", - "on-headers": "~1.0.0", - "parseurl": "~1.3.0", + "on-headers": "1.0.1", + "parseurl": "1.3.1", "pause": "0.1.0", "qs": "4.0.0", - "response-time": "~2.3.1", - "serve-favicon": "~2.3.0", - "serve-index": "~1.7.2", - "serve-static": "~1.10.0", - "type-is": "~1.6.6", + "response-time": "2.3.2", + "serve-favicon": "2.3.2", + "serve-index": "1.7.3", + "serve-static": "1.10.3", + "type-is": "1.6.15", "utils-merge": "1.0.0", - "vhost": "~3.0.1" + "vhost": "3.0.2" }, "dependencies": { "debug": { @@ -1368,10 +1368,10 @@ "integrity": "sha1-3ppexh4zoStu2qt7XwYumMWZuI4=", "dev": true, "requires": { - "debug": "~2.2.0", - "http-errors": "~1.3.1", + "debug": "2.2.0", + "http-errors": "1.3.1", "ms": "0.7.1", - "on-headers": "~1.0.0" + "on-headers": "1.0.1" }, "dependencies": { "debug": { @@ -1460,10 +1460,10 @@ "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", "dev": true, "requires": { - "inherits": "^2.0.1", - "source-map": "^0.1.38", - "source-map-resolve": "^0.3.0", - "urix": "^0.1.0" + "inherits": "2.0.3", + "source-map": "0.1.43", + "source-map-resolve": "0.3.1", + "urix": "0.1.0" }, "dependencies": { "source-map": { @@ -1472,7 +1472,7 @@ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -1485,8 +1485,8 @@ "requires": { "cookie": "0.1.3", "cookie-signature": "1.0.6", - "csrf": "~3.0.0", - "http-errors": "~1.3.1" + "csrf": "3.0.6", + "http-errors": "1.3.1" } }, "currently-unhandled": { @@ -1495,7 +1495,7 @@ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "^1.0.1" + "array-find-index": "1.0.2" } }, "d": { @@ -1504,7 +1504,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "^0.10.9" + "es5-ext": "0.10.24" } }, "dateformat": { @@ -1529,7 +1529,7 @@ "dev": true, "requires": { "debug": "2.3.0", - "memoizee": "^0.4.5", + "memoizee": "0.4.5", "object-assign": "4.1.0" }, "dependencies": { @@ -1583,7 +1583,7 @@ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "clone": "^1.0.2" + "clone": "1.0.2" } }, "del": { @@ -1592,13 +1592,13 @@ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.1" } }, "depd": { @@ -1625,7 +1625,7 @@ "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", "dev": true, "requires": { - "fs-exists-sync": "^0.1.0" + "fs-exists-sync": "0.1.0" } }, "detect-indent": { @@ -1634,7 +1634,7 @@ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "detect-newline": { @@ -1655,8 +1655,8 @@ "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", "dev": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "esutils": "2.0.2", + "isarray": "1.0.0" } }, "dom-serializer": { @@ -1665,8 +1665,8 @@ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", "dev": true, "requires": { - "domelementtype": "~1.1.1", - "entities": "~1.1.1" + "domelementtype": "1.1.3", + "entities": "1.1.1" }, "dependencies": { "domelementtype": { @@ -1689,7 +1689,7 @@ "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "1.3.0" } }, "domutils": { @@ -1698,8 +1698,8 @@ "integrity": "sha1-GVjMC0yUJuntNn+xyOhUiRsPo/8=", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" } }, "duplexer": { @@ -1714,7 +1714,7 @@ "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", "dev": true, "requires": { - "readable-stream": "~1.1.9" + "readable-stream": "1.1.14" }, "dependencies": { "isarray": { @@ -1729,10 +1729,10 @@ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -1750,7 +1750,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "ee-first": { @@ -1771,7 +1771,7 @@ "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", "dev": true, "requires": { - "once": "~1.3.0" + "once": "1.3.3" }, "dependencies": { "once": { @@ -1780,7 +1780,7 @@ "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } } } @@ -1797,7 +1797,7 @@ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "is-arrayish": "0.2.1" } }, "errorhandler": { @@ -1806,8 +1806,8 @@ "integrity": "sha1-t7cO2PNZ6duICS8tIMD4MUIK2D8=", "dev": true, "requires": { - "accepts": "~1.3.0", - "escape-html": "~1.0.3" + "accepts": "1.3.3", + "escape-html": "1.0.3" }, "dependencies": { "accepts": { @@ -1816,7 +1816,7 @@ "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", "dev": true, "requires": { - "mime-types": "~2.1.11", + "mime-types": "2.1.16", "negotiator": "0.6.1" } }, @@ -1834,8 +1834,8 @@ "integrity": "sha1-pVh3yZJLwMjZvTwsvhdJWsFwmxQ=", "dev": true, "requires": { - "es6-iterator": "2", - "es6-symbol": "~3.1" + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" } }, "es6-iterator": { @@ -1844,9 +1844,9 @@ "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", "dev": true, "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-symbol": "^3.1" + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-symbol": "3.1.1" } }, "es6-map": { @@ -1855,12 +1855,12 @@ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-iterator": "2.0.1", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" } }, "es6-plato": { @@ -1869,11 +1869,11 @@ "integrity": "sha1-CSfhXORiC9+OEfBaTVwd3GveW3s=", "dev": true, "requires": { - "eslint": "^3.9.1", - "fs-extra": "^2.0.0", - "glob": "^7.1.1", - "lodash": "^4.16.6", - "posix-getopt": "^1.2.0", + "eslint": "3.19.0", + "fs-extra": "2.1.2", + "glob": "7.1.2", + "lodash": "4.17.4", + "posix-getopt": "1.2.0", "typhonjs-escomplex": "0.0.12" } }, @@ -1883,11 +1883,11 @@ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-iterator": "2.0.1", "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" + "event-emitter": "0.3.5" } }, "es6-symbol": { @@ -1896,8 +1896,8 @@ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "1.0.0", + "es5-ext": "0.10.24" } }, "es6-weak-map": { @@ -1906,10 +1906,10 @@ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", "dev": true, "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" } }, "escape-html": { @@ -1930,11 +1930,11 @@ "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", "dev": true, "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.5.6" + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.5.6" }, "dependencies": { "esprima": { @@ -1951,7 +1951,7 @@ "integrity": "sha1-uj/ir5obBi3uDhMJO3HtOJodcWg=", "dev": true, "requires": { - "typhonjs-escomplex-commons": "^0.0.16" + "typhonjs-escomplex-commons": "0.0.16" } }, "escomplex-plugin-metrics-project": { @@ -1960,7 +1960,7 @@ "integrity": "sha1-cDSXc/DEsZPVjyHqEDLRN1vvD0U=", "dev": true, "requires": { - "typhonjs-escomplex-commons": "^0.0.16" + "typhonjs-escomplex-commons": "0.0.16" } }, "escomplex-plugin-syntax-babylon": { @@ -1969,8 +1969,8 @@ "integrity": "sha1-bh8pnyAR1IfdK0rOtxQ4SKC/23I=", "dev": true, "requires": { - "escomplex-plugin-syntax-estree": "^0.0.13", - "typhonjs-escomplex-commons": "^0.0.16" + "escomplex-plugin-syntax-estree": "0.0.13", + "typhonjs-escomplex-commons": "0.0.16" } }, "escomplex-plugin-syntax-estree": { @@ -1979,7 +1979,7 @@ "integrity": "sha1-/BKGZxuMpo8fC4Abc2SwNBgvIUU=", "dev": true, "requires": { - "typhonjs-escomplex-commons": "^0.0.16" + "typhonjs-escomplex-commons": "0.0.16" } }, "escope": { @@ -1988,10 +1988,10 @@ "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", "dev": true, "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" } }, "eslint": { @@ -2000,41 +2000,41 @@ "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", "dev": true, "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", - "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" + "babel-code-frame": "6.22.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.8", + "doctrine": "2.0.0", + "escope": "3.6.0", + "espree": "3.4.3", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.3", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.9.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" }, "dependencies": { "strip-bom": { @@ -2049,7 +2049,7 @@ "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", "dev": true, "requires": { - "os-homedir": "^1.0.0" + "os-homedir": "1.0.2" } } } @@ -2060,8 +2060,8 @@ "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", "dev": true, "requires": { - "acorn": "^5.0.1", - "acorn-jsx": "^3.0.0" + "acorn": "5.1.1", + "acorn-jsx": "3.0.1" } }, "esprima": { @@ -2076,7 +2076,7 @@ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "4.2.0" } }, "esrecurse": { @@ -2085,8 +2085,8 @@ "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", "dev": true, "requires": { - "estraverse": "^4.1.0", - "object-assign": "^4.0.1" + "estraverse": "4.2.0", + "object-assign": "4.1.1" } }, "estraverse": { @@ -2119,8 +2119,8 @@ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "1.0.0", + "es5-ext": "0.10.24" } }, "event-stream": { @@ -2129,13 +2129,13 @@ "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", + "duplexer": "0.1.1", + "from": "0.1.7", + "map-stream": "0.1.0", "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" + "split": "0.3.3", + "stream-combiner": "0.0.4", + "through": "2.3.8" } }, "exit-hook": { @@ -2150,7 +2150,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "is-posix-bracket": "0.1.1" } }, "expand-range": { @@ -2159,7 +2159,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "^2.1.0" + "fill-range": "2.2.3" } }, "expand-tilde": { @@ -2168,7 +2168,7 @@ "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", "dev": true, "requires": { - "os-homedir": "^1.0.1" + "os-homedir": "1.0.2" } }, "express-session": { @@ -2180,11 +2180,11 @@ "cookie": "0.1.3", "cookie-signature": "1.0.6", "crc": "3.3.0", - "debug": "~2.2.0", - "depd": "~1.0.1", - "on-headers": "~1.0.0", - "parseurl": "~1.3.0", - "uid-safe": "~2.0.0", + "debug": "2.2.0", + "depd": "1.0.1", + "on-headers": "1.0.1", + "parseurl": "1.3.1", + "uid-safe": "2.0.0", "utils-merge": "1.0.0" }, "dependencies": { @@ -2226,7 +2226,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "fancy-log": { @@ -2235,8 +2235,8 @@ "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", "dev": true, "requires": { - "chalk": "^1.1.1", - "time-stamp": "^1.0.0" + "chalk": "1.1.3", + "time-stamp": "1.1.0" } }, "fast-levenshtein": { @@ -2251,7 +2251,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": ">=0.5.1" + "websocket-driver": "0.6.5" } }, "figures": { @@ -2260,8 +2260,8 @@ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" } }, "file-entry-cache": { @@ -2270,8 +2270,8 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "1.2.2", + "object-assign": "4.1.1" } }, "filename-regex": { @@ -2286,11 +2286,11 @@ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^1.1.3", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" } }, "finalhandler": { @@ -2299,10 +2299,10 @@ "integrity": "sha1-llpS2ejQXSuFdUhUH7ibU6JJfZs=", "dev": true, "requires": { - "debug": "~2.2.0", + "debug": "2.2.0", "escape-html": "1.0.2", - "on-finished": "~2.3.0", - "unpipe": "~1.0.0" + "on-finished": "2.3.0", + "unpipe": "1.0.0" }, "dependencies": { "debug": { @@ -2340,8 +2340,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "findup-sync": { @@ -2350,10 +2350,10 @@ "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", "dev": true, "requires": { - "detect-file": "^0.1.0", - "is-glob": "^2.0.1", - "micromatch": "^2.3.7", - "resolve-dir": "^0.1.0" + "detect-file": "0.1.0", + "is-glob": "2.0.1", + "micromatch": "2.3.11", + "resolve-dir": "0.1.1" } }, "fined": { @@ -2362,11 +2362,11 @@ "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", "dev": true, "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" + "expand-tilde": "2.0.2", + "is-plain-object": "2.0.4", + "object.defaults": "1.1.0", + "object.pick": "1.2.0", + "parse-filepath": "1.0.1" }, "dependencies": { "expand-tilde": { @@ -2375,7 +2375,7 @@ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { - "homedir-polyfill": "^1.0.1" + "homedir-polyfill": "1.0.1" } } } @@ -2398,10 +2398,10 @@ "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", "dev": true, "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" } }, "for-in": { @@ -2416,7 +2416,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "^1.0.1" + "for-in": "1.0.2" } }, "formatio": { @@ -2425,7 +2425,7 @@ "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", "dev": true, "requires": { - "samsam": "~1.1" + "samsam": "1.1.2" } }, "fresh": { @@ -2446,7 +2446,7 @@ "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { - "null-check": "^1.0.0" + "null-check": "1.0.0" } }, "fs-exists-sync": { @@ -2461,8 +2461,8 @@ "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0" } }, "fs-readdir-recursive": { @@ -2484,8 +2484,8 @@ "dev": true, "optional": true, "requires": { - "nan": "^2.3.0", - "node-pre-gyp": "^0.6.36" + "nan": "2.6.2", + "node-pre-gyp": "0.6.36" }, "dependencies": { "abbrev": { @@ -2500,8 +2500,8 @@ "dev": true, "optional": true, "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" + "co": "4.6.0", + "json-stable-stringify": "1.0.1" } }, "ansi-regex": { @@ -2521,8 +2521,8 @@ "dev": true, "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "delegates": "1.0.0", + "readable-stream": "2.2.9" } }, "asn1": { @@ -2566,7 +2566,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "block-stream": { @@ -2574,7 +2574,7 @@ "bundled": true, "dev": true, "requires": { - "inherits": "~2.0.0" + "inherits": "2.0.3" } }, "boom": { @@ -2582,7 +2582,7 @@ "bundled": true, "dev": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "brace-expansion": { @@ -2590,7 +2590,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "^0.4.1", + "balanced-match": "0.4.2", "concat-map": "0.0.1" } }, @@ -2621,7 +2621,7 @@ "bundled": true, "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "concat-map": { @@ -2645,7 +2645,7 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x" + "boom": "2.10.1" } }, "dashdash": { @@ -2654,7 +2654,7 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" }, "dependencies": { "assert-plus": { @@ -2697,7 +2697,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "extend": { @@ -2723,9 +2723,9 @@ "dev": true, "optional": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" } }, "fs.realpath": { @@ -2738,10 +2738,10 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" } }, "fstream-ignore": { @@ -2750,9 +2750,9 @@ "dev": true, "optional": true, "requires": { - "fstream": "^1.0.0", - "inherits": "2", - "minimatch": "^3.0.0" + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" } }, "gauge": { @@ -2761,14 +2761,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" } }, "getpass": { @@ -2777,7 +2777,7 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" }, "dependencies": { "assert-plus": { @@ -2793,12 +2793,12 @@ "bundled": true, "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "graceful-fs": { @@ -2818,8 +2818,8 @@ "dev": true, "optional": true, "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" + "ajv": "4.11.8", + "har-schema": "1.0.5" } }, "has-unicode": { @@ -2834,10 +2834,10 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" } }, "hoek": { @@ -2851,9 +2851,9 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" } }, "inflight": { @@ -2861,8 +2861,8 @@ "bundled": true, "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -2881,7 +2881,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-typedarray": { @@ -2907,7 +2907,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "jsbn": { @@ -2928,7 +2928,7 @@ "dev": true, "optional": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json-stringify-safe": { @@ -2973,7 +2973,7 @@ "bundled": true, "dev": true, "requires": { - "mime-db": "~1.27.0" + "mime-db": "1.27.0" } }, "minimatch": { @@ -2981,7 +2981,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.7" } }, "minimist": { @@ -3009,15 +3009,15 @@ "dev": true, "optional": true, "requires": { - "mkdirp": "^0.5.1", - "nopt": "^4.0.1", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "request": "^2.81.0", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^2.2.1", - "tar-pack": "^3.4.0" + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" } }, "nopt": { @@ -3026,8 +3026,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1.1.0", + "osenv": "0.1.4" } }, "npmlog": { @@ -3036,10 +3036,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" } }, "number-is-nan": { @@ -3064,7 +3064,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "os-homedir": { @@ -3085,8 +3085,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "path-is-absolute": { @@ -3123,10 +3123,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "~0.4.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" }, "dependencies": { "minimist": { @@ -3142,13 +3142,13 @@ "bundled": true, "dev": true, "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" } }, "request": { @@ -3157,28 +3157,28 @@ "dev": true, "optional": true, "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" } }, "rimraf": { @@ -3186,7 +3186,7 @@ "bundled": true, "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "safe-buffer": { @@ -3218,7 +3218,7 @@ "dev": true, "optional": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "sshpk": { @@ -3227,15 +3227,15 @@ "dev": true, "optional": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jodid25519": "^1.0.0", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" }, "dependencies": { "assert-plus": { @@ -3251,9 +3251,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "string_decoder": { @@ -3261,7 +3261,7 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.0.1" } }, "stringstream": { @@ -3275,7 +3275,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-json-comments": { @@ -3289,9 +3289,9 @@ "bundled": true, "dev": true, "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" } }, "tar-pack": { @@ -3300,14 +3300,14 @@ "dev": true, "optional": true, "requires": { - "debug": "^2.2.0", - "fstream": "^1.0.10", - "fstream-ignore": "^1.0.5", - "once": "^1.3.3", - "readable-stream": "^2.1.4", - "rimraf": "^2.5.1", - "tar": "^2.2.1", - "uid-number": "^0.0.6" + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" } }, "tough-cookie": { @@ -3316,7 +3316,7 @@ "dev": true, "optional": true, "requires": { - "punycode": "^1.4.1" + "punycode": "1.4.1" } }, "tunnel-agent": { @@ -3325,7 +3325,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.0.1" } }, "tweetnacl": { @@ -3366,7 +3366,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "1.0.2" } }, "wrappy": { @@ -3382,7 +3382,7 @@ "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", "dev": true, "requires": { - "globule": "~0.1.0" + "globule": "0.1.0" } }, "generate-function": { @@ -3397,7 +3397,7 @@ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", "dev": true, "requires": { - "is-property": "^1.0.0" + "is-property": "1.0.2" } }, "get-stdin": { @@ -3412,12 +3412,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-base": { @@ -3426,8 +3426,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "glob-parent": "2.0.0", + "is-glob": "2.0.1" } }, "glob-parent": { @@ -3436,7 +3436,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "2.0.1" } }, "glob-stream": { @@ -3445,12 +3445,12 @@ "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", "dev": true, "requires": { - "glob": "^4.3.1", - "glob2base": "^0.0.12", - "minimatch": "^2.0.1", - "ordered-read-streams": "^0.1.0", - "through2": "^0.6.1", - "unique-stream": "^1.0.0" + "glob": "4.5.3", + "glob2base": "0.0.12", + "minimatch": "2.0.10", + "ordered-read-streams": "0.1.0", + "through2": "0.6.5", + "unique-stream": "1.0.0" }, "dependencies": { "glob": { @@ -3459,10 +3459,10 @@ "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^2.0.1", - "once": "^1.3.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0" } }, "isarray": { @@ -3477,7 +3477,7 @@ "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", "dev": true, "requires": { - "brace-expansion": "^1.0.0" + "brace-expansion": "1.1.8" } }, "readable-stream": { @@ -3486,10 +3486,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -3504,8 +3504,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } } } @@ -3516,7 +3516,7 @@ "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", "dev": true, "requires": { - "gaze": "^0.5.1" + "gaze": "0.5.2" } }, "glob2base": { @@ -3525,7 +3525,7 @@ "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", "dev": true, "requires": { - "find-index": "^0.1.1" + "find-index": "0.1.1" } }, "global-modules": { @@ -3534,8 +3534,8 @@ "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", "dev": true, "requires": { - "global-prefix": "^0.1.4", - "is-windows": "^0.2.0" + "global-prefix": "0.1.5", + "is-windows": "0.2.0" } }, "global-prefix": { @@ -3544,10 +3544,10 @@ "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", "dev": true, "requires": { - "homedir-polyfill": "^1.0.0", - "ini": "^1.3.4", - "is-windows": "^0.2.0", - "which": "^1.2.12" + "homedir-polyfill": "1.0.1", + "ini": "1.3.4", + "is-windows": "0.2.0", + "which": "1.2.14" } }, "globals": { @@ -3562,12 +3562,12 @@ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "globule": { @@ -3576,9 +3576,9 @@ "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", "dev": true, "requires": { - "glob": "~3.1.21", - "lodash": "~1.0.1", - "minimatch": "~0.2.11" + "glob": "3.1.21", + "lodash": "1.0.2", + "minimatch": "0.2.14" }, "dependencies": { "glob": { @@ -3587,9 +3587,9 @@ "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", "dev": true, "requires": { - "graceful-fs": "~1.2.0", - "inherits": "1", - "minimatch": "~0.2.11" + "graceful-fs": "1.2.3", + "inherits": "1.0.2", + "minimatch": "0.2.14" } }, "graceful-fs": { @@ -3616,8 +3616,8 @@ "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", "dev": true, "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" + "lru-cache": "2.7.3", + "sigmund": "1.0.1" } } } @@ -3628,7 +3628,7 @@ "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", "dev": true, "requires": { - "sparkles": "^1.0.0" + "sparkles": "1.0.0" } }, "graceful-fs": { @@ -3649,19 +3649,19 @@ "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", "dev": true, "requires": { - "archy": "^1.0.0", - "chalk": "^1.0.0", - "deprecated": "^0.0.1", - "gulp-util": "^3.0.0", - "interpret": "^1.0.0", - "liftoff": "^2.1.0", - "minimist": "^1.1.0", - "orchestrator": "^0.3.0", - "pretty-hrtime": "^1.0.0", - "semver": "^4.1.0", - "tildify": "^1.0.0", - "v8flags": "^2.0.2", - "vinyl-fs": "^0.3.0" + "archy": "1.0.0", + "chalk": "1.1.3", + "deprecated": "0.0.1", + "gulp-util": "3.0.8", + "interpret": "1.0.3", + "liftoff": "2.3.0", + "minimist": "1.2.0", + "orchestrator": "0.3.8", + "pretty-hrtime": "1.0.3", + "semver": "4.3.6", + "tildify": "1.2.0", + "v8flags": "2.1.1", + "vinyl-fs": "0.3.14" }, "dependencies": { "minimist": { @@ -3678,11 +3678,11 @@ "integrity": "sha1-dSMAUc0NFxND14O36bXREg7u+bA=", "dev": true, "requires": { - "autoprefixer": "^6.0.0", - "gulp-util": "^3.0.0", - "postcss": "^5.0.4", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" + "autoprefixer": "6.7.7", + "gulp-util": "3.0.8", + "postcss": "5.2.17", + "through2": "2.0.3", + "vinyl-sourcemaps-apply": "0.2.1" } }, "gulp-connect": { @@ -3691,11 +3691,11 @@ "integrity": "sha1-8v3zBq6RFGg2jCKF8teC8T7dr04=", "dev": true, "requires": { - "connect": "^2.30.0", - "connect-livereload": "^0.5.4", - "event-stream": "^3.3.2", - "gulp-util": "^3.0.6", - "tiny-lr": "^0.2.1" + "connect": "2.30.2", + "connect-livereload": "0.5.4", + "event-stream": "3.3.4", + "gulp-util": "3.0.8", + "tiny-lr": "0.2.1" } }, "gulp-header": { @@ -3704,10 +3704,10 @@ "integrity": "sha1-yfEP7gYy2B6Tl4nG7PRaFRvzCYs=", "dev": true, "requires": { - "concat-with-sourcemaps": "*", - "gulp-util": "*", - "object-assign": "*", - "through2": "^2.0.0" + "concat-with-sourcemaps": "1.0.4", + "gulp-util": "3.0.8", + "object-assign": "4.1.1", + "through2": "2.0.3" } }, "gulp-jsdoc3": { @@ -3716,11 +3716,11 @@ "integrity": "sha1-Yek1IS6qlrXC5yvD1n0e3d8VKTo=", "dev": true, "requires": { - "bluebird": "^3.1.1", - "debug": "^2.2.0", - "gulp-util": "^3.0.7", - "ink-docstrap": "^1.1.4", - "jsdoc": "^3.4.1", + "bluebird": "3.5.0", + "debug": "2.6.8", + "gulp-util": "3.0.8", + "ink-docstrap": "1.3.0", + "jsdoc": "3.5.3", "map-stream": "0.0.6", "tmp": "0.0.28" }, @@ -3739,39 +3739,39 @@ "integrity": "sha512-SfD7B/3gdc+go261GWql9i/08yq24ZKnTVSzdRpBvdn5n9yZXcWBghxW0zzAQxhgHGBNh1dKakT6i6NUtzcu9Q==", "dev": true, "requires": { - "babel-preset-es2015": "^6.3.13", - "babel-register": "^6.4.3", - "del": "^2.0.2", - "es6-plato": "^1.0.12", - "eslint": "^3.12.2", - "glob-expand": "^0.1.0", - "gulp": "^3.8.11", - "gulp-autoprefixer": "^3.1.0", - "gulp-concat": "^2.5.2", - "gulp-esformatter": "^5.0.0", - "gulp-eslint": "^3.0.1", - "gulp-jshint": "^2.0.0", - "gulp-mocha": "^2.2.0", - "gulp-rename": "^1.2.2", - "gulp-sass": "^2.0.1", - "gulp-uglify": "^1.2.0", - "gulp-util": "^3.0.6", - "jsdoc": "^3.4.0", - "jshint": "^2.9.1", - "jshint-stylish": "^2.0.0", - "karma": "^1.1.0", - "karma-firefox-launcher": "^0.1.7", - "karma-ievms": "^0.1.0", - "karma-safari-launcher": "^0.1.1", - "karma-sauce-launcher": "^0.3.0", - "merge": "^1.2.0", - "metal-karma-config": "^2.2.0", - "metal-tools-build-amd": "^3.0.0", - "metal-tools-build-globals": "^2.0.0", - "metal-tools-build-jquery": "^2.0.0", - "metal-tools-soy": "^3.0.0", + "babel-preset-es2015": "6.24.1", + "babel-register": "6.24.1", + "del": "2.2.2", + "es6-plato": "1.0.14", + "eslint": "3.19.0", + "glob-expand": "0.1.0", + "gulp": "3.9.1", + "gulp-autoprefixer": "3.1.1", + "gulp-concat": "2.6.1", + "gulp-esformatter": "5.0.0", + "gulp-eslint": "3.0.1", + "gulp-jshint": "2.0.4", + "gulp-mocha": "2.2.0", + "gulp-rename": "1.2.2", + "gulp-sass": "2.3.2", + "gulp-uglify": "1.5.4", + "gulp-util": "3.0.8", + "jsdoc": "3.4.3", + "jshint": "2.9.4", + "jshint-stylish": "2.2.1", + "karma": "1.7.0", + "karma-firefox-launcher": "0.1.7", + "karma-ievms": "0.1.0", + "karma-safari-launcher": "0.1.1", + "karma-sauce-launcher": "0.3.1", + "merge": "1.2.0", + "metal-karma-config": "2.3.1", + "metal-tools-build-amd": "3.0.3", + "metal-tools-build-globals": "2.0.2", + "metal-tools-build-jquery": "2.0.2", + "metal-tools-soy": "3.1.0", "open": "0.0.5", - "run-sequence": "^1.1.0", + "run-sequence": "1.2.2", "typhonjs-escomplex": "0.0.12" }, "dependencies": { @@ -3785,7 +3785,7 @@ "bundled": true, "dev": true, "requires": { - "mime-types": "~2.1.11", + "mime-types": "2.1.15", "negotiator": "0.6.1" } }, @@ -3799,7 +3799,7 @@ "bundled": true, "dev": true, "requires": { - "acorn": "^3.0.4" + "acorn": "3.3.0" }, "dependencies": { "acorn": { @@ -3824,8 +3824,8 @@ "bundled": true, "dev": true, "requires": { - "extend": "~3.0.0", - "semver": "~5.0.1" + "extend": "3.0.1", + "semver": "5.0.3" }, "dependencies": { "semver": { @@ -3840,8 +3840,8 @@ "bundled": true, "dev": true, "requires": { - "co": "^4.6.0", - "json-stable-stringify": "^1.0.1" + "co": "4.6.0", + "json-stable-stringify": "1.0.1" } }, "ajv-keywords": { @@ -3854,9 +3854,9 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" } }, "amdefine": { @@ -3884,8 +3884,8 @@ "bundled": true, "dev": true, "requires": { - "arrify": "^1.0.0", - "micromatch": "^2.1.5" + "arrify": "1.0.1", + "micromatch": "2.3.11" } }, "aproba": { @@ -3898,14 +3898,14 @@ "bundled": true, "dev": true, "requires": { - "async": "~0.9.0", - "buffer-crc32": "~0.2.1", - "glob": "~4.3.0", - "lazystream": "~0.1.0", - "lodash": "~3.2.0", - "readable-stream": "~1.0.26", - "tar-stream": "~1.1.0", - "zip-stream": "~0.5.0" + "async": "0.9.2", + "buffer-crc32": "0.2.13", + "glob": "4.3.5", + "lazystream": "0.1.0", + "lodash": "3.2.0", + "readable-stream": "1.0.34", + "tar-stream": "1.1.5", + "zip-stream": "0.5.2" }, "dependencies": { "async": { @@ -3918,10 +3918,10 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^2.0.1", - "once": "^1.3.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0" } }, "isarray": { @@ -3939,7 +3939,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.0.0" + "brace-expansion": "1.1.8" } }, "readable-stream": { @@ -3947,10 +3947,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -3965,8 +3965,8 @@ "bundled": true, "dev": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "delegates": "1.0.0", + "readable-stream": "2.2.11" } }, "argparse": { @@ -3974,7 +3974,7 @@ "bundled": true, "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "sprintf-js": "1.0.3" } }, "arr-diff": { @@ -3982,7 +3982,7 @@ "bundled": true, "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "arr-flatten": "1.0.3" } }, "arr-flatten": { @@ -4010,7 +4010,7 @@ "bundled": true, "dev": true, "requires": { - "array-uniq": "^1.0.1" + "array-uniq": "1.0.3" } }, "array-uniq": { @@ -4083,9 +4083,9 @@ "bundled": true, "dev": true, "requires": { - "chalk": "^1.1.0", - "esutils": "^2.0.2", - "js-tokens": "^3.0.0" + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.1" } }, "babel-core": { @@ -4093,25 +4093,25 @@ "bundled": true, "dev": true, "requires": { - "babel-code-frame": "^6.22.0", - "babel-generator": "^6.25.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.25.0", - "babel-traverse": "^6.25.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "convert-source-map": "^1.1.0", - "debug": "^2.1.1", - "json5": "^0.5.0", - "lodash": "^4.2.0", - "minimatch": "^3.0.2", - "path-is-absolute": "^1.0.0", - "private": "^0.1.6", - "slash": "^1.0.0", - "source-map": "^0.5.0" + "babel-code-frame": "6.22.0", + "babel-generator": "6.25.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.3", + "convert-source-map": "1.5.0", + "debug": "2.6.8", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.7", + "slash": "1.0.0", + "source-map": "0.5.6" } }, "babel-deps": { @@ -4119,8 +4119,8 @@ "bundled": true, "dev": true, "requires": { - "babel-core": "^6.3.0", - "merge": "^1.2.0" + "babel-core": "6.25.0", + "merge": "1.2.0" } }, "babel-generator": { @@ -4128,14 +4128,14 @@ "bundled": true, "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-types": "^6.25.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.2.0", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.6", + "trim-right": "1.0.1" }, "dependencies": { "jsesc": { @@ -4150,11 +4150,11 @@ "bundled": true, "dev": true, "requires": { - "babel-core": "^6.1.2", - "babel-deps": "^2.0.0", - "babel-plugin-external-helpers-2": "^6.0.15", - "babel-plugin-globals": "^2.0.0", - "concat-with-sourcemaps": "^1.0.2" + "babel-core": "6.25.0", + "babel-deps": "2.1.0", + "babel-plugin-external-helpers-2": "6.3.13", + "babel-plugin-globals": "2.0.1", + "concat-with-sourcemaps": "1.0.4" } }, "babel-helper-call-delegate": { @@ -4162,10 +4162,10 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helper-define-map": { @@ -4173,10 +4173,10 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1", - "lodash": "^4.2.0" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" } }, "babel-helper-function-name": { @@ -4184,11 +4184,11 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helper-get-function-arity": { @@ -4196,8 +4196,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-helper-hoist-variables": { @@ -4205,8 +4205,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-helper-optimise-call-expression": { @@ -4214,8 +4214,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-helper-regex": { @@ -4223,9 +4223,9 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1", - "lodash": "^4.2.0" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" } }, "babel-helper-replace-supers": { @@ -4233,12 +4233,12 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-helpers": { @@ -4246,8 +4246,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" } }, "babel-messages": { @@ -4255,7 +4255,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-check-es2015-constants": { @@ -4263,7 +4263,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-external-helpers-2": { @@ -4271,7 +4271,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^5.0.0" + "babel-runtime": "5.8.38" }, "dependencies": { "babel-runtime": { @@ -4279,7 +4279,7 @@ "bundled": true, "dev": true, "requires": { - "core-js": "^1.0.0" + "core-js": "1.2.7" } }, "core-js": { @@ -4294,7 +4294,7 @@ "bundled": true, "dev": true, "requires": { - "babel-core": "^6.1.2" + "babel-core": "6.25.0" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -4302,7 +4302,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -4310,7 +4310,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -4318,11 +4318,11 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1", - "lodash": "^4.2.0" + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "lodash": "4.17.4" } }, "babel-plugin-transform-es2015-classes": { @@ -4330,15 +4330,15 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-define-map": "6.24.1", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -4346,8 +4346,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-destructuring": { @@ -4355,7 +4355,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -4363,8 +4363,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-for-of": { @@ -4372,7 +4372,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -4380,9 +4380,9 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-literals": { @@ -4390,7 +4390,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -4398,9 +4398,9 @@ "bundled": true, "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -4408,10 +4408,10 @@ "bundled": true, "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -4419,9 +4419,9 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -4429,9 +4429,9 @@ "bundled": true, "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0" } }, "babel-plugin-transform-es2015-object-super": { @@ -4439,8 +4439,8 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -4448,12 +4448,12 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.23.0", + "babel-template": "6.25.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -4461,8 +4461,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-spread": { @@ -4470,7 +4470,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -4478,9 +4478,9 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-plugin-transform-es2015-template-literals": { @@ -4488,7 +4488,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -4496,7 +4496,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.23.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -4504,9 +4504,9 @@ "bundled": true, "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "babel-helper-regex": "6.24.1", + "babel-runtime": "6.23.0", + "regexpu-core": "2.0.0" } }, "babel-plugin-transform-node-env-inline": { @@ -4527,8 +4527,8 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0" } }, "babel-preset-es2015": { @@ -4536,30 +4536,30 @@ "bundled": true, "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.24.1" } }, "babel-preset-metal": { @@ -4567,9 +4567,9 @@ "bundled": true, "dev": true, "requires": { - "babel-plugin-transform-es2015-classes": "^6.2.2", - "babel-preset-es2015": "^6.1.18", - "resolve": "^1.1.7" + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-preset-es2015": "6.24.1", + "resolve": "1.3.3" } }, "babel-preset-metal-resolve-source": { @@ -4577,7 +4577,7 @@ "bundled": true, "dev": true, "requires": { - "resolve": "^1.1.7" + "resolve": "1.3.3" } }, "babel-register": { @@ -4585,13 +4585,13 @@ "bundled": true, "dev": true, "requires": { - "babel-core": "^6.24.1", - "babel-runtime": "^6.22.0", - "core-js": "^2.4.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.2" + "babel-core": "6.25.0", + "babel-runtime": "6.23.0", + "core-js": "2.4.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.15" } }, "babel-runtime": { @@ -4599,8 +4599,8 @@ "bundled": true, "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.10.0" + "core-js": "2.4.1", + "regenerator-runtime": "0.10.5" } }, "babel-template": { @@ -4608,11 +4608,11 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.25.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "lodash": "^4.2.0" + "babel-runtime": "6.23.0", + "babel-traverse": "6.25.0", + "babel-types": "6.25.0", + "babylon": "6.17.3", + "lodash": "4.17.4" } }, "babel-traverse": { @@ -4620,15 +4620,15 @@ "bundled": true, "dev": true, "requires": { - "babel-code-frame": "^6.22.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-types": "^6.25.0", - "babylon": "^6.17.2", - "debug": "^2.2.0", - "globals": "^9.0.0", - "invariant": "^2.2.0", - "lodash": "^4.2.0" + "babel-code-frame": "6.22.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "babylon": "6.17.3", + "debug": "2.6.8", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" } }, "babel-types": { @@ -4636,10 +4636,10 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "esutils": "^2.0.2", - "lodash": "^4.2.0", - "to-fast-properties": "^1.0.1" + "babel-runtime": "6.23.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" } }, "babylon": { @@ -4695,7 +4695,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "~1.0.26" + "readable-stream": "1.0.34" }, "dependencies": { "isarray": { @@ -4708,10 +4708,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -4731,7 +4731,7 @@ "bundled": true, "dev": true, "requires": { - "inherits": "~2.0.0" + "inherits": "2.0.3" } }, "bluebird": { @@ -4745,15 +4745,15 @@ "dev": true, "requires": { "bytes": "2.4.0", - "content-type": "~1.0.2", + "content-type": "1.0.2", "debug": "2.6.7", - "depd": "~1.1.0", - "http-errors": "~1.6.1", + "depd": "1.1.0", + "http-errors": "1.6.1", "iconv-lite": "0.4.15", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.4.0", - "raw-body": "~2.2.0", - "type-is": "~1.6.15" + "raw-body": "2.2.0", + "type-is": "1.6.15" }, "dependencies": { "debug": { @@ -4771,7 +4771,7 @@ "bundled": true, "dev": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "bower": { @@ -4784,7 +4784,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -4793,9 +4793,9 @@ "bundled": true, "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" } }, "buffer-crc32": { @@ -4808,7 +4808,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.2.11" } }, "builtin-modules": { @@ -4826,7 +4826,7 @@ "bundled": true, "dev": true, "requires": { - "callsites": "^0.2.0" + "callsites": "0.2.0" } }, "callsite": { @@ -4849,8 +4849,8 @@ "bundled": true, "dev": true, "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "camelcase": "2.1.1", + "map-obj": "1.0.1" } }, "caseless": { @@ -4863,7 +4863,7 @@ "bundled": true, "dev": true, "requires": { - "underscore-contrib": "~0.3.0" + "underscore-contrib": "0.3.0" } }, "center-align": { @@ -4871,8 +4871,8 @@ "bundled": true, "dev": true, "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "align-text": "0.1.4", + "lazy-cache": "1.0.4" } }, "chai": { @@ -4889,11 +4889,11 @@ "bundled": true, "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, "chokidar": { @@ -4901,15 +4901,15 @@ "bundled": true, "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "1.3.0", + "async-each": "1.0.1", + "fsevents": "1.1.2", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" } }, "circular-json": { @@ -4923,7 +4923,7 @@ "dev": true, "requires": { "exit": "0.1.2", - "glob": "^7.1.1" + "glob": "7.1.2" } }, "cli-cursor": { @@ -4931,7 +4931,7 @@ "bundled": true, "dev": true, "requires": { - "restore-cursor": "^1.0.1" + "restore-cursor": "1.0.1" } }, "cli-width": { @@ -4944,9 +4944,9 @@ "bundled": true, "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" } }, "clone": { @@ -4969,9 +4969,9 @@ "bundled": true, "dev": true, "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^1.0.6", - "through2": "^2.0.1" + "inherits": "2.0.3", + "process-nextick-args": "1.0.7", + "through2": "2.0.3" } }, "co": { @@ -4994,7 +4994,7 @@ "bundled": true, "dev": true, "requires": { - "lodash": "^4.5.0" + "lodash": "4.17.4" } }, "combined-stream": { @@ -5002,7 +5002,7 @@ "bundled": true, "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "commander": { @@ -5010,7 +5010,7 @@ "bundled": true, "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } }, "component-bind": { @@ -5033,10 +5033,10 @@ "bundled": true, "dev": true, "requires": { - "buffer-crc32": "~0.2.1", - "crc32-stream": "~0.3.1", - "node-int64": "~0.3.0", - "readable-stream": "~1.0.26" + "buffer-crc32": "0.2.13", + "crc32-stream": "0.3.4", + "node-int64": "0.3.3", + "readable-stream": "1.0.34" }, "dependencies": { "isarray": { @@ -5049,10 +5049,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -5072,9 +5072,9 @@ "bundled": true, "dev": true, "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "inherits": "2.0.3", + "readable-stream": "2.2.11", + "typedarray": "0.0.6" } }, "concat-with-sourcemaps": { @@ -5082,7 +5082,7 @@ "bundled": true, "dev": true, "requires": { - "source-map": "^0.5.1" + "source-map": "0.5.6" } }, "connect": { @@ -5092,7 +5092,7 @@ "requires": { "debug": "2.6.7", "finalhandler": "1.0.3", - "parseurl": "~1.3.1", + "parseurl": "1.3.1", "utils-merge": "1.0.0" }, "dependencies": { @@ -5111,7 +5111,7 @@ "bundled": true, "dev": true, "requires": { - "date-now": "^0.1.4" + "date-now": "0.1.4" } }, "console-control-strings": { @@ -5149,8 +5149,8 @@ "bundled": true, "dev": true, "requires": { - "buffer-crc32": "~0.2.1", - "readable-stream": "~1.0.24" + "buffer-crc32": "0.2.13", + "readable-stream": "1.0.34" }, "dependencies": { "isarray": { @@ -5163,10 +5163,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -5181,8 +5181,8 @@ "bundled": true, "dev": true, "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" + "lru-cache": "4.1.1", + "which": "1.2.14" }, "dependencies": { "lru-cache": { @@ -5190,8 +5190,8 @@ "bundled": true, "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "pseudomap": "1.0.2", + "yallist": "2.1.2" } } } @@ -5201,7 +5201,7 @@ "bundled": true, "dev": true, "requires": { - "boom": "2.x.x" + "boom": "2.10.1" } }, "ctype": { @@ -5214,7 +5214,7 @@ "bundled": true, "dev": true, "requires": { - "array-find-index": "^1.0.1" + "array-find-index": "1.0.2" } }, "custom-event": { @@ -5227,7 +5227,7 @@ "bundled": true, "dev": true, "requires": { - "es5-ext": "^0.10.9" + "es5-ext": "0.10.23" } }, "dashdash": { @@ -5235,7 +5235,7 @@ "bundled": true, "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" }, "dependencies": { "assert-plus": { @@ -5291,13 +5291,13 @@ "bundled": true, "dev": true, "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.1" } }, "delayed-stream": { @@ -5320,7 +5320,7 @@ "bundled": true, "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "di": { @@ -5338,8 +5338,8 @@ "bundled": true, "dev": true, "requires": { - "ansi-styles": "^2.0.1", - "diff": "^1.3.2" + "ansi-styles": "2.2.1", + "diff": "1.4.0" } }, "doctrine": { @@ -5347,8 +5347,8 @@ "bundled": true, "dev": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "esutils": "2.0.2", + "isarray": "1.0.0" } }, "dom-serialize": { @@ -5356,10 +5356,10 @@ "bundled": true, "dev": true, "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" + "custom-event": "1.0.1", + "ent": "2.2.0", + "extend": "3.0.1", + "void-elements": "2.0.1" } }, "dom-serializer": { @@ -5367,8 +5367,8 @@ "bundled": true, "dev": true, "requires": { - "domelementtype": "~1.1.1", - "entities": "~1.1.1" + "domelementtype": "1.1.3", + "entities": "1.1.1" }, "dependencies": { "domelementtype": { @@ -5393,7 +5393,7 @@ "bundled": true, "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "1.3.0" } }, "domutils": { @@ -5401,8 +5401,8 @@ "bundled": true, "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "0.1.0", + "domelementtype": "1.3.0" } }, "duplexer": { @@ -5415,7 +5415,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "~1.1.9" + "readable-stream": "1.1.14" }, "dependencies": { "isarray": { @@ -5428,10 +5428,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -5447,9 +5447,9 @@ "dev": true, "requires": { "end-of-stream": "1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" + "inherits": "2.0.3", + "readable-stream": "2.2.11", + "stream-shift": "1.0.0" }, "dependencies": { "end-of-stream": { @@ -5457,7 +5457,7 @@ "bundled": true, "dev": true, "requires": { - "once": "~1.3.0" + "once": "1.3.3" } }, "once": { @@ -5465,7 +5465,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } } } @@ -5575,7 +5575,7 @@ "bundled": true, "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "is-arrayish": "0.2.1" } }, "es5-ext": { @@ -5583,8 +5583,8 @@ "bundled": true, "dev": true, "requires": { - "es6-iterator": "2", - "es6-symbol": "~3.1" + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" } }, "es6-iterator": { @@ -5592,9 +5592,9 @@ "bundled": true, "dev": true, "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-symbol": "^3.1" + "d": "1.0.0", + "es5-ext": "0.10.23", + "es6-symbol": "3.1.1" } }, "es6-map": { @@ -5602,12 +5602,12 @@ "bundled": true, "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" + "d": "1.0.0", + "es5-ext": "0.10.23", + "es6-iterator": "2.0.1", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" } }, "es6-set": { @@ -5615,11 +5615,11 @@ "bundled": true, "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", + "d": "1.0.0", + "es5-ext": "0.10.23", + "es6-iterator": "2.0.1", "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" + "event-emitter": "0.3.5" } }, "es6-symbol": { @@ -5627,8 +5627,8 @@ "bundled": true, "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "1.0.0", + "es5-ext": "0.10.23" } }, "es6-weak-map": { @@ -5636,10 +5636,10 @@ "bundled": true, "dev": true, "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" + "d": "1.0.0", + "es5-ext": "0.10.23", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" } }, "escape-html": { @@ -5657,11 +5657,11 @@ "bundled": true, "dev": true, "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" }, "dependencies": { "esprima": { @@ -5681,7 +5681,7 @@ "dev": true, "optional": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -5691,10 +5691,10 @@ "bundled": true, "dev": true, "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.1.0", + "estraverse": "4.2.0" } }, "esformatter": { @@ -5702,24 +5702,24 @@ "bundled": true, "dev": true, "requires": { - "debug": "^0.7.4", - "disparity": "^2.0.0", - "espree": "^2.2.4", - "glob": "^5.0.3", - "minimist": "^1.1.1", - "mout": ">=0.9 <2.0", - "npm-run": "^2.0.0", - "resolve": "^1.1.5", - "rocambole": ">=0.7 <2.0", - "rocambole-indent": "^2.0.4", - "rocambole-linebreak": "^1.0.0", - "rocambole-node": "~1.0", - "rocambole-token": "^1.1.2", - "rocambole-whitespace": "^1.0.0", - "stdin": "*", - "strip-json-comments": "~0.1.1", - "supports-color": "^1.3.1", - "user-home": "^2.0.0" + "debug": "0.7.4", + "disparity": "2.0.0", + "espree": "2.2.5", + "glob": "5.0.15", + "minimist": "1.2.0", + "mout": "1.0.0", + "npm-run": "2.0.0", + "resolve": "1.3.3", + "rocambole": "0.7.0", + "rocambole-indent": "2.0.4", + "rocambole-linebreak": "1.0.2", + "rocambole-node": "1.0.0", + "rocambole-token": "1.2.1", + "rocambole-whitespace": "1.0.0", + "stdin": "0.0.1", + "strip-json-comments": "0.1.3", + "supports-color": "1.3.1", + "user-home": "2.0.0" }, "dependencies": { "debug": { @@ -5737,11 +5737,11 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "minimist": { @@ -5766,41 +5766,41 @@ "bundled": true, "dev": true, "requires": { - "babel-code-frame": "^6.16.0", - "chalk": "^1.1.3", - "concat-stream": "^1.5.2", - "debug": "^2.1.1", - "doctrine": "^2.0.0", - "escope": "^3.6.0", - "espree": "^3.4.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "glob": "^7.0.3", - "globals": "^9.14.0", - "ignore": "^3.2.0", - "imurmurhash": "^0.1.4", - "inquirer": "^0.12.0", - "is-my-json-valid": "^2.10.0", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.5.1", - "json-stable-stringify": "^1.0.0", - "levn": "^0.3.0", - "lodash": "^4.0.0", - "mkdirp": "^0.5.0", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.1", - "pluralize": "^1.2.1", - "progress": "^1.1.8", - "require-uncached": "^1.0.2", - "shelljs": "^0.7.5", - "strip-bom": "^3.0.0", - "strip-json-comments": "~2.0.1", - "table": "^3.7.8", - "text-table": "~0.2.0", - "user-home": "^2.0.0" + "babel-code-frame": "6.22.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.8", + "doctrine": "2.0.0", + "escope": "3.6.0", + "espree": "3.4.3", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.3", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.8.4", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" } }, "espree": { @@ -5808,8 +5808,8 @@ "bundled": true, "dev": true, "requires": { - "acorn": "^5.0.1", - "acorn-jsx": "^3.0.0" + "acorn": "5.0.3", + "acorn-jsx": "3.0.1" } }, "esprima": { @@ -5822,7 +5822,7 @@ "bundled": true, "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "4.2.0" } }, "esrecurse": { @@ -5830,8 +5830,8 @@ "bundled": true, "dev": true, "requires": { - "estraverse": "~4.1.0", - "object-assign": "^4.0.1" + "estraverse": "4.1.1", + "object-assign": "4.1.1" }, "dependencies": { "estraverse": { @@ -5856,8 +5856,8 @@ "bundled": true, "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "1.0.0", + "es5-ext": "0.10.23" } }, "eventemitter3": { @@ -5880,9 +5880,9 @@ "bundled": true, "dev": true, "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" + "array-slice": "0.2.3", + "array-unique": "0.2.1", + "braces": "0.1.5" }, "dependencies": { "braces": { @@ -5890,7 +5890,7 @@ "bundled": true, "dev": true, "requires": { - "expand-range": "^0.1.0" + "expand-range": "0.1.1" } }, "expand-range": { @@ -5898,8 +5898,8 @@ "bundled": true, "dev": true, "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" + "is-number": "0.1.1", + "repeat-string": "0.2.2" } }, "is-number": { @@ -5919,7 +5919,7 @@ "bundled": true, "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "is-posix-bracket": "0.1.1" } }, "expand-range": { @@ -5927,7 +5927,7 @@ "bundled": true, "dev": true, "requires": { - "fill-range": "^2.1.0" + "fill-range": "2.2.3" } }, "extend": { @@ -5940,7 +5940,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "extglob": { @@ -5948,7 +5948,7 @@ "bundled": true, "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "extsprintf": { @@ -5961,8 +5961,8 @@ "bundled": true, "dev": true, "requires": { - "chalk": "^1.1.1", - "time-stamp": "^1.0.0" + "chalk": "1.1.3", + "time-stamp": "1.1.0" } }, "fast-levenshtein": { @@ -5975,8 +5975,8 @@ "bundled": true, "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" } }, "file-entry-cache": { @@ -5984,8 +5984,8 @@ "bundled": true, "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "1.2.2", + "object-assign": "4.1.1" } }, "filename-regex": { @@ -5998,11 +5998,11 @@ "bundled": true, "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^1.1.3", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" } }, "finalhandler": { @@ -6011,12 +6011,12 @@ "dev": true, "requires": { "debug": "2.6.7", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.1", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.1", + "statuses": "1.3.1", + "unpipe": "1.0.0" }, "dependencies": { "debug": { @@ -6034,8 +6034,8 @@ "bundled": true, "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "first-chunk-stream": { @@ -6048,10 +6048,10 @@ "bundled": true, "dev": true, "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" + "circular-json": "0.3.1", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" } }, "for-in": { @@ -6064,7 +6064,7 @@ "bundled": true, "dev": true, "requires": { - "for-in": "^1.0.1" + "for-in": "1.0.2" } }, "forever-agent": { @@ -6082,9 +6082,9 @@ "bundled": true, "dev": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.12" + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" } }, "formatio": { @@ -6092,7 +6092,7 @@ "bundled": true, "dev": true, "requires": { - "samsam": "~1.1" + "samsam": "1.1.2" } }, "fs-access": { @@ -6100,7 +6100,7 @@ "bundled": true, "dev": true, "requires": { - "null-check": "^1.0.0" + "null-check": "1.0.0" } }, "fs.realpath": { @@ -6113,10 +6113,10 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" } }, "gauge": { @@ -6124,14 +6124,14 @@ "bundled": true, "dev": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "aproba": "1.1.2", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" } }, "generate-function": { @@ -6144,7 +6144,7 @@ "bundled": true, "dev": true, "requires": { - "is-property": "^1.0.0" + "is-property": "1.0.2" } }, "get-caller-file": { @@ -6162,7 +6162,7 @@ "bundled": true, "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" }, "dependencies": { "assert-plus": { @@ -6177,12 +6177,12 @@ "bundled": true, "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-base": { @@ -6190,8 +6190,8 @@ "bundled": true, "dev": true, "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "glob-parent": "2.0.0", + "is-glob": "2.0.1" } }, "glob-expand": { @@ -6199,8 +6199,8 @@ "bundled": true, "dev": true, "requires": { - "glob": "~4.4.2", - "lodash": "1.2.x" + "glob": "4.4.2", + "lodash": "1.2.1" }, "dependencies": { "glob": { @@ -6208,10 +6208,10 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^2.0.1", - "once": "^1.3.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0" } }, "lodash": { @@ -6224,7 +6224,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.0.0" + "brace-expansion": "1.1.8" } } } @@ -6234,7 +6234,7 @@ "bundled": true, "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "2.0.1" } }, "globals": { @@ -6247,12 +6247,12 @@ "bundled": true, "dev": true, "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "glogg": { @@ -6260,7 +6260,7 @@ "bundled": true, "dev": true, "requires": { - "sparkles": "^1.0.0" + "sparkles": "1.0.0" } }, "graceful-fs": { @@ -6283,10 +6283,10 @@ "bundled": true, "dev": true, "requires": { - "babel-deps": "^2.0.0", - "gulp-util": "^3.0.5", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" + "babel-deps": "2.1.0", + "gulp-util": "3.0.8", + "through2": "2.0.3", + "vinyl-sourcemaps-apply": "0.2.1" } }, "gulp-babel-globals": { @@ -6294,10 +6294,10 @@ "bundled": true, "dev": true, "requires": { - "babel-globals": "^2.0.0", - "gulp-util": "^3.0.4", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" + "babel-globals": "2.0.1", + "gulp-util": "3.0.8", + "through2": "2.0.3", + "vinyl-sourcemaps-apply": "0.2.1" } }, "gulp-concat": { @@ -6305,9 +6305,9 @@ "bundled": true, "dev": true, "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" + "concat-with-sourcemaps": "1.0.4", + "through2": "2.0.3", + "vinyl": "2.0.2" }, "dependencies": { "clone-stats": { @@ -6325,13 +6325,13 @@ "bundled": true, "dev": true, "requires": { - "clone": "^1.0.0", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "is-stream": "^1.1.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" + "clone": "1.0.2", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.0.0", + "is-stream": "1.1.0", + "remove-trailing-separator": "1.0.2", + "replace-ext": "1.0.0" } } } @@ -6341,9 +6341,9 @@ "bundled": true, "dev": true, "requires": { - "esformatter": "^0.8.1", - "gulp-util": "^3.0.0", - "through2": "^2.0.0" + "esformatter": "0.8.2", + "gulp-util": "3.0.8", + "through2": "2.0.3" } }, "gulp-eslint": { @@ -6351,9 +6351,9 @@ "bundled": true, "dev": true, "requires": { - "bufferstreams": "^1.1.1", - "eslint": "^3.0.0", - "gulp-util": "^3.0.6" + "bufferstreams": "1.1.1", + "eslint": "3.19.0", + "gulp-util": "3.0.8" } }, "gulp-if": { @@ -6361,9 +6361,9 @@ "bundled": true, "dev": true, "requires": { - "gulp-match": "^1.0.3", - "ternary-stream": "^2.0.1", - "through2": "^2.0.1" + "gulp-match": "1.0.3", + "ternary-stream": "2.0.1", + "through2": "2.0.3" } }, "gulp-ignore": { @@ -6371,8 +6371,8 @@ "bundled": true, "dev": true, "requires": { - "gulp-match": "^1.0.3", - "through2": "^2.0.1" + "gulp-match": "1.0.3", + "through2": "2.0.3" } }, "gulp-jshint": { @@ -6380,11 +6380,11 @@ "bundled": true, "dev": true, "requires": { - "gulp-util": "^3.0.0", - "lodash": "^4.12.0", - "minimatch": "^3.0.3", - "rcloader": "^0.2.2", - "through2": "^2.0.0" + "gulp-util": "3.0.8", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "rcloader": "0.2.2", + "through2": "2.0.3" } }, "gulp-match": { @@ -6392,7 +6392,7 @@ "bundled": true, "dev": true, "requires": { - "minimatch": "^3.0.3" + "minimatch": "3.0.4" } }, "gulp-mocha": { @@ -6400,12 +6400,12 @@ "bundled": true, "dev": true, "requires": { - "gulp-util": "^3.0.0", - "mocha": "^2.0.1", - "plur": "^2.1.0", - "resolve-from": "^1.0.0", - "temp": "^0.8.3", - "through": "^2.3.4" + "gulp-util": "3.0.8", + "mocha": "2.5.3", + "plur": "2.1.2", + "resolve-from": "1.0.1", + "temp": "0.8.3", + "through": "2.3.8" } }, "gulp-rename": { @@ -6419,8 +6419,8 @@ "dev": true, "requires": { "istextorbinary": "1.0.2", - "readable-stream": "^2.0.1", - "replacestream": "^4.0.0" + "readable-stream": "2.2.11", + "replacestream": "4.0.2" } }, "gulp-sass": { @@ -6428,11 +6428,11 @@ "bundled": true, "dev": true, "requires": { - "gulp-util": "^3.0", - "lodash.clonedeep": "^4.3.2", - "node-sass": "^3.4.2", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" + "gulp-util": "3.0.8", + "lodash.clonedeep": "4.5.0", + "node-sass": "3.13.1", + "through2": "2.0.3", + "vinyl-sourcemaps-apply": "0.2.1" } }, "gulp-sourcemaps": { @@ -6440,11 +6440,11 @@ "bundled": true, "dev": true, "requires": { - "convert-source-map": "^1.1.1", - "graceful-fs": "^4.1.2", - "strip-bom": "^2.0.0", - "through2": "^2.0.0", - "vinyl": "^1.0.0" + "convert-source-map": "1.5.0", + "graceful-fs": "4.1.11", + "strip-bom": "2.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" }, "dependencies": { "strip-bom": { @@ -6452,7 +6452,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "vinyl": { @@ -6460,8 +6460,8 @@ "bundled": true, "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } } @@ -6472,14 +6472,14 @@ "bundled": true, "dev": true, "requires": { - "deap": "^1.0.0", - "fancy-log": "^1.0.0", - "gulp-util": "^3.0.0", - "isobject": "^2.0.0", - "through2": "^2.0.0", + "deap": "1.0.0", + "fancy-log": "1.3.0", + "gulp-util": "3.0.8", + "isobject": "2.1.0", + "through2": "2.0.3", "uglify-js": "2.6.4", - "uglify-save-license": "^0.4.1", - "vinyl-sourcemaps-apply": "^0.2.0" + "uglify-save-license": "0.4.1", + "vinyl-sourcemaps-apply": "0.2.1" } }, "gulp-util": { @@ -6487,24 +6487,24 @@ "bundled": true, "dev": true, "requires": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" + "through2": "2.0.3", + "vinyl": "0.5.3" }, "dependencies": { "minimist": { @@ -6524,8 +6524,8 @@ "bundled": true, "dev": true, "requires": { - "gulp-util": "^3.0.4", - "through2": "^0.6.5" + "gulp-util": "3.0.8", + "through2": "0.6.5" }, "dependencies": { "isarray": { @@ -6538,10 +6538,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -6554,8 +6554,8 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } } } @@ -6565,7 +6565,7 @@ "bundled": true, "dev": true, "requires": { - "glogg": "^1.0.0" + "glogg": "1.0.0" } }, "handlebars": { @@ -6573,10 +6573,10 @@ "bundled": true, "dev": true, "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.6.4" }, "dependencies": { "async": { @@ -6589,7 +6589,7 @@ "bundled": true, "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -6604,8 +6604,8 @@ "bundled": true, "dev": true, "requires": { - "ajv": "^4.9.1", - "har-schema": "^1.0.5" + "ajv": "4.11.8", + "har-schema": "1.0.5" } }, "has-ansi": { @@ -6613,7 +6613,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "has-binary": { @@ -6651,7 +6651,7 @@ "bundled": true, "dev": true, "requires": { - "sparkles": "^1.0.0" + "sparkles": "1.0.0" } }, "has-unicode": { @@ -6664,10 +6664,10 @@ "bundled": true, "dev": true, "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" } }, "hoek": { @@ -6680,8 +6680,8 @@ "bundled": true, "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "hosted-git-info": { @@ -6694,11 +6694,11 @@ "bundled": true, "dev": true, "requires": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" + "domelementtype": "1.3.0", + "domhandler": "2.3.0", + "domutils": "1.5.1", + "entities": "1.0.0", + "readable-stream": "1.1.14" }, "dependencies": { "isarray": { @@ -6711,10 +6711,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -6732,7 +6732,7 @@ "depd": "1.1.0", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" + "statuses": "1.3.1" } }, "http-proxy": { @@ -6740,8 +6740,8 @@ "bundled": true, "dev": true, "requires": { - "eventemitter3": "1.x.x", - "requires-port": "1.x.x" + "eventemitter3": "1.2.0", + "requires-port": "1.0.0" } }, "http-signature": { @@ -6749,9 +6749,9 @@ "bundled": true, "dev": true, "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.1" } }, "https-proxy-agent": { @@ -6759,9 +6759,9 @@ "bundled": true, "dev": true, "requires": { - "agent-base": "2", - "debug": "2", - "extend": "3" + "agent-base": "2.1.1", + "debug": "2.6.8", + "extend": "3.0.1" } }, "iconv-lite": { @@ -6774,11 +6774,11 @@ "bundled": true, "dev": true, "requires": { - "colors": "~0.6.0-1", - "commander": "~1.2.0", - "debug": "~0.7.2", - "moment": "~2.0.0", - "q": "~0.9.6" + "colors": "0.6.2", + "commander": "1.2.0", + "debug": "0.7.4", + "moment": "2.0.0", + "q": "0.9.7" }, "dependencies": { "colors": { @@ -6791,7 +6791,7 @@ "bundled": true, "dev": true, "requires": { - "keypress": "0.1.x" + "keypress": "0.1.0" } }, "debug": { @@ -6821,7 +6821,7 @@ "bundled": true, "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "indexof": { @@ -6834,8 +6834,8 @@ "bundled": true, "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -6848,19 +6848,19 @@ "bundled": true, "dev": true, "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.1.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" } }, "interpret": { @@ -6873,7 +6873,7 @@ "bundled": true, "dev": true, "requires": { - "loose-envify": "^1.0.0" + "loose-envify": "1.3.1" } }, "invert-kv": { @@ -6896,7 +6896,7 @@ "bundled": true, "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "1.8.0" } }, "is-buffer": { @@ -6909,7 +6909,7 @@ "bundled": true, "dev": true, "requires": { - "builtin-modules": "^1.0.0" + "builtin-modules": "1.1.1" } }, "is-dotfile": { @@ -6922,7 +6922,7 @@ "bundled": true, "dev": true, "requires": { - "is-primitive": "^2.0.0" + "is-primitive": "2.0.0" } }, "is-extendable": { @@ -6940,7 +6940,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-fullwidth-code-point": { @@ -6948,7 +6948,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-glob": { @@ -6956,7 +6956,7 @@ "bundled": true, "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "is-my-json-valid": { @@ -6964,10 +6964,10 @@ "bundled": true, "dev": true, "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" } }, "is-number": { @@ -6975,7 +6975,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-path-cwd": { @@ -6988,7 +6988,7 @@ "bundled": true, "dev": true, "requires": { - "is-path-inside": "^1.0.0" + "is-path-inside": "1.0.0" } }, "is-path-inside": { @@ -6996,7 +6996,7 @@ "bundled": true, "dev": true, "requires": { - "path-is-inside": "^1.0.1" + "path-is-inside": "1.0.2" } }, "is-posix-bracket": { @@ -7019,7 +7019,7 @@ "bundled": true, "dev": true, "requires": { - "tryit": "^1.0.1" + "tryit": "1.0.3" } }, "is-stream": { @@ -7070,15 +7070,15 @@ "bundled": true, "dev": true, "requires": { - "babel-core": "^6.1.4", - "escodegen": "^1.6.1", - "esprima": "^2.1.0", - "istanbul": "^0.4.0", - "mkdirp": "^0.5.0", - "nomnomnomnom": "^2.0.0", - "object-assign": "^4.0.1", - "source-map": "^0.5.0", - "which": "^1.0.9" + "babel-core": "6.25.0", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "istanbul": "0.4.5", + "mkdirp": "0.5.1", + "nomnomnomnom": "2.0.1", + "object-assign": "4.1.1", + "source-map": "0.5.6", + "which": "1.2.14" }, "dependencies": { "esprima": { @@ -7098,20 +7098,20 @@ "bundled": true, "dev": true, "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.10", + "js-yaml": "3.8.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.2.14", + "wordwrap": "1.0.0" }, "dependencies": { "abbrev": { @@ -7134,11 +7134,11 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "resolve": { @@ -7151,7 +7151,7 @@ "bundled": true, "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "1.0.0" } } } @@ -7161,8 +7161,8 @@ "bundled": true, "dev": true, "requires": { - "binaryextensions": "~1.0.0", - "textextensions": "~1.0.0" + "binaryextensions": "1.0.1", + "textextensions": "1.0.2" } }, "jade": { @@ -7201,8 +7201,8 @@ "bundled": true, "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^3.1.1" + "argparse": "1.0.9", + "esprima": "3.1.3" } }, "js2xmlparser": { @@ -7215,18 +7215,18 @@ "bundled": true, "dev": true, "requires": { - "bluebird": "~3.4.6", - "catharsis": "~0.8.8", - "escape-string-regexp": "~1.0.5", - "espree": "~3.1.7", - "js2xmlparser": "~1.0.0", - "klaw": "~1.3.0", - "marked": "~0.3.6", - "mkdirp": "~0.5.1", - "requizzle": "~0.2.1", - "strip-json-comments": "~2.0.1", + "bluebird": "3.4.7", + "catharsis": "0.8.8", + "escape-string-regexp": "1.0.5", + "espree": "3.1.7", + "js2xmlparser": "1.0.0", + "klaw": "1.3.1", + "marked": "0.3.6", + "mkdirp": "0.5.1", + "requizzle": "0.2.1", + "strip-json-comments": "2.0.1", "taffydb": "2.6.2", - "underscore": "~1.8.3" + "underscore": "1.8.3" }, "dependencies": { "acorn": { @@ -7239,8 +7239,8 @@ "bundled": true, "dev": true, "requires": { - "acorn": "^3.3.0", - "acorn-jsx": "^3.0.0" + "acorn": "3.3.0", + "acorn-jsx": "3.0.1" } } } @@ -7255,14 +7255,14 @@ "bundled": true, "dev": true, "requires": { - "cli": "~1.0.0", - "console-browserify": "1.1.x", - "exit": "0.1.x", - "htmlparser2": "3.8.x", - "lodash": "3.7.x", - "minimatch": "~3.0.2", - "shelljs": "0.3.x", - "strip-json-comments": "1.0.x" + "cli": "1.0.1", + "console-browserify": "1.1.0", + "exit": "0.1.2", + "htmlparser2": "3.8.3", + "lodash": "3.7.0", + "minimatch": "3.0.4", + "shelljs": "0.3.0", + "strip-json-comments": "1.0.4" }, "dependencies": { "lodash": { @@ -7287,12 +7287,12 @@ "bundled": true, "dev": true, "requires": { - "beeper": "^1.1.0", - "chalk": "^1.0.0", - "log-symbols": "^1.0.0", - "plur": "^2.1.0", - "string-length": "^1.0.0", - "text-table": "^0.2.0" + "beeper": "1.1.1", + "chalk": "1.1.3", + "log-symbols": "1.0.2", + "plur": "2.1.2", + "string-length": "1.0.1", + "text-table": "0.2.0" } }, "json-schema": { @@ -7305,7 +7305,7 @@ "bundled": true, "dev": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json-stringify-safe": { @@ -7356,33 +7356,33 @@ "bundled": true, "dev": true, "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^1.4.1", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^3.8.0", - "log4js": "^0.6.31", - "mime": "^1.3.4", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", + "bluebird": "3.4.7", + "body-parser": "1.17.2", + "chokidar": "1.7.0", + "colors": "1.1.2", + "combine-lists": "1.0.1", + "connect": "3.6.2", + "core-js": "2.4.1", + "di": "0.0.1", + "dom-serialize": "2.2.1", + "expand-braces": "0.1.2", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "http-proxy": "1.16.2", + "isbinaryfile": "3.0.2", + "lodash": "3.10.1", + "log4js": "0.6.38", + "mime": "1.3.6", + "minimatch": "3.0.4", + "optimist": "0.6.1", + "qjobs": "1.1.5", + "range-parser": "1.2.0", + "rimraf": "2.6.1", + "safe-buffer": "5.0.1", "socket.io": "1.7.3", - "source-map": "^0.5.3", + "source-map": "0.5.6", "tmp": "0.0.31", - "useragent": "^2.1.12" + "useragent": "2.1.13" }, "dependencies": { "lodash": { @@ -7397,7 +7397,7 @@ "bundled": true, "dev": true, "requires": { - "babel-core": "^6.0.0" + "babel-core": "6.25.0" } }, "karma-chai": { @@ -7410,8 +7410,8 @@ "bundled": true, "dev": true, "requires": { - "fs-access": "^1.0.0", - "which": "^1.2.1" + "fs-access": "1.0.1", + "which": "1.2.14" } }, "karma-commonjs": { @@ -7424,10 +7424,10 @@ "bundled": true, "dev": true, "requires": { - "dateformat": "^1.0.6", - "istanbul": "^0.4.0", - "minimatch": "^3.0.0", - "source-map": "^0.5.1" + "dateformat": "1.0.12", + "istanbul": "0.4.5", + "minimatch": "3.0.4", + "source-map": "0.5.6" }, "dependencies": { "dateformat": { @@ -7435,8 +7435,8 @@ "bundled": true, "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } } } @@ -7451,7 +7451,7 @@ "bundled": true, "dev": true, "requires": { - "iectrl": "~0.1.0" + "iectrl": "0.1.2" } }, "karma-mocha": { @@ -7469,10 +7469,10 @@ "bundled": true, "dev": true, "requires": { - "q": "^1.4.1", - "sauce-connect-launcher": "^0.13.0", - "saucelabs": "^1.0.1", - "wd": "^0.3.4" + "q": "1.5.0", + "sauce-connect-launcher": "0.13.0", + "saucelabs": "1.4.0", + "wd": "0.3.12" }, "dependencies": { "q": { @@ -7492,7 +7492,7 @@ "bundled": true, "dev": true, "requires": { - "source-map-support": "^0.4.1" + "source-map-support": "0.4.15" } }, "keypress": { @@ -7505,7 +7505,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.5" } }, "klaw": { @@ -7513,7 +7513,7 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.9" + "graceful-fs": "4.1.11" } }, "lazy-cache": { @@ -7526,7 +7526,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "~1.0.2" + "readable-stream": "1.0.34" }, "dependencies": { "isarray": { @@ -7539,10 +7539,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -7557,7 +7557,7 @@ "bundled": true, "dev": true, "requires": { - "invert-kv": "^1.0.0" + "invert-kv": "1.0.0" } }, "levn": { @@ -7565,8 +7565,8 @@ "bundled": true, "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "1.1.2", + "type-check": "0.3.2" } }, "load-json-file": { @@ -7574,11 +7574,11 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" }, "dependencies": { "strip-bom": { @@ -7586,7 +7586,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } } } @@ -7656,7 +7656,7 @@ "bundled": true, "dev": true, "requires": { - "lodash._root": "^3.0.0" + "lodash._root": "3.0.1" } }, "lodash.isarguments": { @@ -7684,9 +7684,9 @@ "bundled": true, "dev": true, "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" } }, "lodash.merge": { @@ -7704,15 +7704,15 @@ "bundled": true, "dev": true, "requires": { - "lodash._basecopy": "^3.0.0", - "lodash._basetostring": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.restparam": "^3.0.0", - "lodash.templatesettings": "^3.0.0" + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" } }, "lodash.templatesettings": { @@ -7720,8 +7720,8 @@ "bundled": true, "dev": true, "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0" + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" } }, "log-symbols": { @@ -7729,7 +7729,7 @@ "bundled": true, "dev": true, "requires": { - "chalk": "^1.0.0" + "chalk": "1.1.3" } }, "log4js": { @@ -7737,8 +7737,8 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "~1.0.2", - "semver": "~4.3.3" + "readable-stream": "1.0.34", + "semver": "4.3.6" }, "dependencies": { "isarray": { @@ -7751,10 +7751,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -7779,7 +7779,7 @@ "bundled": true, "dev": true, "requires": { - "js-tokens": "^3.0.0" + "js-tokens": "3.0.1" } }, "loud-rejection": { @@ -7787,8 +7787,8 @@ "bundled": true, "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" } }, "lru-cache": { @@ -7816,16 +7816,16 @@ "bundled": true, "dev": true, "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.8", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" }, "dependencies": { "minimist": { @@ -7845,7 +7845,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.0.1" + "readable-stream": "2.2.11" } }, "metal-jquery-adapter": { @@ -7858,20 +7858,20 @@ "bundled": true, "dev": true, "requires": { - "babel-plugin-transform-node-env-inline": "^0.1.1", - "babel-preset-metal": "^3.0.0", - "chai": "^2.3.0", - "isparta": "^4.0.0", - "karma-babel-preprocessor": "^6.0.1", - "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^0.2.0", - "karma-commonjs": "^1.0.0", - "karma-coverage": "^0.5.1", - "karma-mocha": "^0.2.0", - "karma-sinon": "^1.0.4", - "karma-source-map-support": "^1.2.0", - "mocha": "^2.2.5", - "sinon": "^1.17.7" + "babel-plugin-transform-node-env-inline": "0.1.1", + "babel-preset-metal": "3.1.0", + "chai": "2.3.0", + "isparta": "4.0.0", + "karma-babel-preprocessor": "6.0.1", + "karma-chai": "0.1.0", + "karma-chrome-launcher": "0.2.3", + "karma-commonjs": "1.0.0", + "karma-coverage": "0.5.5", + "karma-mocha": "0.2.2", + "karma-sinon": "1.0.5", + "karma-source-map-support": "1.2.0", + "mocha": "2.5.3", + "sinon": "1.17.7" } }, "metal-tools-build-amd": { @@ -7879,18 +7879,18 @@ "bundled": true, "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.3.13", - "babel-preset-es2015": "^6.0.0", - "babel-preset-metal-resolve-source": "^1.0.0", - "bower": "^1.7.1", - "gulp-babel-deps": "^2.0.0", - "gulp-if": "^2.0.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-preset-es2015": "6.24.1", + "babel-preset-metal-resolve-source": "1.0.2", + "bower": "1.8.0", + "gulp-babel-deps": "2.0.1", + "gulp-if": "2.0.2", "gulp-sourcemaps": "1.6.0", - "merge": "^1.2.0", - "stream-combiner": "^0.2.2", - "stream-consume": "^0.1.0", - "through2": "^2.0.0", - "vinyl-fs": "^2.2.1" + "merge": "1.2.0", + "stream-combiner": "0.2.2", + "stream-consume": "0.1.0", + "through2": "2.0.3", + "vinyl-fs": "2.4.4" }, "dependencies": { "glob": { @@ -7898,11 +7898,11 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-parent": { @@ -7910,8 +7910,8 @@ "bundled": true, "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, "glob-stream": { @@ -7919,14 +7919,14 @@ "bundled": true, "dev": true, "requires": { - "extend": "^3.0.0", - "glob": "^5.0.3", - "glob-parent": "^3.0.0", - "micromatch": "^2.3.7", - "ordered-read-streams": "^0.3.0", - "through2": "^0.6.0", - "to-absolute-glob": "^0.1.1", - "unique-stream": "^2.0.2" + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" }, "dependencies": { "readable-stream": { @@ -7934,10 +7934,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "through2": { @@ -7945,8 +7945,8 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } } } @@ -7961,7 +7961,7 @@ "bundled": true, "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } }, "isarray": { @@ -7974,7 +7974,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.0.5" + "readable-stream": "2.2.11" } }, "ordered-read-streams": { @@ -7982,8 +7982,8 @@ "bundled": true, "dev": true, "requires": { - "is-stream": "^1.0.1", - "readable-stream": "^2.0.1" + "is-stream": "1.1.0", + "readable-stream": "2.2.11" } }, "string_decoder": { @@ -7996,7 +7996,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "unique-stream": { @@ -8004,8 +8004,8 @@ "bundled": true, "dev": true, "requires": { - "json-stable-stringify": "^1.0.0", - "through2-filter": "^2.0.0" + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" } }, "vinyl": { @@ -8013,8 +8013,8 @@ "bundled": true, "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } }, @@ -8023,23 +8023,23 @@ "bundled": true, "dev": true, "requires": { - "duplexify": "^3.2.0", - "glob-stream": "^5.3.2", - "graceful-fs": "^4.0.0", + "duplexify": "3.5.0", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "^0.3.0", - "lazystream": "^1.0.0", - "lodash.isequal": "^4.0.0", - "merge-stream": "^1.0.0", - "mkdirp": "^0.5.0", - "object-assign": "^4.0.0", - "readable-stream": "^2.0.4", - "strip-bom": "^2.0.0", - "strip-bom-stream": "^1.0.0", - "through2": "^2.0.0", - "through2-filter": "^2.0.0", - "vali-date": "^1.0.0", - "vinyl": "^1.0.0" + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.2.11", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" } } } @@ -8049,15 +8049,15 @@ "bundled": true, "dev": true, "requires": { - "babel-preset-es2015": "^6.0.0", - "babel-preset-metal-resolve-source": "^1.0.0", - "gulp-babel-globals": "^2.0.0", - "gulp-if": "^2.0.0", + "babel-preset-es2015": "6.24.1", + "babel-preset-metal-resolve-source": "1.0.2", + "gulp-babel-globals": "2.0.0", + "gulp-if": "2.0.2", "gulp-sourcemaps": "1.6.0", - "merge": "^1.2.0", - "stream-combiner": "^0.2.2", - "stream-consume": "^0.1.0", - "vinyl-fs": "^2.2.1" + "merge": "1.2.0", + "stream-combiner": "0.2.2", + "stream-consume": "0.1.0", + "vinyl-fs": "2.4.4" }, "dependencies": { "glob": { @@ -8065,11 +8065,11 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-parent": { @@ -8077,8 +8077,8 @@ "bundled": true, "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, "glob-stream": { @@ -8086,14 +8086,14 @@ "bundled": true, "dev": true, "requires": { - "extend": "^3.0.0", - "glob": "^5.0.3", - "glob-parent": "^3.0.0", - "micromatch": "^2.3.7", - "ordered-read-streams": "^0.3.0", - "through2": "^0.6.0", - "to-absolute-glob": "^0.1.1", - "unique-stream": "^2.0.2" + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" }, "dependencies": { "readable-stream": { @@ -8101,10 +8101,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "through2": { @@ -8112,8 +8112,8 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } } } @@ -8128,7 +8128,7 @@ "bundled": true, "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } }, "isarray": { @@ -8141,7 +8141,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.0.5" + "readable-stream": "2.2.11" } }, "ordered-read-streams": { @@ -8149,8 +8149,8 @@ "bundled": true, "dev": true, "requires": { - "is-stream": "^1.0.1", - "readable-stream": "^2.0.1" + "is-stream": "1.1.0", + "readable-stream": "2.2.11" } }, "string_decoder": { @@ -8163,7 +8163,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "unique-stream": { @@ -8171,8 +8171,8 @@ "bundled": true, "dev": true, "requires": { - "json-stable-stringify": "^1.0.0", - "through2-filter": "^2.0.0" + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" } }, "vinyl": { @@ -8180,8 +8180,8 @@ "bundled": true, "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } }, @@ -8190,23 +8190,23 @@ "bundled": true, "dev": true, "requires": { - "duplexify": "^3.2.0", - "glob-stream": "^5.3.2", - "graceful-fs": "^4.0.0", + "duplexify": "3.5.0", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "^0.3.0", - "lazystream": "^1.0.0", - "lodash.isequal": "^4.0.0", - "merge-stream": "^1.0.0", - "mkdirp": "^0.5.0", - "object-assign": "^4.0.0", - "readable-stream": "^2.0.4", - "strip-bom": "^2.0.0", - "strip-bom-stream": "^1.0.0", - "through2": "^2.0.0", - "through2-filter": "^2.0.0", - "vali-date": "^1.0.0", - "vinyl": "^1.0.0" + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.2.11", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" } } } @@ -8216,14 +8216,14 @@ "bundled": true, "dev": true, "requires": { - "gulp-if": "^2.0.0", + "gulp-if": "2.0.2", "gulp-sourcemaps": "1.6.0", - "gulp-wrapper": "^1.0.0", - "metal-jquery-adapter": "^1.0.0-rc.1", - "metal-tools-build-globals": "^2.0.0", - "stream-combiner": "^0.2.2", - "stream-consume": "^0.1.0", - "vinyl-fs": "^2.2.1" + "gulp-wrapper": "1.0.0", + "metal-jquery-adapter": "1.0.0", + "metal-tools-build-globals": "2.0.2", + "stream-combiner": "0.2.2", + "stream-consume": "0.1.0", + "vinyl-fs": "2.4.4" }, "dependencies": { "glob": { @@ -8231,11 +8231,11 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-parent": { @@ -8243,8 +8243,8 @@ "bundled": true, "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, "glob-stream": { @@ -8252,14 +8252,14 @@ "bundled": true, "dev": true, "requires": { - "extend": "^3.0.0", - "glob": "^5.0.3", - "glob-parent": "^3.0.0", - "micromatch": "^2.3.7", - "ordered-read-streams": "^0.3.0", - "through2": "^0.6.0", - "to-absolute-glob": "^0.1.1", - "unique-stream": "^2.0.2" + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" }, "dependencies": { "readable-stream": { @@ -8267,10 +8267,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "through2": { @@ -8278,8 +8278,8 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } } } @@ -8294,7 +8294,7 @@ "bundled": true, "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } }, "isarray": { @@ -8307,7 +8307,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.0.5" + "readable-stream": "2.2.11" } }, "ordered-read-streams": { @@ -8315,8 +8315,8 @@ "bundled": true, "dev": true, "requires": { - "is-stream": "^1.0.1", - "readable-stream": "^2.0.1" + "is-stream": "1.1.0", + "readable-stream": "2.2.11" } }, "string_decoder": { @@ -8329,7 +8329,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "unique-stream": { @@ -8337,8 +8337,8 @@ "bundled": true, "dev": true, "requires": { - "json-stable-stringify": "^1.0.0", - "through2-filter": "^2.0.0" + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" } }, "vinyl": { @@ -8346,8 +8346,8 @@ "bundled": true, "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } }, @@ -8356,23 +8356,23 @@ "bundled": true, "dev": true, "requires": { - "duplexify": "^3.2.0", - "glob-stream": "^5.3.2", - "graceful-fs": "^4.0.0", + "duplexify": "3.5.0", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "^0.3.0", - "lazystream": "^1.0.0", - "lodash.isequal": "^4.0.0", - "merge-stream": "^1.0.0", - "mkdirp": "^0.5.0", - "object-assign": "^4.0.0", - "readable-stream": "^2.0.4", - "strip-bom": "^2.0.0", - "strip-bom-stream": "^1.0.0", - "through2": "^2.0.0", - "through2-filter": "^2.0.0", - "vali-date": "^1.0.0", - "vinyl": "^1.0.0" + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.2.11", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" } } } @@ -8382,18 +8382,18 @@ "bundled": true, "dev": true, "requires": { - "glob-expand": "^0.1.0", - "gulp-if": "^2.0.0", - "gulp-ignore": "^2.0.1", - "gulp-replace": "^0.5.4", - "gulp-util": "^3.0.7", - "gulp-wrapper": "^1.0.0", - "merge": "^1.2.0", - "soyparser": "^0.2.2", - "stream-combiner": "^0.2.2", - "stream-consume": "^0.1.0", - "through2": "^2.0.0", - "vinyl-fs": "^2.2.1" + "glob-expand": "0.1.0", + "gulp-if": "2.0.2", + "gulp-ignore": "2.0.2", + "gulp-replace": "0.5.4", + "gulp-util": "3.0.8", + "gulp-wrapper": "1.0.0", + "merge": "1.2.0", + "soyparser": "0.2.5", + "stream-combiner": "0.2.2", + "stream-consume": "0.1.0", + "through2": "2.0.3", + "vinyl-fs": "2.4.4" }, "dependencies": { "glob": { @@ -8401,11 +8401,11 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "glob-parent": { @@ -8413,8 +8413,8 @@ "bundled": true, "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, "glob-stream": { @@ -8422,14 +8422,14 @@ "bundled": true, "dev": true, "requires": { - "extend": "^3.0.0", - "glob": "^5.0.3", - "glob-parent": "^3.0.0", - "micromatch": "^2.3.7", - "ordered-read-streams": "^0.3.0", - "through2": "^0.6.0", - "to-absolute-glob": "^0.1.1", - "unique-stream": "^2.0.2" + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" }, "dependencies": { "readable-stream": { @@ -8437,10 +8437,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "through2": { @@ -8448,8 +8448,8 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } } } @@ -8464,7 +8464,7 @@ "bundled": true, "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } }, "isarray": { @@ -8477,7 +8477,7 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.0.5" + "readable-stream": "2.2.11" } }, "ordered-read-streams": { @@ -8485,8 +8485,8 @@ "bundled": true, "dev": true, "requires": { - "is-stream": "^1.0.1", - "readable-stream": "^2.0.1" + "is-stream": "1.1.0", + "readable-stream": "2.2.11" } }, "string_decoder": { @@ -8499,7 +8499,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "unique-stream": { @@ -8507,8 +8507,8 @@ "bundled": true, "dev": true, "requires": { - "json-stable-stringify": "^1.0.0", - "through2-filter": "^2.0.0" + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" } }, "vinyl": { @@ -8516,8 +8516,8 @@ "bundled": true, "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } }, @@ -8526,23 +8526,23 @@ "bundled": true, "dev": true, "requires": { - "duplexify": "^3.2.0", - "glob-stream": "^5.3.2", - "graceful-fs": "^4.0.0", + "duplexify": "3.5.0", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "^0.3.0", - "lazystream": "^1.0.0", - "lodash.isequal": "^4.0.0", - "merge-stream": "^1.0.0", - "mkdirp": "^0.5.0", - "object-assign": "^4.0.0", - "readable-stream": "^2.0.4", - "strip-bom": "^2.0.0", - "strip-bom-stream": "^1.0.0", - "through2": "^2.0.0", - "through2-filter": "^2.0.0", - "vali-date": "^1.0.0", - "vinyl": "^1.0.0" + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.2.11", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" } } } @@ -8552,19 +8552,19 @@ "bundled": true, "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" } }, "mime": { @@ -8582,7 +8582,7 @@ "bundled": true, "dev": true, "requires": { - "mime-db": "~1.27.0" + "mime-db": "1.27.0" } }, "minimatch": { @@ -8590,7 +8590,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.8" } }, "minimist": { @@ -8646,8 +8646,8 @@ "bundled": true, "dev": true, "requires": { - "inherits": "2", - "minimatch": "0.3" + "inherits": "2.0.3", + "minimatch": "0.3.0" } }, "minimatch": { @@ -8655,8 +8655,8 @@ "bundled": true, "dev": true, "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" + "lru-cache": "2.7.3", + "sigmund": "1.0.1" } }, "ms": { @@ -8724,19 +8724,19 @@ "bundled": true, "dev": true, "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "2", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" + "fstream": "1.0.11", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.1.0", + "osenv": "0.1.4", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.2.14" }, "dependencies": { "semver": { @@ -8756,22 +8756,22 @@ "bundled": true, "dev": true, "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash.assign": "^4.2.0", - "lodash.clonedeep": "^4.3.2", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.3.2", - "node-gyp": "^3.3.1", - "npmlog": "^4.0.0", - "request": "^2.61.0", - "sass-graph": "^2.1.1" + "async-foreach": "0.1.3", + "chalk": "1.1.3", + "cross-spawn": "3.0.1", + "gaze": "1.1.2", + "get-stdin": "4.0.1", + "glob": "7.1.2", + "in-publish": "2.0.0", + "lodash.assign": "4.2.0", + "lodash.clonedeep": "4.5.0", + "meow": "3.7.0", + "mkdirp": "0.5.1", + "nan": "2.6.2", + "node-gyp": "3.6.2", + "npmlog": "4.1.0", + "request": "2.81.0", + "sass-graph": "2.2.4" }, "dependencies": { "gaze": { @@ -8779,7 +8779,7 @@ "bundled": true, "dev": true, "requires": { - "globule": "^1.0.0" + "globule": "1.2.0" } }, "globule": { @@ -8787,9 +8787,9 @@ "bundled": true, "dev": true, "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.4", - "minimatch": "~3.0.2" + "glob": "7.1.2", + "lodash": "4.17.4", + "minimatch": "3.0.4" } } } @@ -8799,8 +8799,8 @@ "bundled": true, "dev": true, "requires": { - "chalk": "~0.4.0", - "underscore": "~1.6.0" + "chalk": "0.4.0", + "underscore": "1.6.0" }, "dependencies": { "ansi-styles": { @@ -8813,9 +8813,9 @@ "bundled": true, "dev": true, "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" } }, "strip-ansi": { @@ -8835,7 +8835,7 @@ "bundled": true, "dev": true, "requires": { - "abbrev": "1" + "abbrev": "1.1.0" } }, "normalize-package-data": { @@ -8843,10 +8843,10 @@ "bundled": true, "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "2.4.2", + "is-builtin-module": "1.0.0", + "semver": "4.3.6", + "validate-npm-package-license": "3.0.1" } }, "normalize-path": { @@ -8854,7 +8854,7 @@ "bundled": true, "dev": true, "requires": { - "remove-trailing-separator": "^1.0.1" + "remove-trailing-separator": "1.0.2" } }, "npm-path": { @@ -8862,7 +8862,7 @@ "bundled": true, "dev": true, "requires": { - "which": "^1.2.4" + "which": "1.2.14" } }, "npm-run": { @@ -8870,12 +8870,12 @@ "bundled": true, "dev": true, "requires": { - "minimist": "^1.1.1", - "npm-path": "^1.0.1", - "npm-which": "^2.0.0", - "serializerr": "^1.0.1", - "spawn-sync": "^1.0.5", - "sync-exec": "^0.5.0" + "minimist": "1.2.0", + "npm-path": "1.1.0", + "npm-which": "2.0.0", + "serializerr": "1.0.3", + "spawn-sync": "1.0.15", + "sync-exec": "0.5.0" }, "dependencies": { "minimist": { @@ -8890,9 +8890,9 @@ "bundled": true, "dev": true, "requires": { - "commander": "^2.2.0", - "npm-path": "^1.0.0", - "which": "^1.0.5" + "commander": "2.9.0", + "npm-path": "1.1.0", + "which": "1.2.14" } }, "npmlog": { @@ -8900,10 +8900,10 @@ "bundled": true, "dev": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" } }, "null-check": { @@ -8936,8 +8936,8 @@ "bundled": true, "dev": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "for-own": "0.1.5", + "is-extendable": "0.1.1" } }, "on-finished": { @@ -8953,7 +8953,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "onetime": { @@ -8971,8 +8971,8 @@ "bundled": true, "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "minimist": "0.0.8", + "wordwrap": "0.0.3" }, "dependencies": { "wordwrap": { @@ -8987,12 +8987,12 @@ "bundled": true, "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" } }, "options": { @@ -9010,7 +9010,7 @@ "bundled": true, "dev": true, "requires": { - "lcid": "^1.0.0" + "lcid": "1.0.0" } }, "os-shim": { @@ -9028,8 +9028,8 @@ "bundled": true, "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "parse-glob": { @@ -9037,10 +9037,10 @@ "bundled": true, "dev": true, "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" } }, "parse-json": { @@ -9048,7 +9048,7 @@ "bundled": true, "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "parsejson": { @@ -9056,7 +9056,7 @@ "bundled": true, "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseqs": { @@ -9064,7 +9064,7 @@ "bundled": true, "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseuri": { @@ -9072,7 +9072,7 @@ "bundled": true, "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseurl": { @@ -9090,7 +9090,7 @@ "bundled": true, "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } }, "path-is-absolute": { @@ -9113,9 +9113,9 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "performance-now": { @@ -9138,7 +9138,7 @@ "bundled": true, "dev": true, "requires": { - "pinkie": "^2.0.0" + "pinkie": "2.0.4" } }, "plur": { @@ -9146,7 +9146,7 @@ "bundled": true, "dev": true, "requires": { - "irregular-plurals": "^1.0.0" + "irregular-plurals": "1.2.0" } }, "pluralize": { @@ -9214,8 +9214,8 @@ "bundled": true, "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { "is-number": { @@ -9223,7 +9223,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -9231,7 +9231,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.5" } } } @@ -9241,7 +9241,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.5" } } } @@ -9266,7 +9266,7 @@ "bundled": true, "dev": true, "requires": { - "lodash.clonedeep": "^4.3.2" + "lodash.clonedeep": "4.5.0" } }, "rcloader": { @@ -9274,10 +9274,10 @@ "bundled": true, "dev": true, "requires": { - "lodash.assign": "^4.2.0", - "lodash.isobject": "^3.0.2", - "lodash.merge": "^4.6.0", - "rcfinder": "^0.1.6" + "lodash.assign": "4.2.0", + "lodash.isobject": "3.0.2", + "lodash.merge": "4.6.0", + "rcfinder": "0.1.9" } }, "read-pkg": { @@ -9285,9 +9285,9 @@ "bundled": true, "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.8", + "path-type": "1.1.0" } }, "read-pkg-up": { @@ -9295,8 +9295,8 @@ "bundled": true, "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "1.1.2", + "read-pkg": "1.1.0" } }, "readable-stream": { @@ -9304,13 +9304,13 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.0.1", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.0.1", + "string_decoder": "1.0.2", + "util-deprecate": "1.0.2" } }, "readdirp": { @@ -9318,10 +9318,10 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.2.11", + "set-immediate-shim": "1.0.1" } }, "readline2": { @@ -9329,8 +9329,8 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", "mute-stream": "0.0.5" } }, @@ -9339,7 +9339,7 @@ "bundled": true, "dev": true, "requires": { - "resolve": "^1.1.6" + "resolve": "1.3.3" } }, "redent": { @@ -9347,8 +9347,8 @@ "bundled": true, "dev": true, "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "indent-string": "2.1.0", + "strip-indent": "1.0.1" } }, "regenerate": { @@ -9366,9 +9366,9 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "babel-runtime": "6.23.0", + "babel-types": "6.25.0", + "private": "0.1.7" } }, "regex-cache": { @@ -9376,8 +9376,8 @@ "bundled": true, "dev": true, "requires": { - "is-equal-shallow": "^0.1.3", - "is-primitive": "^2.0.0" + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" } }, "regexpu-core": { @@ -9385,9 +9385,9 @@ "bundled": true, "dev": true, "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "regenerate": "1.3.2", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" } }, "regjsgen": { @@ -9400,7 +9400,7 @@ "bundled": true, "dev": true, "requires": { - "jsesc": "~0.5.0" + "jsesc": "0.5.0" } }, "remove-trailing-separator": { @@ -9423,7 +9423,7 @@ "bundled": true, "dev": true, "requires": { - "is-finite": "^1.0.0" + "is-finite": "1.0.2" } }, "replace-ext": { @@ -9436,9 +9436,9 @@ "bundled": true, "dev": true, "requires": { - "escape-string-regexp": "^1.0.3", - "object-assign": "^4.0.1", - "readable-stream": "^2.0.2" + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1", + "readable-stream": "2.2.11" } }, "request": { @@ -9446,28 +9446,28 @@ "bundled": true, "dev": true, "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.1.1", - "har-validator": "~4.2.1", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "oauth-sign": "~0.8.1", - "performance-now": "^0.2.0", - "qs": "~6.4.0", - "safe-buffer": "^5.0.1", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.0.0" + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" } }, "require-directory": { @@ -9485,8 +9485,8 @@ "bundled": true, "dev": true, "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "caller-path": "0.1.0", + "resolve-from": "1.0.1" } }, "requires-port": { @@ -9499,7 +9499,7 @@ "bundled": true, "dev": true, "requires": { - "underscore": "~1.6.0" + "underscore": "1.6.0" }, "dependencies": { "underscore": { @@ -9514,7 +9514,7 @@ "bundled": true, "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "1.0.5" } }, "resolve-from": { @@ -9527,8 +9527,8 @@ "bundled": true, "dev": true, "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "exit-hook": "1.1.1", + "onetime": "1.1.0" } }, "right-align": { @@ -9536,7 +9536,7 @@ "bundled": true, "dev": true, "requires": { - "align-text": "^0.1.1" + "align-text": "0.1.4" } }, "rimraf": { @@ -9544,7 +9544,7 @@ "bundled": true, "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "rocambole": { @@ -9552,7 +9552,7 @@ "bundled": true, "dev": true, "requires": { - "esprima": "^2.1" + "esprima": "2.7.3" }, "dependencies": { "esprima": { @@ -9567,9 +9567,9 @@ "bundled": true, "dev": true, "requires": { - "debug": "^2.1.3", - "mout": "^0.11.0", - "rocambole-token": "^1.2.1" + "debug": "2.6.8", + "mout": "0.11.1", + "rocambole-token": "1.2.1" }, "dependencies": { "mout": { @@ -9584,9 +9584,9 @@ "bundled": true, "dev": true, "requires": { - "debug": "^2.1.3", - "rocambole-token": "^1.2.1", - "semver": "^4.3.1" + "debug": "2.6.8", + "rocambole-token": "1.2.1", + "semver": "4.3.6" } }, "rocambole-node": { @@ -9604,9 +9604,9 @@ "bundled": true, "dev": true, "requires": { - "debug": "^2.1.3", - "repeat-string": "^1.5.0", - "rocambole-token": "^1.2.1" + "debug": "2.6.8", + "repeat-string": "1.6.1", + "rocambole-token": "1.2.1" } }, "run-async": { @@ -9614,7 +9614,7 @@ "bundled": true, "dev": true, "requires": { - "once": "^1.3.0" + "once": "1.4.0" } }, "run-sequence": { @@ -9622,8 +9622,8 @@ "bundled": true, "dev": true, "requires": { - "chalk": "*", - "gulp-util": "*" + "chalk": "1.1.3", + "gulp-util": "3.0.8" } }, "rx-lite": { @@ -9646,10 +9646,10 @@ "bundled": true, "dev": true, "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^7.0.0" + "glob": "7.1.2", + "lodash": "4.17.4", + "scss-tokenizer": "0.2.3", + "yargs": "7.1.0" } }, "sauce-connect-launcher": { @@ -9657,7 +9657,7 @@ "bundled": true, "dev": true, "requires": { - "adm-zip": "~0.4.3", + "adm-zip": "0.4.7", "async": "1.4.0", "lodash": "3.10.1", "rimraf": "2.4.3" @@ -9673,11 +9673,11 @@ "bundled": true, "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "lodash": { @@ -9690,7 +9690,7 @@ "bundled": true, "dev": true, "requires": { - "glob": "^5.0.14" + "glob": "5.0.15" } } } @@ -9700,7 +9700,7 @@ "bundled": true, "dev": true, "requires": { - "https-proxy-agent": "^1.0.0" + "https-proxy-agent": "1.0.0" } }, "scss-tokenizer": { @@ -9708,8 +9708,8 @@ "bundled": true, "dev": true, "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" + "js-base64": "2.1.9", + "source-map": "0.4.4" }, "dependencies": { "source-map": { @@ -9717,7 +9717,7 @@ "bundled": true, "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -9732,7 +9732,7 @@ "bundled": true, "dev": true, "requires": { - "protochain": "^1.0.5" + "protochain": "1.0.5" } }, "set-blocking": { @@ -9755,9 +9755,9 @@ "bundled": true, "dev": true, "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "glob": "7.1.2", + "interpret": "1.0.3", + "rechoir": "0.6.2" } }, "sigmund": { @@ -9778,7 +9778,7 @@ "formatio": "1.1.1", "lolex": "1.3.2", "samsam": "1.1.2", - "util": ">=0.10.3 <1" + "util": "0.10.3" } }, "slash": { @@ -9796,7 +9796,7 @@ "bundled": true, "dev": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "socket.io": { @@ -9936,7 +9936,7 @@ "bundled": true, "dev": true, "requires": { - "source-map": "^0.5.6" + "source-map": "0.5.6" } }, "soyparser": { @@ -9944,8 +9944,8 @@ "bundled": true, "dev": true, "requires": { - "merge": "^1.2.0", - "tunic": "^1.0.0" + "merge": "1.2.0", + "tunic": "1.0.0" } }, "sparkles": { @@ -9958,8 +9958,8 @@ "bundled": true, "dev": true, "requires": { - "concat-stream": "^1.4.7", - "os-shim": "^0.1.2" + "concat-stream": "1.6.0", + "os-shim": "0.1.3" } }, "spdx-correct": { @@ -9967,7 +9967,7 @@ "bundled": true, "dev": true, "requires": { - "spdx-license-ids": "^1.0.2" + "spdx-license-ids": "1.2.2" } }, "spdx-expression-parse": { @@ -9990,14 +9990,14 @@ "bundled": true, "dev": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" }, "dependencies": { "assert-plus": { @@ -10022,8 +10022,8 @@ "bundled": true, "dev": true, "requires": { - "duplexer": "~0.1.1", - "through": "~2.3.4" + "duplexer": "0.1.1", + "through": "2.3.8" } }, "stream-consume": { @@ -10041,7 +10041,7 @@ "bundled": true, "dev": true, "requires": { - "strip-ansi": "^3.0.0" + "strip-ansi": "3.0.1" } }, "string-width": { @@ -10049,9 +10049,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "string_decoder": { @@ -10059,7 +10059,7 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "~5.0.1" + "safe-buffer": "5.0.1" } }, "stringstream": { @@ -10072,7 +10072,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-bom": { @@ -10085,8 +10085,8 @@ "bundled": true, "dev": true, "requires": { - "first-chunk-stream": "^1.0.0", - "strip-bom": "^2.0.0" + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" }, "dependencies": { "strip-bom": { @@ -10094,7 +10094,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } } } @@ -10104,7 +10104,7 @@ "bundled": true, "dev": true, "requires": { - "get-stdin": "^4.0.1" + "get-stdin": "4.0.1" } }, "strip-json-comments": { @@ -10127,12 +10127,12 @@ "bundled": true, "dev": true, "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", "slice-ansi": "0.0.4", - "string-width": "^2.0.0" + "string-width": "2.0.0" }, "dependencies": { "is-fullwidth-code-point": { @@ -10145,8 +10145,8 @@ "bundled": true, "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^3.0.0" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "3.0.1" } } } @@ -10161,9 +10161,9 @@ "bundled": true, "dev": true, "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" } }, "tar-stream": { @@ -10171,10 +10171,10 @@ "bundled": true, "dev": true, "requires": { - "bl": "^0.9.0", - "end-of-stream": "^1.0.0", - "readable-stream": "~1.0.33", - "xtend": "^4.0.0" + "bl": "0.9.5", + "end-of-stream": "1.4.0", + "readable-stream": "1.0.34", + "xtend": "4.0.1" }, "dependencies": { "end-of-stream": { @@ -10182,7 +10182,7 @@ "bundled": true, "dev": true, "requires": { - "once": "^1.4.0" + "once": "1.4.0" } }, "isarray": { @@ -10195,10 +10195,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -10213,8 +10213,8 @@ "bundled": true, "dev": true, "requires": { - "os-tmpdir": "^1.0.0", - "rimraf": "~2.2.6" + "os-tmpdir": "1.0.2", + "rimraf": "2.2.8" }, "dependencies": { "rimraf": { @@ -10229,10 +10229,10 @@ "bundled": true, "dev": true, "requires": { - "duplexify": "^3.5.0", - "fork-stream": "^0.0.4", - "merge-stream": "^1.0.0", - "through2": "^2.0.1" + "duplexify": "3.5.0", + "fork-stream": "0.0.4", + "merge-stream": "1.0.1", + "through2": "2.0.3" } }, "text-table": { @@ -10255,8 +10255,8 @@ "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" + "readable-stream": "2.2.11", + "xtend": "4.0.1" } }, "through2-filter": { @@ -10264,8 +10264,8 @@ "bundled": true, "dev": true, "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" + "through2": "2.0.3", + "xtend": "4.0.1" } }, "time-stamp": { @@ -10278,7 +10278,7 @@ "bundled": true, "dev": true, "requires": { - "os-tmpdir": "~1.0.1" + "os-tmpdir": "1.0.2" } }, "to-absolute-glob": { @@ -10286,7 +10286,7 @@ "bundled": true, "dev": true, "requires": { - "extend-shallow": "^2.0.1" + "extend-shallow": "2.0.1" } }, "to-array": { @@ -10309,7 +10309,7 @@ "bundled": true, "dev": true, "requires": { - "punycode": "^1.4.1" + "punycode": "1.4.1" } }, "trim-newlines": { @@ -10332,8 +10332,8 @@ "bundled": true, "dev": true, "requires": { - "mout": "^0.11.0", - "mtil": "^0.1.3" + "mout": "0.11.1", + "mtil": "0.1.3" }, "dependencies": { "mout": { @@ -10348,7 +10348,7 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.0.1" } }, "type-check": { @@ -10356,7 +10356,7 @@ "bundled": true, "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "1.1.2" } }, "type-detect": { @@ -10370,7 +10370,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.15" + "mime-types": "2.1.15" } }, "typedarray": { @@ -10383,10 +10383,10 @@ "bundled": true, "dev": true, "requires": { - "async": "~0.2.6", - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "async": "0.2.10", + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" }, "dependencies": { "camelcase": { @@ -10399,8 +10399,8 @@ "bundled": true, "dev": true, "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", + "center-align": "0.1.3", + "right-align": "0.1.3", "wordwrap": "0.0.2" } }, @@ -10414,9 +10414,9 @@ "bundled": true, "dev": true, "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", "window-size": "0.1.0" } } @@ -10472,7 +10472,7 @@ "bundled": true, "dev": true, "requires": { - "os-homedir": "^1.0.0" + "os-homedir": "1.0.2" } }, "useragent": { @@ -10480,8 +10480,8 @@ "bundled": true, "dev": true, "requires": { - "lru-cache": "2.2.x", - "tmp": "0.0.x" + "lru-cache": "2.2.4", + "tmp": "0.0.31" }, "dependencies": { "lru-cache": { @@ -10531,8 +10531,8 @@ "bundled": true, "dev": true, "requires": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" } }, "vargs": { @@ -10553,8 +10553,8 @@ "bundled": true, "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } }, @@ -10563,7 +10563,7 @@ "bundled": true, "dev": true, "requires": { - "source-map": "^0.5.1" + "source-map": "0.5.6" } }, "void-elements": { @@ -10576,13 +10576,13 @@ "bundled": true, "dev": true, "requires": { - "archiver": "~0.14.0", - "async": "~1.0.0", - "lodash": "~3.9.3", - "q": "~1.4.1", - "request": "~2.55.0", - "underscore.string": "~3.0.3", - "vargs": "~0.1.0" + "archiver": "0.14.4", + "async": "1.0.0", + "lodash": "3.9.3", + "q": "1.4.1", + "request": "2.55.0", + "underscore.string": "3.0.3", + "vargs": "0.1.0" }, "dependencies": { "asn1": { @@ -10633,9 +10633,9 @@ "bundled": true, "dev": true, "requires": { - "async": "~0.9.0", - "combined-stream": "~0.0.4", - "mime-types": "~2.0.3" + "async": "0.9.2", + "combined-stream": "0.0.7", + "mime-types": "2.0.14" }, "dependencies": { "async": { @@ -10650,10 +10650,10 @@ "bundled": true, "dev": true, "requires": { - "bluebird": "^2.9.30", - "chalk": "^1.0.0", - "commander": "^2.8.1", - "is-my-json-valid": "^2.12.0" + "bluebird": "2.11.0", + "chalk": "1.1.3", + "commander": "2.9.0", + "is-my-json-valid": "2.16.0" } }, "hawk": { @@ -10661,10 +10661,10 @@ "bundled": true, "dev": true, "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" } }, "http-signature": { @@ -10673,7 +10673,7 @@ "dev": true, "requires": { "asn1": "0.1.11", - "assert-plus": "^0.1.5", + "assert-plus": "0.1.5", "ctype": "0.5.3" } }, @@ -10692,7 +10692,7 @@ "bundled": true, "dev": true, "requires": { - "mime-db": "~1.12.0" + "mime-db": "1.12.0" } }, "node-uuid": { @@ -10720,24 +10720,24 @@ "bundled": true, "dev": true, "requires": { - "aws-sign2": "~0.5.0", - "bl": "~0.9.0", - "caseless": "~0.9.0", - "combined-stream": "~0.0.5", - "forever-agent": "~0.6.0", - "form-data": "~0.2.0", - "har-validator": "^1.4.0", - "hawk": "~2.3.0", - "http-signature": "~0.10.0", - "isstream": "~0.1.1", - "json-stringify-safe": "~5.0.0", - "mime-types": "~2.0.1", - "node-uuid": "~1.4.0", - "oauth-sign": "~0.6.0", - "qs": "~2.4.0", - "stringstream": "~0.0.4", - "tough-cookie": ">=0.12.0", - "tunnel-agent": "~0.4.0" + "aws-sign2": "0.5.0", + "bl": "0.9.5", + "caseless": "0.9.0", + "combined-stream": "0.0.7", + "forever-agent": "0.6.1", + "form-data": "0.2.0", + "har-validator": "1.8.0", + "hawk": "2.3.1", + "http-signature": "0.10.1", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.0.14", + "node-uuid": "1.4.8", + "oauth-sign": "0.6.0", + "qs": "2.4.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3" } }, "tunnel-agent": { @@ -10752,7 +10752,7 @@ "bundled": true, "dev": true, "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "which-module": { @@ -10765,7 +10765,7 @@ "bundled": true, "dev": true, "requires": { - "string-width": "^1.0.2" + "string-width": "1.0.2" } }, "window-size": { @@ -10783,8 +10783,8 @@ "bundled": true, "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "string-width": "1.0.2", + "strip-ansi": "3.0.1" } }, "wrappy": { @@ -10797,7 +10797,7 @@ "bundled": true, "dev": true, "requires": { - "mkdirp": "^0.5.1" + "mkdirp": "0.5.1" } }, "ws": { @@ -10805,8 +10805,8 @@ "bundled": true, "dev": true, "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" + "options": "0.0.6", + "ultron": "1.0.2" } }, "wtf-8": { @@ -10839,19 +10839,19 @@ "bundled": true, "dev": true, "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "5.0.0" }, "dependencies": { "camelcase": { @@ -10866,7 +10866,7 @@ "bundled": true, "dev": true, "requires": { - "camelcase": "^3.0.0" + "camelcase": "3.0.0" }, "dependencies": { "camelcase": { @@ -10886,9 +10886,9 @@ "bundled": true, "dev": true, "requires": { - "compress-commons": "~0.2.0", - "lodash": "~3.2.0", - "readable-stream": "~1.0.26" + "compress-commons": "0.2.9", + "lodash": "3.2.0", + "readable-stream": "1.0.34" }, "dependencies": { "isarray": { @@ -10906,10 +10906,10 @@ "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -10933,18 +10933,18 @@ "integrity": "sha1-fMzomaijv8oVk6M0jQ+/Qd0/UeU=", "dev": true, "requires": { - "@gulp-sourcemaps/identity-map": "1.X", - "@gulp-sourcemaps/map-sources": "1.X", - "acorn": "4.X", - "convert-source-map": "1.X", - "css": "2.X", - "debug-fabulous": "0.1.X", - "detect-newline": "2.X", - "graceful-fs": "4.X", - "source-map": "0.X", - "strip-bom-string": "1.X", - "through2": "2.X", - "vinyl": "1.X" + "@gulp-sourcemaps/identity-map": "1.0.1", + "@gulp-sourcemaps/map-sources": "1.0.0", + "acorn": "4.0.13", + "convert-source-map": "1.5.0", + "css": "2.2.1", + "debug-fabulous": "0.1.1", + "detect-newline": "2.1.0", + "graceful-fs": "4.1.11", + "source-map": "0.5.6", + "strip-bom-string": "1.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" }, "dependencies": { "acorn": { @@ -10959,8 +10959,8 @@ "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } } @@ -10972,9 +10972,9 @@ "integrity": "sha1-XVawCEUu32gj2t7LPmJU0G87XT0=", "dev": true, "requires": { - "gulp-util": "^3.0.0", - "strip-debug": "^1.0.0", - "through2": "^2.0.0" + "gulp-util": "3.0.8", + "strip-debug": "1.1.1", + "through2": "2.0.3" } }, "gulp-template": { @@ -10983,9 +10983,9 @@ "integrity": "sha1-Bd42gIxvuZZleNWpTucs7gjNxTs=", "dev": true, "requires": { - "gulp-util": "^3.0.0", - "lodash": "^4.8.2", - "through2": "^2.0.0" + "gulp-util": "3.0.8", + "lodash": "4.17.4", + "through2": "2.0.3" } }, "gulp-util": { @@ -10994,24 +10994,24 @@ "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", "dev": true, "requires": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" + "through2": "2.0.3", + "vinyl": "0.5.3" }, "dependencies": { "minimist": { @@ -11034,7 +11034,7 @@ "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "dev": true, "requires": { - "glogg": "^1.0.0" + "glogg": "1.0.0" } }, "handlebars": { @@ -11043,10 +11043,10 @@ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" }, "dependencies": { "source-map": { @@ -11055,7 +11055,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -11066,7 +11066,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "has-color": { @@ -11087,7 +11087,7 @@ "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", "dev": true, "requires": { - "sparkles": "^1.0.0" + "sparkles": "1.0.0" } }, "home-or-tmp": { @@ -11096,8 +11096,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "homedir-polyfill": { @@ -11106,7 +11106,7 @@ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", "dev": true, "requires": { - "parse-passwd": "^1.0.0" + "parse-passwd": "1.0.0" } }, "hosted-git-info": { @@ -11121,12 +11121,12 @@ "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", "dev": true, "requires": { - "domelementtype": "^1.3.0", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" + "domelementtype": "1.3.0", + "domhandler": "2.4.1", + "domutils": "1.6.2", + "entities": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.3" } }, "http-errors": { @@ -11135,8 +11135,8 @@ "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", "dev": true, "requires": { - "inherits": "~2.0.1", - "statuses": "1" + "inherits": "2.0.3", + "statuses": "1.3.1" } }, "iconv-lite": { @@ -11163,7 +11163,7 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "inflight": { @@ -11172,8 +11172,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -11194,8 +11194,8 @@ "integrity": "sha1-6QBeW7kCXMmpvo5ErYf4rViIyB0=", "dev": true, "requires": { - "moment": "^2.14.1", - "sanitize-html": "^1.13.0" + "moment": "2.18.1", + "sanitize-html": "1.14.1" } }, "inquirer": { @@ -11204,19 +11204,19 @@ "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", "dev": true, "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.1.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" } }, "interpret": { @@ -11231,7 +11231,7 @@ "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", "dev": true, "requires": { - "loose-envify": "^1.0.0" + "loose-envify": "1.3.1" } }, "is-absolute": { @@ -11240,8 +11240,8 @@ "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", "dev": true, "requires": { - "is-relative": "^0.2.1", - "is-windows": "^0.2.0" + "is-relative": "0.2.1", + "is-windows": "0.2.0" } }, "is-arrayish": { @@ -11257,7 +11257,7 @@ "dev": true, "optional": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "1.9.0" } }, "is-buffer": { @@ -11272,7 +11272,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "^1.0.0" + "builtin-modules": "1.1.1" } }, "is-dotfile": { @@ -11287,7 +11287,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "^2.0.0" + "is-primitive": "2.0.0" } }, "is-extendable": { @@ -11308,7 +11308,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-fullwidth-code-point": { @@ -11317,7 +11317,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-glob": { @@ -11326,7 +11326,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "is-my-json-valid": { @@ -11335,10 +11335,10 @@ "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", "dev": true, "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" } }, "is-number": { @@ -11347,7 +11347,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-path-cwd": { @@ -11362,7 +11362,7 @@ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", "dev": true, "requires": { - "is-path-inside": "^1.0.0" + "is-path-inside": "1.0.0" } }, "is-path-inside": { @@ -11371,7 +11371,7 @@ "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", "dev": true, "requires": { - "path-is-inside": "^1.0.1" + "path-is-inside": "1.0.2" } }, "is-plain-object": { @@ -11380,7 +11380,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -11421,7 +11421,7 @@ "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", "dev": true, "requires": { - "is-unc-path": "^0.1.1" + "is-unc-path": "0.1.2" } }, "is-resolvable": { @@ -11430,7 +11430,7 @@ "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", "dev": true, "requires": { - "tryit": "^1.0.1" + "tryit": "1.0.3" } }, "is-unc-path": { @@ -11439,7 +11439,7 @@ "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", "dev": true, "requires": { - "unc-path-regex": "^0.1.0" + "unc-path-regex": "0.1.2" } }, "is-utf8": { @@ -11481,15 +11481,15 @@ "integrity": "sha1-HekZlvSAsi3LGsqFECVbrhV0RG4=", "dev": true, "requires": { - "babel-core": "^6.1.4", - "escodegen": "^1.6.1", - "esprima": "^2.1.0", - "istanbul": "^0.4.0", - "mkdirp": "^0.5.0", - "nomnomnomnom": "^2.0.0", - "object-assign": "^4.0.1", - "source-map": "^0.5.0", - "which": "^1.0.9" + "babel-core": "6.25.0", + "escodegen": "1.9.0", + "esprima": "2.7.3", + "istanbul": "0.4.5", + "mkdirp": "0.5.1", + "nomnomnomnom": "2.0.1", + "object-assign": "4.1.1", + "source-map": "0.5.6", + "which": "1.2.14" }, "dependencies": { "esprima": { @@ -11506,20 +11506,20 @@ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.11", + "js-yaml": "3.9.0", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.2.14", + "wordwrap": "1.0.0" }, "dependencies": { "escodegen": { @@ -11528,11 +11528,11 @@ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", "dev": true, "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" } }, "esprima": { @@ -11553,11 +11553,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "resolve": { @@ -11573,7 +11573,7 @@ "dev": true, "optional": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } }, "supports-color": { @@ -11582,7 +11582,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "1.0.0" } } } @@ -11629,8 +11629,8 @@ "integrity": "sha512-0LoUNELX4S+iofCT8f4uEHIiRBR+c2AINyC8qRWfC6QNruLtxVZRJaPcu/xwMgFIgDxF25tGHaDjvxzJCNE9yw==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "1.0.9", + "esprima": "4.0.0" } }, "js2xmlparser": { @@ -11639,7 +11639,7 @@ "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=", "dev": true, "requires": { - "xmlcreate": "^1.0.1" + "xmlcreate": "1.0.2" } }, "jsbn": { @@ -11655,18 +11655,18 @@ "integrity": "sha512-K9mjBmCm2P62kqJ5UU6Zj7zZnJoLxZBzgLm2yVv98tqLHYSpIvxUkM+dGBua+yUsvOhXsAh232a/joE+86D4CQ==", "dev": true, "requires": { - "babylon": "~7.0.0-beta.16", - "bluebird": "~3.5.0", - "catharsis": "~0.8.9", - "escape-string-regexp": "~1.0.5", - "js2xmlparser": "~3.0.0", - "klaw": "~2.0.0", - "marked": "~0.3.6", - "mkdirp": "~0.5.1", - "requizzle": "~0.2.1", - "strip-json-comments": "~2.0.1", + "babylon": "7.0.0-beta.18", + "bluebird": "3.5.0", + "catharsis": "0.8.9", + "escape-string-regexp": "1.0.5", + "js2xmlparser": "3.0.0", + "klaw": "2.0.0", + "marked": "0.3.6", + "mkdirp": "0.5.1", + "requizzle": "0.2.1", + "strip-json-comments": "2.0.1", "taffydb": "2.6.2", - "underscore": "~1.8.3" + "underscore": "1.8.3" }, "dependencies": { "babylon": { @@ -11689,7 +11689,7 @@ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "dev": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json5": { @@ -11704,7 +11704,7 @@ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "jsonify": { @@ -11725,7 +11725,7 @@ "integrity": "sha1-euHT5klQ2+EfQht0BAqwj7WmbCE=", "dev": true, "requires": { - "babel-core": "^6.0.0" + "babel-core": "6.25.0" } }, "karma-chai": { @@ -11740,8 +11740,8 @@ "integrity": "sha1-TG1wDRY6nTTGGO/YeRi+SeekqMk=", "dev": true, "requires": { - "fs-access": "^1.0.0", - "which": "^1.2.1" + "fs-access": "1.0.1", + "which": "1.2.14" } }, "karma-commonjs": { @@ -11756,10 +11756,10 @@ "integrity": "sha1-sNWLECXVnVxmICYxhvHVj11TSMU=", "dev": true, "requires": { - "dateformat": "^1.0.6", - "istanbul": "^0.4.0", - "minimatch": "^3.0.0", - "source-map": "^0.5.1" + "dateformat": "1.0.12", + "istanbul": "0.4.5", + "minimatch": "3.0.4", + "source-map": "0.5.6" }, "dependencies": { "dateformat": { @@ -11768,8 +11768,8 @@ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } } } @@ -11792,7 +11792,7 @@ "integrity": "sha1-G/gee7SwiWJ6s1LsQXnhF8QGpUA=", "dev": true, "requires": { - "source-map-support": "^0.4.1" + "source-map-support": "0.4.15" } }, "kind-of": { @@ -11801,7 +11801,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.5" } }, "klaw": { @@ -11810,7 +11810,7 @@ "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=", "dev": true, "requires": { - "graceful-fs": "^4.1.9" + "graceful-fs": "4.1.11" } }, "lazy-cache": { @@ -11826,8 +11826,8 @@ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "1.1.2", + "type-check": "0.3.2" } }, "liftoff": { @@ -11836,15 +11836,15 @@ "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", "dev": true, "requires": { - "extend": "^3.0.0", - "findup-sync": "^0.4.2", - "fined": "^1.0.1", - "flagged-respawn": "^0.3.2", - "lodash.isplainobject": "^4.0.4", - "lodash.isstring": "^4.0.1", - "lodash.mapvalues": "^4.4.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" + "extend": "3.0.1", + "findup-sync": "0.4.3", + "fined": "1.1.0", + "flagged-respawn": "0.3.2", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.mapvalues": "4.6.0", + "rechoir": "0.6.2", + "resolve": "1.4.0" } }, "livereload-js": { @@ -11859,11 +11859,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" }, "dependencies": { "strip-bom": { @@ -11872,7 +11872,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } } } @@ -11943,7 +11943,7 @@ "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", "dev": true, "requires": { - "lodash._root": "^3.0.0" + "lodash._root": "3.0.1" } }, "lodash.isarguments": { @@ -11976,9 +11976,9 @@ "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "dev": true, "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" } }, "lodash.mapvalues": { @@ -11999,15 +11999,15 @@ "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", "dev": true, "requires": { - "lodash._basecopy": "^3.0.0", - "lodash._basetostring": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.restparam": "^3.0.0", - "lodash.templatesettings": "^3.0.0" + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" } }, "lodash.templatesettings": { @@ -12016,8 +12016,8 @@ "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", "dev": true, "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0" + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" } }, "lolex": { @@ -12038,7 +12038,7 @@ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { - "js-tokens": "^3.0.0" + "js-tokens": "3.0.2" } }, "loud-rejection": { @@ -12047,8 +12047,8 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" } }, "lru-cache": { @@ -12063,7 +12063,7 @@ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", "dev": true, "requires": { - "es5-ext": "~0.10.2" + "es5-ext": "0.10.24" } }, "map-cache": { @@ -12102,14 +12102,14 @@ "integrity": "sha1-G8PqHkvgVt1HXVIZede+PV5bIcg=", "dev": true, "requires": { - "d": "1", - "es5-ext": "^0.10.13", - "es6-weak-map": "^2.0.1", - "event-emitter": "^0.3.4", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "0.1" + "d": "1.0.0", + "es5-ext": "0.10.24", + "es6-weak-map": "2.0.2", + "event-emitter": "0.3.5", + "is-promise": "2.1.0", + "lru-queue": "0.1.0", + "next-tick": "1.0.0", + "timers-ext": "0.1.2" } }, "meow": { @@ -12118,16 +12118,16 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" }, "dependencies": { "minimist": { @@ -12154,9 +12154,9 @@ "resolved": "https://registry.npmjs.org/metal-ajax/-/metal-ajax-2.1.1.tgz", "integrity": "sha512-r61ku32uivdaBd3joWrTiGV2kyG9Nvpt4gq4Npo/9MDWj2Tcm4xk2PZ7iKpIAF88JD4dwW+etjgK5Il3SzC9+g==", "requires": { - "metal": "^2.0.0", - "metal-promise": "^2.0.0", - "metal-uri": "^2.0.0" + "metal": "2.16.5", + "metal-promise": "2.0.1", + "metal-uri": "2.2.6" } }, "metal-debounce": { @@ -12169,8 +12169,8 @@ "resolved": "https://registry.npmjs.org/metal-dom/-/metal-dom-2.16.5.tgz", "integrity": "sha512-PNAh5EBw0YN3fXd0Kvt1kWAOL0OAJDmgcXim1kDBaj0w5447Cztn+QxohbB3C6MRabqqO5Ozfm4OeBnZjXkslg==", "requires": { - "metal": "^2.16.5", - "metal-events": "^2.16.5" + "metal": "2.16.5", + "metal-events": "2.16.5" } }, "metal-events": { @@ -12178,7 +12178,7 @@ "resolved": "https://registry.npmjs.org/metal-events/-/metal-events-2.16.5.tgz", "integrity": "sha512-XW8s1NSwsdZyhhcAhjKkvixQCt1uyz9CY0eIdwurRXIEtp5dRjHLBCPHgE6raRwS4OBji2JVTzQ0Vpby6xYMrA==", "requires": { - "metal": "^2.16.5" + "metal": "2.16.5" } }, "metal-karma-config": { @@ -12187,20 +12187,20 @@ "integrity": "sha512-zeYWrQ9IIe+7J177qFs6eCFfD7WhK2chmdc/lkePrHWazahX+SgLir5VwX3cqx3SsOUuEhRYujhdc5hLcGVBXw==", "dev": true, "requires": { - "babel-plugin-transform-node-env-inline": "^0.1.1", - "babel-preset-metal": "^3.0.0", - "chai": "^2.3.0", - "isparta": "^4.0.0", - "karma-babel-preprocessor": "^6.0.1", - "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^0.2.0", - "karma-commonjs": "^1.0.0", - "karma-coverage": "^0.5.1", - "karma-mocha": "^0.2.0", - "karma-sinon": "^1.0.4", - "karma-source-map-support": "^1.2.0", - "mocha": "^2.2.5", - "sinon": "^1.17.7" + "babel-plugin-transform-node-env-inline": "0.1.1", + "babel-preset-metal": "3.1.0", + "chai": "2.3.0", + "isparta": "4.0.0", + "karma-babel-preprocessor": "6.0.1", + "karma-chai": "0.1.0", + "karma-chrome-launcher": "0.2.3", + "karma-commonjs": "1.0.0", + "karma-coverage": "0.5.5", + "karma-mocha": "0.2.2", + "karma-sinon": "1.0.5", + "karma-source-map-support": "1.2.0", + "mocha": "2.5.3", + "sinon": "1.17.7" }, "dependencies": { "babel-preset-metal": { @@ -12209,9 +12209,9 @@ "integrity": "sha1-55TKuzcQJ9YyNqDwTQLHKPkRcCU=", "dev": true, "requires": { - "babel-plugin-transform-es2015-classes": "^6.2.2", - "babel-preset-es2015": "^6.1.18", - "resolve": "^1.1.7" + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-preset-es2015": "6.24.1", + "resolve": "1.4.0" } } } @@ -12221,7 +12221,7 @@ "resolved": "https://registry.npmjs.org/metal-path-parser/-/metal-path-parser-1.0.3.tgz", "integrity": "sha1-PQisK1bfLTlxfJ1k0eo+4BfsQPc=", "requires": { - "metal": "^2.0.0" + "metal": "2.16.5" } }, "metal-promise": { @@ -12229,7 +12229,7 @@ "resolved": "https://registry.npmjs.org/metal-promise/-/metal-promise-2.0.1.tgz", "integrity": "sha1-KP9DIQ5MaeX/9R2/IB5K4v5vg9U=", "requires": { - "metal": "^2.0.0" + "metal": "2.16.5" } }, "metal-structs": { @@ -12237,7 +12237,7 @@ "resolved": "https://registry.npmjs.org/metal-structs/-/metal-structs-1.0.1.tgz", "integrity": "sha1-VIJy9xjunXKeMHm3Sj8SVBQ9t1s=", "requires": { - "metal": "^2.0.0" + "metal": "2.16.5" } }, "metal-tools-build-rollup": { @@ -12246,16 +12246,16 @@ "integrity": "sha1-Ax0zOIxMpCqpt4RKAZSxrs5s/5I=", "dev": true, "requires": { - "babel-preset-es2015-rollup": "^3.0.0", - "babel-runtime": "^6.20.0", - "gulp": "^3.9.1", - "gulp-sourcemaps": "^2.4.0", - "merge": "^1.2.0", - "rollup-plugin-babel": "^2.7.1", - "rollup-plugin-node-resolve": "^2.0.0", - "rollup-stream": "^1.18.0", - "vinyl-buffer": "^1.0.0", - "vinyl-source-stream": "^1.1.0" + "babel-preset-es2015-rollup": "3.0.0", + "babel-runtime": "6.25.0", + "gulp": "3.9.1", + "gulp-sourcemaps": "2.6.0", + "merge": "1.2.0", + "rollup-plugin-babel": "2.7.1", + "rollup-plugin-node-resolve": "2.1.1", + "rollup-stream": "1.23.1", + "vinyl-buffer": "1.0.0", + "vinyl-source-stream": "1.1.0" } }, "metal-uri": { @@ -12263,10 +12263,10 @@ "resolved": "https://registry.npmjs.org/metal-uri/-/metal-uri-2.2.6.tgz", "integrity": "sha512-j+hPueDxf5z5eVgtaIOEo1flwEIqNDhrrmiq5Wi3zZ0FEWlqC1g3ZC0I5sqHm1XV54PX0iSG23A66PfaxFg8fg==", "requires": { - "metal": "^2.0.0", - "metal-structs": "^1.0.0", + "metal": "2.16.5", + "metal-structs": "1.0.1", "path-browserify": "0.0.0", - "url": "^0.11.0" + "url": "0.11.0" } }, "metal-useragent": { @@ -12274,7 +12274,7 @@ "resolved": "https://registry.npmjs.org/metal-useragent/-/metal-useragent-3.0.0.tgz", "integrity": "sha512-jDHGjYhR/ZqPTT23IAg2NoHBQ2Lhb1E61QtBj0R/5WSqr+nQzZd1X1Lwc0tReOqZv3zeewXMmoxTNdUUjifHRA==", "requires": { - "metal": "^2.16.5" + "metal": "2.16.5" } }, "method-override": { @@ -12284,9 +12284,9 @@ "dev": true, "requires": { "debug": "2.6.8", - "methods": "~1.1.2", - "parseurl": "~1.3.1", - "vary": "~1.1.1" + "methods": "1.1.2", + "parseurl": "1.3.1", + "vary": "1.1.1" }, "dependencies": { "vary": { @@ -12309,19 +12309,19 @@ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.3" } }, "mime": { @@ -12342,7 +12342,7 @@ "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", "dev": true, "requires": { - "mime-db": "~1.29.0" + "mime-db": "1.29.0" } }, "minimatch": { @@ -12351,7 +12351,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.8" } }, "minimist": { @@ -12414,8 +12414,8 @@ "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", "dev": true, "requires": { - "inherits": "2", - "minimatch": "0.3" + "inherits": "2.0.3", + "minimatch": "0.3.0" } }, "minimatch": { @@ -12424,8 +12424,8 @@ "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", "dev": true, "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" + "lru-cache": "2.7.3", + "sigmund": "1.0.1" } }, "ms": { @@ -12454,11 +12454,11 @@ "integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=", "dev": true, "requires": { - "basic-auth": "~1.0.3", - "debug": "~2.2.0", - "depd": "~1.0.1", - "on-finished": "~2.3.0", - "on-headers": "~1.0.0" + "basic-auth": "1.0.4", + "debug": "2.2.0", + "depd": "1.0.1", + "on-finished": "2.3.0", + "on-headers": "1.0.1" }, "dependencies": { "debug": { @@ -12490,8 +12490,8 @@ "integrity": "sha1-Nd5oBNwZZD5SSfPT473GyM4wHT8=", "dev": true, "requires": { - "readable-stream": "~1.1.9", - "stream-counter": "~0.2.0" + "readable-stream": "1.1.14", + "stream-counter": "0.2.0" }, "dependencies": { "isarray": { @@ -12506,10 +12506,10 @@ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -12572,8 +12572,8 @@ "integrity": "sha1-siOfAxyNBNpn4yg24eMZnhL3qOI=", "dev": true, "requires": { - "chalk": "~0.4.0", - "underscore": "~1.6.0" + "chalk": "0.4.0", + "underscore": "1.6.0" }, "dependencies": { "ansi-styles": { @@ -12588,9 +12588,9 @@ "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", "dev": true, "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" } }, "strip-ansi": { @@ -12613,7 +12613,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1" + "abbrev": "1.0.9" } }, "normalize-package-data": { @@ -12622,10 +12622,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "4.3.6", + "validate-npm-package-license": "3.0.1" } }, "normalize-path": { @@ -12634,7 +12634,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "^1.0.1" + "remove-trailing-separator": "1.0.2" } }, "normalize-range": { @@ -12673,10 +12673,10 @@ "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "dev": true, "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" + "array-each": "1.0.1", + "array-slice": "1.0.0", + "for-own": "1.0.0", + "isobject": "3.0.1" }, "dependencies": { "for-own": { @@ -12685,7 +12685,7 @@ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { - "for-in": "^1.0.1" + "for-in": "1.0.2" } }, "isobject": { @@ -12702,8 +12702,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "for-own": "0.1.5", + "is-extendable": "0.1.1" } }, "object.pick": { @@ -12712,7 +12712,7 @@ "integrity": "sha1-tTkr7peC2m2ft9avr1OXefEjTCs=", "dev": true, "requires": { - "isobject": "^2.1.0" + "isobject": "2.1.0" } }, "on-finished": { @@ -12736,7 +12736,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "onetime": { @@ -12751,8 +12751,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "minimist": "0.0.8", + "wordwrap": "0.0.3" }, "dependencies": { "wordwrap": { @@ -12769,12 +12769,12 @@ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" } }, "orchestrator": { @@ -12783,9 +12783,9 @@ "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", "dev": true, "requires": { - "end-of-stream": "~0.1.5", - "sequencify": "~0.0.7", - "stream-consume": "~0.1.0" + "end-of-stream": "0.1.5", + "sequencify": "0.0.7", + "stream-consume": "0.1.0" } }, "ordered-read-streams": { @@ -12812,9 +12812,9 @@ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1" } }, "parse-filepath": { @@ -12823,9 +12823,9 @@ "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", "dev": true, "requires": { - "is-absolute": "^0.2.3", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" + "is-absolute": "0.2.6", + "map-cache": "0.2.2", + "path-root": "0.1.1" } }, "parse-glob": { @@ -12834,10 +12834,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" } }, "parse-json": { @@ -12846,7 +12846,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "parse-passwd": { @@ -12872,7 +12872,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } }, "path-is-absolute": { @@ -12899,7 +12899,7 @@ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "dev": true, "requires": { - "path-root-regex": "^0.1.0" + "path-root-regex": "0.1.2" } }, "path-root-regex": { @@ -12914,9 +12914,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "pause": { @@ -12931,7 +12931,7 @@ "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { - "through": "~2.3" + "through": "2.3.8" } }, "pify": { @@ -12952,7 +12952,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "^2.0.0" + "pinkie": "2.0.4" } }, "pluralize": { @@ -12973,10 +12973,10 @@ "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", "dev": true, "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" + "chalk": "1.1.3", + "js-base64": "2.1.9", + "source-map": "0.5.6", + "supports-color": "3.2.3" }, "dependencies": { "supports-color": { @@ -12985,7 +12985,7 @@ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "1.0.0" } } } @@ -13060,8 +13060,8 @@ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { "is-number": { @@ -13070,7 +13070,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -13079,7 +13079,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.5" } } } @@ -13090,7 +13090,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.5" } } } @@ -13132,9 +13132,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" } }, "read-pkg-up": { @@ -13143,8 +13143,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "1.1.2", + "read-pkg": "1.1.0" } }, "readable-stream": { @@ -13153,13 +13153,13 @@ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" } }, "readdirp": { @@ -13169,10 +13169,10 @@ "dev": true, "optional": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" } }, "readline2": { @@ -13181,8 +13181,8 @@ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", "mute-stream": "0.0.5" } }, @@ -13192,7 +13192,7 @@ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "resolve": "^1.1.6" + "resolve": "1.4.0" } }, "redent": { @@ -13201,8 +13201,8 @@ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "indent-string": "2.1.0", + "strip-indent": "1.0.1" } }, "regenerate": { @@ -13223,9 +13223,9 @@ "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", "dev": true, "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "babel-runtime": "6.25.0", + "babel-types": "6.25.0", + "private": "0.1.7" } }, "regex-cache": { @@ -13234,8 +13234,8 @@ "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", "dev": true, "requires": { - "is-equal-shallow": "^0.1.3", - "is-primitive": "^2.0.0" + "is-equal-shallow": "0.1.3", + "is-primitive": "2.0.0" } }, "regexp-quote": { @@ -13250,9 +13250,9 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "regenerate": "1.3.2", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" } }, "regjsgen": { @@ -13267,7 +13267,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "~0.5.0" + "jsesc": "0.5.0" }, "dependencies": { "jsesc": { @@ -13302,7 +13302,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "^1.0.0" + "is-finite": "1.0.2" } }, "replace-ext": { @@ -13323,8 +13323,8 @@ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "caller-path": "0.1.0", + "resolve-from": "1.0.1" } }, "requizzle": { @@ -13333,7 +13333,7 @@ "integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=", "dev": true, "requires": { - "underscore": "~1.6.0" + "underscore": "1.6.0" }, "dependencies": { "underscore": { @@ -13350,7 +13350,7 @@ "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "1.0.5" } }, "resolve-dir": { @@ -13359,8 +13359,8 @@ "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", "dev": true, "requires": { - "expand-tilde": "^1.2.2", - "global-modules": "^0.2.3" + "expand-tilde": "1.2.2", + "global-modules": "0.2.3" } }, "resolve-from": { @@ -13381,8 +13381,8 @@ "integrity": "sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=", "dev": true, "requires": { - "depd": "~1.1.0", - "on-headers": "~1.0.1" + "depd": "1.1.1", + "on-headers": "1.0.1" }, "dependencies": { "depd": { @@ -13399,8 +13399,8 @@ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "dev": true, "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "exit-hook": "1.1.1", + "onetime": "1.1.0" } }, "right-align": { @@ -13410,7 +13410,7 @@ "dev": true, "optional": true, "requires": { - "align-text": "^0.1.1" + "align-text": "0.1.4" } }, "rimraf": { @@ -13419,7 +13419,7 @@ "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "rndm": { @@ -13434,7 +13434,7 @@ "integrity": "sha1-MEj2SyOIuN2Okz+a1EPws4mrYI8=", "dev": true, "requires": { - "esprima": "^2.0" + "esprima": "2.7.3" }, "dependencies": { "esprima": { @@ -13451,7 +13451,7 @@ "integrity": "sha1-vUmxPb5hInWDdP/SR9inOeghSG8=", "dev": true, "requires": { - "rocambole-token": "^1.1.0" + "rocambole-token": "1.2.1" } }, "rocambole-node-update": { @@ -13460,7 +13460,7 @@ "integrity": "sha1-o//JaLDzvNnPKpM23A234lTIPFo=", "dev": true, "requires": { - "rocambole-token": "^1.2.1" + "rocambole-token": "1.2.1" } }, "rocambole-strip-alert": { @@ -13469,7 +13469,7 @@ "integrity": "sha1-OyVf5vGNYwH4BaFOVwsfHy26hX8=", "dev": true, "requires": { - "rocambole-node-update": "^1.0.1" + "rocambole-node-update": "1.0.1" } }, "rocambole-strip-console": { @@ -13478,7 +13478,7 @@ "integrity": "sha1-K5fj36bhnUUo6+galCMdyeiqygs=", "dev": true, "requires": { - "rocambole-node-update": "^1.0.0" + "rocambole-node-update": "1.0.1" } }, "rocambole-strip-debugger": { @@ -13487,7 +13487,7 @@ "integrity": "sha1-HFUCQgw9bvXiOnC4BUff0dS7y3Y=", "dev": true, "requires": { - "rocambole-node-remove": "^1.0.0" + "rocambole-node-remove": "1.0.0" } }, "rocambole-token": { @@ -13502,7 +13502,7 @@ "integrity": "sha512-2+bq5GQSrocdhr+M92mOQRmF1evtLRzv9NdmEC2wo7BILvTG8irHCtD0q+zg8ikNu63iJicdN5IzyxAXRTFKOQ==", "dev": true, "requires": { - "source-map-support": "^0.4.0" + "source-map-support": "0.4.15" } }, "rollup-plugin-babel": { @@ -13511,10 +13511,10 @@ "integrity": "sha1-FlKBl7D5OKFTb0RoPHqT1XMYL1c=", "dev": true, "requires": { - "babel-core": "6", - "babel-plugin-transform-es2015-classes": "^6.9.0", - "object-assign": "^4.1.0", - "rollup-pluginutils": "^1.5.0" + "babel-core": "6.25.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "object-assign": "4.1.1", + "rollup-pluginutils": "1.5.2" } }, "rollup-plugin-node-resolve": { @@ -13523,9 +13523,9 @@ "integrity": "sha1-y7eDsNFbAnlNWJFTULLw2QK43cg=", "dev": true, "requires": { - "browser-resolve": "^1.11.0", - "builtin-modules": "^1.1.0", - "resolve": "^1.1.6" + "browser-resolve": "1.11.2", + "builtin-modules": "1.1.1", + "resolve": "1.4.0" } }, "rollup-pluginutils": { @@ -13534,8 +13534,8 @@ "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=", "dev": true, "requires": { - "estree-walker": "^0.2.1", - "minimatch": "^3.0.2" + "estree-walker": "0.2.1", + "minimatch": "3.0.4" } }, "rollup-stream": { @@ -13544,7 +13544,7 @@ "integrity": "sha512-niUbTM3sqckz1FNebsSiN+koCR7RdgrRZ2HCcR4V2DT9PSs53tB4z1xzdTGxrX6bo3QT00R2sQA5n1jr/to69Q==", "dev": true, "requires": { - "rollup": "^0.45.1" + "rollup": "0.45.2" } }, "run-async": { @@ -13553,7 +13553,7 @@ "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", "dev": true, "requires": { - "once": "^1.3.0" + "once": "1.4.0" } }, "run-sequence": { @@ -13562,8 +13562,8 @@ "integrity": "sha1-UJWgvr6YczsBQL0I3YDsAw3azes=", "dev": true, "requires": { - "chalk": "*", - "gulp-util": "*" + "chalk": "1.1.3", + "gulp-util": "3.0.8" } }, "rx-lite": { @@ -13590,9 +13590,9 @@ "integrity": "sha1-cw/6Ikm98YMz7/5FsoYXPJxa0Lg=", "dev": true, "requires": { - "htmlparser2": "^3.9.0", + "htmlparser2": "3.9.2", "regexp-quote": "0.0.0", - "xtend": "^4.0.0" + "xtend": "4.0.1" } }, "semver": { @@ -13607,18 +13607,18 @@ "integrity": "sha1-dl52B8gFVFK7pvCwUllTUJhgNt4=", "dev": true, "requires": { - "debug": "~2.2.0", - "depd": "~1.1.0", - "destroy": "~1.0.4", - "escape-html": "~1.0.3", - "etag": "~1.7.0", + "debug": "2.2.0", + "depd": "1.1.1", + "destroy": "1.0.4", + "escape-html": "1.0.3", + "etag": "1.7.0", "fresh": "0.3.0", - "http-errors": "~1.3.1", + "http-errors": "1.3.1", "mime": "1.3.4", "ms": "0.7.1", - "on-finished": "~2.3.0", - "range-parser": "~1.0.3", - "statuses": "~1.2.1" + "on-finished": "2.3.0", + "range-parser": "1.0.3", + "statuses": "1.2.1" }, "dependencies": { "debug": { @@ -13662,10 +13662,10 @@ "integrity": "sha1-3UGeJo3gEqtysxnTN/IQUBP5OB8=", "dev": true, "requires": { - "etag": "~1.7.0", + "etag": "1.7.0", "fresh": "0.3.0", "ms": "0.7.2", - "parseurl": "~1.3.1" + "parseurl": "1.3.1" }, "dependencies": { "ms": { @@ -13682,13 +13682,13 @@ "integrity": "sha1-egV/xu4o3GP2RWbl+lexEahq7NI=", "dev": true, "requires": { - "accepts": "~1.2.13", + "accepts": "1.2.13", "batch": "0.5.3", - "debug": "~2.2.0", - "escape-html": "~1.0.3", - "http-errors": "~1.3.1", - "mime-types": "~2.1.9", - "parseurl": "~1.3.1" + "debug": "2.2.0", + "escape-html": "1.0.3", + "http-errors": "1.3.1", + "mime-types": "2.1.16", + "parseurl": "1.3.1" }, "dependencies": { "debug": { @@ -13714,8 +13714,8 @@ "integrity": "sha1-zlpuzTEB/tXsCYJ9rCKpwpv7BTU=", "dev": true, "requires": { - "escape-html": "~1.0.3", - "parseurl": "~1.3.1", + "escape-html": "1.0.3", + "parseurl": "1.3.1", "send": "0.13.2" } }, @@ -13732,9 +13732,9 @@ "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", "dev": true, "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "glob": "7.1.2", + "interpret": "1.0.3", + "rechoir": "0.6.2" } }, "sigmund": { @@ -13758,7 +13758,7 @@ "formatio": "1.1.1", "lolex": "1.3.2", "samsam": "1.1.2", - "util": ">=0.10.3 <1" + "util": "0.10.3" } }, "slash": { @@ -13785,10 +13785,10 @@ "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", "dev": true, "requires": { - "atob": "~1.1.0", - "resolve-url": "~0.2.1", - "source-map-url": "~0.3.0", - "urix": "~0.1.0" + "atob": "1.1.3", + "resolve-url": "0.2.1", + "source-map-url": "0.3.0", + "urix": "0.1.0" } }, "source-map-support": { @@ -13797,7 +13797,7 @@ "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", "dev": true, "requires": { - "source-map": "^0.5.6" + "source-map": "0.5.6" } }, "source-map-url": { @@ -13818,7 +13818,7 @@ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", "dev": true, "requires": { - "spdx-license-ids": "^1.0.2" + "spdx-license-ids": "1.2.2" } }, "spdx-expression-parse": { @@ -13839,7 +13839,7 @@ "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { - "through": "2" + "through": "2.3.8" } }, "sprintf-js": { @@ -13860,7 +13860,7 @@ "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { - "duplexer": "~0.1.1" + "duplexer": "0.1.1" } }, "stream-consume": { @@ -13875,7 +13875,7 @@ "integrity": "sha1-3tJmVWMZyLDiIoErnPOyb6fZR94=", "dev": true, "requires": { - "readable-stream": "~1.1.8" + "readable-stream": "1.1.14" }, "dependencies": { "isarray": { @@ -13890,10 +13890,10 @@ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -13910,9 +13910,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "string_decoder": { @@ -13921,7 +13921,7 @@ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } }, "strip-ansi": { @@ -13930,7 +13930,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-bom": { @@ -13939,8 +13939,8 @@ "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", "dev": true, "requires": { - "first-chunk-stream": "^1.0.0", - "is-utf8": "^0.2.0" + "first-chunk-stream": "1.0.0", + "is-utf8": "0.2.1" } }, "strip-bom-string": { @@ -13955,10 +13955,10 @@ "integrity": "sha1-aYJBmGdp3O9RPcbHymKbBryfIXs=", "dev": true, "requires": { - "rocambole": "^0.5.0", - "rocambole-strip-alert": "^1.0.0", - "rocambole-strip-console": "^1.0.0", - "rocambole-strip-debugger": "^1.0.0" + "rocambole": "0.5.1", + "rocambole-strip-alert": "1.0.0", + "rocambole-strip-console": "1.0.0", + "rocambole-strip-debugger": "1.0.0" } }, "strip-indent": { @@ -13967,7 +13967,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "^4.0.1" + "get-stdin": "4.0.1" } }, "strip-json-comments": { @@ -13988,12 +13988,12 @@ "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", "dev": true, "requires": { - "ajv": "^4.7.0", - "ajv-keywords": "^1.0.0", - "chalk": "^1.1.1", - "lodash": "^4.0.0", + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", "slice-ansi": "0.0.4", - "string-width": "^2.0.0" + "string-width": "2.1.1" }, "dependencies": { "ansi-regex": { @@ -14014,8 +14014,8 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" } }, "strip-ansi": { @@ -14024,7 +14024,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "3.0.0" } } } @@ -14053,8 +14053,8 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" + "readable-stream": "2.3.3", + "xtend": "4.0.1" } }, "tildify": { @@ -14063,7 +14063,7 @@ "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", "dev": true, "requires": { - "os-homedir": "^1.0.0" + "os-homedir": "1.0.2" } }, "time-stamp": { @@ -14078,8 +14078,8 @@ "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", "dev": true, "requires": { - "es5-ext": "~0.10.14", - "next-tick": "1" + "es5-ext": "0.10.24", + "next-tick": "1.0.0" } }, "tiny-lr": { @@ -14088,12 +14088,12 @@ "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", "dev": true, "requires": { - "body-parser": "~1.14.0", - "debug": "~2.2.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.2.0", - "parseurl": "~1.3.0", - "qs": "~5.1.0" + "body-parser": "1.14.2", + "debug": "2.2.0", + "faye-websocket": "0.10.0", + "livereload-js": "2.2.2", + "parseurl": "1.3.1", + "qs": "5.1.0" }, "dependencies": { "body-parser": { @@ -14103,15 +14103,15 @@ "dev": true, "requires": { "bytes": "2.2.0", - "content-type": "~1.0.1", - "debug": "~2.2.0", - "depd": "~1.1.0", - "http-errors": "~1.3.1", + "content-type": "1.0.2", + "debug": "2.2.0", + "depd": "1.1.1", + "http-errors": "1.3.1", "iconv-lite": "0.4.13", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "5.2.0", - "raw-body": "~2.1.5", - "type-is": "~1.6.10" + "raw-body": "2.1.7", + "type-is": "1.6.15" }, "dependencies": { "qs": { @@ -14169,7 +14169,7 @@ "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=", "dev": true, "requires": { - "os-tmpdir": "~1.0.1" + "os-tmpdir": "1.0.2" } }, "to-fast-properties": { @@ -14221,7 +14221,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "1.1.2" } }, "type-detect": { @@ -14237,7 +14237,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.15" + "mime-types": "2.1.16" } }, "typedarray": { @@ -14258,10 +14258,10 @@ "integrity": "sha1-wrDlpzOdeG3d03R7FT5/ZDPx/iA=", "dev": true, "requires": { - "babylon": "^6.0.0", - "commander": "^2.0.0", - "typhonjs-escomplex-module": "^0.0.12", - "typhonjs-escomplex-project": "^0.0.12" + "babylon": "6.17.4", + "commander": "2.11.0", + "typhonjs-escomplex-module": "0.0.12", + "typhonjs-escomplex-project": "0.0.12" } }, "typhonjs-escomplex-commons": { @@ -14276,11 +14276,11 @@ "integrity": "sha1-xZm7PeKzj/LYMmJa7iwgXxUxvmE=", "dev": true, "requires": { - "escomplex-plugin-metrics-module": "^0.0.13", - "escomplex-plugin-syntax-babylon": "^0.0.13", - "typhonjs-ast-walker": "^0.1.0", - "typhonjs-escomplex-commons": "^0.0.16", - "typhonjs-plugin-manager": "^0.0.3" + "escomplex-plugin-metrics-module": "0.0.13", + "escomplex-plugin-syntax-babylon": "0.0.13", + "typhonjs-ast-walker": "0.1.1", + "typhonjs-escomplex-commons": "0.0.16", + "typhonjs-plugin-manager": "0.0.3" } }, "typhonjs-escomplex-project": { @@ -14289,10 +14289,10 @@ "integrity": "sha1-EKHWvzJ/czOKG9eHFZ/GMka5x5g=", "dev": true, "requires": { - "escomplex-plugin-metrics-project": "^0.0.13", - "typhonjs-escomplex-commons": "^0.0.16", - "typhonjs-escomplex-module": "^0.0.12", - "typhonjs-plugin-manager": "^0.0.3" + "escomplex-plugin-metrics-project": "0.0.13", + "typhonjs-escomplex-commons": "0.0.16", + "typhonjs-escomplex-module": "0.0.12", + "typhonjs-plugin-manager": "0.0.3" } }, "typhonjs-plugin-manager": { @@ -14308,9 +14308,9 @@ "dev": true, "optional": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "source-map": "0.5.6", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" } }, "uglify-to-browserify": { @@ -14326,7 +14326,7 @@ "integrity": "sha1-Otbzg2jG1MjHXsF2I/t5qh0HHYE=", "dev": true, "requires": { - "random-bytes": "~1.0.0" + "random-bytes": "1.0.0" } }, "unc-path-regex": { @@ -14426,7 +14426,7 @@ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { - "user-home": "^1.1.1" + "user-home": "1.1.1" } }, "validate-npm-package-license": { @@ -14435,8 +14435,8 @@ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", "dev": true, "requires": { - "spdx-correct": "~1.0.0", - "spdx-expression-parse": "~1.0.0" + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" } }, "vary": { @@ -14457,8 +14457,8 @@ "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", "dev": true, "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", + "clone": "1.0.2", + "clone-stats": "0.0.1", "replace-ext": "0.0.1" } }, @@ -14468,8 +14468,8 @@ "integrity": "sha1-ygZ+oIQx1QdyKx3lCD9gJhbrwjQ=", "dev": true, "requires": { - "bl": "^0.9.1", - "through2": "^0.6.1" + "bl": "0.9.5", + "through2": "0.6.5" }, "dependencies": { "isarray": { @@ -14484,10 +14484,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -14502,8 +14502,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } } } @@ -14514,14 +14514,14 @@ "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", "dev": true, "requires": { - "defaults": "^1.0.0", - "glob-stream": "^3.1.5", - "glob-watcher": "^0.0.6", - "graceful-fs": "^3.0.0", - "mkdirp": "^0.5.0", - "strip-bom": "^1.0.0", - "through2": "^0.6.1", - "vinyl": "^0.4.0" + "defaults": "1.0.3", + "glob-stream": "3.1.18", + "glob-watcher": "0.0.6", + "graceful-fs": "3.0.11", + "mkdirp": "0.5.1", + "strip-bom": "1.0.0", + "through2": "0.6.5", + "vinyl": "0.4.6" }, "dependencies": { "clone": { @@ -14536,7 +14536,7 @@ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", "dev": true, "requires": { - "natives": "^1.1.0" + "natives": "1.1.0" } }, "isarray": { @@ -14551,10 +14551,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -14569,8 +14569,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } }, "vinyl": { @@ -14579,8 +14579,8 @@ "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", "dev": true, "requires": { - "clone": "^0.2.0", - "clone-stats": "^0.0.1" + "clone": "0.2.0", + "clone-stats": "0.0.1" } } } @@ -14591,8 +14591,8 @@ "integrity": "sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas=", "dev": true, "requires": { - "through2": "^0.6.1", - "vinyl": "^0.4.3" + "through2": "0.6.5", + "vinyl": "0.4.6" }, "dependencies": { "clone": { @@ -14613,10 +14613,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -14631,8 +14631,8 @@ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" + "readable-stream": "1.0.34", + "xtend": "4.0.1" } }, "vinyl": { @@ -14641,8 +14641,8 @@ "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", "dev": true, "requires": { - "clone": "^0.2.0", - "clone-stats": "^0.0.1" + "clone": "0.2.0", + "clone-stats": "0.0.1" } } } @@ -14653,7 +14653,7 @@ "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", "dev": true, "requires": { - "source-map": "^0.5.1" + "source-map": "0.5.6" } }, "websocket-driver": { @@ -14662,7 +14662,7 @@ "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", "dev": true, "requires": { - "websocket-extensions": ">=0.1.1" + "websocket-extensions": "0.1.1" } }, "websocket-extensions": { @@ -14677,7 +14677,7 @@ "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", "dev": true, "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "window-size": { @@ -14705,7 +14705,7 @@ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { - "mkdirp": "^0.5.1" + "mkdirp": "0.5.1" } }, "xmlcreate": { @@ -14727,9 +14727,9 @@ "dev": true, "optional": true, "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", "window-size": "0.1.0" } } diff --git a/package.json b/package.json index 68c0993..d7735e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "senna", - "version": "2.7.5", + "version": "2.7.6", "description": "A blazing-fast Single Page Application engine", "license": "BSD-3-Clause", "repository": "liferay/senna.js",